David and others: I created a new repo 
(https://github.com/tbreloff/ModuleSafety.jl) where I'm going to play 
around with some helper functions/macros to help with to safely use "using" 
and module-local methods.  If anyone wants to brainstorm on useful 
functionality or contribute, please feel free.

On Friday, May 1, 2015 at 1:40:19 PM UTC-4, David Gold wrote:
>
> Thank you both, Isaiah and Peter! I'm fairly new to programming and Julia, 
> and you've both helped along my understanding of Expr objects and macros a 
> great deal. I thought I'd share my results:
>
>                _
>    _       _ _(_)_     |  A fresh approach to technical computing
>   (_)     | (_) (_)    |  Documentation: http://docs.julialang.org
>    _ _   _| |_  __ _   |  Type "help()" for help.
>   | | | | | | |/ _` |  |
>   | | |_| | | | (_| |  |  Version 0.3.7 (2015-03-23 21:36 UTC)
>  _/ |\__'_|_|_|\__'_|  |  Official http://julialang.org/ release
> |__/                   |  x86_64-apple-darwin13.4.0
>
> julia> include("/Users/David/Local projects/metamerge.jl")
> makemethod (generic function with 1 method)
>
> julia> module A
>
>        export f
>        immutable Foo end
>        f(::Foo) = print("This is Foo.")
>
>        end
>
> julia> module B
>
>        export f
>        immutable Bar end
>        f(::Bar) = print("This is Bar.")
>
>        end
>
> julia> f(x::Int64)=x
> f (generic function with 1 method)
>
> julia> metamerge(A.f, A, B.f, B, f) 
> f (generic function with 3 methods)
>
> julia> methods(f)
> # 3 methods for generic function "f":
> f(x::Int64) at none:1
> f(x1::Foo)
> f(x1::Bar)
>
> julia> f(A.Foo())
> This is Foo.
> julia> f(B.Bar())
> This is Bar.
> julia> f(1)
> 1
>
>
> I've included the code in this gist: 
> https://gist.github.com/davidagold/cb77a5d9ebb8fa17ee66 --- just in case 
> anybody is interested. Of course, this doesn't do anything about 
> conflicting methods, but that functionality shouldn't be hard to add now 
> that I've gotten the basics of reflection down.
>
> Thanks again!
> David
>  
>
> On Thursday, April 30, 2015 at 6:07:28 PM UTC-4, Peter Brady wrote:
>>
>> Looks like I deleted my post.
>>
>> If you can include the function name in the macro argument list this 
>> should work
>>
>> julia> macro repper(fname, args...)
>>            ex = Expr(:call, fname)
>>            for (i, arg) in enumerate(args)
>>                push!(ex.args, Expr(:(::), symbol("x$i"), arg))
>>            end
>>        ex
>>        end
>>
>> julia> (@repper h Int64 Int64) = x1+x2
>> h (generic function with 1 method)
>>
>> julia> h(1, 2)
>> 3
>>
>> julia> h(1, 4)
>> 5
>>
>>
>>
>>
>> On Thursday, April 30, 2015 at 3:19:38 PM UTC-6, David Gold wrote:
>>>
>>> I'm working (in 3.7) on a function that takes two functions f and g as 
>>> inputs, merges all non-conflicting methods of f and g into one function h, 
>>> and returns h. I'm trying to use macros to generate the signatures of each 
>>> method for h:
>>>
>>> macro argsgen(typle, n::Int64)
>>>     y = eval(:($typle))
>>>     xn = symbol("x$n")
>>>     return :( $xn :: $(y[n]) )
>>> end
>>>
>>> macro repper(typle, n::Int64)
>>>     ex = "@argsgen($typle, 1)"
>>>     for i in 2:n
>>>         ex = string(ex, ", @argsgen($typle, $n)")
>>>     end
>>>
>>>     return parse(ex)
>>> end
>>>
>>> So, if f has a method with signature (x::Int64), then I can feed the 
>>> 1-tuple '(Int64,)' to @argsgen, which generates the proper signature: 
>>>
>>> julia> ex1 = macroexpand( :(@argsgen((Int64,), 1) ))
>>> :(x1::Int64)
>>>
>>> and I can thereby define a method for h:
>>>
>>>
>>> julia> h(@argsgen((Int64,), 1)) = x1 + 1
>>> foobar (generic function with 1 method)
>>>
>>> julia> h(1)
>>> 2
>>>
>>> The problem is when I try to do this for a signature of more than one 
>>> argument, say (Int64, Int64). Above I've tried implementing a macro that 
>>> generates an expression of repeated '@argsgen' calls with the appropriate 
>>> second argument:
>>>
>>> ex = macroexpand( :( @repper (Int64, Int64) 2 ) )
>>> :((x1::Int64,x2::Int64))
>>>
>>> which doesn't quite work when I attempt to use it for a signature:
>>>
>>> julia> h(@repper (Int64, Int64) 2) = x1 + x2
>>> ERROR: syntax: "(x1::Int64,x2::Int64)" is not a valid function argument 
>>> name
>>>
>>> How can I get @repper to return an expression that isn't a tuple, but 
>>> also has two @argsgen calls separated by a comma? I've tried a couple of 
>>> other ways of doing this, but each expression wants to be returned as a 
>>> tuple. And I can't find out how to make the tuple splat in such a way that 
>>> works as a signature for h. Any thoughts? (Also, I imagine the tupocalypse 
>>> will break this, but I can deal with that later.) 
>>>
>>> Thank you all!
>>> David
>>>
>>

Reply via email to