# Using ntuple() in generated function

**URL:** https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020
**Category:** Performance
**Tags:** ntuple, generated
**Created:** [June 7, 2023, 7:54pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020 "2023-06-07T19:54:52Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [June 7, 2023, 7:54pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/1 "2023-06-07T19:54:52Z")

</div>

I have found that using `ntuple` in generated functions produces better code (faster, and with fewer allocations), than constructing the tuple expression manually. Presumably the code that `ntuple` generates is more inferable. From a maintenance perspective it feels preferable to use it too.

However, I can only use `ntuple` on the compile time constants. I have been unable to get it work with variables. To show you what I mean, the following code throws an error:

```julia
@generated function myfunc1(x::T, ::Val{N}) where {T, N}
    ex = Expr(:tuple, [:(x * $i) for i in 1:N]...)
    return :(SVector{N, T}($ex))
end

@generated function myfunc2(x::T, ::Val{N}) where {T, N}
    ex = ntuple(i -> :(x * $i), N)
    return :(SVector{N, T}($ex))
end

display(myfunc1(2., Val(3)))
display(myfunc2(2., Val(3)))

```

Output:

> 3-element SVector{3, Float64} with indices SOneTo(3):  
> 2.0  
> 4.0  
> 6.0  
> ERROR: MethodError: Cannot `convert` an object of type Expr to an object of type Float64

How can I fix `myfunc2 `to work like `myfun1`?

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [June 7, 2023, 7:58pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/2 "2023-06-07T19:58:54Z")

</div>

Don’t you want `ex = :(ntuple(i -> x * i, $N))`

---

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [June 7, 2023, 9:11pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/3 "2023-06-07T21:11:46Z")

</div>

Thank you. But this gives the error:

> ERROR: The function body AST defined by this @generated function is not pure. This likely means it contains a closure, a comprehension or a generator.

---

<div class="post-metadata">

### Author: ![user664303](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/user664303/32/37843_2.png) [@user664303](https://discourse.julialang.org/u/user664303)
#### Post date: [June 7, 2023, 9:15pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/4 "2023-06-07T21:15:50Z")

</div>

However, this works:

```julia
mult(a, b) = a * b
@generated function myfunc2(x::T, ::Val{N}) where {T, N}
    ex = :(ntuple(Base.Fix1(mult, x), $N))
    return :(SVector{N, T}($ex))
end

```

Many thanks for the nudge in the right direction.

---

<div class="post-metadata">

### Author: ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)
#### Post date: [June 7, 2023, 9:16pm UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/5 "2023-06-07T21:16:41Z")

</div>

You can go one step simpler with

```julia
@generated function myfunc2(x::T, ::Val{N}) where {T, N}
    ex = :(ntuple(Base.Fix1(*, x), $N))
    return :(SVector{N, T}($ex))
end

```

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [June 8, 2023, 12:48am UTC](https://discourse.julialang.org/t/using-ntuple-in-generated-function/100020/6 "2023-06-08T00:48:47Z")

</div>

Also, without resorting to `Base.Fix1` (which is completely appropriate here):

```julia
nt(x,n) = ntuple(i->i*x,n)
@generated function myfunc3(x::T, ::Val{N}) where {T, N}
       ex = :(nt(x, $N))
       return :(SVector{N, T}($ex))
end

```

The non-pureness earlier comes from defining the anonymous function.  
This example will work in other cases where `Base.Fix1` will not fit.
