On Mon, Mar 21, 2016 at 4:16 PM, Yichao Yu <[email protected]> wrote:
> On Mon, Mar 21, 2016 at 4:11 PM,  <[email protected]> wrote:
>> I think I got that much down:
>>
>> function macroexpand(ex::Expr)
>>   if ex.head == :module
>>     Expr(:module, ex.args[1], ex.args[2], macroexpand(ex.args[3]))
>>   else
>>     macroexpand(ex)
>>   end
>> end
>
> Seems that this will infinitely recurse?
>
>>
>>
>> the issue is that now I want to resolve all imports and such in the module
>> so that when I expand it, I get properly qualified names for the macros.
>>
>> so if I had
>>
>> module M
>>
>> include("X.jl")
>> import X: @y, @z
>>
>> f(x) = X.@y(3)
>>
>> end
>>
>> It would still be able to find X.@y.
>> Evaluating the include/import myself would be kind of risky since someone
>> could clobber a module name in my global namespace (of the program that's
>> running to macroexpand this stuff).
>> Is there a way to sandbox it?

And as I said, you should eval into the new module, not the one your
own toplevel interpreter is running in.

>
> You are looking for a way to sandbox the whole julia runtime. I don't
> think it's currently possible. Also note that macroexpansion is also
> calling arbitrary code.
>
>>
>>
>> On Monday, March 21, 2016 at 1:00:01 PM UTC-7, Yichao Yu wrote:
>>>
>>> On Mon, Mar 21, 2016 at 3:57 PM,  <[email protected]> wrote:
>>> > So there's no way to macroexpand the module in the module scope itself?
>>> > I don't mind evaluating the module, but how do I then dump out the
>>> > macroexpanded version of it?
>>> >
>>> > If there's a way to "clear" global scope then it would also be possible
>>> > to
>>> > eval the module, expand in global scope, clean global scope,
>>> > rinse/repeat on
>>> > next module.
>>> > Is there a way to do that instead?
>>> >
>>>
>>> If you want to just repeat what the global interpreter is doing, you
>>> can parse the module, create the module yourself, then macroexpand,
>>> print and evaluate each statement.
>>>
>>> >
>>> > On Monday, March 21, 2016 at 11:55:47 AM UTC-7, Tim Holy wrote:
>>> >>
>>> >> Interesting. julia's `macroexpand` function doesn't seem to work for
>>> >> expressions inside a module:
>>> >>
>>> >> julia> macroexpand( :(module M @time(1+1) end))
>>> >> :(module M
>>> >>     eval(x) = begin  # none, line 1:
>>> >>             top(Core).eval(M,x)
>>> >>         end
>>> >>     eval(m,x) = begin  # none, line 1:
>>> >>             top(Core).eval(m,x)
>>> >>         end # none, line 1:
>>> >>     @time 1 + 1
>>> >>     end)
>>> >>
>>> >> which is the same thing you get back if you omit the `macroexpand`.
>>> >>
>>> >> Try commenting out the module declaration and see if you like it
>>> >> better.
>>> >>
>>> >> Best,
>>> >> --Tim
>>> >>
>>> >> On Monday, March 21, 2016 11:15:56 AM [email protected] wrote:
>>> >> > The MacroExpandJL package seems promising, but maybe I'm not able to
>>> >> > get
>>> >> > it
>>> >> > to work. After updating syntax to match julia 0.4,
>>> >> > MacroExpandJL.macroexpand_jl(STDOUT, :(module M function f(x) 1+@m(2)
>>> >> > end
>>> >> > end))
>>> >> > module M
>>> >> > begin  # line 1:
>>> >> >     function f(x) # line 1:
>>> >> >         1 + @m 2
>>> >> >     end
>>> >> > endend
>>> >> >
>>> >> > Notice how the @m 2 is still there. Also, why is everything wrapped
>>> >> > in
>>> >> > an
>>> >> > extra do block inside the module? Is this a printing issue, because
>>> >> > that
>>> >> > expression doesn't have one.
>>> >> >
>>> >> > How would I go about evaluating a module and it's macros, macro
>>> >> > expanding
>>> >> > the whole thing, and then dumping it out? @eval seems like, name
>>> >> > wise,
>>> >> > it
>>> >> > should do this but it doesn't.
>>> >> > Do you first eval() the module, then @eval the module? That didn't
>>> >> > work
>>> >> > for
>>> >> > me either.
>>> >> >
>>> >> > Predefining a macro and then trying to evaluate:
>>> >> > > macro m(x) 1 end
>>> >> > > @eval(:(module M function f(x) @m 2 end end))
>>> >> > :
>>> >> > :(module M
>>> >> >
>>> >> >     eval(x) = begin  # none, line 1:
>>> >> >             top(Core).eval(M,x)
>>> >> >         end
>>> >> >     eval(m,x) = begin  # none, line 1:
>>> >> >             top(Core).eval(m,x)
>>> >> >         end # none, line 1:
>>> >> >     function f(x) # none, line 1:
>>> >> >         @m 2
>>> >> >     end
>>> >> >     end)
>>> >> >
>>> >> > Also doesn't work.
>>> >> >
>>> >> > On Monday, March 21, 2016 at 7:54:59 AM UTC-7, Tim Holy wrote:
>>> >> > > On Monday, March 21, 2016 09:34:19 AM Stefan Karpinski wrote:
>>> >> > > > Tim, I'm assuming that module must assume that no macros are
>>> >> > > > defined
>>> >> > >
>>> >> > > *and*
>>> >> > >
>>> >> > > > then used within the module body. If that does occur, the only
>>> >> > > > way
>>> >> > > > to do
>>> >> > > > macro expansion correctly is to evaluate the module since the
>>> >> > > > module
>>> >> > > > definition can depend on arbitrary previously evaluated code.
>>> >> > >
>>> >> > > Probably true. I haven't played with it in a long time, but it's
>>> >> > > possible
>>> >> > > you
>>> >> > > could load the module (so the macros are defined) and then parse
>>> >> > > the
>>> >> > > file...but
>>> >> > > I can't remember if that works.
>>> >> > >
>>> >> > > Best,
>>> >> > > --Tim
>>> >> > >
>>> >> > > > On Sun, Mar 20, 2016 at 9:00 PM, Tim Holy <[email protected]
>>> >> > >
>>> >> > > <javascript:>> wrote:
>>> >> > > > > It probably needs updating, but
>>> >> > > > > https://github.com/timholy/MacroExpandJL.jl
>>> >> > > > > might help. It lets you macroexpand a whole source file.
>>> >> > > > >
>>> >> > > > > Best,
>>> >> > > > > --Tim
>>> >> > > > >
>>> >> > > > > On Sunday, March 20, 2016 08:53:49 PM Yichao Yu wrote:
>>> >> > > > > > On Sun, Mar 20, 2016 at 8:26 PM,  <[email protected]
>>> >> > > > > > <javascript:>>
>>> >> > >
>>> >> > > wrote:
>>> >> > > > > > > Hi all,
>>> >> > > > > > >
>>> >> > > > > > > I'd like to be able to load in a module, then macroexpand
>>> >> > > > > > > the
>>> >> > >
>>> >> > > whole
>>> >> > >
>>> >> > > > > thing,
>>> >> > > > >
>>> >> > > > > > > then print out the macroexpanded version.
>>> >> > > > > > >
>>> >> > > > > > > This should be a full, recursive macroexpand.
>>> >> > > > > > >
>>> >> > > > > > > I've noticed there is a function called macroexpand that
>>> >> > > > > > > normally
>>> >> > >
>>> >> > > does
>>> >> > >
>>> >> > > > > > > what
>>> >> > > > > > >
>>> >> > > > > > > i want:
>>> >> > > > > > >> macro m(x) 1 end
>>> >> > > > > > >
>>> >> > > > > > > ..
>>> >> > > > > > >
>>> >> > > > > > >> @m(2)
>>> >> > > > > > >
>>> >> > > > > > > 1
>>> >> > > > > > >
>>> >> > > > > > >> macroexpand(:(1 + @m(2)))
>>> >> > > > > > >>
>>> >> > > > > > > :(1 + 1)
>>> >> > > > > > >
>>> >> > > > > > > so that is fine and dandy, but inside a module this doesn't
>>> >> > > > > > > seem
>>> >> > >
>>> >> > > to
>>> >> > >
>>> >> > > > > work:
>>> >> > > > > > >> macroexpand(:(
>>> >> > > > > > >>
>>> >> > > > > > >        module M
>>> >> > > > > > >        macro m(x) 1 end
>>> >> > > > > > >        x = 1 + @m(2)
>>> >> > > > > > >        end
>>> >> > > > > > >        ))
>>> >> > > > > > > :
>>> >> > > > > > > :(module M
>>> >> > > > > > > :
>>> >> > > > > > >     eval(x) = begin  # none, line 2:
>>> >> > > > > > >             top(Core).eval(M,x)
>>> >> > > > > > >
>>> >> > > > > > >         end
>>> >> > > > > > >
>>> >> > > > > > >     eval(m,x) = begin  # none, line 2:
>>> >> > > > > > >             top(Core).eval(m,x)
>>> >> > > > > > >
>>> >> > > > > > >         end # none, line 3:
>>> >> > > > > > >     $(Expr(:macro, :(m(x)), quote  # none, line 3:
>>> >> > > > > > >     1
>>> >> > > > > > >
>>> >> > > > > > > end)) # none, line 4:
>>> >> > > > > > >     x = 1 + @m(2)
>>> >> > > > > > >     end)
>>> >> > > > > > >
>>> >> > > > > > > As you can see in the second to last line, @m(2) is not
>>> >> > > > > > > expanded,
>>> >> > >
>>> >> > > and
>>> >> > >
>>> >> > > > > I'm
>>> >> > > > >
>>> >> > > > > > > confused as to why that is.
>>> >> > > > > > >
>>> >> > > > > > > Ideally, this macroexpanding of a module would allow me to
>>> >> > > > > > > also
>>> >> > > > > > > resolve
>>> >> > > > > > > imports and includes properly, so I could just slurp up a
>>> >> > > > > > > file
>>> >> > > > > > > and
>>> >> > > > > > > dump
>>> >> > > > > > > out
>>> >> > > > > > > the macroexpanded version.
>>> >> > > > > >
>>> >> > > > > > TL;DR this is generally not possible without evaluating the
>>> >> > > > > > whole
>>> >> > > > > > module.
>>> >> > > > > >
>>> >> > > > > > Macros are executed at parse time and therefore resolved in
>>> >> > > > > > global
>>> >> > > > > > scope (since local scope doesn't even exist yet) or in
>>> >> > > > > > another
>>> >> > > > > > word
>>> >> > > > > > module scope.
>>> >> > > > > > Therefore when doing macro expansion in a new module, the
>>> >> > > > > > macros
>>> >> > >
>>> >> > > needs
>>> >> > >
>>> >> > > > > > to be resolved in the new module and since there's no way to
>>> >> > > > > > statically know what macros are available in a module you
>>> >> > > > > > can't
>>> >> > > > > > do
>>> >> > > > > > that without evaluating the module.
>>> >> > > > > >
>>> >> > > > > > > Thank you!
>>> >> > > > > > >
>>> >> > > > > > > Vishesh
>>> >>
>>> >

Reply via email to