With struct do

If you’re willing to explicitly mark which symbols should be treated as fields, then this is easier to implement. Here’s a macro which will replace all expressions of the form &a with container.a:

julia> using MacroTools: postwalk

julia> macro with(container, expr)
         esc(postwalk(expr) do ex
           if @capture(ex, &field_)
             :(($container).$field)
           else
             ex
           end
         end)
       end
@with (macro with 1 method)

Usage:

julia> mutable struct Bar
           field1
           field2
           field3
       end

julia> b = Bar(1, 2, 0)
Bar(1, 2, 0)

julia> @with b begin
         &field3 = &field1 + &field2
       end
3

julia> b
Bar(1, 2, 3)

This implementation doesn’t have any problem with local variables which happen to match the names of fields, since the user is responsible (by adding &) for explicitly marking which symbols should be treated as fields:

julia> field1 = π
π = 3.1415926535897...

julia> @with b begin
         # The left-hand side is unambiguously `b.field1` 
         # and the right-hand side is unambiguously
         # the local variable `field1`.
         &field1 = field1
       end
π = 3.1415926535897...

julia> b
Bar(π, 2, 3)
6 Likes