# Assigning inside a macro, and proper way to create this expr

**URL:** <https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724>\
**Category:** General Usage\
**Created:** [June 16, 2018, 8:33pm UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724 "2018-06-16T20:33:17Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 16, 2018, 8:33pm UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724/1 "2018-06-16T20:33:17Z")

</div>

I (as a beginner to macros) was looking to write a macro `@deal` such that I could write:

```julia
@deal R a b

```

(where `length(a)+length(b)==length(R)`), and have it distribute the values in R into a and b - for eg. if `length(R)==10`, `length(a)==4`, `length(b)==6`, then R[1:4] would go into a, and R[5:10] into b.

Similarly `@deal R x y z`, with x, y, z having lengths 2, 5, and 3 respectively, should effectively mean `x[:] = R[1:2]`, `y[:] = R[3:7]`, `z[:] = R[8:10]`.

I barely understand macros though, and after a lot of bumbling around came up with this:

```julia
macro deal(V, x...)
    assigns = quote starter = 1 end
    for i in 1:length(x)
        push!(assigns.args, (quote
                  esc($(x[i])) = esc($V)[starter:starter + length(esc($(x[i])))]
                  starter += length($(x[i]))
              end).args[2])
    end
    assigns
end

```

I’m sure it’s terrible in all sorts of ways, but it doesn’t even work - the assignment to `esc($(x[i])` ends up being seen as a function definition `esc(a)` and so doesn’t change the values of a or b.

How does one assign to a caller-scope variable inside a macro correctly?

And what’s the not-so-terrible way to write this macro? Hints towards how I can add things like type-checking and length-checking are also welcome.

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [June 16, 2018, 8:51pm UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724/2 "2018-06-16T20:51:58Z")

</div>

The `esc` goes inside the interpolation, say `esc($V)` should be `$(esc(V))`, as `esc` acts on the symbols and is not passed onward to the code which the macro generates.

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 17, 2018, 12:58am UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724/3 "2018-06-17T00:58:27Z")

</div>

Thank you! `esc` had been one large part of what confused me about macros (it just seemed too magical and handwavy before), but your explanation prompted me to try it out on the REPL by itself, and I believe I have a better understanding of it now.

Here’s my current code for the macro:

```julia

macro deal(V, x...)
    assigns = quote
        starter = 1 
        C = $(esc(V))
    end

    for i in 1:length(x)
        q = quote
            a = $(esc(x[i]))
            a[1:end] = C[starter : starter + length(a) - 1]
            starter += length(a)
            nothing
        end
        append!(assigns.args, q.args[2:end])
    end

    assigns
end

```

---

<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:** [June 17, 2018, 6:40am UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724/4 "2018-06-17T06:40:25Z")

</div>

> [@digital\_carver](#):
>
> And what’s the not-so-terrible way to write this macro? Hints towards how I can add things like type-checking and length-checking are also welcome.

It is unclear why you need a macro for this. Eg

```julia
function deal!(src, dest...)
    i = 0
    for d in dest
        n = length(d)
        d .= src[(i+1):(i+n)]
        i += n
    end
    # length checking and generalized indexing
    # left as an exercise for the reader 😎
end

R = 1:10
a = zeros(4)
b = zeros(6)
deal!(R, a, b)

```

---

<div class="post-metadata">

**Author:** ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)\
**Post date:** [June 18, 2018, 5:58pm UTC](https://discourse.julialang.org/t/assigning-inside-a-macro-and-proper-way-to-create-this-expr/11724/5 "2018-06-18T17:58:24Z")

</div>

> [@Tamas\_Papp](#):
>
> It is unclear why you need a macro for this.

True enough. I was thinking that a macro would let me add code to handle more complex input in the future, things like:

```julia
julia> c = ones(7);

julia> @deal R a[2:4] c

```

(right now, neither the macro nor the function change the contents of `a` in this case.)

But such uses are rare enough that I can afford to simply write it as `deal!(R, @view(a[2:4]), c)` rather than try to make too DWIMmy a macro.

The other reason was to try and understand macros better through writing this - and that part worked out reasonably well. 🙂
