as a tech demo project (prior to precompilation being on master), I created a package around this idea (but with the output going to a file instead of the screen) with handling for some bonus concepts, like recursing through submodule definitions, tracking file/line number information, and overriding the `Base.include` definition to make it work across files (assuming the author was not being hostile to the code injection). The primary line of interest is probably: https://github.com/vtjnash/Speed.jl/blob/e3712b9cb40aeb0af0fa2af025f58d673b14e7a9/src/Speed.jl#L149
developing Yichao's code into a similar package seems like a great debugging tool for incorporating into the REPL or an idea like Juno On Tuesday, March 22, 2016 at 10:04:47 PM UTC-4, [email protected] wrote: > > Ah, thank you! I didn't know you could do things like instantiate a module > that way. > > On Monday, March 21, 2016 at 3:21:45 PM UTC-7, Yichao Yu wrote: >> >> On Mon, Mar 21, 2016 at 5:54 PM, <[email protected]> wrote: >> > Oops, maybe name it differently >> > >> > function expand(ex::Expr) >> > if ex.head == :module >> > Expr(:module, ex.args[1], ex.args[2], macroexpand(ex.args[3])) >> > else >> > macroexpand(ex) >> > end >> > end >> > >> >> FYI, expand is another base function. >> >> > >> > So if someone were to give me: >> > >> > >> > module M >> > >> > include("X.jl") >> > import X: @y, @z >> > >> > f(x) = X.@y(3) >> > >> > end >> > >> > I would then... >> > >> > eval(:(module M >> > include("X.jl") >> > import X: @y, @z >> > >> > f(x) = X.@y(3) >> > >> > end) >> > >> > expand(:(module M ... end)) >> > >> > ? >> > Sorry, not sure how this contextual evaluating/expanding would look >> like. >> > It's not clear to me how evaluating the module M will make relevant >> > definitions accessible to the expand function, since that ignores the >> fact >> > that I'm inside module M when expanding each form. >> > >> >> As I said, you need to manually go through each of the statement in >> the module, macro expand and evaluate them. >> Try this: >> >> ``` >> julia> function expand_module(ex::Expr) >> @assert ex.head === :module >> std_imports = ex.args[1]::Bool >> name = ex.args[2]::Symbol >> body = ex.args[3]::Expr >> mod = Module(name, std_imports) >> newbody = quote end >> modex = Expr(:module, std_imports, name, newbody) >> for subex in body.args >> expandf = ()->macroexpand(subex) >> subex = eval(mod, :($expandf())) >> push!(newbody.args, subex) >> eval(mod, subex) >> end >> modex, mod >> end >> expand_module (generic function with 1 method) >> >> julia> expand_module(:(module A >> macro X() >> 1 >> end >> b = 1 + @X >> @show b >> end)) >> b = 2 >> (:(module A >> eval(x) = begin # none, line 1: >> top(Core).eval(A,x) >> end >> eval(m,x) = begin # none, line 1: >> top(Core).eval(m,x) >> end # none, line 2: >> $(Expr(:macro, :(X()), quote # none, line 3: >> 1 >> end)) # none, line 5: >> b = 1 + 1 # none, line 6: >> begin >> Base.println("b = ",Base.repr(begin # show.jl, line 166: >> #2#value = b >> end)) >> #2#value >> end >> end),A) >> ``` >> >> > >> > >> >
