Skip to content

Instantly share code, notes, and snippets.

@bishabosha
Last active January 31, 2026 17:29
Show Gist options
  • Select an option

  • Save bishabosha/95880882ee9ba6c53681d21c93d24a97 to your computer and use it in GitHub Desktop.

Select an option

Save bishabosha/95880882ee9ba6c53681d21c93d24a97 to your computer and use it in GitHub Desktop.
Scala break/continue zero-cost loop abstraction
//> using scala "3.3.0"
import scala.util.boundary, boundary.break
object Loops:
type ExitToken = Unit { type Exit }
type ContinueToken = Unit { type Continue }
type Exit = boundary.Label[ExitToken]
type Continue = boundary.Label[ContinueToken]
object loop:
inline def apply(inline op: (Exit, Continue) ?=> Unit): Unit =
boundary[ExitToken]:
while true do
boundary[ContinueToken]:
op
inline def exit()(using Exit) = break(().asInstanceOf[ExitToken])
inline def continue()(using Continue) = break(().asInstanceOf[ContinueToken])
import Loops.*
@main def oddsUpToLimit(limit: Int) =
var i = 0
loop:
i += 1
if i == limit then loop.exit()
if i % 2 == 0 then loop.continue()
println(i)
@bishabosha
Copy link
Author

bishabosha commented Jan 31, 2026

Note: in 3.3.0 the trick with type ExitToken = Unit { type Exit }; type ContinueToken = Unit { type Continue } worked, and exception throwing is replaced with jumps, but in later versions of scala aparently now it deoptimises

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment