lzwang2
lzwang2

Reputation: 95

Find the enclosing f of return in anonymous funcion

In Scala Language Specification 6.20 Return Expressions, it says: "A return expression return e must occur inside the body of some enclosing named method or function.The innermost enclosing named method or function in a source program, f..."

There is a innermost enclosing f here, and I want to find that f for return. But when it comes to anonymous function, things becomes a little complicated.

Example1: The innermost enclosing f here is f1. In the decompiled java code, we can see that the exception is caught by f1.

def main(args: Array[String]) { 
  def f1() { () => return }
}

Example2: The innermost enclosing f here is still f1. In the decompiled java code, we can see that the exception is still caught by f1, even though, from the execution view, f2 is return's innermost enclosing f.

def main(args: Array[String]) { 
  def f2(x: Any) { println(x) }
  def f1() { f2(() => return) }
}

Perhaps we can say, that in Example2, x is not trully executed in f2. But here is another weird example.

Example3: The innermost enclosing f here is main, not map and println.(But I know that the class file of map or println cannot be changed here.)

def main(args: Array[String]) {
  val list = List(1, 2, 3)
  println(list.map(x => return x * 2))
}

In a word, it seems that this innermost enclosing f is exactly the method with that exact def which contains the return expression directly.

Am I right?

Upvotes: 1

Views: 44

Answers (1)

Andrey Tyukin
Andrey Tyukin

Reputation: 44918

Yes, you are right. "Enclosing" refers to "enclosing definition".

As you yourself have noticed, it cannot refer to "enclosing method invocations", because then even something as simple as the following canonical use case of an early return:

def findFirstGreaterZero(as: List[Int]): Option[Int] = {
  for (a <- as) {
    if (a > 0) return Some(a)
  }
  None
}

wouldn't work, even though there are no explicit lambdas in here. The for would desugar to (a <- as).foreach{ a => ... return }, and if the { a => ... return ...} would "enclose" the return keyword, the return would only return from the current invocation of the body of foreach, instead of returning from the method findFirstGreaterZero, which would make return mostly useless.

Upvotes: 1

Related Questions