We seemed to have reached the conclusion that even with loops, we still want to have effectful counterparts of have functions like List.walk
. I was going to include that in the Purity Inference PR, but I think we should do that separately once we have come up with the right API.
Here's a starting point for the discussion.
An effectful List.walk!
function seem essential:
List.walk! : List elem, state, (state, elem => state) => state
...and if you're running effects, most times you probably want to stop when one fails, so we should probably also have:
List.walkTry! : List elem, state, (state, elem => Result state err) => Result state err
You can also use this to stop early even if something didn't go wrong which is useful.
What about walkBackwards
, walkWithIndex
, walkUntil
, walkWithIndexUntl
, walkFrom
, walkFromUntil
?
It's probably going to be common to have to run an effect for each element of a List
, so we could have:
List.forEach! : List a, (a => {}) => {}
In practice, a lot of effectful functions in real platforms will return Result
which you won't want to discard, so we probably also need:
List.forEachTry! : List a, (a => Result {} err) => Result {} err
Should we have List.map!
? At first, I thought I wouldn't perform effects while mapping a List
, but actually some effects would fit:
contents = List.map! filesToRead File.read!
but of course, File.read!
would probably return a Result
, so what you really want is List.mapTry!
:smile:
Maybe we just need the _Try!
versions to start?
If we did that, I would probably still keep the Try
suffix in their names for consistency
I honestly think we should start with only forEach
and leave everything else to be standard recursive functions in userland until there is clear need and use cases
Especially with the for loop proposal on the horizon which I think would remove most of the need for these functions
Do you mean forEachTry!
?
I don’t expect forEach!
to be very useful in platforms like basic-cli
, but maybe it would be for things like roc-ray
I personally have only had uses for forEach!
so far
Oh wait....I might have had errors and results.....so maybe I need the try version
But yeah, would add both forEach variants as a starter.
I'd like to propose we add an Result.onErr!
so we don't need to do things like this... unless I'm missing something about how this should work in a purity inference world.
main! = \{} ->
when run! {} is
Ok {} -> Ok {}
Err err -> handleErr! err
main! = \{} ->
run! {}
|> Result.onErr! handleErr!
Last updated: Jul 06 2025 at 12:14 UTC