Heres a short overview.
Note: I wrote this on my phone and haven’t been able to test it so there may be some bugs in the sample code.
quote or :( )
Use it for constructing blocks of code.
edit: added missing esc
macro shared_fields()
esc(quote
field1::Int
field2::Float64
end)
end
struct astruct
@shared_fields()
field3::Uint
end
struct bstruct
@shared_fields()
field3::String
end
$
Splices in code
macro double_input(fn, x)
quote
# If x is an expression with side effects like `print(b)`
# we don't want to do that twice so we assign it to `z` first.
z = $(x)
$(fn)(z, z)
end
end
@double_input div 3
# returns 1
esc
Use it for variables assigned to in macros that you want visible externally
macro setvar(x, y)
quote
$(esc(x)) = $(y)
end
end
Meta.quot
Allows you to splice in code without interpolating it.
macro print_code(x)
:(println($(Meta.quot(x))))
end
eval
Shouldn’t be used in macros or functions for the most part. It can be however useful to use at top level if you have a large number of similar functions to define.
struct MyType
x::Int64
end
for op in [:(+), :(-), :(*), :(/)]
@eval Base.$(op)(x::MyType, y::MyType) = MyType($(op)(x.x, y.x))
end
ERROR: syntax: field name "Main.field1" is not a symbol around REPL[2]:1
Stacktrace:
[1] top-level scope at REPL[2]:1
I was using eval for something similar, but it seems that if a macro could be used for that, it would be better. What is the best way to share fields between structs?
I just realized there was actually a mistake in that section of the documentation that I linked to so I edited my comment to use the 1.6-dev docs that have fixed the mistake. @lmiq , you may want to use the updated link so it makes more sense.
I think these contents are actually very useful for anyone who wants to understand the julia macros.
Don’t you guys think we should collect the resources at the end of the https://docs.julialang.org/en/v1/manual/metaprogramming/ ?
And by time someone will definitely group these information and provide some extension to the understanding of the topic?
I thought many times that we should have a “Julia by examples” docs, built from community experiences. To be sincere, I have read many times the docs as they are, for example this metaprogramming section, and I have a hard time understanding what those things are for. I am not a computer scientist, and most times I only get the idea of what the experts are trying to explain after seeing a few examples of the functions in different contexts. After I understand how things work, when I read the docs again, I find that they are most of the time perfectly written, but a dedicated docs only for examples would be a great addition. This is how we do for plots, isn’t it?
On the other hand, perhaps the search history of this same discourse is going to achieve that goal.
I think the manual, and particularly that section, would benefit a lot from more examples, practical tips, common use cases, pitfalls.
Incremental additions are great, but I hope one of these days someone knowledgeable about Julia’s metaprogramming will sit down and do a major rewrite. I used Common Lisp macros extensively for years, but I still think of Julia’s macros as a minefield.