SE-0258: Property Wrappers (second review)

(Taking off my review-manager hat again.)

In my mind, there are really two kinds of property wrappers:

  • property wrappers that are just a convenient way to get some common behavior in the implementation, like @Lazy or @Cloning or whatever, and
  • property wrappers that represent a more fundamental aspect of the property, where you can't really understand the property without knowing that it's a @Blah property.

The former are likely to only provide low-level operations on the wrapper type. For example, it would be reasonable for @Lazy to have a reset() method, but that's probably something that only the property's defining context should be able to use, because executing the lazy initializer twice might mess up a lot of invariants for the enclosing type.

The latter are more likely to offer high-level operations. For example, the entire point of a @Subscribable wrapper type is that it offers APIs to subscribe to changes to the property, and it's probably the right choice for those APIs to be available to anyone who can access the property itself. (The restriction to at most internal seems unfortunate to me.) It's unlikely that such a property would ever be made non-@Subscribable, and having to write public(wrapper) @Subscribable on pretty much every such property seems like a really unfortunate usability cost.

It seems to me that that difference is inherent to a wrapper type rather than inherent to a particular use of it. Whether the presence of a wrapperValue property is a reasonable proxy for that difference, I have no opinions about.

2 Likes