# How to design with immutable and also mutable type?

**URL:** <https://discourse.julialang.org/t/how-to-design-with-immutable-and-also-mutable-type/34465>\
**Category:** General Usage\
**Created:** [February 11, 2020, 12:25pm UTC](https://discourse.julialang.org/t/how-to-design-with-immutable-and-also-mutable-type/34465 "2020-02-11T12:25:17Z")\
**Posts on this page:** 2\
**Page:** 2

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [February 12, 2020, 9:26am UTC](https://discourse.julialang.org/t/how-to-design-with-immutable-and-also-mutable-type/34465/21 "2020-02-12T09:26:26Z")

</div>

more help needed… I’m so bad in metaprogramming 😵 Suppose I wanna build a macro `@Δ` such that:

```julia
@Δ(f, obj, x)

```

expands to:

```julia
obj = f(obj, x)

```

in the “calling” scope, i.e. works fine in REPL or inside a function.

my initial attempt is:

```julia
julia> macro Δ(fun, obj, x)
           :($obj = $fun($obj, $x) )
       end
@Δ (macro with 1 method)

julia> @macroexpand @Δ(setdataΔ, v, [3, 4])
:(var"#4#v" = Main.setdataΔ(var"#4#v", [3, 4]))

```

now there’s a lot of `Main.`, meaning that this macro does not work inside a function… 😵

the second attempt use `esc`:

```julia
julia> macro ΔΔ(fun, obj, x)
           :($(esc(obj)) = $(esc(fun))($(esc(obj)), $(esc(x)) ) )
       end
@ΔΔ (macro with 1 method)

julia> @macroexpand @ΔΔ(setdataΔ, v, [3, 4])
:(v = setdataΔ(v, [3, 4]))

```

now, the `Main.` disappears… is it the correct implementation? does `@ΔΔ` works in all calling scope? thanks. 🙏

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 13, 2020, 6:11am UTC](https://discourse.julialang.org/t/how-to-design-with-immutable-and-also-mutable-type/34465/22 "2020-02-13T06:11:48Z")

</div>

@tomtom I think `@ΔΔ` does what you want. FYI an easier way to do this is

```julia
julia> macro ΔΔ(fun, obj, x)
           esc(:($obj = $fun($obj, $x)))
       end
@ΔΔ (macro with 1 method)

julia> @macroexpand @ΔΔ(setdataΔ, v, [3, 4])
:(v = setdataΔ(v, [3, 4]))

```

although `esc(expr)` is incorrect if you have something that does not come from the argument (e.g., `esc(:($obj = setdataΔ($obj, $x)))` probably does something bad).

@Tamas_Papp Maybe a better example of what you were pointing out is `qr!(A)`? The caller allows the callee to modify the input `A` but it is done in an unspecified way. I think not mutating the input at all is an acceptable implementation. Generalizing it, there are `!` functions that _may_ mutate the arguments because they are treated as workspace. I do agree this and my first comment was perhaps generalizing too much. However, I don’t think it’s popular to expose a public API that may or may not mutate “output argument” (e.g., the first argument of `push!`). At least I don’t remember seeing such API in Julia.

[Previous page](https://discourse.julialang.org/t/how-to-design-with-immutable-and-also-mutable-type/34465.md?page=1)
