As far as I can tell, you can't have a custom function to use with ! or ?, right? Any reason for this? I feel this feature would be so much more powerful if you could have a custom bind function. I wanted to create a monad-based parser package, and having a custom version of ! or ? would make consuming the API much better. Coming from Gleam and being used to its very powerful use
feature (backpassing), I was kind of unpleasantly surprised that this wasn't already possible.
We used to have backpassing, but we got rid of it because it was a source of confusion and it increased the Roc learning curve. We've been getting along great so far with just !
and ?
:)
Personally, even though I was new to FP when learning Gleam, I was never confused about backpassing. It seemed quite logical since the desugaring rules are always the same.
Anway—back to my original q—will there be a feature enabling custom version of ! and/or ? in Roc, something akin to
with Parser.andThen do
Parser.token! ...
ident = parse_ident!
Parser.token! ...
Parser.return (SomeAst ident)
I actually kind of like that syntax that I just made up, haha
There are no such plans currently. Only task and result
Couldn't you just use tasks for that as-is?
@MystPi have you seen the purity inference proposals?
I don't think these are really related to be clear.
What @MystPi wants is being able to chain no Task/Result types. For example generators, parsers, and the like. This is ident <- Parser.ident |> Parser.andThen
in the backpassing world. So any Task or Result solution may not apply. That said, Task may apply if the parser is running Tasks. Most likely the parser is just over a Str, so no Task is wanted at all
This is a common monadic pattern
The closest we have today is record builders
Like what is done for weaver
Otherwise, this all has to be done manually
This also can be done pretty well with shadowing (or mutable variables), but is more verbose than implicit state thread like is done with monads.
If we get mutable varibles _
suffix, the parser could be:
state_ = ...
state_ = Parser.token state_ ...
state_, ident = parse_ident state_
state_ = Parser.token state_ ...
state_ = Parser.return state_ (SomeAst ident)
A lot more verbose and less nice than having arbitrary monadic chaining with !
or backpassing.
I think if we get enough demand for it, we may one day open up !
like is suggested above (or some other similar solution), but currently there has been minimal demand.
Got it—I see that Roc's syntax is still very much in the development stage, which I can def understand
Luke Boswell said:
MystPi have you seen the purity inference proposals?
No I haven't, though after reading (skimming) it I can't say I really get what it's about, haha. Not sure how it applies to my question either
I see that Roc's syntax is still very much in the development stage
Yeah, it has changed a lot over the last year. Generally speaking, we start with the more minimal version of a feature (eg !
just for task) before we expand to something more powerful (eg generic !
)
Last updated: Jul 06 2025 at 12:14 UTC