I think there is a basic criterion:
- macros should yield to functions whenever possible
I know it is necessary to have macros build expressions, e.g.
JuMP.@expression(m, sum(c[i]x[i] for i = 1:I))
since the last arg may be a highly complicated hand-written construct that needs to be parsed.
But I don’t think this applies to variables: I almost only need regular Array container for variables, so the desired return has the same shape as, say, rand()
or rand(3)
, rand(3, 4)
, rand(2, 3, 4)
…
corresponding to
@variable(model)
,
@variable(model, [1:3])
,
@variable(model, [1:3, 1:4])
,
@variable(model, [1:2, 1:3, 1:4])
…
Yes, I also think that register a name into the model
is not a must. Therefore I think the anonymous syntax above is fairly sufficient. So we may find that the only “demanding” part in @variable
is the container, whose utility is not very indispensable.
So the question is:
- Can I use a functional API, to achieve the identical effect and performance as a macro API?
Say, I have already defined a A::Matrix{Any}
with size(A) == (2, 3)
, e.g. via A = rand(2, 3)
. And I want to add a similar-shape decision variable. Following the existing fashion I’ll have to write
z = @variable(model, [1:2, 1:3], integer = true)
Note that the [1:2, 1:3]
part requires hand-written—not amenable to program manipulation (otherwise can anyone teach me how to?).
Now I wonder if there is an alternative so I can write
z = my_add_variable(model; size = (2, 3), integer = true)
or even simpler
z = my_add_variable(model; similar_array = A, integer = true)
instead? I think there is not any technical hurdles here, right? Since the lowered tasks of @variable
are still functions.