Dotty: non-local returns through inlining?

Hello,

I just saw surfing the Internet that Dotty will have inlining, see https://dotty.epfl.ch/docs/reference/metaprogramming/inline.html. So this could be a way to make non-local returns transparent again as in Scala 2.

There is this code in https://github.com/lampepfl/dotty/issues/4240

def test(xs: List[Int]): Int = Returning {
    xs foreach { x =>
      if (x > 2)
        throwReturn(x)
    }
   0
}

which with inlining could be written like this:

def inline test(xs: List[Int]): Int = {
    xs foreach { x =>
      if (x > 2)
       return x
    }
   0
}

Just wanted to ask whether inlining to implement non-local returns would be considered, because the proposed workaround with throwReturn brings a bit a tear to my eye if you compare it with Scala 2.

Other languages have this as well as Smalltalk, Ruby and probably several more. Those languages don’t have to fight with the limitations of the JVM, but it would still be nice if it could be accomplished somehow ;-).

Regards, Haddock

The proposed workaround shows exactly what’s going on. Previously the mechanism was hidden and unpleasingly suprising. I think that rarely used (and thus not well known) constructs should be intentionally verbose to reduce probability of mistake.

If they don’t have to fight then maybe it’s a different problem after all? Presence of limitations shouldn’t be an excuse for making error prone solutions.

Overall I think that the semantics of return in Scala is weird. It returns from nearest enclosing method instead of nearest enclosing expression block. In case of local returns the difference doesn’t exist, so that’s the case where there’s no confusion.

1 Like

Hmm…, it seems you are seeking for some kind of hygienic mixin injecting code into the caller which is accomplished to some degree with inlining but afaict, inlining turns returns into assignments.

Inlining means, that the generated byte code of a method is inserted in the class file rather than the call to the method.

This is the way the Kotlin guys have implemented non-local returns quite nicely, see https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns

Yes, this is Kotlin’s view of inlining, but not the usual view of inlining. Traditionally, inlining shouldn’t change semantic at all, just performance.

What you want is a hygienic mixin where any call of it doesn’t introduce a new scope but all locals are prefixed for collision safety.

I think what you want seems not to be possible.

I hope I missed something as there are definitely use cases, e.g. return if null or None.

I would be perfectly happy with the solution the Kotlin guys came up with. Having to declare the method with inline is way better than having to go with returning and throwReturn.

Anyway, the purpose of my post was to ask the Scala compiler guys kindly to consider the issue.