Stream: beginners

Topic: ✔ This looks like an operator


view this post on Zulip Dan (Jan 09 2024 at 20:52):

Pardon me for the stupid question. But I don't really understand what am I doing wrong:

This works:

ip = "127.0.0.1"
url = "http://\(ip)/win&T=2"

This does not

ip = "127.0.0.1"
Str.concat "IP: " ip
    |> Stdout.line

url = "http://\(ip)/win&T=2"

with error

This looks like an operator, but it's not one I recognize!

12│      ip = "127.0.0.1"
13│      "IP: \(ip)"
14│          |> Stdout.line
15│
16│      url = "http://\(ip)/win&T=2"
             ^

I have no specific suggestion for this operator, see TODO for the full
list of operators in Roc.⏎

view this post on Zulip Dan (Jan 09 2024 at 20:54):

Slightly different code

12│       ip = "127.0.0.1"
13│>      Stdout.line "IP: \(ip)"
14│>
15│>      url = "http://\(ip)/win&T=2"

Looks like you are trying to define a function. In roc, functions are
always written as a lambda, like increment = \n -> n + 1.⏎

view this post on Zulip Agus Zubiaga (Jan 09 2024 at 21:44):

Stdout.line constructs a Task, but it doesn't run it right away. In order to do so and continue doing other stuff after, you can use Task.await like this:

ip = "127.0.0.1"
{} <- Stdout.line "IP: \(ip)" |> Task.await
url = "http://\(ip)/win&T=2"

view this post on Zulip Agus Zubiaga (Jan 09 2024 at 21:57):

The type of Task.await looks like this:

await : Task a b, (a -> Task c b) -> Task c b

It takes a Task (in this case the one returned by Stdout.line ...), and a callback which takes the value produced by running the Task (in this case {}, since printing doesn't produce any meaningful values) and returns the next Task.

The <- syntax is called Backpassing, and it's just a convenient way to pass a callback to a function without increasing the indentation level.

You could also write it like this without Backpassing:

ip = "127.0.0.1"

Stdout.line "IP: \(ip)" |> Task.await \{} ->
    url = "http://\(ip)/win&T=2"

    # The rest of your code...

view this post on Zulip Dan (Jan 09 2024 at 21:57):

Thanks! I was trying Task.await but this was needed:

{} <- ...

I'm not yet completely understand why.

view this post on Zulip Dan (Jan 09 2024 at 22:01):

Ah, seems I need to tell Roc to "discard" I/O operation result.
Thanks again!

view this post on Zulip Notification Bot (Jan 09 2024 at 22:02):

Dan has marked this topic as resolved.

view this post on Zulip Agus Zubiaga (Jan 09 2024 at 22:05):

Yes. If instead you used a Task that produces values such as Stdin.line, you'd give them a name instead of discarding them:

input <- Stdout.line |> Task.await

Last updated: Jul 06 2025 at 12:14 UTC