Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason behind having only one return value in C++ and Java?

Tags:

java

c++

People also ask

Why does a function return only one value?

So, if we write more than one return statement in our code, the control goes back to the calling function on occurence of first return statement itself. So,there is no question of returning more than one value. 2.

Why do we return 1 in Java?

Your method has no return type, Provide a return type of int in your method. And return -1 means nothing in java, you are just returning a int value, thats it.

Should you only have one return statement?

It is sometimes said that a method should have only one return statement (i.e. one exit point) and that to code using more than one return per method is bad practice. It is claimed to be a risk to readability or a source of error. Sometimes this is even given the title of the “single exit point law”.


Whenever you have multiple values x1 ... xN, you trivially have the tuple (x1, ..., xN) which is a single (albeit composite) value. If you don't have tuples in your language, use any aggregate type (struct, class, arrays, other collections) at will. So from this perspective, returning "multiple" values and returning a single value is completely equivalent.

That just means that you only need one, but why omit the other?

First, you need aggregate types anyway, so the choice is between having both or only having aggregate types. Second, if a function can return "multiple values", you face a semantic conundrum: Suddenly an expression does not evaluate to value (which we have previously defined very specifically), it's this new, different category of thing called "multiple values". Now what is the static type of this result? What can the program do and not do with it? What does it mean in implementation terms?

You can of course artificially answer these questions, but any sensible approach will just amount to tuple types. Ignoring that makes you blind to a very useful perspective, and refusing to make them first-class values is probably more complicated than saying "these are tuple types, they can be constructed like this and deconstructed like this".


When a function returns multiple things, the things are related to each other, at the very least by virtue of being returned by a single function. This consideration alone is sufficient to require the authors of functions that return multiple things to group these multiple things together by creating an appropriate data structure, which is already possible with functions returning a single item.

For example, in C++ std::set::insert needs to return two values - an iterator, and a bool to indicate whether the iterator is some old element or the element that we have just inserted. The solution was to return an std::pair:

pair<iterator,bool> insert (const value_type& val);

The second consideration is purely practical: dealing with multiple returned value in expressions like that

int x = f(y);

is simple and intuitive when there is only one return value. Trying to return multiple values, as in

int x, y = f(w, z);

would become hard to parse, because the reader must check the return type of f and see if it returns an int or two ints.

I am not even touching the situation when the data types of the returned items are not the same! The syntax would quickly become a nightmare, without a comparable gain in expressive power of the language.


Your question doesn't make it clear which exactly feature you're looking for: syntactic sugar which makes it "look" like you're returning several values, or the essential ability of a function to return several values.

If it is the former, then there's no big answer to give: languages just differ in the level of syntactical support they provide for this. For example, LISP has full support for multiple value return and many languages (Scala, Clojure) support the destructuring bind idiom which quite closely resembles what you're looking for, but work against reference-typed tuples. Java happens to be poor on syntax in general so its lack of support for the destructuring bind is no surprise.

As for the latter — in C, returning a struct type is exactly the functionality you are looking for. The struct will be placed on the stack frame and will contain an arbitrary number of values. Other languages, which don't let you control stack/heap placement at such a level of detail, still allow you to return a pointer to such a struct.


This is purely historical. This is how usually mathematical functions work. Moreover, some languages (quite a lot actually) allow to return more than one value - usually using a tuple object.

The idea that it would be nice to return more than one object came late. Why was it chosen to be done via objects, and not language syntax? Because OO programming was in wild use and generally accepted.

Semantically both ways have the same meaning - "return more than one thing". So adding such functionality would be an equivalent to supporting another syntax for the same meaning. Having two ways to do one thing is not very welcomed in programming. Programmers wonder which way to chose, some only know one method, and compiler developers would have to maintain two mechanisms that do not differ in their functionality. It's a pretty good rationale. Okham's razor is appreciated tool. And objects are more useful.

Another thing is that, your argument: "a declared function as a contract which states how a function can be called, which parameters it should take, and which return value type it has", is not really good at the bold part.

Return type is often not considered a part of function signature. You can't have overloads that differ only in return value. That being said, of course compiler needs to know how many bytes it should take of the stack, after function finished, as the return value. So it's not totally irrelevant, though usually languages do not consider this.


I wish people stopped interpreting “I can't do X in language Y” as “language Y has a limitation that prevents me from doing X”. Sometimes this is in fact just true – for instance C++' const modifiers basically just forbid you from mutating values in a way that, syntax-wise, could be expressed perfectly well, but just isn't deemed wise if you want to ensure your program behaves in a certain predictable way.

OTOH, for most features X you could come up with it just doesn't make any sense to want them in a language. How about if I asked, “what is the reason I can't just differentiate all C++ functions?” For a physicist or engineer who knows nothing about programming this wouldn't seem a far-fetched thing to want, as these guys traditionally only deal with1a particular kind of functions in the maths sense, which can always be differentiated as often as you like.

But for most functions in programming languages, it absolutely doesn't make any sense, conceptually, to take the derivative. To a programmer, the analytic functions can be but a tiny subset of all functions, simply because the idea of derivatives only applies to continuous domains (in practice, basically to vector spaces)2, and of course it is completely incompatible with the side-effects that “functions” in procedural and OO languages are allowed to have.

Now, allowing to return multiple values sure appears a much more mundane thing than allowing to differentiate functions, but it still changes in quite a fundamental way what's meant by “function”. You can't just refer to the return type of a function anymore, you need to clarify what it means to compose functions with multiple return values, you need to come up with some new syntax for function pointers, etc. etc.
Unlike the differentiation example, all of this this would probably be possible, but it should be clear that it would change pretty much all of the language. It would very much not be just “stop preventing me from returning multiple things!”

Some languages, e.g. Fortran and Matlab, have hard-wired support for multiple return values into the language. Oh boy, I can tell you this does not make programming in these languages nicer: many things you can easily do with C++ functions are just blocked because they would get messed up by the multiple returns!
Other languages, e.g. Python, have a lightwight alternative: it looks like you're returning multiple things, but really you're just returning a single tuple and get some syntactic sugar for pattern-matching the components back into individual variables.

Returning tuples or something similar is of course, as said by the other answers, the sensible solution to your problem, though it can sometimes get a bit clumsy in languages that don't have very good syntactic support for tuples. (But that's just a bit of harmless boilerplate.)


1Well, at least they pretend they're dealing with analytic functions. Often, this is barely acceptable mathematically. Really, they're just approximating everything by analytic functions.

2Interestingly, in a language with proper algebraic data types, a remarkable analogue to the classical idea of differentiation turns up in quite a surprising way, without actually needing continuous domains. That's still something quite different from e.g. “take the derivative of x2 / (1+ex)”.


Going further: it can be argued that functions should also have only a single argument. That, too, can be a composite type, but you don't even need tuples here: there's a thing called Currying – any function of two arguments can also be expressed as a function of a single argument, returning a function of the second argument. This may seem a bit of a strange way of thinking, but actually it works out quite nicely. Haskell does this consequently, and many people consider it one of the crazy things about the language, but it allows you to express some operations more consisely than possible in most other languages, while at the same time the syntax is actually kept very simple.