I am playing around with Roc and thought of a way to get trivial OO semantics using function closures and records:
math = \n -> {
addn: \a, b ->
a + b + n,
subn: \a, b -> a - b + n,
foo: \_ -> n
}
p = math 10
expect p.addn 1 2 == 13
expect p.subn 5 2 == 13
expect p.foo 1 == 10
But I could not specify functions that take no parameters. I had to use a placeholder, foo: \_ -> n
to do so. I tried foo: \ -> n
, but the compiler gets stuck with: "TODO provide more context."
A pure function with no parameters cannot change its output and so is a constant =)
So foo: n
To work around this the convention I think is to pass an empty value - {}
, and pattern match it in the argument to {}
foo: \ {} -> n
But I think the only advantage this gives in Roc is deferring the execution of the body until needed
Yep
And it allows more polymorphisms of the type. A value becomes a concrete type. A function can return something that can become one of multiple possible types.
As in List a
will become a concrete type when used like maybe List U32
. A function that returns a List a
can generate a different list type on each call. So maybe List U32
one time and List U8
another time.
Last updated: Jul 06 2025 at 12:14 UTC