There’s a minor metaprogramming annoyance I’m working through, hoping someone can help me understand the best idiomatic Julia (“Julianic”?) way to do this.
I’m seeing a lot of redundant blocks coming from the MetaTools “
@capture” pattern. This generally happens when replacing one
:block element with several. For a silly example, suppose we wanted to rewrite every
v = foo(k) as
v = 3k v += 2
MacroTools makes this pretty easy:
using MacroTools: @capture, postwalk rewrite(expr) = postwalk(expr) do x if @capture(x, v_ = foo(k_)) @q begin $v = 3*$k $v += 2 end else x end end
Ok great, let’s try it out:
julia> myExpr = @q begin a = 0 b = foo(a) end quote a = 0 b = foo(a) end julia> rewrite(myExpr) quote a = 0 begin b = 3a b += 2 end end
begin block is redundant; the code is the exquivalent to
quote a = 0 b = 3a b += 2 end
There’s no harm in the inner block other than aesthetic, but it would still be nice to get rid of it.
MacroTools has an
unblock function, but this seem to only solve the simpler problem of a
block containing only a single sub-
block. More generally, it seems we could flatten any element of a block that is itself just a block.
This morning the “flattening” idea became a sort of side-quest - we ought to be able to just treat this an an iterator. But this seems to involve a lot lower-level code than I would have expected, especially compared to Python’s
yield keyword. I would think there’d be a similar approach here, or maybe some existing combinator I could build on.