mita
mita copied to clipboard
RFC: Multiple Returns
Introduction
Functions typically return a single value. However multiple return values from a single Function can help structure code and avoid repetition. Further, in recent years multiple return has been popularized again.
Current Situation
Currently we only support a single return value.
Proposal
We could support multiple return values by extending the function declaration, return statement and variable declaration. Using a simple form of pattern matching users could utilize multiple returns. As is common in other languages the _ character becomes the wildcard for ignoring values. Return values can not be named.
Code Example
func plusAndMinus(a : i32, b : i32) : (i32, i32) {
let p = a + b
let m = a - b
// Multiple return is here. One always has to return a complete set of values
return p, m
}
func main() {
// use _ to ignore return values
var r, _ = plusAndMinus(10, 2)
// you cannot use multiple-return functions in other statements than variable declarations
// This is not a valid statement!
if(a, _ = plusAndMinus(10, 2) == 12) {
}
}
Implementation
We are already passing result values back out via pointer. This change would simply mean adding more pointer and adding more logic to variable declarations.
@andreasmuelder: As a complement to multiple return values we should introduct a TupleExpression to make the handling with multiple return values a bit more explicit and avoid confusion with multi variable assignments like int r, g, b = 0;
Code Example
func plusAndMinus(a : i32, b : i32) : (i32, i32) {
let p = a + b
let m = a - b
// return a tuple, a list of objects of potentially different types
return (p, m)
}
func main() {
// use _ to ignore return values
var (r, _) = plusAndMinus(10, 2)
r += 1
//or assign to a tuple of predefined variables
var x : i32
var y : i32
(x,y) = plusAndMinus(1,1)
}
Implementation
The YAKINDU Type System must be adopted to support multiple return types. the TupleExpression can be hooked into the Expression Language.
TupleExpression returns expressions::Expression:
{TupleExpression} (('(' (expressions+=Expression (',' expressions+=Expression)*)? ')')
@32leaves: The tupple idea looks great. It's much cleaner as it's not yet another exception. Would we add tupples as feature to the language and introduce a (generated?) tupple type with some syntactic sugar as described above? If so, how would tupples compile to C code?
Tuples are product types, so they map to structs, and since C is a nice language, you can just inline the definition:
let x = (1, 4, "abc", -1 as int8);
struct /*struct type name is optional*/ {
int32_t _1;
int32_t _2;
char _3[4];
int8_t _4;
} tuple_x = { 1, 4, "abc", (int8_t) -1 };
printf("%d, %d, %s, %d", tuple_x._1, tuple_x._2, tuple_x._3, tuple_x._4);