Stream: beginners

Topic: Opaque types perf question


view this post on Zulip Agus Zubiaga (Mar 15 2023 at 01:40):

I'm curious. Is @MyOpaqueType 42 a no-op? What about List.map @MyOpaqueType items?

view this post on Zulip Ayaz Hafiz (Mar 15 2023 at 01:44):

Yes, it is the same as if the opaque type was unwrapped to the underlying type.

view this post on Zulip Richard Feldman (Mar 15 2023 at 02:59):

yeah so all of these have no runtime overhead:

view this post on Zulip Richard Feldman (Mar 15 2023 at 02:59):

they all get compiled down to the unwrapped version of the thing

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:00):

and the unwrapping nests, so if you have an opaque wrapper around a record with one field and that one field is a single tag union with a payload of a string, all of that will be just a string at runtime

view this post on Zulip Agus Zubiaga (Mar 15 2023 at 03:22):

That’s awesome

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:26):

also: records, tag union payloads, and tuples all have the exact same runtime representation

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:26):

so there's no perf advantage to choosing a record, a single-tag union, or a tuple, as long as they all have the same number of fields

view this post on Zulip Agus Zubiaga (Mar 15 2023 at 03:26):

Will List.map still walk through the list in my example above? Or can it somehow tell the function I passed is basically identity at runtime?

view this post on Zulip Nick Hallstrom (Mar 15 2023 at 03:27):

Wait, I thought Roc didn’t really have tuples. I’ve been using tags for that. Did I miss something?

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:28):

they're WIP

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:28):

like they parse but don't make it all the way through the pipeline yet :big_smile:

view this post on Zulip Nick Hallstrom (Mar 15 2023 at 03:28):

Nice! Have somewhere that I can check them out?

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:28):

I think @Joshua Warner may have a branch with more somewhere?

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:30):

Agus Zubiaga said:

Will List.map still walk through the list in my example above? Or can it somehow tell the function I passed is basically identity at runtime?

it will still walk through the list at the moment...I'd definitely like to optimize that away in the future if possible, but we don't have the optimization infrastructure in place to detect a pattern like that right now

view this post on Zulip Agus Zubiaga (Mar 15 2023 at 03:39):

That makes sense!

view this post on Zulip Agus Zubiaga (Mar 15 2023 at 03:39):

Great, thanks for the explanation

view this post on Zulip Agus Zubiaga (Mar 15 2023 at 03:40):

Love all this zero-overhead stuff

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:44):

yeah part of the design goal with those is to remove the tension between choosing the nicest representation and choosing the fastest representation

view this post on Zulip Richard Feldman (Mar 15 2023 at 03:44):

ideally the contenders for nicest are all equally fast, so you only have that one axis to think about :big_smile:

view this post on Zulip Joshua Warner (Mar 15 2023 at 03:55):

Tuples should work; please file bugs if they don't!

view this post on Zulip Nick Hallstrom (Mar 15 2023 at 03:59):

Are there docs on tuples somewhere? I would love to try them out

view this post on Zulip Nick Hallstrom (Mar 15 2023 at 03:59):

Or even just a quick example of the syntax

view this post on Zulip Anton (Mar 15 2023 at 08:56):

f : I64 -> (I64, I64)
f = \x -> (x, x + 1)

f 42

view this post on Zulip Richard Feldman (Mar 16 2023 at 19:29):

Joshua Warner said:

Tuples should work; please file bugs if they don't!

found one! :big_smile:

https://github.com/roc-lang/roc/issues/5148


Last updated: Jul 06 2025 at 12:14 UTC