Stream: ideas

Topic: Exposing an ability, but not all of its members


view this post on Zulip Ayaz Hafiz (Mar 22 2023 at 16:54):

Currently you can expose an ability and none, some, or all of its members. For example, with an interface A with ability

ability Mine has
  one : {} -> a | a has Mine
  two : {} -> a | a has Mine

it's legal to say any of the following currently

I think generally it makes the most sense to expose all members in an ability, since abilities are interfaces, and you can't do much with an interface other than to act on it - and the only way to act on an interface are via its members, which you can't access if they're not exposed.

However, there can be some benefit to not exposing ability members. If you expose no ability members, this gives you a way to define an "opaque ability" - an opaque ability is like an opaque type, but it can be generic over many opaque types that implement the opaque ability. Of course, the opaque types that implement the ability can only come from the same module that defines the ability, in this case. The case for partial exposing of members is similar - you can have "private" methods in your abilities, but again the only types that can implement the ability are those in the defining module.

I think exposing an ability with no members is useful, as it enables defining an ability that only your types in your package can implement, but other packages can use the ability name to vary over those types in the package. This is similar to closed typeclasses in Haskell or sealed traits in Rust, which help protect against downstream packages implementing the ability - which means a change to the ability members is not a breaking change.

However, I don't really see a great reason for allowing exposing some, but not all, members in an ability. It seems like doing so is probably just a bad design - if you have both private and public interfaces for an ability, you probably want to break that up into several smaller types.

What do folks think?

view this post on Zulip Brendan Hansknecht (Mar 22 2023 at 17:35):

Is there ever a case for an ability having internal methods but exposing a limited higher level API to the end user? Maybe that would be formulated as partially exposed? Just trying to think of a use case.


Last updated: Jun 16 2026 at 16:19 UTC