Why do functions in some popular languages return only a single result?
views:
718answers:
14To simplify matter.
You can always return a T[]
, Pair<L,R>
, Set<E>
, etc in these languages to emulate returning multiple values. That takes care of most multiple return
values scenarios out there.
It's not worth changing the semantics of the language so much for a gain so little.
Related questions
A function (in languages you mentioned in your tags) does have a single output , but that output does not have to be a single value. Your output can easily be a class which encapsulates any amount of data you want.
Also, note that you can also pass multiple input arguments by reference to your function, thereby increasing the number of returned outputs.
How would you call such a function?
Brainfart:
int int Get2Ints();
{
return 1, 2;
}
int a,b = Get2Ints();
Very unlogical. You will get the same effect using references (and only 1 return)
The function return an answer, why would it be designed to give more answers? And that answer can be any data structure you like so it could hold lots of values :)
My best guess is that it carried over from mathematics. There you can have a function with multiple parameters, and value that's the result.
f(x1, x2, ...) = y (the formula might be something like x1 + x2^2 + x3^3 + ...)
Even if you want to map a multidimensional domain to a multidimensional range you usually write as:
f1(x1, x2, ...) = y1 (perhaps y1 = x1 + x2^1 + ... like above)
f2(x1, x2, ...) = y2 (and y2 = x1 - x2^2 + x3^3 - x4^4 +...)
...
since each y gets it's own mathematical formula based on the inputs, which in programming would just translate to multiple functions, it makes sense to separate it like this.
The problem is sometimes the formulas for y1 and y2 may be very similar or rely on iterating the same thing or whatnot, that doing them together might make more sense. In python you can do
return a1, a2;
and then call it like
x, y = f();
but in most languages you can only return one variable. That doesn't stop you from making it a complex object with multiple values included.
You can do this in perl:
sub foo
{
return (10, 20);
}
my ($a, $b) = foo(); # sets $a to 10 and $b to 20
And similar constructs in other languages.
Functions return only one value because its the way "they" invented it in the old days of assembler. Basically what happens is that function pushes return value on the stack. Caller then pops the value from the stack. If function returned more values, caller wouldnt know how many values to pop and the stack would be unbalanced (leading to program crash).
I guess in most cases one return value is sufficient, and the mathematical notion of a function (or Lambda calculus) has one return value as well, so it's kind of understandable that language designers try to stick with the "standard". In fact having several functions which need multiple return values can be confusing and may be a sign of poor design, e.g. a missing compound class.
The "classical" approach for returning multiple values is using Tuples. Some languages have a built-in Tuple type (like Scala), but you can define it yourself in all languages that support type parameters in some form (templates, generics...). For Java, there is the nice JavaTuple lib.
It is to help reading source code. It's SOOOOO human-friendly this way! If this function would have more than one return value, this line could not be written:
if (SomeFunction(a, b) != SUCCESS)
{
// do error handling
}
A function has to fullfill a clearly defined task. Aside from the fact that you can always return an array: probably something was completely wrong with your softwaredesign if you'd need to return different values from different datatypes.
Besides that, it's much easier for a human to read a function with one return value.
Lua does also support multiple return values: you can for example write the following:
function foo()
return 1, 2, 3
end
a, b, c, d = foo()
after execution, a, b, c will hold the values 1, 2, 3 and d will be nil. You can in the same way do the following:
function bar()
return true, 2, 3
end
if bar() then
-- do something intelligent
end
the if statement will in this case only work with the first value returned - if you need the other values, you will have to store them in variables like usual:
a, b, c = bar()
if a then
-- do something intelligent
end
so you see: in Lua, all the return values that are not needed are thrown away (like 2, 3 in the example with the if).
Daniel Weinreb -- who worked on both Lisp dialects (which had multiple return values) and Java (which didn't), explains why:
When we added the multiple-value return feature to Lisp machine Lisp (from whence it went into Common Lisp), I believe that the desire to avoid consing was one of the serious motivations. Back then, we did not have good GC technology, and writing Lisp programs to carefully minimize consing was very common.
The other reason was for expressiveness: to make it clear that the function was really returning more than one result, rather than introducing a little list "type" (e.g. "a two-list of the file handle and a boolean to say whether...").
In Java, I've seen definitions of little classes whose only purpose is to be a way to return multiple values. The advantage of this approach is that the types and meanings of the returned values are documented (at least if you pick clear names and put in comments!). But it's rather verbose, in my opinion.
When I was first reviewing the early Java spec, I was surprised to see that there was no way to return multiple values. I wanted to lobby for adding that, so I tried to come up with a use case that was both simple and very compelling. I was unable to do so! So I didn't try lobbying for it. The designers of Java were pretty clearly trying to avoid a lot of bells and whistles (and syntactic sugar), and there's certainly a lot to be said for that.
I think the question is about memory allocation and stack organization The main thing is context switching at time of function call . the function frame is stored on the stack the frame contains function variables,general purpose registers and return values i know that much