This issue adds the ability for functions to return values to their caller. It adds return types, return statements, and implicit returns.
func add(a: int, b: int): int {
% ^ return type
return a + b;
% ^ return statement
}
func subtract(a: int, b: int): int => a - b;
% ^ implicit return
When a function returns, it completes execution and returns control back to the caller where the call occurs. When a function returns a value, it sends a value along with control back to the caller. The return type of a function is the static type of the returned value, and it tells the compiler the type of the call expression (v0.7.0). If a function returns a value, then its body, the statement block, must have a return statement, which contains the expression to evaluate and return. A function may have no body but an implicit return (using a fat arrow =>), which is the single expression that is returned. A function with an implicit return cannot contain any statements.
The above applies to function expressions as well.
let math: [
add: (a: int, b: int) => int,
subtract: (x: int, y: int) => int,
multiply: (int, int) => int,
% ^ return type
] = [
add= (a: int, b: int): int {
'''The sum will be {{ a + b }}.''';
return a + b;
},
subtract= (x as a: int, y as b: int): int => a - b,
multiply= (x: int, y: int): int => x * y;
];
A function body may have no return statement, or it may have an empty return statement (return; with no expression), in which case the function “returns void” (it returns, but it does not return a value) and its return type is void. Functions with implicit returns cannot return void — they must return a value. Functions that do not return (do not complete execution) are not covered in this issue, nor are asynchronous functions.
func divide(a: int, b: int): void {
'''I am not going to divide {{ a }} and {{ b }}.''';
% automatically returns here since it’s the end of the function body
}
let exp: obj = (a: int, b: int): void {
'''{{ a }} to the {{ b }} power is {{ a ^ b }}.''';
return; % explicit empty return statement
};
Variance
Function return types are covariant. This means that when assigning a function g to a function type F, the return type of g must be assignable to the return type of F.
type BinaryOperator = (int | float, int | float) => int | float;
let subtract: BinaryOperator = (minuend: int | float, subtrahend: int | float): float => minuend - subtrahend;
When a caller calls an implementation of BinaryOperator, they should expect its return value to be assignable to int | float. Since the return type of subtract is narrower, it satisfies that requirement.
Non-void functions return values.
Discussion
This issue adds the ability for functions to return values to their caller. It adds return types,
return
statements, and implicit returns.When a function returns, it completes execution and returns control back to the caller where the call occurs. When a function returns a value, it sends a value along with control back to the caller. The return type of a function is the static type of the returned value, and it tells the compiler the type of the call expression (v0.7.0). If a function returns a value, then its body, the statement block, must have a
return
statement, which contains the expression to evaluate and return. A function may have no body but an implicit return (using a fat arrow=>
), which is the single expression that is returned. A function with an implicit return cannot contain any statements.The above applies to function expressions as well.
A function body may have no return statement, or it may have an empty return statement (
return;
with no expression), in which case the function “returns void” (it returns, but it does not return a value) and its return type isvoid
. Functions with implicit returns cannot return void — they must return a value. Functions that do not return (do not complete execution) are not covered in this issue, nor are asynchronous functions.Variance
Function return types are covariant. This means that when assigning a function
g
to a function typeF
, the return type ofg
must be assignable to the return type ofF
.When a caller calls an implementation of
BinaryOperator
, they should expect its return value to be assignable toint | float
. Since the return type ofsubtract
is narrower, it satisfies that requirement.Specification
Lexicon
Syntax
Semantics
Decorate
FunctionTypeOf