Returning from a method if code block returns


#1

Let’s say I have the following code

def foo(b: => Unit) = {
    b()
    println("hello")
}

foo( { 
    println("cool")
    return
})

I know return statements are only allowed in methods/functions
One good use case I can see is

Option(32).getOrElse(println, { return });

Today something like this can only be achieved is using

if (Option(32).isPresent) println(32) else return

which is no good than null checks

Having the ability to return from a method/function if the underlying code block returns can be a good thing to have


#2

Here is one way to do it:

def foo(b: (=> Nothing) => Int): Unit = {
  val r = b(return)
  println(r)
}

def test(b: Boolean) = foo { break => if (b) break else 42 }
test(true)  // does not print anything
test(false) // prints 42

But this is not very idiomatic. For the Option use-case, you probably just want to use map & co.


#4

“return” is a problem if the closure evaluation is deferred or done in another thread. “returns” in closures are implemented by throwing and catching some special exceptions (so they also incur performance cost), so you need to be careful to only invoke a “return” if you are inside the try/ catch block generated by the compiler.

Functional equivalent (or maybe generalization) of returns is continuation passing style. Scala has plugin for delimited continuations: https://github.com/scala/scala-continuations
Continuations are very flexible but they have their own problem when used on JVM. Because JVM doesn’t do tail call optimization, continuations can result in StackOverflowExceptions if used heavily.


#5

By the way, I suspect that result of this expression

is really far from result of this one:

because you probably are messing up
Option.getOrElse[B >: A](default: => B): B and
Map.getOrElse(key: K, default: => V): V.

Code like Option(32).getOrElse(println, ()) compiles only because several arguments for a single-argument-function is interpreted as a tuple containing all given arguments (in this case, (Unit, Unit)).