Thanks to all for the responses! Pierre, you have made me positively giddy.
Your response was enough to make Julia's metaprogramming finally "click"
for me, and now I realize how incredibly powerful it is. I was able to make
something even better than I'd hoped for.
Once I realized how easily you can just manipulate the AST, I made this
really simple version which I didn't particularly like:
# Usage:
# function(x::Int, @Optional(y, MyType))
macro Optional(name, ptype)
Expr(:kw, :($name::Union(Nothing, $ptype)), nothing)
end
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
This is exactly the type of thing I was hoping to be able to do with Julia;
I'm certainly going to try to make it my goto language over python now.
On Thursday, May 8, 2014 11:06:11 AM UTC-4, Pierre-Yves Gérardy wrote:
>
> On Friday, February 21, 2014 9:36:07 PM UTC+1, Joosep Pata wrote:
>
>> #2) def. value in expression, does not work
>> ex = :(x=1)
>> q = quote
>> function f2($ex)
>> x
>> end
>> end
>> println("does not work")
>> macroexpand(q)|>println
>> eval(q)
>> f2()|>println
>> ~~~
>>
>> 2) gives me
>> > ERROR: syntax: "x=1" is not a valid function argument name
>>
>
> It works if you define ex as :(f(x=1)).args[2]. While superficially
> identical, your expression is a :(=), while this one is a :kw.
>
> —Pierre-Yves
>