>
> Is there a clear language spec for macros, or is it still evolving? I
> understand that relying on implementation to learn a language feature can
> be risky.
>

There is no formal spec that I am aware of. However, I don't remember any
substantive changes except for this one in 0.5-dev:

https://github.com/JuliaLang/julia/pull/14563


(which is fairly minor: macro-methods can now dispatch on number of
arguments IIUC)

There's one major proposal related to hygiene; no final decision on
whether/when it will be accepted:

https://github.com/JuliaLang/julia/pull/6910 (rebased in #10940)


When I call retMacro(), I get an error saying "Macro definition not allowed
> in local scope". What I tried to do in my earlier example (pre post) is to
> hide the macro definition in a string and then parse and evaluate it to get
> the same effect as the above function. Obviously the behaviour is
> different.
>

Your earlier example works because `eval` always operates at module-global
scope. Macro definitions, type declarations, and a handful of other things,
are only allowed at global scope.


> Does it mean every macro is its own type?
>

Yes (and further, on 0.5-dev all functions are internally represented as
types)


> Should it not be a predefined type like "macro" (just as there is type for
> functions)? If macros are "pre-processed away", then there can't be an
> independent existence for them?
>

Here's some more detail that will hopefully clarify. Macro invocations are
represented as :macrocall expressions:

julia> parse("@foo(1, 2)") |> dump
Expr
  head: Symbol macrocall
  args: Array{Any}((3,))
    1: Symbol @foo
    2: Int64 1
    3: Int64 2
  typ: Any


The first step of lowering is to walk the AST to find all :macrocall
expressions, call the corresponding macro-function -- exactly the function
returned by `eval(Symbol("@foo"))` -- with the appropriate arguments, and
paste the result expression into the AST. (see
http://docs.julialang.org/en/latest/devdocs/julia/ for some more details)

Finally, in 0.5-dev, if "returnMacro()" works as expected, then calling
> myMacro("1+1") should return 2 (and not the parsed structure), isn't it?
> The reason is does an additional evaluation?
>

No, `myMacro` is just a handle to the macro-function, exactly the same as
`myMacro(x) = parse(x)`. There is no evaluation of the return expression
when directly calling a macro-function.


As I had mentioned in my first post, these questions are based on my
> experience with Lisp and I am trying to digest the differences, if any.
>
> -Rangarajan
>
> On Tuesday, July 5, 2016 at 9:35:52 PM UTC+5:30, Isaiah wrote:
>
>> Anonymous functions are a bit incomplete / not-fully-integrated in 0.4,
>> and I think this falls out as a consequence.
>>
>> You can simulate the result you want with:
>>
>> julia> function returnMacro()
>>          eval(parse("""
>>          macro myMacro(anexpr)
>>            parse(anexpr)
>>          end
>>          """))
>>          eval(symbol("@myMacro"))
>>        end
>>
>> julia> mymacro = returnMacro()
>> (anonymous function)
>>
>> julia> mymacro("1+1")
>> :(1 + 1)
>>
>> However, there have been significant improvements to anonymous functions
>> in the nightly (0.5-dev), and the result is what you expect:
>>
>> julia> function returnMacro()
>>          eval(parse("""
>>          macro myMacro(anexpr)
>>            parse(anexpr)
>>          end
>>          """))
>>        end
>> returnMacro (generic function with 1 method)
>>
>> julia> mymacro = returnMacro()
>> @myMacro (macro with 1 method)
>>
>> julia> typeof(mymacro)
>> #@myMacro
>>
>> julia> mymacro("1+1")
>> :(1 + 1)
>>
>> That said, `mymacro` here is purely a function handle -- totally
>> identical to writing `mymacro(expr) = parse(expr)`. There is no special
>> behavior.
>>
>> (are you trying to do something specific?)
>>
>> On Tue, Jul 5, 2016 at 11:04 AM, Rangarajan Krishnamoorthy <
>> [email protected]> wrote:
>>
>>> Consider this function:
>>>
>>> function returnMacro()
>>>   eval(parse("""
>>>   macro myMacro(anexpr)
>>>     parse(anexpr)
>>>   end
>>>   """))
>>> end
>>>
>>> I assign the function's result to a variable:
>>> mymacro = returnMacro()
>>>
>>> Then, typeof(mymacro) returns "Void". Is this correct? Because macros
>>> are parse time entities, wouldn't it be better for "eval" to raise some
>>> sort of exception?
>>>
>>> -Rangarajan
>>>
>>
>>

Reply via email to