Stream: ideas

Topic: Indentation parsing


view this post on Zulip Kiryl Dziamura (Jun 01 2024 at 21:27):

I want to ask about the possibility of changing the parsing flow. In short, can we consider each line with the same indentation either a separate expression or statement (except pipes, if/when patterns, and the other comprehendible cases)? So the parser doesn't assume what the author meant but asks for clarification via parsing error.

I admit I could be naive and not recognize a larger problem behind this proposal.

Let's talk about the expectations behind this snippet:

main =
    c = a
    b
    c

Right now it's parsed as if c is the continuation of b expression

main =
    c = a
    b
        c

But it may have been meant that b is the continuation of a:

main =
    c = a
        b
    c

There is also a third option now! It might be the await bang was missed:

main =
    c = a
    b!
    c

(I will omit further explorations of parser behavior after the bang is added. But for example, since the parser now implies the last two lines in my first snippet as b a, it makes sense to expect the last two lines in the bang example are b! a. It's not like this now)

So the original snippet is very ambiguous at least for me. I would expect a parsing error to be thrown instead. Smth like

main =
    c = a
    b
    c <-- unexpected expression, might be caused by missed indentation or lack of await bang

Or even

main =
    c = a
    b <-- unused expression. maybe you meant await bang or application?
    c

Because my gut feeling says each line on the same indentation level is either a statement or a separate expression.

view this post on Zulip Brendan Hansknecht (Jun 01 2024 at 21:40):

+1 to the general idea

view this post on Zulip Richard Feldman (Jun 01 2024 at 22:33):

@Joshua Warner brought up a similar idea awhile ago, although I'm not sure if it's written down anywhere? :sweat_smile:

view this post on Zulip Joshua Warner (Jun 01 2024 at 23:51):

Yep, I think that's here: https://roc.zulipchat.com/#narrow/stream/304641-ideas/topic/Design.3A.20Indents.20and.20Blocks

view this post on Zulip Joshua Warner (Jun 02 2024 at 00:07):

But yeah, I think especially with the new ! syntax this makes more sense than ever

view this post on Zulip Joshua Warner (Jun 15 2024 at 03:30):

Took another swing at this: https://github.com/roc-lang/roc/pull/6809 (wip; not quite ready for review)

view this post on Zulip Joshua Warner (Jun 15 2024 at 03:31):

A notable change here is that this used to parse, but no longer does:

when b is   3->4
            9
                |8->9

view this post on Zulip Joshua Warner (Jun 15 2024 at 03:33):

In particular, the issue is that when we enter the ->4 block, we set the min_indent to be the indent of the current line plus one (i.e. min_indent=1), which leads to the rest of the input being parsed as part of the expression (which of course doesn't work!)

view this post on Zulip Joshua Warner (Jun 15 2024 at 03:35):

It's unclear to me whether that's an important case to have parse + reformat :thinking:

view this post on Zulip Brendan Hansknecht (Jun 15 2024 at 04:52):

That used to parse? I'm kinda stunned

view this post on Zulip Brendan Hansknecht (Jun 15 2024 at 04:52):

I would assume a new line is required before the 3

view this post on Zulip Joshua Warner (Jun 15 2024 at 04:53):

Haha, yeah - it's with_multiline_pattern_indentation from test_fmt :)

view this post on Zulip Joshua Warner (Jun 15 2024 at 04:56):

My suspicion is that this is left over from some point in the past when when branches were required to line up exactly in column number, as I've seen be the style in some other languages.

view this post on Zulip Joshua Warner (Jun 15 2024 at 04:56):

Or at least this is a test that tries to make sure we can accept that style and do something sensible


Last updated: Jun 16 2026 at 16:19 UTC