Stream: contributing

Topic: Parens and commas work


view this post on Zulip Anthony Bullard (Dec 27 2024 at 05:27):

Got my first unit test with PNC to work - alongside whitespace application. Long way to go, but I'll use this thread to collect feedback and share progress

view this post on Zulip Anthony Bullard (Dec 27 2024 at 05:29):

THese two are passing

    #[test]
    fn single_line_application_with_parens() {
        expr_formats_same(indoc!(
            r"
            combine(peanut_butter, chocolate)
            "
        ));
    }

    #[test]
    fn multi_line_application_with_parens() {
        expr_formats_same(indoc!(
            r"
            combine(
                peanut_butter,
                chocolate
            )
            "
        ));
    }

Any especially tricky cases you'd like to see tested let me know

view this post on Zulip Anthony Bullard (Dec 27 2024 at 05:30):

And yes, I will make the second case allow trailing comma and make sure it formats to that

view this post on Zulip Brendan Hansknecht (Dec 27 2024 at 05:33):

One really nice feature in some language formatters: if you add the trailing commas, it formats to multiline. If you delete the trailing comma it formats back to single line.

view this post on Zulip Brendan Hansknecht (Dec 27 2024 at 05:33):

Note: I think they generally will still override and go to multiple if a line gets way too long

view this post on Zulip Anthony Bullard (Dec 27 2024 at 13:11):

I can do that

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:23):

Brendan Hansknecht said:

Note: I think they generally will still override and go to multiple if a line gets way too long

I like the "trailing comma means I want multiline" idea, but I don't think we should enforce line lengths in any way.

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:23):

having spent a lot of time with formatters that do and don't enforce line lengths, I still find the line lengths enforcement a significant source of annoyance and not a significant source of helpfulness

view this post on Zulip Anthony Bullard (Dec 27 2024 at 13:25):

Thank you for that Richard! And I agree totally

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:25):

that said, I do think having a line-length-enforcing formatter would be helpful for docs generation, because then we can tell it exactly how many monospace chars are going to be available on the page, and wrap gracefully based on that (since there's no way to avoid wrapping in that scenario)

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:27):

and sometimes we want to generate inferred types for docs that weren't annotated, so in those cases we have to add line breaks somewhere anyway

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:27):

but I think that's a separate use case, and I don't think roc format should enforce at all :big_smile:

view this post on Zulip Anthony Bullard (Dec 27 2024 at 13:29):

I think for docs you don’t really need tooling

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:39):

agreed, but I do think it would be helpful (someday) when it comes to wrapping!

view this post on Zulip Richard Feldman (Dec 27 2024 at 13:39):

another way to think of it: if we don't have our own wrapping logic, the browser is going to decide how to wrap on overflow, and it's not going to look right (compared to if we did it ahead of time)

view this post on Zulip Anthony Bullard (Dec 27 2024 at 13:47):

Yeah you’d want that tool to output differently wrapped output based on screen width

view this post on Zulip Anthony Bullard (Dec 27 2024 at 13:54):

Which would require a derivative of the “A prettier printer” algo

view this post on Zulip Richard Feldman (Dec 27 2024 at 14:03):

yeah, we could (for example) include different wrapping widths at different breakpoints in the HTML, and then hide all but 1 of them as the screen resizes

view this post on Zulip Richard Feldman (Dec 27 2024 at 14:04):

so you're only ever seeing one, but they've all been precomputed to look nice at a few different widths

view this post on Zulip Anthony Bullard (Dec 27 2024 at 14:07):

You’d probably want to move our formatter to using a prettier algo, with a default width of Infinity.

view this post on Zulip Richard Feldman (Dec 27 2024 at 14:10):

that could work! :+1:

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:39):

I've run into a weird failure with the test_fmt tests: I get that these are not the same, but I've tested in my editor and these are byte for byte equivalent:

 combine(
     mix(vodka, gin),
     FoodItems.Juices({
<        color: Colors.orange,
<        flavor: Flavors.orange,
>        color: Colors.orange,
>        flavor: Flavors.orange,
         amount: 1 + 2,
     }),
 )

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:39):

Has anyone ran into this before, and what things should I be looking for?

view this post on Zulip Sam Mohr (Dec 27 2024 at 15:40):

Are there escape sequences being hidden?

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:40):

Sam Mohr said:

Are there escape sequences being hidden?

I can check, but my editor sure didn't catch it. I copied one line, but it in find and it finds both lines

view this post on Zulip Sam Mohr (Dec 27 2024 at 15:41):

Try manually typing, copy-paste would hide the issue

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:42):

Screenshot 2024-12-27 at 9.42.04 AM.png

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:42):

I did that as well

view this post on Zulip Sam Mohr (Dec 27 2024 at 15:42):

Super weird. Probably not worth the investigation

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:43):

So I should get rid of the test?

view this post on Zulip Sam Mohr (Dec 27 2024 at 15:46):

Can you not just update the result?

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:47):

This isn't a snapshot

view this post on Zulip Anthony Bullard (Dec 27 2024 at 15:47):

This is an indoc test

view this post on Zulip Sam Mohr (Dec 27 2024 at 15:48):

You can comment it out and I'll try to fix it once this gets to the PR stage

view this post on Zulip Notification Bot (Dec 27 2024 at 19:51):

24 messages were moved from this topic to #contributing > 🚨 Whitespace application and whitespace - breaking change! 🚨 by Anthony Bullard.

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:01):

Another interesting bit.

Currently creating a Type with type parameters has this syntax:

List a : [Cons a (List a), Nil]

But with PNC right now this would look like:

List(a) : [Cons(a, List(a)), Nil]

Is that lhs desired? or would we instead expect

List : a -> [Cons(a, List(a)), Nil]

I honestly don't know which why I'd go with this, but this does give it the feel of List is a type that needs a type arg a to be supplied for it to be "applied" and made concrete.

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:05):

Another advantage of the latter is that any form of application in types would be uniform

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:09):

Well of course I didn't think about the obvious problem - this is not obviously distinguishable from a Function type being defined :-(

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:10):

So I guess List(a) : [Cons(a, List(a)), Nil] it is! Unless someone else has a genius idea here

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:13):

This is the only real example from the static dispatch proposal, and it is using non-PNC syntax for this one and only case, and I don't think that's a good outcome:

Sort a : a
    where a.order(elem, elem) -> [LT, EQ, GT]

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:14):

@Richard Feldman if you could opine here, that would probably help unblock me.

view this post on Zulip Richard Feldman (Dec 27 2024 at 22:15):

current plan is to leave type syntax completely unchanged relative to today

view this post on Zulip Richard Feldman (Dec 27 2024 at 22:15):

we can discuss in a thread if we want to make changes, but currently no plans to change anything

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:29):

So only when using the constructors as values?

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:31):

I think seeing Cons a (List a) in a type annotation and Cons(123, Nil) when used as a value might be....confusing

view this post on Zulip Anthony Bullard (Dec 27 2024 at 22:31):

But maybe not more confusing than Str, Str -> Str / |a, b| a contrast

view this post on Zulip Richard Feldman (Dec 27 2024 at 22:42):

it's a fair point, but we haven't discussed it before, and I think we should discuss before making any implementation changes :big_smile:

view this post on Zulip Anthony Bullard (Dec 28 2024 at 12:46):

So here is the first Roc program to compile with 100% PNC usage:

app [main!] {
    pl: platform "../../basic-cli/platform/main.roc",
}

import pl.Stdout
import pl.Stdin
import pl.Stderr

main! = \_args ->
    tick!({})

tick! = \{} ->
    try Stdout.write!("Enter a number: ")
    when Stdin.line!({}) is
        Ok(str) ->
            num =
                Str.toU8(str)
                |> Result.withDefault(255)
                |> addOne()
            try Stdout.line!("Did you write $(Num.toStr(num)) (Y/n)")
            when Stdin.line!({}) is
                Ok "n" -> Ok({})
                Ok _ -> tick!({})
                Err _ -> Err(Done)

        Err(EndOfFile) ->
            try Stderr.line!("EOF")
            Err(Done)

        Err(StdinErr(_)) ->
            try Stderr.line!("Couldn't read from stdin")
            Err(Done)

addOne = \n ->
    if n == 255 then
        255
    else
        n + 1

view this post on Zulip Anthony Bullard (Dec 28 2024 at 12:47):

It's very dumb, but it was something that was quick to translate...working on migrating some of my AOC

view this post on Zulip Anthony Bullard (Dec 28 2024 at 12:47):

(NOTE: This is with PI as well)

view this post on Zulip Anthony Bullard (Dec 28 2024 at 12:57):

PR is up: https://github.com/roc-lang/roc/pull/7421

view this post on Zulip Brendan Hansknecht (Dec 28 2024 at 18:18):

This doesn't look like correct PNC:

num =
    Str.toUtf8(str)
    |> Result.withDefault 255
    |> addOne

Should be:

num =
    Str.toUtf8(str)
    |> Result.withDefault(255)
    |> addOne()

view this post on Zulip Anthony Bullard (Dec 28 2024 at 18:21):

You got me. I’ll fix that

view this post on Zulip Anthony Bullard (Dec 28 2024 at 18:33):

Thanks for pointing that out Brendan, think I caught a formatter error

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:13):

I just wanted to share this, from someone I know who's planning to try Roc soon and who didn't know PNC was coming:

This is super exciting stuff. My only points of friction are not having a version manager and getting used to the omitted parens

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:13):

(I told him about our "cli versions itself plans, and asked to clarify if the second thing was referring to whitespace calling)

Yeah having spaces only is a trip for me, as I’m already dyslexic and struggle to read code I’ve been used to for years, but I know this isn’t a roc thing, I’ve seen it in other languages in the functional world
But, I’m excited to play with it
And an optimistic that my brain will adjust

view this post on Zulip Anthony Bullard (Jan 22 2025 at 22:14):

Nice to hear!

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:14):

(I explained about PNC)

Wait
You have parenthesis now?

view this post on Zulip Anthony Bullard (Jan 22 2025 at 22:15):

I wonder if people with dyslexia and maybe mild forms of ADHD struggle to parse whitespace application as a general rule? Maybe the parens and then commas help guide their eyes from left to right?

view this post on Zulip Anthony Bullard (Jan 22 2025 at 22:16):

Would be interesting if there has been any science done on something like that

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:16):

(yup!)

:tada:
Hell yeah! I didn’t expect that. I think that was literally my only “I don’t know if I can read/write this” point when looking at the language lol
The parenthesis stuff was my biggest worry
And prob the main thing that kept from digging in sooner
It’s always been on my list, literally an apple notes list I have to play with new tech, roc has been there since [before he'd even met me]

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:16):

Anthony Bullard said:

I wonder if people with dyslexia and maybe mild forms of ADHD struggle to parse whitespace application as a general rule? Maybe the parens and then commas help guide their eyes from left to right?

yeah it's the first time I've heard of it, but it was really heartwarming to hear! :smiley:

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:17):

makes me feel better about the loss of aesthetics I like, knowing that for others the benefit is much more than aesthetic

view this post on Zulip Anthony Bullard (Jan 22 2025 at 22:18):

Yes, a lot of things that make a language easier to parse for a computer, makes it easier for (many) humans to parse

view this post on Zulip Anthony Bullard (Jan 22 2025 at 22:19):

Us humans just have a lot more natural variance than computers

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:20):

also, this is someone who has done Gleam in the past, so it's interesting that whitespace calling was specifically a barrier to trying Roc where functional semantics weren't at all a barrier (this is someone coming from an imperative background)

view this post on Zulip Richard Feldman (Jan 22 2025 at 22:22):

anyway, thanks to all who made it happen! :smiley:


Last updated: Jul 06 2025 at 12:14 UTC