Stream: beginners

Topic: Printing progress for things that take a while


view this post on Zulip Gerco Dries (Dec 06 2023 at 00:38):

When I have a function that takes a while (not because of IO or whatever, just computation), is it possible to output something to the console when that function runs? I know about "dbg", but that doesn't do anything when running the binary, only when running "roc dev".

Something like this:

processRange: Nat, Nat -> Nat
processRange = \start, length ->
  Stdout.line "Processing range: \(start) - \(start+length-1)"
  somethingThatTakesLongToCompute start length

I haven't been able to find any syntax that makes Stdout.line work in a function other than main, maybe it's not possible? Am I doing this wrong? There should be some way to indicate to the user that the program is still running, just working on whatever task it's been given, right?

view this post on Zulip Brendan Hansknecht (Dec 06 2023 at 00:49):

We want debug to work in this case...It just doesn't currently.

view this post on Zulip Brendan Hansknecht (Dec 06 2023 at 00:49):

For Stdout.line to work in an arbitrary function, that function would need to be changed to return a Task

view this post on Zulip Brendan Hansknecht (Dec 06 2023 at 00:49):

Then you would need to await that task

view this post on Zulip Brendan Hansknecht (Dec 06 2023 at 00:49):

It is a solid bit of extra juggling

view this post on Zulip Isaac Van Doren (Dec 06 2023 at 00:50):

specifically, you could do something like this

processRange: Nat, Nat -> Task Nat *
processRange = \start, length ->
    {} <- Stdout.line "Processing range: \(start |> Num.toStr) - \(start + length - 1 |> Num.toStr)" |> Task.await
    somethingThatTakesLongToCompute start length |> Task.ok

view this post on Zulip Brendan Hansknecht (Dec 06 2023 at 00:51):

Then you also have to change the caller to await the returned task

view this post on Zulip Gerco Dries (Dec 06 2023 at 00:52):

Yes, that would be some extra juggling since there is really no other need to change the type of that function than to be able to report progress to a user waiting for the result. It would just be nice to be able to provide an ETA or some indication that something is still happening while long computations run.

view this post on Zulip Gerco Dries (Dec 06 2023 at 00:59):

For example, right now I'm running something that might take minutes, hours or days and I have no idea which unless I can see some progress. In "roc dev" it will take days, for sure, but --optimize speeds things up a lot so it may be only hours in that case but I have no way of knowing.

I'll try and see if I can type-juggle that Task into the function. What I'm doing is probably wrong since I didn't expect it to take anywhere near this long, I was hoping for seconds.

view this post on Zulip Luke Boswell (Dec 06 2023 at 01:38):

I would break the input into chunks and print an update after each chunk is processed.

view this post on Zulip Gerco Dries (Dec 06 2023 at 01:49):

So now I have a List (Task Nat *) that I'd like to each await, get the result and do something with the resulting list of results. I'm trying to List.map using Task.await and I'm not getting anywhere. Probably because that's not how things are done in Roc.

main =
    ranges
    |> List.map \range -> searchRange range
    |> List.map \task -> await task ???
    |> List.min
    |> Task.ok

searchRange : Range -> Task Nat *
searchRange = range ->
      {} <- (Stdout.line "Searching range \(Num.toStr range.start) \(Num.toStr range.length)") |> await
    somethingThatTakesALongTime range |> Task.ok

Is it possible to wrap the awaiting of a bunch of tasks into another task that can then process the results of each of the smaller tasks?

view this post on Zulip Luke Boswell (Dec 06 2023 at 01:53):

You need something like https://www.roc-lang.org/packages/basic-cli/Task#loop

view this post on Zulip Gerco Dries (Dec 06 2023 at 03:05):

Took me a while and I had to sprinkle await and Task.ok everywhere until it compiled, but I finally did manage to get it working with Task.loop, thanks! It's still taking way too long, but that's just because my implementation is slow. I did manage to print status updates while the computation is running.


Last updated: Jul 05 2025 at 12:14 UTC