Thanks for these pieces of wizardry. I had a need for also adding a body to 
the module being created. Got it to work based on the code below; sharing 
if someone else needs more examples than in the ones Patrick linked to:

julia> function create_module(modname::Symbol)
         Expr(:toplevel, :(module ($modname) end))
       end
create_module (generic function with 1 method)

julia> add_module(modname::Symbol) = begin
         eval(Main, create_module(modname))
         eval(Main, modname)
       end
add_module (generic function with 1 method)

julia> vm1 = add_module(:MyModule1)
MyModule1

julia> typeof(MyModule1)
Module

julia> eval(MyModule1, quote
         function somefunc(); 1; end
       end)
somefunc (generic function with 1 method)

julia> eval(vm1, quote
         function someotherfunc(); 2; end
       end)
someotherfunc (generic function with 1 method)

julia> MyModule1.somefunc()
1

julia> MyModule1.someotherfunc()
2

julia> function add_module(modname::Symbol, body::Expr)
         mod = add_module(modname)
         eval(mod, body)
         mod
       end
add_module (generic function with 2 methods)

julia> varmod = add_module(:MyModule2, quote
         function somefunc(); 2; end
       end)
MyModule2

julia> MyModule2.somefunc()
2

julia> varmod.somefunc()
2

Cheers,

Robert Feldt

Den onsdagen den 29:e januari 2014 kl. 23:48:50 UTC+1 skrev Patrick O'Leary:
>
> Might need some super-secret trickery
>
> https://github.com/JuliaLang/julia/issues/5276
> https://github.com/JuliaLang/julia/issues/1639
>
> On Wednesday, January 29, 2014 4:28:26 PM UTC-6, Mauro wrote:
>>
>> Good catch! But a quote-block and :() should be equivalent, right?  Is 
>> this a bug? 
>>
>> The trouble is that my use-case, I have two lines of code and then the 
>> :()-trick doesn't work anymore because it get translated into a 
>> quote-block: 
>>
>> julia> eval(:(x=1; module MO end)) 
>> ERROR: invalid method definition: not a generic function 
>>
>> On Wed, 2014-01-29 at 21:08, [email protected] wrote: 
>> > The problem seems to have to do with it getting wrapped in a quote 
>> block. 
>> > 
>> > ~~~ 
>> > julia> quote module MO end end 
>> > quote  # none, line 1: 
>> >     $(Expr(:module, true, :MO, quote 
>> >         eval(x) = top(Core).eval(MO,x) 
>> >         eval(m,x) = top(Core).eval(m,x) 
>> >     end)) 
>> > end 
>> > 
>> > julia> :(module MO end) 
>> > :($(Expr(:module, true, :MO, quote 
>> >         eval(x) = top(Core).eval(MO,x) 
>> >         eval(m,x) = top(Core).eval(m,x) 
>> >     end))) 
>> > 
>> > julia> eval(quote module MO end end) 
>> > ERROR: invalid method definition: not a generic function 
>> > 
>> > julia> eval(:(module MO end)) 
>> > Warning: replacing module MO 
>> > ~~~ 
>> > 
>> > 
>> > On Wed, Jan 29, 2014 at 2:13 PM, Mauro <[email protected]> wrote: 
>> > 
>> >> As far as I can tell, below macro is the identity-macro and works for 
>> >> everything I tried but for module definitions.  Why?  In fact, I 
>> >> struggle to get a module definition working within a macro. 
>> >> 
>> >>     julia> macro id(ex) 
>> >>                :($(esc(ex))) 
>> >>            end 
>> >> 
>> >>     julia> @id x=5 
>> >>     5 
>> >>     julia> @id type MT end 
>> >> 
>> >>     julia> @id module MO end 
>> >>     ERROR: invalid method definition: not a generic function 
>> >> 
>> >> Second example: 
>> >> 
>> >>     macro typ(ex) # this works and produces type TY 
>> >>         :(esc(type TY end)) 
>> >>     end 
>> >> 
>> >>     macro mod(ex) # this doesn't 
>> >>         :(esc(module MO end)) 
>> >>     end 
>> >> 
>> >>     ERROR: syntax: malformed module expression 
>> >> 
>> >> Is there a way to define modules within macros? 
>> >> 
>>
>> -- 
>> Sent with my mu4e 
>>
>>

Reply via email to