I expected the following is equivalent to AssertionError("1 == 1")
. But I was thrown an error.
julia> AssertionError($(string(:(1 == 1))))
ERROR: unsupported or misplaced expression $
Why am I wrong? Thanks!
I expected the following is equivalent to AssertionError("1 == 1")
. But I was thrown an error.
julia> AssertionError($(string(:(1 == 1))))
ERROR: unsupported or misplaced expression $
Why am I wrong? Thanks!
AssertionError
takes a String argument (so not sure what is intention of $
interpolation)
Julia-0.6.0> AssertionError(string(:(1 == 1)))
AssertionError("1 == 1")
Thanks, @greg_plowman. In fact, I was trying to reproduce/mimick step by step part of the second line in the first example of the section “Building an advanced macro” on this page. The example is about the macro @assert
:
julia> macro assert(ex)
return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
end
@assert (macro with 1 method)
Still confused why a dollar sign is needed in the above example.
The dollar sign is used because the macro returns an Expr
. Dollar sign means expression interpolation, so it is used inside of a :(...)
quote block. Outside of a quote block, it is misplaced.
To make it more clear, In the example ex
is interpolated into the the return
expression of the macro
. In your use case, you are not interpolating any expression.
Thanks, @chakravala. I understand your explanation - $
is needed because the macro returns an Expr.
I also tried the following:
julia> ex = :(1 == 1)
:(1 == 1)
julia> ex1 = :(AssertionError($(string(ex))))
:(AssertionError("1 == 1"))
julia> eval(ex1)
AssertionError("1 == 1")
julia> ex2 = :(AssertionError(string(ex)))
:(AssertionError(string(ex)))
julia> eval(ex2)
AssertionError("1 == 1")
Since eval(ex1)
and eval(ex2)
are identical, can I remove the dollar sign in the macro above? Thanks!!
They are only identical because you defined ex
in the REPL, so evaluating them gives the same result. However, ex1
can always be evaluated even if ex
is not defined in your current scope, while ex2
could not be evaluated if you do not have ex
defined in your current scope. So whether you want to use the dollar sign depends on what context you need it for.
Also, what you posted is not a macro
, it is an Expr
.
Yes, I see. Thanks for the hints. In fact, I’m talking about this in the context of the macro example I posted above:
julia> macro assert(ex)
return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
end
@assert (macro with 1 method)
I can’t remove $ here, can I? Because? Thanks.
It wouldn’t work without the $
there because ex
is undefined when the macro evaluates its returned expression. The point of the $
is to insert or “splice” the expression ex
into the code that the macro evaluates.
Thanks! So, without $
, ex
will be expected to be a variable, which, of course, is undefined, right? With $
, Julia knows that ex
is a placeholder which will be interpolated/spliced at a later time? Am I right?
That is correct, the variable ex
is only defined within the macro itself, but is not defined in the evaluation scope of the macro. So you need to insert the value of ex
into the expression before it is evaluated, otherwise it will try to look for the value of ex
when it is evaluting.
Thank you so much for your help and the patience, buddy!!