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


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?


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] <javascript:>> 
> 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