Stream: compiler development

Topic: Bringing `then` back?


view this post on Zulip Aurélien Geron (Jun 26 2026 at 03:48):

Am I the only one who misses the then keyword?

For example, I find the following more readable with then than without it:

fact = |n| if n == 1 then 1 else n * fact(n-1)

fact = |n| if n == 1 1 else n * fact(n-1)

I can make it a bit more readable by adding curly braces, but I still find the then version easier to read:

fact = |n| if n == 1 then 1 else n * fact(n-1)

fact = |n| if n == 1 { 1 } else { n * fact(n-1) }

fact = |n| if n == 1 { 1 } else n * fact(n-1)

In fact, I think I also prefer if .. then .. else .. over Python's .. if .. else .. syntax:

fact = lambda n: 1 if n == 1 else n * fact(n-1)

view this post on Zulip Luke Boswell (Jun 26 2026 at 04:11):

See these previous discussions
#ideas > alternative to "then" for if/then/else? @ 💬
#ideas > eliminate `then` keyword @ 💬

view this post on Zulip Luke Boswell (Jun 26 2026 at 04:12):

I like then personally... I dont feel strongly about it or anything

view this post on Zulip Aurélien Geron (Jun 26 2026 at 04:21):

Thanks @Luke Boswell , interesting discussions, I should have searched further in the past. Most examples in these discussions surround the condition with parentheses, which does help quite a bit:

fact = |n| if (n == 1) 1 else n * fact(n-1)

If also like the multiline examples in the discussions:

if n == 1
    1
else if n == 2
    2
else if n == 3
    3
else
    4

This does look better than with the then keyword:

if n == 1 then
    1
else if n == 2 then
    2
else if n == 3 then
    3
else
    4

But in these cases a match is often preferable.

view this post on Zulip Luke Boswell (Jun 26 2026 at 04:22):

It can be hard searching further back... I love throwing Haiku at it on the zulip export

view this post on Zulip Richard Feldman (Jun 26 2026 at 17:45):

how do you feel about it with and without parens around the condition when it's a function call specifically?

fact = |n| if (n == 1) 1 else n * fact(n-1)
fact = |n| if n.is_eq(1) 1 else n * fact(n-1)
fact = |n| if (n.is_eq(1)) 1 else n * fact(n-1)

view this post on Zulip Aurélien Geron (Jun 26 2026 at 23:47):

Tbh I still prefer with then for all single-line examples. In your 3 examples, I prefer 1 and 2. Not a fan of the double parentheses in the 3rd example.

view this post on Zulip Richard Feldman (Jun 26 2026 at 23:59):

fair, but I just don't think it's worth the weirdness budget - it's not confusing per se, but no mainstream languages have it, and the benefit seems super minor

view this post on Zulip Aurélien Geron (Jun 27 2026 at 01:12):

Haskell and Ruby have if cond then A else B. Scala and Kotlin have if (cond) A else B. But the only language I know of that has if cond A B is Clojure.
I guess I'm happy with if cond A else B in general, except when cond and A are hard to tell apart, like in if x == 1 1 else 11. Maybe a style guide could encourage to use parentheses in such cases: if (x == 1) 1 else 11.

view this post on Zulip Jared Ramirez (Jun 27 2026 at 01:14):

coming in late, but imo i like encouraging using {} for the bodies over () for the condition. this is what rust does and it feels clear to me, but just one person’s opinion

view this post on Zulip Richard Feldman (Jun 27 2026 at 01:34):

ah so like:

fact = |n| if n == 1 { 1 } else { n * fact(n-1) }

view this post on Zulip Jared Ramirez (Jun 27 2026 at 01:46):

yeah exactly

view this post on Zulip Jared Ramirez (Jun 27 2026 at 01:46):

but on the flip side it’s a little more verbose

view this post on Zulip Jared Ramirez (Jun 27 2026 at 01:47):

i still prefer it tho, and if you really want a terse 1-liner you can leave them off, but that could be the exception rather than the rule

view this post on Zulip Norbert Hajagos (Jun 27 2026 at 08:49):

I still don't get how we can get away with this. I used to learn that the parens around the cond are there, because there needs to be a delimiter that marks the end of the cond. So the opening paren is completely useless, it's just there so that the closing paren , which is the delimiter has a pair so it doesn't look weird for a human. If you get rid of them, you need another delimiter, like then, : or the beginning of the branch has to be well specified, like always starting a new block with {, a la rust.

What language feature did we say not to that enables this syntax where we don't have a delimiter between the cond and A? Clojure ofcourse embraced the list syntax which is easy to parse, but Roc's look totally normal.

view this post on Zulip Richard Feldman (Jun 27 2026 at 19:10):

depend on what else is going on with the syntax

view this post on Zulip Richard Feldman (Jun 27 2026 at 19:11):

in Roc's new syntax (very much unlike the original syntax), if a b is unambiguously if and then an expression a and then an expression b

view this post on Zulip Richard Feldman (Jun 27 2026 at 19:12):

before, a b could have been a function call, so you couldn't tell where the condition ended without some sort of close-delimiter

view this post on Zulip Richard Feldman (Jun 27 2026 at 19:12):

I'm assuming there are other languages (e.g. C) that have something similar going on: there's some reason you can't tell where an expression ends just with whitespace

view this post on Zulip Richard Feldman (Jun 27 2026 at 19:13):

either that or they decided they don't want whitespace to mark the end of an expression, so that whitespace can always be optional and never semantic

view this post on Zulip Norbert Hajagos (Jun 27 2026 at 21:16):

Yes, i've looked at C and apparently you can call fn-s with a space before the open paren.

// Ambiguous Code, could just be a function call
if foo (x) ;

view this post on Zulip Richard Feldman (Jun 27 2026 at 21:45):

ah yeah we don't allow that

view this post on Zulip Richard Feldman (Jun 27 2026 at 21:46):

that's probably part of the reason why we don't need semicolons and C does


Last updated: Jul 23 2026 at 13:15 UTC