roc fmt, changes this:
expect [1, 2, 3] |> List.keep_if(|_| Bool.False) |> List.is_empty()
to this:
expect [1, 2, 3] |> List.keep_if(|_| Bool.False) |> List.is_empty
it removes the () on List.is_empty, is this intended behaviour? If so it is really confusing, I think the () should stay, so it is clear that it is a function.
Yes, it's intended behaviour, I remember discussions about that. I think it's just a matter of style. I agree that it's a bit inconsistent.
By the way, in your examples I would use static dispatch instead:
[1,2,3].keep_if(|_| Bool.False).is_empty()
also you don't need to write Bool.False unless you really want to; False will work just fine! :smile:
Hmm, okay thanks. For own functions, that e.g. work on Lists your suggestion does not work, and I would love to have the input value on the left and and what is tested on the right, so it is really good readable.
own_keep = |list, fun| list.keep_if(fun)
expect [1, 2, 3] |> own_keep(|_| False) |> List.is_empty
I think this would be the most elegant, but it does not work.
own_keep = |list, fun| list.keep_if(fun)
expect [1, 2, 3] |> own_keep(|_| False).is_empty()
expect [1, 2, 3].own_keep(|_| False).is_empty()
Love the |> pipe operator.
Was just wondering and these are just small things I wanted to explore, thank you :)
You actually need an extra space in this case. This works:
expect [1, 2, 3] |> own_keep(|_| False) .is_empty()
roc fmt will add parentheses to avoid any confusion:
expect ([1, 2, 3] |> own_keep(|_| False)).is_empty()
But you'll often want to define a pipe chain across multiple lines:
expect [1, 2, 3]
|> own_keep(|_| False)
.is_empty()
Interesting, this looks nice and lovely:
expect [1, 2, 3] |> own_keep(|_| False) .is_empty()
Unlucky that fmt adds the parentheses.
I'm not sure you can have a space after the dot, I think it must be before only (afk rn)
Just tested it, the compiler is really mad about that space after the dot, it gives it four errors. :sweat_smile:
── ✗ expected record accessor ──────────────────────────────────────────────────────────────────────── that-dot.roc:2:41
I was parsing access after `.`, and I expected a field name or tuple index.
expect [1, 2, 3] |> own_keep(|_| False) . is_empty()
^
Required record access uses .name, optional record access uses .?name, and tuple access uses .0. Accessor names must be lowercase and adjacent to their punctuation.
For example:
person.name
maybe_person.?name
pair.0
I found . here.
── ✗ unexpected statement ──────────────────────────────────────────────────────────────────────────── that-dot.roc:2:43
I was parsing a statement, and this token cannot start a statement here.
expect [1, 2, 3] |> own_keep(|_| False) . is_empty()
^^^^^^^^
Statements can be declarations, type annotations, imports, expectations, returns, crashes, loops, or expression statements inside a block.
For example:
answer = 42
I found is_empty here.
Names that start with lowercase letters are value names or record field names, depending on the surrounding syntax.
── ✗ unexpected statement ──────────────────────────────────────────────────────────────────────────── that-dot.roc:2:51
I was parsing a statement, and this token cannot start a statement here.
expect [1, 2, 3] |> own_keep(|_| False) . is_empty()
^
Statements can be declarations, type annotations, imports, expectations, returns, crashes, loops, or expression statements inside a block.
For example:
answer = 42
I found ( here.
── ✗ unexpected statement ──────────────────────────────────────────────────────────────────────────── that-dot.roc:2:52
I was parsing a statement, and this token cannot start a statement here.
expect [1, 2, 3] |> own_keep(|_| False) . is_empty()
^
Statements can be declarations, type annotations, imports, expectations, returns, crashes, loops, or expression statements inside a block.
For example:
answer = 42
I found ) here.
This closes the current construct, so the parser was looking for the missing item before it.
Last updated: Oct 15 2026 at 17:56 UTC