Variable reference in a function created by a macro


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 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!

Please read Please read: make it easier to help you and provide a minimal working example with what you have tried and what you are trying to achieve.

1 Like

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

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

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

Currently unable to process expressions with ex.head=quote

According to the relevant passage of the docs, this is the one I feel should work.

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

It looks like parameters aren’t fully supported:

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

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

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

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):

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

The reason for this is that it doesn’t typecheck, @functions to be used in @constraints 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!

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.

1 Like