# The idea behind this generated function

**URL:** https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095
**Category:** General Usage
**Created:** [August 12, 2024, 1:46pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095 "2024-08-12T13:46:00Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![mohamed.d180](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed.d180/32/52028_2.png) [@mohamed.d180](https://discourse.julialang.org/u/mohamed.d180)
#### Post date: [August 12, 2024, 1:46pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/1 "2024-08-12T13:46:00Z")

</div>

Inspecting the source code of [ForwardDiff.jl)](https://github.com/JuliaDiff/ForwardDiff.jl) , we can found this function

```julia
@generated function single_seed(::Type{NTuple{N,V}}, ::Val{i}) where {N,V,i}
           ex = Expr(:tuple, [ifelse(i === j, :(one(V)), :(zero(V))) for j in 1:N]...)
           return :(NTuple($(ex)))
       end

```

which returns tuples with variable length of zeros with just one at specified location `i`

What is benefits of using `@generated` while it can be implemented as regular function, And get the results like

```julia
function single_seed_not_gen(::Type{NTuple{N,V}}, ::Val{i}) where {N,V,i}
           return tuple([ifelse(i == j , one(V), zero(V)) for j in 1:N]...)
       end

```

with results

```julia
julia> single_seed_not_gen(NTuple{10,Int} ,Val(4))
(0, 0, 0, 1, 0, 0, 0, 0, 0, 0)

julia> single_seed_not_gen(NTuple{20,Int} ,Val(4))
(0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [August 12, 2024, 1:50pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/2 "2024-08-12T13:50:58Z")

</div>

> [@mohamed.d180](#):
>
> `return tuple([ifelse(i == j , one(V), zero(V)) for j in 1:N]...)`

This is very inefficient. Not only does it first heap-allocate an array before converting it to a tuple, but it is also type-unstable (because constructing it in this way means that the compiler is not able to infer the length of the tuple).

However,

```julia
return ntuple(j -> i == j ? one(V) : zero(V), Val{N}())

```

should be efficient and type stable. I’m not sure why they went for a `@generated` function instead.

---

<div class="post-metadata">

### Author: ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)
#### Post date: [August 12, 2024, 2:30pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/3 "2024-08-12T14:30:31Z")

</div>

Note that `ntuple` is implemented as a generated function IIRC, but yes it is a better choice.

Likely the code there existed before `ntuple` or before it was reliable

---

<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: [August 12, 2024, 3:15pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/4 "2024-08-12T15:15:12Z")

</div>

The basic answer to most questions around why did ForwardDiff (or StaticArrays) do this is that the code predates Julia’s ability to express the cleaner version.

---

<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: [August 12, 2024, 3:23pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/5 "2024-08-12T15:23:23Z")

</div>

> [@vchuravy](#):
>
> Note that `ntuple` is implemented as a generated function

Only for generated callers:

> <https://github.com/JuliaLang/julia/blob/cf4c30accd92755bc39d52364ae6549c490a4bc8/base/ntuple.jl#L69-L77>

So the most general implementation is just `Tuple(f(i) for i = 1:(N::Int))`, not counting the error checks.

---

<div class="post-metadata">

### Author: ![mohamed.d180](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed.d180/32/52028_2.png) [@mohamed.d180](https://discourse.julialang.org/u/mohamed.d180)
#### Post date: [August 12, 2024, 5:47pm UTC](https://discourse.julialang.org/t/the-idea-behind-this-generated-function/118095/6 "2024-08-12T17:47:51Z")

</div>

that’s make sense, Thank you.
