# Is there a \`with\` operator or usage pattern?

**URL:** <https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [January 1, 2021, 1:05pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693 "2021-01-01T13:05:06Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![cce](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cce/32/460_2.png) [@cce](https://discourse.julialang.org/u/cce)\
**Post date:** [January 1, 2021, 1:05pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/1 "2021-01-01T13:05:06Z")

</div>

In Visual Basic, the `With` scope operator lets you work with the attributes of a given object without having to repeat the object’s name. Perhaps something like…

```julia
julia> subtotal = (price=12.99, shipping=3.99)
(price = 12.99, shipping = 3.99)

julia> with(subtotal) price+shipping; end
16.98

```

Basically, it’s something akin to NamedTuple’s `merge` only that it’d work with current lookup space and delegate lookup to a set of objects.

Something like this is helpful when working with database records, so you don’t have to repeat the structure(s) that you’re working with. I’m curious what the normal pattern for something like this might be in Julia; ideally one that could work in nested way.

Anyway, it probably doesn’t exist, or there’s probably someone who wrote a macro that does it. I’m just curious if there are any usage patterns, besides the obvious one – use short variable names.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 1, 2021, 1:15pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/2 "2021-01-01T13:15:59Z")

</div>

Generally, a macro cannot do this without enumerating the fields since macros transform source ASTs and do not have type information.

I would recommend the excellent Parameters.jl for an idiomatic solution (`@unpack`), its README has a list of [related packages](https://github.com/mauro3/Parameters.jl#related-packages).

---

<div class="post-metadata">

**Author:** ![cce](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cce/32/460_2.png) [@cce](https://discourse.julialang.org/u/cce)\
**Post date:** [January 1, 2021, 1:17pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/3 "2021-01-01T13:17:35Z")

</div>

Thanks Tamas. This works…

```julia
julia> let price=12.99, shipping=3.99
          price + shipping
       end
16.98

```

So, perhaps it could be extended to work with splat?

```julia
julia> subtotal = (price=12.99, shipping=3.99)
julia> let subtotal...
          price + shipping
       end
ERROR: syntax: invalid let syntax around REPL[16]:1

```

---

<div class="post-metadata">

**Author:** ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)\
**Post date:** [January 1, 2021, 1:18pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/4 "2021-01-01T13:18:09Z")

</div>

Sounds like [https://github.com/joshday/PropertyUtils.jl](https://github.com/joshday/PropertyUtils.jl)!

```julia
julia> using PropertyUtils

julia> subtotal = (price=12.99, shipping=3.99)
(price = 12.99, shipping = 3.99)

julia> @with subtotal begin
           price+shipping
       end
16.98

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 1, 2021, 2:29pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/5 "2021-01-01T14:29:16Z")

</div>

Note that this solution uses `eval`, which breaks a lot of things that would otherwise work, eg type inference:

```julia
julia> using PropertyUtils

julia> function f(nt)
       @with nt a + b
       end
f (generic function with 1 method)

julia> @code_warntype f((a = 1, b = 2))
Variables
  #self#::Core.Const(f)
  nt::NamedTuple{(:a, :b), Tuple{Int64, Int64}}

Body::Any
1 ─ %1 = PropertyUtils.replace_props!::Core.Const(PropertyUtils.replace_props!)
│ %2 = $(Expr(:copyast, :($(QuoteNode(:(a + b))))))::Expr
│ %3 = (%1)(nt, %2)::Expr
│ %4 = Main.eval(%3)::Any
└── return %4

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 1, 2021, 3:25pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/6 "2021-01-01T15:25:32Z")

</div>

I am not sure what you mean here. Do you are saying that the macro has no way to difference between struct fields and other external (or new) bindings? Because it seems to me that a macro could do it by just creating `getfield` calls, if it could assume every reference to a binding is a reference to a field.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 1, 2021, 3:31pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/7 "2021-01-01T15:31:31Z")

</div>

The macro _per se_ has no way of knowing what `subtotal` is (a `struct`, a `NamedTuple`, etc).

Yes, it could walk the AST and replace all references to variables with `getproperty` (which the compiler will transform into `getfield` when applicable), with a clever fallback like `PropertyUtils.@with`. Then there is the issue of properties calculated on demand.

I am not saying that these could not be dealt with, but it is not as easy as doing the same in R, where “scope” if kind of a first-class object you can manipulate freely.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 1, 2021, 3:59pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/8 "2021-01-01T15:59:29Z")

</div>

> [@Tamas\_Papp](#):
>
> Then there is the issue of properties calculated on demand

What is the issue? AFAIK properties computed on demand are implemented by specializing `getproperty`, so it should be transparent to the macro if they are or not computed on demand.

> [@Tamas\_Papp](#):
>
> I am not saying that these could not be dealt with, but it is not as easy as doing the same in R, where “scope” if kind of a first-class object you can manipulate freely.

I have neither the knowledge to dispute this claim, nor any doubt it probably is correct, XD. I only wanted to point out that it is not impossible to assemble a solution with a Julia macro that does not interfere with the type inference (or, more generally, need not to invoke `eval`)

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 1, 2021, 4:43pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/9 "2021-01-01T16:43:52Z")

</div>

> [@Henrique\_Becker](#):
>
> What is the issue?

The user may not be aware that repeated uses of a property will involve repeated calculation on demand (since this could be an implementation detail of a given type). Cf `UnPack.@unpack`, for which this is not an issue — variables in the scope are assigned once, and that’s it.

> [@Henrique\_Becker](#):
>
> it is not impossible to assemble a solution with a Julia macro that does not interfere with the type inference

Possibly, I would not speculate. It is generally hard to establish that something is impossible, and I didn’t say it was.

However, I fully understand that people coming from other languages would miss `with` if they are used to it. I just don’t think this kind of macro meshes well with how Julia works. YMMV.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [January 1, 2021, 5:23pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/10 "2021-01-01T17:23:33Z")

</div>

> [@Tamas\_Papp](#):
>
> The user may not be aware that repeated uses of a property will involve repeated calculation on demand

Oh, I did not think about this. However, this seems to me to be the responsibility of the user, not of the macro. If the user is not aware of this, the macro does nothing special, the user could as well compute the field two times without using the macro. If the user is aware of this, the user will try to mention the field a single time in the `@with` scope, and this will correctly translate to the computation only happening a single time.

> [@Tamas\_Papp](#):
>
> I just don’t think this kind of macro meshes well with how Julia works.

I think it is worth pointing out that `DataframesMeta.jl` has a [`@with`](https://juliadata.github.io/DataFramesMeta.jl/stable/#@with) macro that works with dataframe objects (this is, instead of fields from `struct`s, or named tuples, it considers columns from dataframes). It is a little different, as instead od bindings it replaces `Symbol`s by columns, and have an escape (`^`) for using `Symbol` literals inside the block.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 1, 2021, 5:29pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/11 "2021-01-01T17:29:17Z")

</div>

If we could generate a function `f` as below, then you could just splat the `NamedTuple` into the keyword parameters of `f`

```julia
subtotal = (price=12.99, shipping=3.99)
f(; price, shipping) = price + shipping
f(; subtotal ...) # 16.98

```

I feel like I’m almost there:

```julia
julia> subtotal = (price=12.99, shipping=3.99)
(price = 12.99, shipping = 3.99)

julia> function genfunc(nt, body)
           local props = propertynames(nt)
               f = :( (; $(props...) )-> $body )
           g = Meta.eval(f)
           Base.invokelatest(g; nt...)
       end
genfunc (generic function with 1 method)

julia> genfunc(subtotal, quote
           shipping + price
       end)
16.98

```

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [January 1, 2021, 6:09pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/12 "2021-01-01T18:09:25Z")

</div>

I got it, and I think this addresses @Tamas_Papp’s type inference issues:

```julia
module WithMacro

export @with

macro with(nt,body)
    local b = QuoteNode(body)
    quote
        let f = genfunc($(esc(nt)), $b)
            f(; $(esc(nt))...)
        end
    end
end

function genfunc(nt, body)
    local props = propertynames(nt)
    f = :( (; $(props...) )-> $body )
    g = Meta.eval(f)
    # Base.invokelatest(g; nt...)
end

end

```

Usage:

```julia
julia> using .WithMacro

julia> subtotal = (price=12.99, shipping=3.99)
(price = 12.99, shipping = 3.99)

julia> @with subtotal begin
           price + shipping
       end
16.98

julia> person = (first="Mark", last="Kittisopikul")
(first = "Mark", last = "Kittisopikul")

julia> @with person begin
           "$first $last"
       end
"Mark Kittisopikul"

```

Analysis:

```julia
julia> f = WithMacro.genfunc(subtotal,quote
           price + shipping
       end)
#11 (generic function with 1 method)

julia> @code_warntype f(; subtotal...)
Variables
  #unused#::Core.Compiler.Const(Base.Meta.var"#11#13##kw"(), false)
  @_2::NamedTuple{(:price, :shipping),Tuple{Float64,Float64}}
  @_3::Core.Compiler.Const(Base.Meta.var"#11#13"(), false)
  price::Float64
  shipping::Float64
  @_6::Float64
  @_7::Float64

Body::Float64
1 ─ %1 = Base.haskey(@_2, :price)::Core.Compiler.Const(true, false)
│ %1
│ (@_6 = Base.getindex(@_2, :price))
└── goto #3
2 ─ Core.Compiler.Const(:(Core.UndefKeywordError(:price)), false)
└── Core.Compiler.Const(:(@_6 = Core.throw(%5)), false)
3 ┄ (price = @_6)
│ %8 = Base.haskey(@_2, :shipping)::Core.Compiler.Const(true, false)
│ %8
│ (@_7 = Base.getindex(@_2, :shipping))
└── goto #5
4 ─ Core.Compiler.Const(:(Core.UndefKeywordError(:shipping)), false)
└── Core.Compiler.Const(:(@_7 = Core.throw(%12)), false)
5 ┄ (shipping = @_7)
│ %15 = (:price, :shipping)::Core.Compiler.Const((:price, :shipping), false)
│ %16 = Core.apply_type(Core.NamedTuple, %15)::Core.Compiler.Const(NamedTuple{(:price, :shipping),T} where T<:Tuple, false)
│ %17 = Base.structdiff(@_2, %16)::Core.Compiler.Const(NamedTuple(), false)
│ %18 = Base.pairs(%17)::Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false)
│ %19 = Base.isempty(%18)::Core.Compiler.Const(true, false)
│ %19
└── goto #7
6 ─ Core.Compiler.Const(:(Base.kwerr(@_2, @_3)), false)
7 ┄ %23 = Base.Meta.:(var"#11#12")(price, shipping, @_3)::Float64
└── return %23

julia> f = WithMacro.genfunc(person,quote
           "$first $last"
       end)
#14 (generic function with 1 method)

julia> @code_warntype f(;person...)
Variables
  #unused#::Core.Compiler.Const(Base.Meta.var"#14#16##kw"(), false)
  @_2::NamedTuple{(:first, :last),Tuple{String,String}}
  @_3::Core.Compiler.Const(Base.Meta.var"#14#16"(), false)
  first::String
  last::String
  @_6::String
  @_7::String

Body::String
1 ─ %1 = Base.haskey(@_2, :first)::Core.Compiler.Const(true, false)
│ %1
│ (@_6 = Base.getindex(@_2, :first))
└── goto #3
2 ─ Core.Compiler.Const(:(Core.UndefKeywordError(:first)), false)
└── Core.Compiler.Const(:(@_6 = Core.throw(%5)), false)
3 ┄ (first = @_6)
│ %8 = Base.haskey(@_2, :last)::Core.Compiler.Const(true, false)
│ %8
│ (@_7 = Base.getindex(@_2, :last))
└── goto #5
4 ─ Core.Compiler.Const(:(Core.UndefKeywordError(:last)), false)
└── Core.Compiler.Const(:(@_7 = Core.throw(%12)), false)
5 ┄ (last = @_7)
│ %15 = (:first, :last)::Core.Compiler.Const((:first, :last), false)
│ %16 = Core.apply_type(Core.NamedTuple, %15)::Core.Compiler.Const(NamedTuple{(:first, :last),T} where T<:Tuple, false)
│ %17 = Base.structdiff(@_2, %16)::Core.Compiler.Const(NamedTuple(), false)
│ %18 = Base.pairs(%17)::Core.Compiler.Const(Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}(), false)
│ %19 = Base.isempty(%18)::Core.Compiler.Const(true, false)
│ %19
└── goto #7
6 ─ Core.Compiler.Const(:(Base.kwerr(@_2, @_3)), false)
7 ┄ %23 = Base.Meta.:(var"#14#15")(first, last, @_3)::String
└── return %23

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [January 1, 2021, 8:36pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/13 "2021-01-01T20:36:18Z")

</div>

Note that this doesn’t work at all within a function:

```julia
julia> function f(subtotal)
         @with subtotal begin
           price + shipping
         end
       end
f (generic function with 1 method)

julia> f(subtotal)
ERROR: MethodError: no method matching (::Base.Meta.var"#14#16")(; price=12.99, shipping=3.99)
Closest candidates are:
  #14(; price, shipping) at REPL[1]:16
Stacktrace:
 [1] macro expansion at ./REPL[1]:9 [inlined]
 [2] f(::NamedTuple{(:price, :shipping),Tuple{Float64,Float64}}) at ./REPL[8]:2
 [3] top-level scope at REPL[9]:1

```

and for the same reason it cannot be benchmarked with `@btime` from BenchmarkTools.

For a much simpler solution which works in local and global scope and imposes no performance penalty at all, see: [With struct do - #12 by rdeits](https://discourse.julialang.org/t/with-struct-do/41341/12)

For example:

```julia
julia> using MacroTools

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)

julia> subtotal = (price=12.99, shipping=3.99)
(price = 12.99, shipping = 3.99)

julia> @with subtotal begin
         &price + &shipping
       end
16.98

julia> function f(subtotal)
         @with subtotal begin
           &price + &shipping
         end
       end
f (generic function with 1 method)

julia> f(subtotal)
16.98

julia> using BenchmarkTools

julia> @btime f($subtotal)
  0.029 ns (0 allocations: 0 bytes)
16.98

```

Note that the suspiciously-fast benchmark time of \< 1ns means that the compiler has actually eliminated all of the code in the benchmark and just replaced it with the answer. That’s actually great news for us–it means that the revised `@with` macro doesn’t make the code any harder for the compiler to analyze and optimize.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [January 1, 2021, 8:37pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/14 "2021-01-01T20:37:44Z")

</div>

It’s also worth noting that you could simply write:

```julia
let s = subtotal
  s.price + s.shipping
end

```

which only requires two more characters but avoids needing any metaprogramming at all. Sometimes the simplest solution is the best 🙂

---

<div class="post-metadata">

**Author:** ![cce](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cce/32/460_2.png) [@cce](https://discourse.julialang.org/u/cce)\
**Post date:** [January 1, 2021, 9:14pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/15 "2021-01-01T21:14:44Z")

</div>

Yep. One could also use `subtotal.price + subtotal.shipping` for what it’s worth. This is a trivial example to ask the question. What I would hope from something like this is that it’d not limit the variables only to the tuple. Secondly, that it could be used in a nested way so that 3-part hierarchical data could be flattened. Third, that I don’t have to use prefixes when there’s no collisions in the field names. Sometimes using prefixes like this make sense, sometimes they get in the way. It depends on the context.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [January 1, 2021, 9:16pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/16 "2021-01-01T21:16:33Z")

</div>

A MWE of what you want to do would be useful.

---

<div class="post-metadata">

**Author:** ![cce](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cce/32/460_2.png) [@cce](https://discourse.julialang.org/u/cce)\
**Post date:** [January 1, 2021, 10:07pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/17 "2021-01-01T22:07:04Z")

</div>

Firstly, this was mostly just a question to learn more about Julia – my knowledge is really variable. It’s always interesting to learn more about how macros work, especially with regard to type stability when processing something in a hard loop.

So, my data source, has 3 levels. I’d like the last level of my operations to be written without having to know exactly where the field came from.

```julia
using Faker
orders = [(last_name=Faker.last_name(), region=rand(1:3),
           lines=[(amount=rand(10:20), size=rand(1:10),
                   product= Faker.sentence(number_words=6))
              for j in 1:3]) for i in 1:2]

discount = .10
for o in orders
  let region = o.region, last_name = o.last_name
    for l in o.lines
     let amount = l.amount, product = l.product, size = l.size
       println(last_name, " ", product, " ",   
               (amount * discount) + (region*size))
     end
    end
  end
end 

```

I was picturing something like… using `let` but letting the splat syntax pull variable names from a tuple into my current working namespace. This lets the fields in the data structure update where I only have to worry about changing the leaf nodes without updating the various levels of wrapping…

```julia
for order in orders
  let order...
    for line in lines
      let line...
        println(last_name, " ", product, " ",   
               (amount * discount) + (region*size))
      end
    end
  end
end 

```

Anyway. As I noted, I’m not struggling with this. There are plenty of work-arounds. This is a curiosity, since I’ll have to work with lots of situations like this, and writing the code as above seems redundant. I mean, Julia already knows what fields are in my tuple, why should I have to tell it again? Thanks!

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [January 1, 2021, 10:13pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/18 "2021-01-01T22:13:43Z")

</div>

[StaticModules.jl](https://github.com/MasonProtter/StaticModules.jl) has a performant `@with` macro as well.

Though `@unpack` I think is best since its the most explicit.

---

<div class="post-metadata">

**Author:** ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)\
**Post date:** [January 1, 2021, 10:45pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/19 "2021-01-01T22:45:11Z")

</div>

I admit, I also kind of like the VB `with` statement - mostly because it kind of shows the user that your are doing something “with” object `MyObjectWithAFairlyLongName`.

Taken from the Microsoft web site ([HERE](https://docs.microsoft.com/en-us/dotnet/visual-basic/language-reference/statements/with-end-with-statement)):

### VB `with` pattern

```vb
Private Sub AddCustomer()
    Dim theCustomer As New Customer

    With theCustomer
        .Name = "Coho Vineyard"
        .URL = "http://www.cohovineyard.com/"
        .City = "Redmond"
    End With

    With theCustomer.Comments
        .Add("First comment.")
        .Add("Second comment.")
    End With
End Sub

```

### Comparable (simple) Julia Pattern

Since, in Julia, you don’t allocate new memory with variables (you basically create a new reference), you can do something fairly similar without any special macros or anything:

```julia
function AddCustomer()
    theCustomer= Customer()

    c = theCustomer
        c.Name = "Coho Vineyard"
        c.URL = "http://www.cohovineyard.com/"
        c.City = "Redmond"
    #Done with c = theCustomer

    c = theCustomer.Comments
        add(c, "First comment.")
        add(c, "Second comment.")
    #Done with c = theCustomer.Comments
end #AddCustomer()

```

Note that:

- Assignments `c.field=X` are only possible with `mutable struct`-ures.
- If you perform `c=theCustomer` on an immutable `Customer` object (for read-only operations), Julia MIGHT perform a copy - but will probably just point to the original data - because it knows it cannot change.

### Conclusion

So I probably wouldn’t go to the lengths of using macros when you can just apply this simple pattern.

---

<div class="post-metadata">

**Author:** ![MA\_Laforge](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ma_laforge/32/385_2.png) [@MA\_Laforge](https://discourse.julialang.org/u/MA_Laforge)\
**Post date:** [January 1, 2021, 10:48pm UTC](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693/20 "2021-01-01T22:48:50Z")

</div>

> [@rdeits](#):
>
> It’s also worth noting that you could simply write:
> 
> ```julia
> let s = subtotal
> s.price + s.shipping
> end
> 
> ```

Did not notice @rdeits gave a similar answer as I just did. But his solution is even better because it also limits the scope of the new variable in the same way VB’s `with` statement does.

[Next page](https://discourse.julialang.org/t/is-there-a-with-operator-or-usage-pattern/52693.md?page=2)
