mita icon indicating copy to clipboard operation
mita copied to clipboard

RFC: Multiple Returns

Open wegendt-bosch opened this issue 6 years ago • 3 comments

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.

wegendt-bosch avatar Apr 25 '18 14:04 wegendt-bosch

@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)*)? ')') 

wegendt-bosch avatar Apr 25 '18 14:04 wegendt-bosch

@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?

wegendt-bosch avatar Apr 25 '18 14:04 wegendt-bosch

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);

wegendt-bosch avatar Apr 25 '18 14:04 wegendt-bosch