# Should there be a macro or command for variable-depth nested loops?

**URL:** https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199
**Category:** Internals & Design
**Created:** [June 12, 2019, 5:00pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199 "2019-06-12T17:00:17Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![frank](https://avatars.discourse-cdn.com/v4/letter/f/3d9bf3/32.png) [@frank](https://discourse.julialang.org/u/frank)
#### Post date: [June 12, 2019, 5:00pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/1 "2019-06-12T17:00:17Z")

</div>

Recently I needed N (a variable number of) nested for-loops. A vector len contained the max counter of each loop.

The dumb way would have been this:

```julia
if n==1
    for a=1:len[1]
        # Loop body
    end
elseif n==2
    for a=1:len[1], b=1:len[2]
        # Loop body
    end
# ... and so on

```

Instead, here’s what I came up with, which at least is less dumb:

```julia
a = ones(Int64,n)
a[n] = 0
breakwhile = false
while true
    for k=0:n-1
        if a[n-k] < len[n-k]
            a[n-k] += 1
            break
        elseif n-k == 1
            breakwhile = true
            break
        else a[n-k]=1 end
    end
    breakwhile && break
    # Loop body goes here.
end

```

It was fun coming up with that and it worked, but I feel like this situation arises often enough that, in a perfect world, there would be a macro or command for it.

Maybe something like “@nest for k in v”

where v is a Vector{Int64} of the loop durations, and k is a vector of counters (created locally if not already existing).

Is this just noob babbling, or a good idea? Does it already exist in some form? If not, perhaps I’ll take a stab at making a macro.

---

<div class="post-metadata">

### Author: ![oatlzzvztd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oatlzzvztd/32/3285_2.png) [@oatlzzvztd](https://discourse.julialang.org/u/oatlzzvztd)
#### Post date: [June 12, 2019, 5:04pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/2 "2019-06-12T17:04:53Z")

</div>

Have you read [Multidimensional algorithms and iteration](https://julialang.org/blog/2016/02/iteration)? Seems like a more flexible tool.

---

<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: [June 12, 2019, 5:14pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/3 "2019-06-12T17:14:34Z")

</div>

It seems like `Iterators.product` already does what you’re looking for:

```julia
julia> for k in Iterators.product(1:2, 1:3, 1:4)
         @show k
       end
k = (1, 1, 1)
k = (2, 1, 1)
k = (1, 2, 1)
k = (2, 2, 1)
k = (1, 3, 1)
k = (2, 3, 1)                                                                                                                                                                                                                                                                                                                         
k = (1, 1, 2)
...

```

For example, you could do something like this:

```julia
julia> function loops(v)
         for k in Iterators.product(Base.OneTo.(v)...)
           @show k
         end
       end
loops (generic function with 1 method)

julia> loops((2, 3))
k = (1, 1)
k = (2, 1)
k = (1, 2)
k = (2, 2)
k = (1, 3)
k = (2, 3)

```

---

<div class="post-metadata">

### Author: ![frank](https://avatars.discourse-cdn.com/v4/letter/f/3d9bf3/32.png) [@frank](https://discourse.julialang.org/u/frank)
#### Post date: [June 12, 2019, 5:19pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/4 "2019-06-12T17:19:00Z")

</div>

Thanks to both! I will play around with those.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 12, 2019, 5:30pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/5 "2019-06-12T17:30:25Z")

</div>

While I strongly recommend using a smart multidimensional iterator like `Iterators.product` or `CartesianIndices`, we do have an internal macro that generates an arbitrary (albeit constant-at-compile-time) number of nested loops: [`Base.Cartesian.@nloops`](https://docs.julialang.org/en/v1/devdocs/cartesian/#Base.Cartesian-1).

---

<div class="post-metadata">

### Author: ![frank](https://avatars.discourse-cdn.com/v4/letter/f/3d9bf3/32.png) [@frank](https://discourse.julialang.org/u/frank)
#### Post date: [June 12, 2019, 6:25pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/6 "2019-06-12T18:25:12Z")

</div>

@nloops doesn’t appear to be a solution. For instance I have a function whose parameters determine the # of nested loops that will be needed, so I don’t know in advance what the # will be.

The docs say:

> The first argument must be an integer (not a variable) specifying the number of loops.

Indeed, when I try

```julia
n = 3
@nloops n i A begin ...

```

an error is thrown: no method matching \_nloops(::symbol, …

Is there a workaround I’m overlooking?

(Sorry if this topic was better suited for Usage)

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [June 12, 2019, 6:34pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/7 "2019-06-12T18:34:11Z")

</div>

That’s the constant-at-compile-time caveat that I list. The way around it is to use a parametric type and a generated function — the typical answer is to capture the `N` parameter of an array and splice it into the generated body like this:

[https://docs.julialang.org/en/v1/devdocs/cartesian/#Supplying-the-number-of-expressions-1](https://docs.julialang.org/en/v1/devdocs/cartesian/#Supplying-the-number-of-expressions-1)

But you can also use a `::Val{N}` argument similarly, passing `Val(3)` to the generated function that creates the loops.

---

<div class="post-metadata">

### Author: ![cortner](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cortner/32/204_2.png) [@cortner](https://discourse.julialang.org/u/cortner)
#### Post date: [June 13, 2019, 6:47am UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/8 "2019-06-13T06:47:34Z")

</div>

And use a function barrier!

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [June 13, 2019, 6:54pm UTC](https://discourse.julialang.org/t/should-there-be-a-macro-or-command-for-variable-depth-nested-loops/25199/9 "2019-06-13T18:54:40Z")

</div>

Using recursion is the traditional way to do this though and probably more efficient for many use cases.
