Heard recently that there's a new plan for how Roc will be handling effects, essentially moving away from Tasks entirely.
One of the best things IMO about haivng a concrete type to represent "an effect that will be executed by the runtime" is that it makes testing so much easier. Instead of having to set up mocks, or do some complicated dependency injection, you can just assert that your code returns a certain kind of task with the payload that you expect. Testing the code that handles this result is usually really easy too, because you can just pass in some data that you expect the runtime to give you back.
When you have code that can call an effect anywhere inside, it becomes much harder to test (even if you have the guarantees from the type checker about pure functions vs effectful functions). If you can directly call an effect, now it's up to the author to minimize the other code surrounding the effect. For example, if you have a function that transforms its arguments in some way, then calls some effect, and then transforms the result in some way, this is much harder to test.
I'm curious what the thoughts are here - is this something that's considered? Am I just misunderstanding the way this will work?
Tasks where not reasonably testable before, so I don't think this makes much of a difference on that front. Unlike elm where you return a message that is easily concrete for testing, tasks have never been that way. So I don't think we lost anything there
I do agree that it still leaves a hole around testing. A number ideas exist for making that nice, but nothing implemented currently.
I'd say the only difference between Tasks and effectful functions is laziness. They literally compile to the same thing, except one is \{} -> run effect
and the other is run! effect
.
So any problems with one apply to the other, except for all the lambda set bugs we've avoided by not using a bunch of thunks.
Yeah I guess I'm mainly comparing it to Elm, where you would just really test your main update function with some inputs and assert that the return value is the state you expect and the effect you expect to run, as well as your update function with the next state and result of the previous Cmd
.
Effects are still tracked though. If a function has an effect, it has a different type to a function which doesn't. And a function which doesn't have effects cannot call a function which does (kind of like async in other languages). So you always know when effects happen. And you are encouraged to minimize effect usage
the same as elm could be done in roc, but it would be very limiting. You would make a platform that takes a union of commands as output. So it would have no effects. Everything would go through that one tag. It would actually be 100% pure. Would make it a lot more directly testable like in elm.
This is basically the exact design of the platform I hope to build once I have time. The language I designed and was trying to build before I came to Roc was basically Roc with Actors, managed effect runtime, and less sugar and no ad hoc polymorphism.
So building a platform that just defines a Cmd tag union and expects a function that returns an Actor type (maybe tag union as well) would allow me to test building apps using the same basic design.
I love actors :) Did you use akka in the past as well?
I had contact with Akka, I think I only really helped on one ETL system that used it when I was at a Scala shop for 4 years.
But I really nerded out on Elixir/Erlang for awhile after learning about the concept
And in late 2018/early 2019 I even tried to contribute to Pony (a very performant, but very complicated Actor-oriented language)
Combine that with a love of Elm, and you get Chakra (my language)
But Chakra will probably never be now that there is Roc.
Kilian Vounckx said:
Effects are still tracked though. If a function has an effect, it has a different type to a function which doesn't. And a function which doesn't have effects cannot call a function which does (kind of like async in other languages). So you always know when effects happen. And you are encouraged to minimize effect usage
Yup, I watched the the Functional Purity Inference Plan talk, so I'm aware of the plan with A => B
vs A -> B
. I imagine the feel will be similar to Haskell, where you try to minimize the code that needs to be in any kind of IO
code.
Brendan Hansknecht said:
the same as elm could be done in roc, but it would be very limiting. You would make a platform that takes a union of commands as output. So it would have no effects. Everything would go through that one tag. It would actually be 100% pure. Would make it a lot more directly testable like in elm.
Basically making a platform that's using the Elm Architechture? That might be limited but I can see it being great for things like command line apps.
Yeah, definitely can have its uses. TEA can be amazing when designed well for a domain
Last updated: Jul 05 2025 at 12:14 UTC