That was very helpful. Thanks for your patience. -Rangarajan
On Wednesday, July 6, 2016 at 9:39:56 AM UTC+5:30, Isaiah wrote: > > 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 >>>> >>> >>> >
