Return multiple values not in a tuple?

I have a function that takes several arguments. I have another function that returns several values. I’d like the second function to be able to directly feed the first. But my attempt doesn’t work because multiple return values get bundled together in a tuple and my first function doesn’t expect a tuple. (And I don’t want it to, because in most contexts it won’t be eating the direct output of another function.)

Here’s a toy example

function test1(x,y,z)
   return x+y+z
end

function test2()
   return 1,2,3
end

julia> test1(test2())
ERROR: MethodError: no method matching test1(::Tuple{Int64,Int64,Int64})
Closest candidates are:
  test1(::Any, ::Any, ::Any) at REPL[15]:1
Stacktrace:
 [1] top-level scope at REPL[20]:1

Anyone have pointers on how to do this in an acceptly Julian way?

Try test1(test2()...). The ... “splats” a collection, which is what you want to accomplish.

3 Likes

Oh yeah, I forgot about the splat operator. I’m still a beginner, I guess.

I know you said you don’t want to add a method to test1 that accepts a tuple, but this can be done in a neat way using argument destructuring:

test1(x, y, z) = x + y + z
test1((x, y, z)) = test1(x, y, z)

test2() = 1, 2, 3
julia> test1(test2())
6
6 Likes

Or test1(x) = test1(x...)

(But I never understand when or whether the splatting has a performance penalty.)

2 Likes

Yeah, that has the advantage (or disadvantage, depending on the desired API) that it will throw a method error if you provide a tuple that is too long.

foo(x, y) = x + y
foo((x, y)) = foo(x, y)

bar(x, y) = x + y
bar(x) = bar(x...)
julia> foo((1, 2, 3))
3

julia> bar((1, 2, 3))
ERROR: MethodError: no method matching bar(::Int64, ::Int64, ::Int64)

Oh yeah. That’s a good solution too.

This is relatively verbose, but if you prefer the argument destructuring approach:

julia> buz((x, y)::Tuple{Vararg{Any,2}}) = buz(x, y)
 buz (generic function with 2 methods)

julia> buz((1, 2.0))
 3.0

julia> buz((1, 2.0, 3))
ERROR: MethodError: no method matching buz(::Tuple{Int64,Float64,Int64})
3 Likes