Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

And speaking of control structures...

    index, value := with
        i := 0
        count := len(haystack)
    loop
        while i < count else not_found
        elem := haystack[i]
        if is_special(elem) then continue
        if match(elem, needle) then break found(elem)
        // could also have been
        //   while not match(elem, needle) else found(elem)
        //   until match(elem, needle) then found(elem)
    always
        i = i + 1
    on not_found
        -1, _
    on found(result)
        i, result  // "i" is in scope here, but not "elem"
    ...
That, I believe, is one of the most generic forms of a loop, with a pre-header for declaring loop-local variables, multiple exit points (that accept parameters!), flexible condition checking ("while/until" being syntax sugar for "if ... then break ...", "continue" is "goto" the "always" block), and expanded space for the increment statement — and AFAIK no modern language supports it.

I mean, if you are making a new language, that's your chance to not stick with the old and tried stuff but try something more adventurous, like this loop device from Knuth's old paper.



I think the reason you won't find this in many languages is because people gravitate towards fewer constructs rather than more, and this syntax can be expressed using more general purpose semantics without any additional cost.

The syntax debate is usually something like, "what does this buy us and do we have the budget for it" and imo that loop syntax is not sufficiently general (it cannot express recursion, for example) nor does it make code easier to read (you now have what's essentially a few if/else blocks split across four different code blocks, I would reject this if I saw it in a code review to make the loop simpler), and it doesn't really prevent a user from making mistakes.

Extremely generic control flow constructs have also been shunned a bit. There's a lot of "call/cc considered harmful" content on the internet from a few years back, and I predict we'll see the same thing about new-fangled control flow constructs like algebraic effects.


There are languages with

    while cond1
       stmts1
    elif cond2
       stmts2
    elif cond3
       stmts3
syntax which is essentially a few if/else blocks pulled up to the enclosing loop level. Makes writing e.g.

   while a > b
     a := a - b
   elif b > a
     b := b - a
somewhat more concise. And Rust's "while let" loop easily could have allowed several clauses instead of single one.

And yes, you can express all of that with either "while true: ..." with early breaks/returns or with "while <OR'ing lots of Boolean flags>: ..." with post-processing those flags to determines why the loop has ended... but why not have explicitly named, limited continuations? IMO it would simplify dealing with "there maybe many reasons why the loop ended" kinds of iterations. Putting every loop into its own (anonymous) function that returns an ad-hoc sum type doesn't sound like a much better solution to me, to be fair.


from what i can tell, the only things here not supported by CL's LOOP is "continue", and there being named exit points with parameters, though I fail to see the usefulness of that when you could just use return.


Yes especially if you can make an inner (embedded) function just for that, that won't spill over the global function namespace. Ada's good in that aspect.




Consider applying for YC's Winter 2026 batch! Applications are open till Nov 10

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: