Stream: ideas

Topic: shared namespace for vars and typevars


view this post on Zulip Kiryl Dziamura (Oct 05 2025 at 17:24):

What if roc had shared namespace for vars and typevars? I'm going off the fact that type names are already can be used in the values world explicitly: Type.[exported thing from the Type module], e.g. List.map(list, fn). Type there is not a record but a namespace. The idea is to allow the namespace be taken from the types annotation.

# type namespace
decode_json = |bytes| {
    Json.decode(bytes)
}

# typevar namespace
decode_anonymous : List(U8) -> Result(dest, [DecodeErr])
decode_anonymous = |bytes| {
    dest.decode(bytes)
}

It means now outer space affects typevars naming, but it might be a pro since now there's no confusion about possibly same names in type annotations and value variables.

The decode problem is not only about the return type, but more generally, about the ability to express static methods (or any exports) of an inferred type. Static methods are functions exported from a module that don't have the module type as a first argument. E.g Type.from_digits

formula : num, num -> num
formula = |radius| {
    3.14.num * radius * radius
}

One of the things that the module can export is the type constructor: Type(...). It's possible to use this with typevar as well, but likely never needed.

There's also syntax idea for type clarification syntax. The same way type annotation is var : type, it might be extended to expr : type:

decode_anonymous = |bytes| {
    dest.decode(bytes) : Result(dest, [DecodeErr])
}

view this post on Zulip Richard Feldman (Oct 05 2025 at 18:58):

hm, what would happen if you just returned a type variable like dest?

view this post on Zulip Kiryl Dziamura (Oct 05 2025 at 19:14):

A constructor function I think. I assumed that in the message above, but now I'm not sure if it's possible to do. It seems constructors are allowed only within the type module scope? In such case, the rule is the same as for the Type: if it cannot be considered as a function, only as a namespace - it shouldn't be possible to use it as value.

view this post on Zulip Richard Feldman (Oct 05 2025 at 20:39):

what is a constructor function? :sweat_smile:

view this post on Zulip Kiryl Dziamura (Oct 05 2025 at 21:21):

The type wrapper. As I said, it's useless. It only makes sense for tags.
Anyway, the point is that if you return a typevar from a function - you get the same outcome as if you returned List or U64 from the function

view this post on Zulip Richard Feldman (Oct 05 2025 at 21:58):

hm, I dunno - seems pretty inconvenient to not be able to write things like |list, elem| in the implementation of append because elem would be shadowed

view this post on Zulip Richard Feldman (Oct 05 2025 at 21:59):

and it's to accommodate an edge case


Last updated: Jun 16 2026 at 16:19 UTC