aleksandar.ristovski@gmail.com wrote:
Quote:
Hello all,
>
I have been thinking about a possible extension to C/C++ syntax.
>
The current syntax allows declaring a function that returns a value:
>
int foo();
>
however, if I were to return more than one value, for example three
int-s, I would have to change my "logic" and pass the references to my
return values (i.e. declare them in the argument list) or to declare an
extra-struct representing the return type of three ints (extra work and
extra types). The function would look something like:
>
int foo(int&,int&);
or
void foo(int &, int&, int&);
or
struct rettype
{
int a, b, c;
};
>
rettype foo();
>
>
>
Would it not be nice if I could keep the thinking "return values are on
the left-hand side" and do something like this:
>
----
declaration:
>
{int, int, int} foo();
----
definition:
>
{int, int, int} foo()
{
...
return {1, 42, 0};
}
----
code:
>
int a, b, c;
{a, b, c} = foo();
>
>
----
I picked the curly braces, but it could be something else, it doesn't
matter - I am talking about the principle.
>
What do you think?
I think that you should also have the possibility that the function
need not supply all of the return values. In that case, the return
values have to have default initializers;
{int, int = 42} foo() { return 3; } // returns 3, 42
The callers should not be required to capture all of the return values.
Presently, you can call a function and ignore the result. Multiple
return values would preserve this freedom:
foo(); // 3, 42 thrown away
int x = foo(); // x = 3
{ x } = foo(); // x = 3
It might be worthwhile to look at Common Lisp multiple values.
Here is a possible alternative syntax:
// group together destinations for multiple values
// mnemonic: "into"
// capture multiple values emanating from expression
// mnemonic: "extract"
<{ expr }
The >{ and <{ could be recognized as tokens, which gets rid of
ambiguities against compound statements.
This would allow for these uses:
// foo takes three arguments
// bar yields three values
// here, bar's three values become arguments for foo:
// analogous to Common Lisp multiple-value-call.
foo(<{bar()});
// here quux is a one argument function
// it takes only the first return value of bar
quux(bar());
// assignment of four values to four lvalues
Quote:
>{x, y, z.field, *p} = <{returns_four_values()};
The >{ } could be permitted to enclose a declaration, allowing for the
binding of a group of variables to multiple values:
Quote:
>{ unsigned int x, y; double z = 42 } = <{ func(arg); }
Here, z gets 42 if the function returns only three values, otherwise it
takes the fourth value.