No worries; if you are missing S-expressions too much, you might enjoy
playing with https://github.com/swadey/LispSyntax.jl

On Wed, Jul 6, 2016 at 12:41 AM, Rangarajan Krishnamoorthy <
[email protected]> wrote:

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

Reply via email to