I think this is pretty intentionally avoided most of the time since it clutters up the continuation-passing semantics of the code... With `return` you have a much more complex base language. Especially since you can achieve it using monads.
Monads don't (quite) short-circuit the later computations unlike a return statement. Anyway, I'd like to see an example of writing this using monads, since it makes the idea more concrete.
I can write a continuation monad in Haskell which would. Something like
{-# LANGUAGE DeriveFunctor #-}
module Return where
import Control.Monad
newtype Cont r a = Cont { runCont :: (a -> r) -> r } deriving Functor
instance Monad (Cont r) where
return a = Cont (\k -> k a)
m >>= f = Cont (\k -> runCont m (\a -> runCont (f a) k))
early :: r -> Cont r a
early a = Cont (\_ -> a)
ex :: Cont Integer [Integer]
ex = do
forM [1..] $ \i -> do
when (i == 33) (early i)
return i