Hi,
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 “postwalk
/@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
That inner 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.
Any ideas?