Long ago I began a project to add exercises (with answers) to the documentation. We needed better web infrastructure (and more/better problems) to make that practical, so that was abandoned. But for metaprogramming I can imagine that a few exercises might help it click.
--Tim On Thursday, May 08, 2014 10:11:34 AM Adam Smith wrote: > I could see the potential for others to want to use this, so I made a gist > for it: > https://gist.github.com/sunetos/0714ae73647160d76aae > > As an aside, I'm really not sure why I didn't understand macros better > until Pierre's comment; I had read the metaprogramming > docs<http://julia.readthedocs.org/en/latest/manual/metaprogramming/> > multiple times. I'm only mentioning it now because I wanted to offer a > suggestion for improving the docs, but now that I re-read that page, the > docs seem quite thorough, so I'm just going to chalk it up to my being in a > daze or something. > > On Thursday, May 8, 2014 12:47:03 PM UTC-4, Adam Smith wrote: > > 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
