Many thanks, your message has clarified me many doubts!
But - sorry for my difficulty about these items - I cannot found a way
to obtain desired result in a more articulated scenario.
I would pass an expression into a macro to another one, manipulating it
as expression in nested macro. Eg:
z = 5
b = [(z-3)*2 , 3*z , 5-2*z , 7*z+15]
macro tst2(a2)
println("tst2#1: ",a2)
:(println("tst2#2: ",$(esc(a2))))
end
macro tst1(a1)
quote
println("tst1#1: ",$(esc(a1))[1])
@tst2 $(esc(a1))[1]
end
end
@tst1 b
that returns:
tst2#1: b[1]
tst1#1: 4
tst2#2: 4
but I would have as output:
tst2: (z-3)*2
How can I do it?
Thanks in advance
Leonardo
Il 28/09/2015 13:43, Yichao Yu ha scritto:
On Mon, Sep 28, 2015 at 2:45 AM, Tomas Lycken <[email protected]> wrote:
What is correct form in this case?
The exact same problem again: you need to quote the returned expression from
the macro, to make sure that the code is run when the macro is called, and
not when it’s defined.
This will work as intended:
macro tst(i::Int)
quote
tst3(i)
end
end
# or
macro tst(i::Int)
:(tst3(i))
end
This won't work either. When you have
The argument to the macro is always the expression and not the value
of it (because for local scope, the macro is executed at compile time
and the symbols doesn't have a value yet). So for `@tst b`, the
argument for `@tst` is always `:b` and `i::Int` won't accept it.
```
macro tst(i)
:(tst3(i))
end
```
Also, as a general note, almost all the `::Int` in your code below are
unnecessary.
function tst3(i::Int)
This one is fine if you want to define other methods for `tst3` or if
you want to make sure only `Int` can be accepted.
macro tst(i::Int)
This is bad as mentioned above unless you only want to accept integer
literals i.e. `@tst 2`
Also note that macros cannot be extended. If you want to call
different methods depending on the type of the argument to the macro,
use a helper function. (i.e. `macro tst(i) tst_function(i) end;
tst_function(i::TypeA) = ...; tst_function(i::TypeB) = ...;`). Still
keep in mind that the arguments will be the expression and not the
value.
julia> b = 2::Int
The `:Int` in this one is useless. The type of a literal is already as
concrete as it could be and adding type assertion on it only add
useless code.
This section of the manual might be worth reading (again) :)
// T
On Monday, September 28, 2015 at 7:20:03 AM UTC+2, Leonardo wrote:
Many thanks!
I have a similar problem calling a function in following scenario:
function tst3(i::Int)
println(i)
end
macro tst(i::Int)
tst3(i)
end
I obtain an error executing code:
julia> b = 2::Int
julia> @tst b
complaining for a problem of type, because tst3 seems to receive a Symbol
instead an Integer:
ERROR: TypeError: anonymous: in typeassert, expected Int64, got Symbol
What is correct form in this case?
Leonardo
Il 27/09/2015 18:58, Yichao Yu ha scritto:
On Sun, Sep 27, 2015 at 12:20 PM, Leonardo <[email protected]> wrote:
Hi all,
I need manipulate AST of an expression in a macro, and pass same
expression
in input to another macro, but I experience some problem.
I try to express my doubt with a simplified example:
macro tst2(e2::Expr)
println(e2.head)
end
macro tst(e1::Expr)
@tst2 esc(e1)
end
```
macro tst(e1::Expr)
quote
@tst2 $(esc(e1))
end
end
```
otherwise, `@tst2` will be run at `tst` definition time.
In previous code I want that call to @tst2 behave exact like call to @tst.
E.g. calling @tst2 in REPL I obtain:
julia> a = 2
julia> @tst2(a < 3)
comparison
but same call to @tst has no effect, and I cannot find an alternative
working form for @tst
Someone can help me to understand this odd behaviour of Julia's macro?
Many thanks in advance
Leonardo