I would like to propose a macro to be added to Julia to make the operations between elements of structures easier.
For example, let’s say you have a structure with lots of fields called
Then, you need to compute some variables that depends on the values inside this structure. I can do something like:
conf.a * exp( - (conf.b)^2 / (conf.c) )
However, wouldn’t it be nice if we can have a macro in Julia to do something like:
@instruct conf a*exp( -b^2/c )
and it automatically replace all variables to the ones in the struct
I know we have Parameters.jl, but this is something more simple.
What do you think?
The nice thing about macros is that there’s no particular reason they need to live in Julia itself–you can always just make your own package to define the macro and then anyone who wants it can use it.
That said, I’m not sure what you’re asking for is possible. Even in the example you gave, how would the macro know that
b are fields of
exp is not? The macro just sees them all as symbols. You’d have to also pass the set of symbols to be extracted, something like:
@instruct(conf, (a, b, c), a * exp(-b^2/c))
I actually have no idea how this can be done, just thought it should be nice
The macro can use the
fieldnames and if a symbol belong to it, then replace by
getfield. Is it possible?
The macro sees only the
:conf symbol. It doesn’t know it is referencing a
fieldnames would be called on a
symbol not on the instance of a
Hum, maybe a
@generated function would have access to the type, so you could conceivably operate on its
fieldnames(), yes. But which function should be generated? You’d have to make every function that wants to use this feature an
Or, you could just use
Parameters.jl and do:
@unpack a, b, c = conf
a * exp(-b ^2 / c)
which already works
what’s old is new again ! you want the semantics of the Pascal “with” statement.
conf = Configuration(1,2,3,4)
x = a * b + c * d
It seems like it should be very possible to define something like that.
After all, Pascal could do it…
Here’s a nice example of how the “with” statement works
I knew I have already used this!
At type construction of
Conf a macro
@with_Conf could be defined, similarly to the
@unpack_Conf macro which Parameters.jl defines. And then:
x = a * b + c * d
However, as with
@unpack_Conf there are pitfalls, say:
x = sin(pi*a)
And then years later you change the
Conf type to contain a field
pi and now above code does something else…
Someone may have mentioned this, but it may be worth checking out Parameters.jl. It doesn’t do exactly what you want, but it does similar things that save quite a bit of coding time.
I actually use Parameters.jl a lot! This is more simple.
The suggestion of @mauro3 is very good indeed, and I think Parameters.jl is a good place to put such feature if @mauro3 allows.
I will do my best and send you a PR
DataFramesMeta (and a few other packages) do something similar by using Symbols as markers, so it’d become something like:
@with(x, :a * exp(-:b ^2 / :c))
@with x begin
z = :a * exp(-:b ^2 / :c)