Returning a value: there is no return
EK9 has no return statement. A function or method declares its result with '<-', assigns it, and the result is whatever it holds when the body ends. The compiler proves every path leaves it with a value.
Why
EK9 has no 'return'. It is not in the grammar, so there is no warning to ignore and no linter to switch off: writing one is E01072, and the message says what to do instead.
The reason is that an early exit is where function bugs live. A path that forgets to return anything, cleanup that is skipped because the function left early, code after a return that can never run, and the famous duplicated 'goto fail' that skipped the signature verification of a server's key exchange: each is an exit that the reader did not see coming. A function with one way out has none of them.
So a function names its result. 'rtn as String: "unknown"' declares the result and gives it a value, and that value is the answer unless a later statement replaces it. Or declare it with no value, 'rtn as String?', and the compiler proves that every path assigns it before the body ends. A path that does not is E08050, reported on the declaration, which is where the fix goes.
What used to need an early return has an answer that cannot be misread. A guard ('if name <- lookup(code)') runs its body only when the value is set, so the initial value stands otherwise. A 'switch' or a stream produces the value itself. 'filter' skips what 'continue' would skip, and 'head' stops where 'break' would stop.
That is the pattern throughout EK9's control flow: take away the construct that hides the bug, and give the legitimate use a form the compiler can check. The flow control page (linked under Related) makes the same argument for 'break' and 'continue', with the evidence.
The correct form
#!ek9 defines module site.functions.noreturn defines constant noon <- 12 evening <- 18 defines function //The initial value is the answer unless a later statement replaces it. greeting() as pure -> hour as Integer <- rtn as String: "Good evening" if hour < noon rtn: "Good morning" else if hour < evening rtn: "Good afternoon" //No initial value: the compiler proves that every path gives it one. sign() as pure -> amount as Integer <- rtn as String? if amount < 0 rtn: "negative" else if amount > 0 rtn: "positive" else rtn: "zero" //A switch returns a value through its own '<-' variable. dayKind() as pure -> day as String <- rtn as String: switch day <- kind as String? case "Saturday", "Sunday" kind: "weekend" default kind: "weekday" lookup() as pure -> code as String <- rtn as String? if code == "GB" rtn: "United Kingdom" else rtn: String() //A guard replaces the early return: the body runs only when lookup gives a set value, //otherwise the initial value stands. countryName() as pure -> code as String <- rtn as String: "unknown" if name <- lookup(code) rtn: name isPositive() as pure -> amount as Integer <- rtn as Boolean: amount > 0 //A stream replaces a loop with 'continue' or 'break': 'filter' skips items ('head n' would stop //early), and '>' adds each Integer into the returning variable. sumOfPositives() as pure -> amounts as List of Integer <- rtn as Integer: 0 cat amounts | filter by isPositive > rtn defines program NoReturn() stdout <- Stdout() stdout.println(greeting(9)) stdout.println(greeting(20)) stdout.println(sign(-4)) stdout.println(sign(0)) stdout.println(dayKind("Sunday")) stdout.println(dayKind("Monday")) stdout.println(countryName("GB")) stdout.println(countryName("XX")) stdout.println($ sumOfPositives([-3, 0, 7, 2]))
Download functions_no_return.ek9
Output
Good morning Good evening negative zero weekend weekday United Kingdom unknown 9
Wrong forms
Each of these is written by people and by models, and each fails to compile - the error is what the compiler tells you.
Writing 'return'
There is no 'return' statement: declare the result with '<-' and assign it; the function ends at the end of its body.
Fails with E01072: 'return' does not exist in EK9 - declare return values with '<-' and compiler ensures all paths initialize
#!ek9 defines module bad.site.functions.noreturn.keyword defines function sign() as pure -> amount as Integer <- rtn as String? if amount < 0 return "negative" return "not negative"
Download functions_no_return_keyword.ek9
Read about E01072: 'return' does not exist in EK9 - declare return values with '<-' and compiler ensures all paths initialize
A returning variable a path never sets
A returning variable declared with no initial value must be given one on EVERY path; the 'zero' path here gives it none. Add the missing 'else', or give it an initial value.
Fails with E08050: return value is not always initialised
#!ek9 defines module bad.site.functions.noreturn.missedpath defines function sign() as pure -> amount as Integer <- rtn as String? if amount < 0 rtn: "negative" else if amount > 0 rtn: "positive"
Download functions_no_return_missed_path.ek9
Read about E08050: return value is not always initialised