On Thursday, May 8, 2014 12:47:03 PM UTC-4, Adam Smith wrote:
>
> ....
> Then I was able to develop a flexible macro that better supports the 
> standard syntax, and I think is rather elegant:
> # Flag a function argument of any type as optional by generating a Union.
> # If a default value is not defined, it assumes "nothing".
> # Usage:
> #   function(x::Int, @maybe y::MyType)
> #   function(x::Int, @maybe y::MyType=someval)
> macro maybe(argexpr)
>     default = nothing
>     if argexpr.head == :(=)
>         argexpr, default = argexpr.args
>         default = eval(default)
>     end
>     @assert argexpr.head == :(::)
>     name, ptype = argexpr.args
>     deftype = typeof(default)
>     Expr(:kw, :($name::Union($deftype, $ptype)), default)
> end
>

If you're going to eval the default expression, then you need to quote it 
in the Expr you return so it doesn't get evaluated again at run time. 
 Except for that, and the unfortunate need to throw in esc in a couple 
places to trick Julia into using the intended context for ptype and 
default, this looks great.

It would be much cleaner not to evaluate the default expression, just plug 
it into the returned Expr and let it get evaluated at run time.  But then 
instead of calling typeof, you would need to call into compile-time type 
inference to get the deftype.  I am too lazy to read through all the 
documentation to try to figure out if there is an API that 
exposes compile-time type inference.  But if people are going to write 
macros like this, there should be.

I recommend updating the gist after you have a good fix for that.

--Dave Moon

Reply via email to