On Mon, Oct 5, 2015 at 2:54 PM, Leonardo <[email protected]> wrote:
> 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.

print, macroexpand, Meta.show_sexpr are your friends.

>
> I would pass an expression into a macro to another one, manipulating it as
> expression in nested macro. Eg:

I can kind of see what you might want but don't want to do too much
guessing so I'll just insert some printing that can hopefully help you
figure out what happens and what you can do (I'm not showing
`Meta.show_sexpr` but it's a more consistent way to print the ast and
can avoid ambiguity in some cases.)

>
> z = 5
> b = [(z-3)*2 , 3*z , 5-2*z , 7*z+15]

julia> println(b)
[4,15,-5,50]

julia> println([:((z-3)*2) , :(3*z) , :(5-2*z) , :(7*z+15)])
[:((z - 3) * 2),:(3z),:(5 - 2z),:(7z + 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

julia> c = [:((z-3)*2) , :(3*z) , :(5-2*z) , :(7*z+15)]
4-element Array{Expr,1}:
 :((z - 3) * 2)
 :(3z)
 :(5 - 2z)
 :(7z + 15)

julia> macroexpand(:(@tst1 b))
tst2#1: b[1]
quote  # none, line 3:
    println("tst1#1: ",b[1]) # none, line 4:
    println("tst2#2: ",b[1])
end

julia> macroexpand(:(@tst1 c))
tst2#1: c[1]
quote  # none, line 3:
    println("tst1#1: ",c[1]) # none, line 4:
    println("tst2#2: ",c[1])
end

julia> @tst1 b
tst2#1: b[1]
tst1#1: 4
tst2#2: 4

julia> @tst1 c
tst2#1: c[1]
tst1#1: (z - 3) * 2
tst2#2: (z - 3) * 2

>
> 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?

Note that passing expressions around is usually not a good idea (since
they have to be `eval`'d). You might be better off with anonymous
functions (depending on what you want to use them fore).

>
> 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
>>>>
>>>>
>

Reply via email to