This page is no longer maintained — Please continue to the home page at www.scala-lang.org

scala.runtime.NonLocalReturnControl

5 replies
tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.

Hi!

What's precisely scala.runtime.NonLocalReturnControl? It's thrown when I tried
to explicitly leave (return) code embedded in 2 using(){}s.

using(...){
foo =>
using(...){
bar =>
...
if(true) return "hooray, I'm done" // boom
...
}
}

This works (I hate this style):

var r = "default"
...
if(true) r = "hooray, I'm done"
...
r

def using[A <: {def close() : Unit}, B](param: A)(f: A => B): B = {
try {
f(param)
} finally {
if (param != null) {
try {
param.close()
} catch {case _ => ()}
}
}
}

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: scala.runtime.NonLocalReturnControl

On Fri, Jun 18, 2010 at 02:00:49PM +0200, Timo Nentwig wrote:
> What's precisely scala.runtime.NonLocalReturnControl? It's thrown when
> I tried to explicitly leave (return) code embedded in 2 using(){}s.

It is a control flow exception necessary to implement the semantics of
the construct you are using. If you call return inside a closure, the
actual point of departure is in another class.

def f: Unit = List(1) foreach { x => if (x > 0) return else () }

Compile that and you'll see a second object which needs to return from a
method in the first one.

> } catch {case _ => ()}

This is your problem. Catching all Throwables is a disastrously bad
idea. You can find me talking about this a lot in the googly. I'm
still hoping to make code like that a compile time error: you'd have to
write catch _: Throwable => () to communicate that you know what you're
doing.

This is far from the only hard to figure out problem you will cause
yourself by catching everything.

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: scala.runtime.NonLocalReturnControl


On Fri, Jun 18, 2010 at 7:57 AM, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Fri, Jun 18, 2010 at 02:00:49PM +0200, Timo Nentwig wrote:
> What's precisely scala.runtime.NonLocalReturnControl? It's thrown when
> I tried to explicitly leave (return) code embedded in 2 using(){}s.

It is a control flow exception necessary to implement the semantics of
the construct you are using.  If you call return inside a closure, the
actual point of departure is in another class.

 def f: Unit = List(1) foreach { x => if (x > 0) return else () }

Compile that and you'll see a second object which needs to return from a
method in the first one.

>         } catch {case _ => ()}

This is your problem.  Catching all Throwables is a disastrously bad
idea.  You can find me talking about this a lot in the googly.  I'm
still hoping to make code like that a compile time error: you'd have to
write catch _: Throwable => () to communicate that you know what you're
doing.

This is far from the only hard to figure out problem you will cause
yourself by catching everything.

Is it the case that all throwables the represent program errors (e.g., MatchError) are now subclasses of Exception rather than Throwable?  In the past, the likes of MatchError (which I see is now a subclass of RuntimeException... which is should be) were Throwables and my general behavior in catching "Exceptions" is to catch Throwables because in the past, they bubbled up from Scala.
 

--
Paul Phillips      | All men are frauds.  The only difference between
Caged Spirit       | them is that some admit it.  I myself deny it.
Empiricist         |     -- H. L. Mencken
up hill, pi pals!  |----------* http://www.improving.org/paulp/ *----------



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Blog: http://goodstuff.im
Surf the harmonics
extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: scala.runtime.NonLocalReturnControl

On Fri, Jun 18, 2010 at 09:04:32AM -0700, David Pollak wrote:
> Is it the case that all throwables the represent program errors (e.g.,
> MatchError) are now subclasses of Exception rather than Throwable? In
> the past, the likes of MatchError (which I see is now a subclass of
> RuntimeException... which is should be) were Throwables and my general
> behavior in catching "Exceptions" is to catch Throwables because in
> the past, they bubbled up from Scala.

It is not the case. I cleaned that situation up a fair bit but it is
not done. There should be a complete review of all Throwable derived
classes: what they're named, how they're used, whether they suppress
stack traces, etc. And we should have either a language or (more likely)
library mechanism for saying things like "catch everything except what I
shouldn't catch."

But for now, you had best be alert.

nilskp
Joined: 2009-01-30,
User offline. Last seen 1 year 27 weeks ago.
Re: scala.runtime.NonLocalReturnControl
On Fri, Jun 18, 2010 at 12:27 PM, Paul Phillips <paulp [at] improving [dot] org> wrote:

It is not the case.  I cleaned that situation up a fair bit but it is
not done.  There should be a complete review of all Throwable derived
classes: what they're named, how they're used, whether they suppress
stack traces, etc. And we should have either a language or (more likely)
library mechanism for saying things like "catch everything except what I
shouldn't catch."

It would seem to me that any exception used by Scala for hidden control flow ought to all be derived from a special subclass of Throwable, and the compile should filter those out of any case _ or case _: Throwable. In other words, it should be impossible to catch them, enforced by the compiler.
tcn
Joined: 2010-04-02,
User offline. Last seen 2 years 18 weeks ago.
Re: scala.runtime.NonLocalReturnControl

On Fri, 18 Jun 2010, Paul Phillips wrote:

>> } catch {case _ => ()}
>
> This is your problem. Catching all Throwables is a disastrously bad
> idea. You can find me talking about this a lot in the googly. I'm
> still hoping to make code like that a compile time error: you'd have to
> write catch _: Throwable => () to communicate that you know what you're
> doing.

You're right. BTW IMHO it's a good idea utils like using() to be
part of the standard library. I use the same construct to measure the execution
time of the closure, too.

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland