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

Reply via email to