# Golfing question

**URL:** https://discourse.julialang.org/t/golfing-question/124864
**Category:** New to Julia
**Created:** [January 17, 2025, 9:57am UTC](https://discourse.julialang.org/t/golfing-question/124864 "2025-01-17T09:57:09Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)
#### Post date: [January 17, 2025, 9:57am UTC](https://discourse.julialang.org/t/golfing-question/124864/1 "2025-01-17T09:57:09Z")

</div>

Hi, I often have the following structure in my code: a function `Bar` calls a function `Foo` with multiple outputs and then uses all its outputs to return something (MWE below). Is there a performant way of golfing such functions into one-line functions? Performant here means: no loss in speed (or even an improvement), no decrease in type stability etc.

Very simple example (where it is of course not the purpose to unfold the definition of Foo in Bar, that defeats the purpose):

```julia
function Foo(x::Real) 
    return x, x^2, x^3
end

function Bar(x::Real)
    x, y, z = Foo(x)
    return Foo2(x, z, y)
end

```

here, Foo2 is some complicated function.

I know how to golf Foo:

```julia
Foo(x::Real) = (x, x^2, x^3)

```

But how do I golf Bar to something like

```julia
Bar(x::Real) = Foo2(Foo(x)[1], Foo(x)[3], Foo(x)[2])

```

without recomputing Foo(x) three times? (Note the change of order in the arguments).

---

<div class="post-metadata">

### Author: ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)
#### Post date: [January 17, 2025, 10:04am UTC](https://discourse.julialang.org/t/golfing-question/124864/2 "2025-01-17T10:04:33Z")

</div>

> [@JADekker](#):
>
> `Bar(x::Real) = Foo2(Foo(x)[1], Foo(x)[2])`

You can use [splatting](https://docs.julialang.org/en/v1/manual/faq/#...-splits-one-argument-into-many-different-arguments-in-function-calls): `Bar(x::Real) = Foo2(Foo(x)...)`

---

<div class="post-metadata">

### Author: ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)
#### Post date: [January 17, 2025, 11:01am UTC](https://discourse.julialang.org/t/golfing-question/124864/3 "2025-01-17T11:01:00Z")

</div>

Thank you for your response! I’m aware of splatting, but I thought there were performance concerns with this?

Also, it wouldn’t work if I needed something like `Foo2(Foo(x)[1], Foo(x)[3], Foo(x)[2])`; I’ll change the original post to reflect that!

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [January 17, 2025, 11:09am UTC](https://discourse.julialang.org/t/golfing-question/124864/4 "2025-01-17T11:09:51Z")

</div>

You can do `Foo2(getindex.(Foo(x), (1, 3, 2))...)` and that should not lead to any overhead due to the literal tuple const folding away. If `Foo` is not scalar-broadcastable you can wrap it in `Ref(...)`

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [January 17, 2025, 11:13am UTC](https://discourse.julialang.org/t/golfing-question/124864/5 "2025-01-17T11:13:30Z")

</div>

> [@JADekker](#):
>
> I’m aware of splatting, but I thought there were performance concerns with this?

The performance concerns with splatting is when the compiler does not know the length and types of the elements. Splatting an `NTuple{3, T}` the compiler knows exactly which method to call.

Splatting a `Vector{T}`, on the other hand, has performance implications, since its length is not statically known.

---

<div class="post-metadata">

### Author: ![JADekker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jadekker/32/210281_2.png) [@JADekker](https://discourse.julialang.org/u/JADekker)
#### Post date: [January 17, 2025, 11:14am UTC](https://discourse.julialang.org/t/golfing-question/124864/6 "2025-01-17T11:14:27Z")

</div>

Thanks for clarifying! Does this also apply if each output element has a different type?

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [January 17, 2025, 11:14am UTC](https://discourse.julialang.org/t/golfing-question/124864/7 "2025-01-17T11:14:55Z")

</div>

> [@JADekker](#):
>
> Does this also apply if each output element has a different type?

Yes, as long as the types are known.

---

<div class="post-metadata">

### Author: ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)
#### Post date: [January 17, 2025, 4:04pm UTC](https://discourse.julialang.org/t/golfing-question/124864/8 "2025-01-17T16:04:47Z")

</div>

If you’re willing to use the full `function` syntax you can also simply

```julia
function Bar(x::Real)
    x1, x2, x3 = Foo(x)
    return Foo2(x1, x3, x2)
end

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [January 17, 2025, 4:07pm UTC](https://discourse.julialang.org/t/golfing-question/124864/9 "2025-01-17T16:07:28Z")

</div>

> [@mike.ingold](#):
>
> If you’re willing to use the full `function` syntax

But for code golfing using the long syntax basically defeats the purpose…

---

<div class="post-metadata">

### Author: ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)
#### Post date: [January 17, 2025, 4:39pm UTC](https://discourse.julialang.org/t/golfing-question/124864/10 "2025-01-17T16:39:59Z")

</div>

Ah, “golfing” as in code-minimization…

```julia
Foo(x) = x.^(1:3)
f(x, y, z) = (x, z, y)
Bar(x) = Foo2(f(x)...)

```
