# Variable reference in a function created by a macro

**URL:** <https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722>\
**Category:** Optimization (Mathematical)\
**Tags:** macros, intervals\
**Created:** [July 24, 2019, 8:08am UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722 "2019-07-24T08:08:49Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![bocc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bocc/32/7546_2.png) [@bocc](https://discourse.julialang.org/u/bocc)\
**Post date:** [July 24, 2019, 8:08am UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/1 "2019-07-24T08:08:50Z")

</div>

Hello,

I am trying to use IntervalConstraintProgramming & associated packages to solve a geometric feasibility problem. In order to be able to use functions in constraints, the ICP package provides a [macro](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/blob/a726e5c211a145cb427b8c09daa65347fc24d209/src/functions.jl#L45) for function definitions.

For example, one such function looks like this (phi1 is going to be an interval):  
@function calc\_a3(phi1) = sqrt($a1^2 + $a2^2 - 2\*$a1\*$a2\*cos(phi1));

I can go further and embed those functions in each other (both phis are intervals here):  
@function calc\_l2\_phi2(phi1,phi2) = (  
a3 = calc\_a3(phi1);  
cos(phi2) \* a3  
)

Constraint creation with these functions works like this:  
@constraint $r - calc\_a3(phi1) \< 0

In Julia, you can refer to variables in functions from the scope the function was created in:  
r = 5  
get\_r() = r

I want to achieve something similar using the @function macro (I could probably work around it, but it would make my life easier), but I have no clue about how quoting, AST parsing, etc works in macros, so I have tried the following at random (hoping that a Shakespeare sonnet comes out):

@function get\_r() =  
$r, :(r ), :($r)

but none of these could be ‘flattened’.

Any help is appreciated!

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 24, 2019, 2:44pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/2 "2019-07-24T14:44:34Z")

</div>

Please read [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757) and provide a minimal working example with what you have tried and what you are trying to achieve.

---

<div class="post-metadata">

**Author:** ![bocc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bocc/32/7546_2.png) [@bocc](https://discourse.julialang.org/u/bocc)\
**Post date:** [July 24, 2019, 4:08pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/3 "2019-07-24T16:08:14Z")

</div>

Well, I cannot provide a working example, but I can provide a stripped down one:

```julia
using ValidatedNumerics
r = 5
@function f1() = r

```

Out of the things I could come up with, :($r) provided the most interesting error message:

```julia
Currently unable to process expressions with ex.head=quote

```

According to the relevant [passage](https://docs.julialang.org/en/v1/manual/metaprogramming/index.html#Interpolation-1) of the docs, this is the one I feel should work.

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 24, 2019, 4:53pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/4 "2019-07-24T16:53:10Z")

</div>

“Working” in the sense that it creates the same error message.

It looks like parameters aren’t fully supported:  
[https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/pull/142](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/pull/142)  
[https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/issues/140](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/issues/140)  
[https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/issues/113](https://github.com/JuliaIntervals/IntervalConstraintProgramming.jl/issues/113)

---

<div class="post-metadata">

**Author:** ![bocc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bocc/32/7546_2.png) [@bocc](https://discourse.julialang.org/u/bocc)\
**Post date:** [July 24, 2019, 6:08pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/5 "2019-07-24T18:08:13Z")

</div>

Yes, this seems to be the case. Thank you!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [July 25, 2019, 1:36am UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/6 "2019-07-25T01:36:09Z")

</div>

Can you state in a mathematical (rather than julia) language exactly which problem you are trying to solve?

---

<div class="post-metadata">

**Author:** ![bocc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bocc/32/7546_2.png) [@bocc](https://discourse.julialang.org/u/bocc)\
**Post date:** [July 25, 2019, 2:27pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/7 "2019-07-25T14:27:07Z")

</div>

Hello David,

unfortunately my background is corporate, so I’d rather not share the full story with the public, but I attempted to describe it in a private message to you.

In the meantime I found out (I am kind of goofy) that the `@function` macro works well, as evidenced by being able to say

```julia
using ValidatedNumerics
a1 = 3
a2 = 5
@function calc_a3(phi1) = sqrt($a1^2 + $a2^2 - 2*$a1*$a2*cos(phi1));

```

Here, there is no problem with referring to outside scalars (not as parameters, mind you, just as constants, like in a closure). I got an error when I tried to do something along the lines of this (as an intermediate step):

```julia
r = 5
@function get_r(phi1) = $r

```

The reason for this is that it doesn’t typecheck, `@function`s to be used in `@constraint`s must return intervals. The error message (`MethodError: no method matching iterate(::Expr)`) startled me a bit, and I ran to the forums immediately. Sorry for that!

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [July 25, 2019, 3:56pm UTC](https://discourse.julialang.org/t/variable-reference-in-a-function-created-by-a-macro/26722/8 "2019-07-25T15:56:31Z")

</div>

I’m glad you got it working. The support for parameters is _very_ flaky and seriously needs to be improved.

There is now a new interface via `ModelingToolkit.jl`. I hope that the docs for that will be available shortly.
