I’m trying to wrap my head around macros and wanted to make (what I assumed is) a simple macro which you prefix to an expression in order to get the expression printed with its evaluated value.
Example Let us call the macro
@db. What I imagine is the following:
@db 2 + 2
2 + 2 = 4
f(a,b) = begin
@db a + b
a + b = 4
It seems to me that I need something along the following lines. But this version doesn’t work!
:(print($(string(ex)) * " = " * string(eval($ex))))
This does the correct thing in case #1, but fails in case #2.
Anyone who can help me provide a working example of a macro like this?
To get the value of
ex you need to escape it. You will probably find this blog post useful: Julia macros for beginners
eval in a macro. A macro shouldn’t actually evaluate any code — you just want to rewrite it — the macro happens before the code is compiled and run (so the variables don’t have values yet). i.e. you would write
val = $(esc(ex))
println("@db ", $(string(ex)), " = ", val)
julia> @db 3 + 4
@db 3 + 4 = 7
This way, writing
@db 3 + 4 is equivalent to writing
<somevar> = 3 + 4
println("@db ", "3 + 4", " = ", <somevar>)
where I’m writing
<somevar> because macro hygiene causes Julia to rename the
val variable to a unique identifier so that it doesn’t conflict with any of your variables. This is what macros do: they rewrite your code, they don’t execute it.
Note that you don’t want to declare
ex::Expr, since the argument to the macro could be e.g. a literal number instead of an expression node:
julia> @db 3
@db 3 = 3
This kind of macro, by the way, is an exception to my rule that you should generally avoid metaprogramming, because this is something that can really only be done using macros without copy-paste code. It’s so useful that, in fact, it’s built-in as the
@show macro as @johnmyleswhite pointed out.