Stream: beginners

Topic: Point-free function definition


view this post on Zulip Tobias (May 18 2025 at 23:34):

Is there a way to get rid of the first line (the line line)?

parse = |line| line
    |> Str.replace_each(":", " ") |> Str.split_on(" ")

view this post on Zulip Anthony Bullard (May 18 2025 at 23:59):

not really. Roc does not support automatic partial application

view this post on Zulip Anthony Bullard (May 19 2025 at 00:00):

but this will be a single line in the future with Static Dispatch

view this post on Zulip Anthony Bullard (May 19 2025 at 00:02):

Tobias said:

Is there a way to get rid of the first line (the line line)?

parse = |line| line
    |> Str.replace_each(":", " ") |> Str.split_on(" ")

will become

parse = |line| line.replace_each(":", " ").split_on(" ")

view this post on Zulip Anthony Bullard (May 19 2025 at 00:02):

This is v0.1 syntax

view this post on Zulip Anthony Bullard (May 19 2025 at 00:02):

and semantics :wink:

view this post on Zulip Anton (May 19 2025 at 09:15):

You can actually do it like this

parse = |line|
    Str.replace_each(line, ":", " ") |> Str.split_on(" ")

But this is the way I would write it

parse = |line|
    line
    |> Str.replace_each(":", " ")
    |> Str.split_on(" ")

view this post on Zulip Tobias (May 19 2025 at 16:19):

I read the FAQ on currying. But I feel like pipe support is sabotaging the argument.

view this post on Zulip Tobias (May 19 2025 at 16:19):

Where can I read about v0.1? Curious how this works with type inference.

view this post on Zulip Anton (May 19 2025 at 16:46):

That particular v0.1 feature is called static dispatch, here is the design doc:
https://docs.google.com/document/d/1OUd0f4PQjH8jb6i1vEJ5DOnfpVBJbGTjnCakpXAYeT8/edit?tab=t.0#heading=h.vuo6e14bvfkt

view this post on Zulip Anthony Bullard (May 19 2025 at 17:39):

@Tobias the difference between currying and pipe is that you immediately consume the partially applied function and you can't pass it around

view this post on Zulip Tobias (May 19 2025 at 22:31):

Thanks for the link. It doesn't mention type inference, and all the examples specify at least one module. Would the following from Anthony even compile? (without a signature)
parse = |line| line.replace_each(":", " ").split_on(" ")

view this post on Zulip Anthony Bullard (May 19 2025 at 22:33):

yes. it should by looking into the imported modules to look for one with matching functions and then infer line to be a Str

view this post on Zulip Tobias (May 19 2025 at 22:36):

What if that's ambiguous? IIRC that's why OCAML requires modules everywhere.

view this post on Zulip Anthony Bullard (May 19 2025 at 22:36):

it would first be a a -> c where { module(a).replace_each(Str, Str) -> b, module(b).split_on(Str) -> c }

view this post on Zulip Anthony Bullard (May 19 2025 at 22:38):

And then it finds that Str.replace_each matches and replaces module(a) with Str, inferring a as Str and then b as Str then we know that module(b) is Str - finding split_on in that module and inferring c to be Str. so the final type is Str -> Str

view this post on Zulip Tobias (May 19 2025 at 22:38):

I see. So the compiler will be as slow as Scala :stuck_out_tongue_wink:

view this post on Zulip Anthony Bullard (May 19 2025 at 22:39):

we hope not!

view this post on Zulip Anthony Bullard (May 19 2025 at 22:39):

but we will see

view this post on Zulip Anthony Bullard (May 19 2025 at 22:39):

that inference may only happen when we try to unify

view this post on Zulip Anthony Bullard (May 19 2025 at 22:40):

we don't have meta programming so that will gelp

view this post on Zulip Anthony Bullard (May 19 2025 at 22:40):

help

view this post on Zulip Anthony Bullard (May 19 2025 at 22:40):

also we have a compiler in Zig not on top of the JVM

view this post on Zulip Richard Feldman (May 19 2025 at 22:45):

oh that dispatch algorithm should be almost no cost

view this post on Zulip Richard Feldman (May 19 2025 at 22:46):

we already have all the relevant info after normal type inference, we just need to use it in a new way during code gen

view this post on Zulip Tobias (May 19 2025 at 22:57):

Python has a kind of partial application for methods.

f = "Hello".replace
f("l", "p")

Do you think that's useful?

view this post on Zulip Anthony Bullard (May 19 2025 at 23:19):

yeah that's called a method tear off. super useful for OOP languages

view this post on Zulip Anthony Bullard (May 19 2025 at 23:19):

at least that's what we called them in Dart


Last updated: Jul 05 2025 at 12:14 UTC