Do I need to define all of the abilities supported by a type when I define that type?
Yep
Hmm I wonder if this will become a problem.
F# does not have traits / type-classes but at least it has interfaces to fall back on in the style of Java/C#
I assume Roc does not have interfaces due to heap allocation / general slowness.
Is there a plan in Roc to handle these situations?
you don't necessarily have to write out the whole implementation
like you can say implements [Eq, Hash, Inspect]
and it will infer an implementation based on the inner type the opaque type is wrapping
If the type comes from somewhere else (like say in a library), I guess there is no way to "extend" it?
that's correct, and that's by design
part of the reason for defining all of the abilities explicitly is that it's important for opaque types to be opaque by default (that is, not exposing their internal implementations) so that backwards-compatible changes can be made to them later
Fair enough!
I do wonder if this will lead to lots of boilerplate situations, however.
part of this is not letting others implement those abilities, because then if the original implementor later decides to add an ability, it might conflict with the userspace implementations and cause problems
I suspect not, but an important consideration is that editor plugins can make it very quick to add them :big_smile:
also keep in mind that this is just for opaque types and not type aliases
so for example if you just want a User
record and you do User : { email : Str, ... }
then it gets all the abilities inferred and you don't need to write anything
it's only if you want to make a new custom type that this comes up
I'm thinking of a situation like...
- Library A implements operations on tree-like things and defines an ability
- Library B implements some type T I want to use
- To use T instances with Library A functions, I need to write my own type that has the abilities defined in Library A and I also need to convert T instances T into my type
to me, in this scenario the author of Library A made a mistake :big_smile:
I think "implementing operations on tree-like things" is not a good idea for a library
it's better to implement operations on one specific tree implementation
I think this is something Java encouraged that hasn't worked out well in practice (at least based on my past career as a Java developer)
that is, "build lots of things in terms of interfaces and then that way you can swap out implementations" - I don't think the benefits of doing everything in that style have outweighed the drawbacks in practice, so I don't want to encourage that style in Roc
I was more thinking about Haskell libraries but I can understand if this is not the direction for Roc
yeah same consideration there! :big_smile:
You can easily get this feature by passing in a record of needed functions
This was the reponse Dom Syme (F#) gave too
Just a more explicit form of the interface
njlr has marked this topic as resolved.
Last updated: Jul 06 2025 at 12:14 UTC