# Macro to make a nested loop with threads

**URL:** https://discourse.julialang.org/t/macro-to-make-a-nested-loop-with-threads/93717
**Category:** General Usage
**Created:** [January 29, 2023, 12:55am UTC](https://discourse.julialang.org/t/macro-to-make-a-nested-loop-with-threads/93717 "2023-01-29T00:55:09Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![mkoculak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkoculak/32/28310_2.png) [@mkoculak](https://discourse.julialang.org/u/mkoculak)
#### Post date: [January 29, 2023, 12:55am UTC](https://discourse.julialang.org/t/macro-to-make-a-nested-loop-with-threads/93717/1 "2023-01-29T00:55:09Z")

</div>

This is a reoccurring question, but with a twist that I can’t figure out (as this is my first time fiddling with macros).

I have gone through most of the threads here and on SO concerning using macro to conditionally use `@threads` macro on loops (and [this one](https://discourse.julialang.org/t/toggle-threads-threads-with-a-variable/71818) and [this](https://discourse.julialang.org/t/condition-to-use-or-not-to-use-threaded-for-loop/77935) show couple of ways to get there).  
But I was interested in going a step further and having something like this:

```julia
@alt_thread 4 for i in collection
    print(i)
end

```

and transforming it to a nested loop with threading on collection partitioned into given number of chunks. So in this case it would result in code analogous to:

```julia
@threads for j in collect(partition(collection, 4))
    for i in j
        print(i)
    end
end

```

It seems like it would be such a clean way to control if and how many threads are spawned for a given task.

So doing all steps without threading seem to work fine:

```julia
macro alt_thread(num, loop)
    i = esc(loop.args[1].args[1])
    iter = esc(loop.args[1].args[2])
    body = esc(loop.args[2])
    
    quote
        batch = collect(Iterators.partition($iter, $num))
        for j in batch
            for $i in j
                print("$j ")
                $body
            end
        end
    end
end

```

but trying to add threading breaks the macro.  
When I do `@macroexpand` on my code I can see threading fails when called with less threads than available (it seems to be falling automatically to `:static` scheduling with errors as not composable in macro.  
I thought about using directly `_threadsfor` but writing out the whole new nested body seemed way over my head for a first attempt.  
**Can anyone help me fix it (or tell me why it can’t be done, if that’s the case)?**

**Bonus points:** I read the docs and watched a nice yt video about macro hygiene, but can anyone explain why I have to have `$i` in the quote since I overwrite it immediately? But without the dollar sign it says it is not defined.

Disclaimer: After trying to make it work for some time I have acknowledged that probably all of this is easily achievable with a custom function producing partition that could e.g. read `preferences` object to decide how many to make (or leaving it as one collection, which would in a sense turn off threading), but still would be nice to learn some more about macros.
