It is surprising to me that join_with can't be called on a List with static dispatch:
my_list.join_with(" ") # missing method error!
I understand that this is because join_with is a function in Str.
But since its first arg is a List, and it's intuitive to call it on a List as above, should join_with be a List function? Or am I missing something?
Complete example (run from test/fx):
app [main!] { pf: platform "./platform/main.roc" }
import pf.Stdout
main! = || {
newline_separated = "1\n2\n3"
list = newline_separated.split_on("\n")
space_separated = list.join_with(" ")
Stdout.line!(space_separated)
}
I also realize this function doesn't take just any List, but specifically List Str.
On the other hand, there is already at least one List function that operates on a specific List type: concat_utf8 : List U8, Str -> List U8
:thinking: I can't think of a reason not to offer a generic one:
join_with : List(item), item -> List(item)
that would Just Work in this case, as well as others!
also, congratulations @Felipe Vogel - this is officially the first time someone has made a feature request based on real usage of static dispatch! :smiley:
Yay! I'm having fun with it .
Related question: how can I "break out" of static dispatch and call a function in a different module? For example, if I rewrite the above example in a "pipeline" style, my instinct is to use the pipe operator, but I know that's not available anymore in the new compiler:
main! = || {
"1\n2\n3"
.split_on("\n")
|> Str.join_with(" ")
|> Stdout.line!
}
Also, should I go ahead and open a GitHub Issue for a generic join_with?
yes please!
can you link to it here after you've created it?
regarding "break out" - we have -> which works just like |> in e.g. Gleam
so you can do ->Str.join_with(" ")
(at least, in theory! there may be bugs in the new compiler :laughing:)
Oh right, now I remember. I gave that a try just now and got a "not yet implemented" error:
-- NOT IMPLEMENTED -------------------------------
This feature is not yet implemented: canonicalize local_dispatch expression
This error doesn't have a proper diagnostic report yet. Let us know if you want to help improve Roc's error messages!
Found 1 error(s) and 0 warning(s) for test/fx/my_test.roc.
Roc crashed: runtime error
When running the following program (in test/fx):
app [main!] { pf: platform "./platform/main.roc" }
import pf.Stdout
main! = || {
"1\n2\n3"
.split_on("\n")
->Str.join_with(" ")
->Stdout.line!
}
Here's the GH Issue for generic join_with: https://github.com/roc-lang/roc/issues/8486
ah, I'll add -> support then!
Richard Feldman said:
:thinking: I can't think of a reason not to offer a generic one:
join_with : List(item), item -> List(item)
This would have different behavior than Str.join_with no?
Like ["a", "b"]->Str.join_with(" ") == "a b", but ["a", "b"]->List.generic_join_with(" ") == ["a", " ", "b"]?
Yeah, I think that is why it is a function on str
I think that is also why in python they switch it to be a method on the joiner " ".join(myList)
I'm just woke up and realized this and came here to say the same thing :joy:
interestingly, we could offer:
Str.join_with : List(Str), Str -> Str
List.join_with : List(item), item -> item
where [item.join_with : List(item), item -> item]
then either would work
I'm kinda into trying it out, see how it feels
Love the idea
https://github.com/roc-lang/roc/pull/8495 fixes the -> operator!
@Richard Feldman Thank you! -> is now working for local functions, but I'm getting errors when using it with builtins. I created an Issue with examples: https://github.com/roc-lang/roc/issues/8498
thanks! I'll look into that
That last pair of type annotations above is really neat. The bulk of my experience with static typing is in TypeScript, where expressing something like that would take a lot more than an extra line. Even in Haskell it would require more ceremony.
added List.join_with in https://github.com/roc-lang/roc/pull/8651
Last updated: Jun 16 2026 at 16:19 UTC