# Function \`apply\`, that calls a function with a tuple of arguments?

**URL:** <https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898>\
**Category:** General Usage\
**Created:** [December 10, 2021, 3:53pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898 "2021-12-10T15:53:05Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![bert](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@bert](https://discourse.julialang.org/u/bert)\
**Post date:** [December 10, 2021, 3:53pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/1 "2021-12-10T15:53:05Z")

</div>

Julia makes it very easy to map/broadcast a function over a collection of argument tuples. But I don’t think it makes it so easy to map/broadcast multiple functions over one tuple of arguments.

We can do this:

```julia
f.((1, 2, 3)) == (f(1), f(2), f(3))

```

Is there a way to do this?

```julia
(f, g, h).(1) == (f(1), g(1), h(1))

```

Obviously this syntax can’t be made to work; it errors with `MethodError: objects of type Tuple{...} are not callable`. But there should be some “apply” function (or is there, and I just can’t find it). Something like this would make sense to me:

```julia
apply(f::Function, args::Tuple) = f(args...)
@assert apply.((f, g, h), Ref(args)) == (f(args), g(args), h(args))

```

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [December 10, 2021, 3:57pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/2 "2021-12-10T15:57:23Z")

</div>

You can use the pipe operator for this:

```julia
julia> f, g, h = sin, cos, tan
(sin, cos, tan)

julia> 1 .|> (f, g, h)
(0.8414709848078965, 0.5403023058681398, 1.5574077246549023)

```

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [December 10, 2021, 6:07pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/3 "2021-12-10T18:07:24Z")

</div>

> [@simeonschaub](#):
>
> `1 .|> (f, g, h)`

Like it, but I then needed horizontal orientation (matrix) for vector input

```julia
julia> [1 2 3] .|> (sin, cos, tan)
3×3 Matrix{Float64}:
 0.841471 0.909297 0.14112
 0.540302 -0.416147 -0.989992
 1.55741 -2.18504 -0.142547

```

As alternative one could use a comprehension:

```julia
julia> apply(funs, x) = [f.(x) for f in funs]
julia> apply((sin, cos, tan), [1,2,3])
3-element Vector{Vector{Float64}}:
 [0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
 [0.5403023058681398, -0.4161468365471424, -0.9899924966004454]
 [1.5574077246549023, -2.185039863261519, -0.1425465430742778]

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [December 10, 2021, 6:45pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/4 "2021-12-10T18:45:47Z")

</div>

we must have a previous discussion or even github issue on this I swear

---

<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:** [December 10, 2021, 7:38pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/5 "2021-12-10T19:38:35Z")

</div>

> [@Bardo](#):
>
> Like it, but I then needed horizontal orientation (matrix) for vector input

What do you mean? You can do

```julia
1.7.0> [1,2,3] .|> (sin, cos, tan)
3-element Vector{Float64}:
  0.8414709848078965
 -0.4161468365471424
 -0.1425465430742778

```

or

```julia
1.7.0> (1,2,3) .|> (sin, cos, tan)
(0.8414709848078965, -0.4161468365471424, -0.1425465430742778)

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [December 10, 2021, 7:43pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/6 "2021-12-10T19:43:52Z")

</div>

these are both columns, what if they want the result of broadcast to be a row?

---

<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:** [December 10, 2021, 8:01pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/7 "2021-12-10T20:01:14Z")

</div>

What do you mean? Isn’t it obvious how to get that?

---

<div class="post-metadata">

**Author:** ![Bardo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bardo/32/21601_2.png) [@Bardo](https://discourse.julialang.org/u/Bardo)\
**Post date:** [December 10, 2021, 8:02pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/8 "2021-12-10T20:02:52Z")

</div>

> [@DNF](#):
>
> `3-element Vector{Float64}:`

That’s not the same and so depends on what you want.  
In the example, we have 3 functions and 3 input values.  
I expect 3x3 output values

---

<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:** [December 10, 2021, 8:06pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/9 "2021-12-10T20:06:20Z")

</div>

Yes, but you seemed to indicate that there was a problem.

> [@Bardo](#):
>
> Like it, but I then needed horizontal orientation (matrix) for vector input

But you don’t need horizontal orientation for vector input, you need it for matrix output.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [December 10, 2021, 8:06pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/10 "2021-12-10T20:06:26Z")

</div>

how?

```julia
julia> [1,2,3] .|> [sin, cos, tan]
3-element Vector{Float64}:
  0.8414709848078965
 -0.4161468365471424
 -0.1425465430742778

julia> [1,2,3] .|> permutedims([sin, cos, tan])
3×3 Matrix{Float64}:
 0.841471 0.540302 1.55741
 0.909297 -0.416147 -2.18504
 0.14112 -0.989992 -0.142547

```

this doesn’t work, we want a row, not a matrix

---

<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:** [December 10, 2021, 8:09pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/11 "2021-12-10T20:09:08Z")

</div>

A row is a matrix. But anyway:

```julia
1.7.0> [1 2 3] .|> [sin cos tan]
1×3 Matrix{Float64}:
 0.841471 -0.416147 -0.142547

1.7.0> ([1, 2, 3] .|> [sin, cos, tan])'
1×3 adjoint(::Vector{Float64}) with eltype Float64:
 0.841471 -0.416147 -0.142547

```

I’m sure there are more ways.

I mean, how is this different from any other examples of broadcasting?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [December 10, 2021, 8:30pm UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/12 "2021-12-10T20:30:35Z")

</div>

Although `apply` or `funcall` are not as useful in Julia as in some lisps, I sometimes miss them.

An example (completely different from the OP) is that I sometimes wish we could write function barriers like so:

```julia
arr = Any[1, 2, 3] # elements of type unknown to the compiler

apply(arr[1]) do x
    # This anonymous function will get compiled & specialized for typeof(x)
    for _ in 1:1_000_000
        do_something_with(x)
    end
end

```

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [December 11, 2021, 1:43am UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/13 "2021-12-11T01:43:30Z")

</div>

You can easily define your own “apply” function — the syntax `f <| x` is good for this:

```nohighlight
julia> f <| x = f(x)
<| (generic function with 1 method)

julia> (sin, cos, tan) .<| [1, 2, 3]
3-element Array{Float64,1}:
  0.8414709848078965
 -0.4161468365471424
 -0.1425465430742778

julia> (sin, cos, tan) .<| π
(1.2246467991473532e-16, -1.0, -1.2246467991473532e-16)

```

---

<div class="post-metadata">

**Author:** ![bert](https://avatars.discourse-cdn.com/v4/letter/b/9e8a1a/32.png) [@bert](https://discourse.julialang.org/u/bert)\
**Post date:** [December 12, 2021, 4:03am UTC](https://discourse.julialang.org/t/function-apply-that-calls-a-function-with-a-tuple-of-arguments/72898/14 "2021-12-12T04:03:33Z")

</div>

> [@Jollywatt](#):
>
> ```julia
> julia> f <| x = f(x)
> <| (generic function with 1 method)
> 
> ```

I’d support this being in `Base`. In fact I find this a more natural (if a tiny bit more verbose) syntax for function calling than parentheses. I think it already meshes well with the rest of Julia. Broadcasting currently looks like `f.([1,2,3])` or `map(f, [1,2,3])` (not quite the same as broadcasting, but sometimes equivalent). In comparison,

1. The relationship between `args |> f` (left associative) and `f <| args` (right associative) is intuitive.
2. If you know about both `+` and `<|`, then it’s easy to extrapolate from `[a,b,c] .+ [1,2,3],` to `[f,g,h] .<| [1,2,3]`, and then to `[f g h] .<| [1,2,3]` (for a matrix of all pairs).
3. There would be a uniform syntax for choosing the direction (LTR or RTL) in which function calls are written.
