I added a FAQ for some questions we've seen come up a few times - thoughts and feedback welcome!
https://github.com/rtfeldman/roc/blob/15a6193670a0393fe6d7dee6c0e4a2ef5fc10c1c/FAQ.md
I left some comments on https://github.com/rtfeldman/roc/pull/2522
Might be worth reversing the order of the questions. The first one is a bit intimidating!
Something I don't understand (and maybe is FAQ worthy) is how code like this
decoder =
Json.Decode.succeed Point
|> Json.Decode.field "x" Decoder.int
|> Json.Decode.field "y" Decoder.int
parser =
Parser.succeed Point
|= Parser.int
|. Parser.symbol ","
|= Parser.int
translates over to Roc. Since there's no currying this won't work directly right?
Here's a refactoring of your Elm code that uses explicit currying instead of implicit.
decoder =
Json.Decode.succeed Point
|> (\a -> Json.Decode.field "x" Decoder.int a)
|> (\a -> Json.Decode.field "y" Decoder.int a)
And you could translate that more directly to Roc
I think the way to go here is backpassing?
True, that works in this example. Does it work for replacing all instances of currying? Because I thought that was more what Martin was getting at.
Brian Carroll said:
Here's a refactoring of your Elm code that uses explicit currying instead of implicit.
decoder = Json.Decode.succeed Point |> (\a -> Json.Decode.field "x" Decoder.int a) |> (\a -> Json.Decode.field "y" Decoder.int a)
I don't think this works. The issue is that after |> (\a -> Json.Decode.field "x" Decoder.int a)
only the x value is applied to Point which isn't possible if you don't have currying.
I think the way to go here is backpassing?
Maybe this could work. Perhaps an example of this could be added to the FAQ?
this is the backpassing translation:
decoder =
x <- required "x" int
y <- required "y" int
succeed { x, y }
(using an API similar to json-decode-pipeline)
Is backpassing only for monads (if I may be forgiven for using the M-word)?
no, it's just syntactic sugar; you can use it for anything!
oh I see. I was incorrectly thinking of it as an equivalent of do
notation from Haskell
we're more general than haskell
oh that's fun to say
That should be a slogan on the website
technically instead of writing this:
List.map list \elem ->
stuff
you can write this:
elem <- List.map list
stuff
...but I'm not saying I recommend it :big_smile:
(or for any higher-order function)
@Martin Stewart the backpassing version of the parser one would look similar, except it would be like <- keep (...)
or <- drop (...)
instead of |.
and |=
Cool! The backpassing approach looks nicer than the pipeline style in Elm. It's something I've gotten used to but it's strange to start with Json.Decode.succeed MyValue
. I imagine backpassing is easier to explain.
yeah I expect it to be easier to learn, although the Abilities approach might make it a moot point in the specific case of decoders
still relevant for parsers though!
Last updated: Jul 05 2025 at 12:14 UTC