Is Direct Style Boundary and Break not just labels and goto in disguise?

I saw Martin Odersky’s “direct scala style” video here Martin Odersky DIRECT STYLE SCALA Scalar Conference 2023 - YouTube and wanted to discuss it but I wasn’t sure where.

From the introduction, the goal is to provide Await/Async without the boilerplate of cats effect / zio. Seems very reasonable.

What concerns me, is that we introduce Boundaries and Breaks. A Boundary is a label and Break is a goto/return statement. Since break outside of the label’s function (by design), it is equivilent to a C-style long jump.

What are the differences between “boundaries and labels” vs “goto/return and break” and what does this mean for the language? Are we hoping our code will look like assembly in the future, disregarding function definitions for high-performance labelled code blocks?

Why would we reimplement a solution that was intentionally dropped in the 80s as being terrible for managing complexity (goto)? Is this not a step backwards? Will we need to copy coding styles from other languages to minimise the data corruption that is inevitable with code paths that can’t be reasoned about?

Am I alone in my concerns or is there some part of this which I’ve overlooked? It feels like Async/Await could be achived in other ways and keeping the language small is important. Maybe resume on Exceptions is an interesting concept but again I think it’s achievable in other ways.

I’m interested in hearing other people’s thoughts.

boundary/break is not a goto. It’s essentially a try..catch and a throw. You can see their entire implementation here:

See? No goto!

What may have gotten you confused is that the compiler sometimes optimizes a boundary/break with what is basically a goto or a return. But that’s no different from the fact it uses gotos anyway to implement your if..then..elses, while loops and @tailrec methods. :wink:

I appreciate it doesn’t use “goto”, ,my concern is that it provides something similar to Goto. Therefore the following Scala would be valid (with a bit of syntax cleanup):


object DirectScalaStyle {

// Style scala allows programming
// without functions since it labels/goto
// were the approach assembly used before
// their invention.

main:  // (this is a boundary)

    println("welcome to Scala")
    
    start:         // (this is a boundary)
        var i = 10
        var label :Label = main   // (next cpu instruction)

    printFunc:
        println(s"i is $i")
        break(None)(label)        // effective goto. returns to where variable says.

    minus1:
        break(i - 1)(label)
        
    retry:
        i = 10

    loopBody:
        i -= 1
        next:
            label = next                   // where to return control
            break(None)(minus1)   // goto    (with label set, break comes back here!)
            break(None)(println)     // jump out
            if (i > 0):
                break(i)(next)
            else:
                break(i)(loopBody)
    break(None)(retry)
}

Does boundary and break allow code like this to be the the future of Scala?

No, that doesn’t work. You can only break out of a boundary. Once you’re out of a boundary, you can’t “break” to it anymore. Your break(None)(minus1) for example is already impossible to do.

So you are limited to behaviour like this:

firstline:
   maybe:
       break(if (new java.util.Random().nextBoolean) break(None)(firstLine) else break(None)(maybe)
   println("maybe")
println("always")

Like the same mechanics as an Exception, and this is okay because it’s how Exceptoins currently work? Ok, thanks for clearing that up.

Sadly, despite all the keynote speeches about “simple Scala” or “Scala, simply”, the language could have been made much simpler by expunging if/then/else and while/do in favor of goto.

That would have had the salubrious result that all discussion about if/then/else and while/do syntax would have ended immediately, as well as the tiresome debates about braces. With goto, there is no longer some mysterious uncertainty about where you’re jumping to.

IDEs such as Metals+VSCode and Ensime:TNG could display code with a configured set of elements such as while loops, and could also warn if the gotos no longer conform to old-style control structures. This is just a user preference, like “expand tabs to spaces” or “fold comments”.

As has been discussed in the community this year, Scala could finally gain some ground on “go” by becoming the pragmatic “goto” language. Obviously, this would be an immense rebranding effort and would require a SIP. But thanks for bringing this effort back into the discussion.

It’s worth adding that it’s important for our mental and physical health to have boundaries and also to take breaks.

10 Likes