# @nloops and @generated function

**URL:** <https://discourse.julialang.org/t/nloops-and-generated-function/121051>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 8, 2024, 8:31am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051 "2024-10-08T08:31:05Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![JM\_Beckers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jm_beckers/32/22482_2.png) [@JM\_Beckers](https://discourse.julialang.org/u/JM_Beckers)\
**Post date:** [October 8, 2024, 8:31am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/1 "2024-10-08T08:31:05Z")

</div>

I know macros should only be used in very specific cases and I’m not an expert at all on the topic. Nevertheless I managed to make work a skeleton of my planned code (where actually the loop limits at each level are different and calculated). A simplified version is below.  
The obvious thing I want to do now is of course to replace the value 4 using the parameter twon (passed to the function). I know this should be feasible using @generated function, block and $twon, but I do not succeed to find the right syntax.

```julia
using Base.Cartesian
using BenchmarkTools

function looper(lower,upper)
   twon=4
   val=zeros(Int32,twon)
   @nloops(4, v, i -> (i < twon) ? range(twon-i,v_{i+1}-1) : (lower:upper),
        begin 
            @nexprs 4 j -> val[j] = v_j
            @show val
            # Actual work on val from here on
        end
           )
end

looper(5,10)

```

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [October 8, 2024, 9:08am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/2 "2024-10-08T09:08:46Z")

</div>

`@generated` can only use type information (e.g. the dimensionality of your array) but not runtime values (such as a number):

```julia
help?> @generated
  @generated f

  @generated is used to annotate a function which will be generated. In the body of
  the generated function, only types of arguments can be read (not the values). The
  function returns a quoted expression evaluated when the function is called. The
  @generated macro should not be used on functions mutating the global scope or
  depending on mutable elements.

  See Metaprogramming for further details.

  Examples
  ≡≡≡≡≡≡≡≡

  julia> @generated function bar(x)
             if x <: Integer
                 return :(x ^ 2)
             else
                 return :(x)
             end
         end
  bar (generic function with 1 method)
  
  julia> bar(4)
  16
  
  julia> bar("baz")
  "baz"

```

Can you provide details about your specific problem? Using `@nloops` is not quite recommended.  
Also see this [blog post by Tim Holy](https://julialang.org/blog/2016/02/iteration/)

---

<div class="post-metadata">

**Author:** ![JM\_Beckers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jm_beckers/32/22482_2.png) [@JM\_Beckers](https://discourse.julialang.org/u/JM_Beckers)\
**Post date:** [October 8, 2024, 9:29am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/3 "2024-10-08T09:29:22Z")

</div>

I know that @nloops is not recommended and used extensively Tim Holy’s blog concepts.

The basic objective here is to create one at a time all possible different arrays `val` of length `2n` where each element satisfies some constraints compared to the others and has a different lower bound

```julia
B1<val[2n]<B2
lb_i < val[i] < val[i+1] i = 2 ... 2n-1
val[1]=C

```

and on each of those arrays perform some work and return a value.

Of course, I could iterate over the full space and just ignoring the unnecessary parts, but later the 4 will be replaced by 6, 8 maybe even 14…

Maybe an iterator could be constructed, but that does not simple neither for such a case ?

From a practical point of view, if I can only use type information to “pass the information”, I just could define an array at the calling level just for that purpose ? I would be happy with that.

Also it is a one shot program, not to be included into any module, I just want to solve one specific problem with it.

So actually if passing the information is too complicated, I could just change the parameter by hand.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [October 8, 2024, 9:55am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/4 "2024-10-08T09:55:54Z")

</div>

How about taking a step back? Forget about generated functions, macros and metaprogramming. Just describe your problem, so we could give you the right solution.

---

<div class="post-metadata">

**Author:** ![JM\_Beckers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jm_beckers/32/22482_2.png) [@JM\_Beckers](https://discourse.julialang.org/u/JM_Beckers)\
**Post date:** [October 8, 2024, 10:56am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/5 "2024-10-08T10:56:36Z")

</div>

Tried to clarify the previous post. Basically visit a subspace of a hypercube to to some work on each of these points. And the subspace is becoming smaller and smaller compared to the hypercube when the dimension goes up.

---

<div class="post-metadata">

**Author:** ![roflmaostc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/roflmaostc/32/30123_2.png) [@roflmaostc](https://discourse.julialang.org/u/roflmaostc)\
**Post date:** [October 9, 2024, 12:44pm UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/6 "2024-10-09T12:44:51Z")

</div>

I mean one dirty workaround would be to work with something like:

```julia
for i in 1:10
     do_something(Val(i))
end

```

This lifts the number to the type domain but it will result in (slow) dynamic dispatch since `Val(i)` is in the type domain but it’s type is runtime depending on the for loop. Slow of course can be relative.

But `@generated` should be able to work with it. I think you need to figure out how the exact syntax with `@generated` and `@nloops` combines.

Again to repeat: This is **not** really **Julia idiomatic** and `CartesianIndex` iterators would be more clear. Perhaps also some sort of recursive algorithms.

---

<div class="post-metadata">

**Author:** ![JM\_Beckers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jm_beckers/32/22482_2.png) [@JM\_Beckers](https://discourse.julialang.org/u/JM_Beckers)\
**Post date:** [October 10, 2024, 4:33am UTC](https://discourse.julialang.org/t/nloops-and-generated-function/121051/7 "2024-10-10T04:33:15Z")

</div>

In the meanwhile I tried indeed a recursive approach which works fine.
