[swift-evolution] [Draft proposal] Extending read-only properties with setters

Marc Knaup marc at knaup.koeln
Wed Feb 22 07:01:20 CST 2017

We ran into that annoying limitation too and worked around it by importing
the module's .swift file containing the extension directly into each module
relying on it. It's not pretty but it works.
I reported it at https://bugs.swift.org/browse/SR-4017 but now when
searching through the evolution archives I found this nice thread which
totally reflects our issue.

I'd still like to propose support for declaring only setters for a property!
It's valid to do in extensions to add a setter for a read-only property in
the type to be extended:

extension CGRect {

	public var height: CGFloat {
		mutating set { size.height = newValue }

	public var width: CGFloat {
		mutating set { size.width = newValue }

@Jordan Rose I understand your concern regarding introducing new
ambiguities. In this case however there's no difference from the ambiguous
getter problem we already have today or the ambiguous symbol errors you can
get from using *any* extension symbol which collides with another module's
extension. Resolving ambiguities is a distinct problem to be solved.

To increase the value of setter-only declarations I'd go even a step
Setter-only declarations are also allowed in subclasses to override only
the setter of a property without having to override the getter just to call
super's implementation. The same applies to protocol conformances where the
getter would already be covered by a default implementation so the
conforming type just has to provide a setter.
Also this is then completely analogous to overriding either just getXYZ()
or setXYZ() functions as developers are used from most other languages,
including ObjC.

It may happen that developers who are new to Swift try to declare just a
setter for a *new* property in order to execute special logic there.
In that case the compiler would emit an error for not providing a getter
can offer three quick-fixes:

   - replace "(mutating) set" with "didSet"
   - replace "(mutating) set" with "willSet"
   - add "get {}" to provide a getter

On Thu, Feb 4, 2016 at 1:40 AM Jarod Long via swift-evolution <
swift-evolution at swift.org> wrote:

> On Feb 3, 2016, at 15:23, Jordan Rose <jordan_rose at apple.com> wrote:
> This violates the "what if two people did this?" rule; while you might be
> able to disambiguate between two modules that define the same method or
> property, it seems *really hard* to pick a particular module's *setter.*
> I think I don't have a complete understanding of how disambiguation works,
> because it's not quite clear to me how disambiguating setters is harder
> than methods or properties. As far as I understand it, to disambiguate a
> symbol, you prefix it with the module name. I'm actually not sure how to
> disambiguate anything that isn't directly accessible in the current scope
> (where does the module name go?), so getters, setters, and methods seem
> equally difficult to disambiguate.
> Apologies if I'm overlooking something here.
> I think it would be better to just request that the width and height
> fields get setters, since they're already being defined in Swift
> <https://github.com/apple/swift/blob/master/stdlib/public/SDK/CoreGraphics/CoreGraphics.swift#L172>.
> If you want to attack the general problem, I think it would be better to
> come up with ways to disambiguate overloads that differ only by module.
> Interesting -- thank you for the link! I was originally going to suggest a
> change in the Objective-C API translation thread, but I had assumed that
> the width and height properties came from a generic rule that automatically
> translated the CGRectGet___ functions and that making explicit translation
> rules for CGRect would be undesirable.
> I would like to solve the general problem if there's a reasonable way to
> do so, since I do think there are applications outside of these specific
> properties. To use another CGRect example, you may want the midX/Y
> properties (among others) to be settable, but introducing built-in setters
> for all of these kinds of properties is likely not something we would want
> to do.
> If it turns out that this isn't a feasible thing to do, then I think
> building these particular setters into Swift is the next best thing, but
> I'd like to explore the possibilities here for a bit before trying to go
> that route.
> Best,
> Jordan
> On Feb 3, 2016, at 14:30, Jarod Long via swift-evolution <
> swift-evolution at swift.org> wrote:
> Swift extensions are fantastic for filling in gaps in an API, but they
> don't currently allow you to convert a read-only property into a read-write
> property by extending it with your own setter. I'd like to propose that an
> extension may contain a set-only computed property iff the extended type
> already has a getter for that property.
> My specific motivation for this proposal stems from CGRect's translated
> API. If you frequently work with rects, it's very convenient to be able to
> access their x/y/width/height properties directly. It's easy to extend
> CGRect with x/y properties, but width and height are problematic because of
> the CGRectGetWidth and CGRectGetHeight functions that get imported as
> read-only width and height properties on CGRect.
> If you extend CGRect with read-write width/height properties, they'll work
> within the module they're defined because the getters shadow the imported
> Objective-C versions, but using the getters in other modules becomes
> impossible due to ambiguity errors. If it was possible to only define the
> width/height setters, the ambiguity wouldn't exist.
> This particular issue is pretty narrow, but it's moderately frustrating if
> you write a lot of layout code or do other work with rects, and I think
> this is just one of many situations where adding a setter to a property
> would be useful.
> This proposal is somewhat related to the "support for pure setters"
> discussion, but since it doesn't involve the tradeoffs of introducing
> actual set-only properties, I feel that this warrants its own separate
> discussion.
> Looking forward to your input!
> Jarod
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170222/9829408b/attachment.html>

More information about the swift-evolution mailing list