# Generated function with multiple return values

**URL:** <https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483>\
**Category:** New to Julia\
**Tags:** metaprogramming\
**Created:** [January 10, 2019, 4:09pm UTC](https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483 "2019-01-10T16:09:16Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![moesphere](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moesphere/32/3348_2.png) [@moesphere](https://discourse.julialang.org/u/moesphere)\
**Post date:** [January 10, 2019, 4:09pm UTC](https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483/1 "2019-01-10T16:09:16Z")

</div>

How can I create a generated function, that returns two arguments, see the following example:

```julia
ex = [:(x+y), :(x-y)]
@generated function f(x,y)
   ex[1]
end
f(2,3) # returns 5

```

That works fine. And how about returning two arguments (similar to the following code)?

```julia
@generated function f(x,y)
ex[1],ex[2]
end

```

---

<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:** [January 10, 2019, 4:28pm UTC](https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483/2 "2019-01-10T16:28:12Z")

</div>

The generator (the body of the generated function) must _always_ return exactly one expression. That is to say, it must return exactly the entire body of the function you want to generate. That’s why your second example fails: you’re returning two expressions, not a single expression.

What you need to do instead is to think about what the function you’re trying to generate would look like. It would probably look something like this:

```julia
julia> function f_generated(x, y)
         ((x + y), (x - y))
       end

```

Your generator needs to return the body of that function, or, in other words, it needs to return:

```julia
julia> :((x + y), (x - y))

```

Now you need to figure out how to construct `:((x + y), (x - y))` out of your two expressions in `ex`. You can do that by splicing each expression into a new tuple expression:

```julia
julia> :($(ex[1]), $(ex[2]))
:((x + y, x - y))

```

So that’s exactly what your generator should return:

```julia
julia> @generated function f(x, y)
           :($(ex[1]), $(ex[2]))
       end
f (generic function with 1 method)

julia> f(1, 2)
(3, -1)

```

---

<div class="post-metadata">

**Author:** ![moesphere](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/moesphere/32/3348_2.png) [@moesphere](https://discourse.julialang.org/u/moesphere)\
**Post date:** [January 10, 2019, 4:33pm UTC](https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483/3 "2019-01-10T16:33:25Z")

</div>

Thanks for the thourough and clear answer! 🙂

One small further question as I do not manage to get that working with expressions:  
How would the return code line `:($(ex[1]), $(ex[2]))` look like assuming the array `ex` has many entries and I want to use something like the splatting syntax?

---

<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:** [January 10, 2019, 4:51pm UTC](https://discourse.julialang.org/t/generated-function-with-multiple-return-values/19483/4 "2019-01-10T16:51:07Z")

</div>

I find that cases like this are easier to handle by constructing the expression directly. You can construct any Julia expression by directly building an `Expr()`, and you can find out how a particular expression is built using `dump()`. For example:

```julia
julia> dump(:(a, b))
Expr
  head: Symbol tuple
  args: Array{Any}((2,))
    1: Symbol a
    2: Symbol b

```

We can infer from that `dump()` output that we can construct a tuple expression like so:

```julia
julia> Expr(:tuple, :a, :b)
:((a, b))

```

Or to construct a tuple expression from arbitrarily many other expressions, we can do:

```julia
julia> Expr(:tuple, ex...)
:((x + y, x - y))

```

By the way, I should mention that you actually don’t need a `@generated` function in the case you posted originally. A `@generated` function is necessary when you want the generated code to depend on the types of the input arguments, but your code doesn’t actually depend on the types of `x` or `y`.

Instead, you can just use `@eval` to construct the function right away:

```julia
julia> @eval function f(x, y)
         ($(ex[1]), $(ex[2]))
       end
f (generic function with 1 method)

julia> f(1, 2)
(3, -1)

```

or, using the splatting syntax:

```julia
julia> @eval function f(x, y)
         $(Expr(:tuple, ex...))
       end
f (generic function with 1 method)

julia> f(1, 2)
(3, -1)

```
