This pitch is breaking, and should be considered under the phase 1 timeframe.
gist here: https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b

As usual, I will update the gist with feedback. Please refer to gist rather 
than 
this email for the latest revisions.

-- E


Removing Setter/Observer Name Overrides

Proposal: TBD
Author: Erica Sadun <https://github.com/erica>
Status: TBD
Review manager: TBD
 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#introduction>Introduction

This proposal removes setter and observer name overrides from the Swift 
programming language, limiting their use to the defaults of newValue and 
oldValue. 

Swift-evolution thread: TBD 
<https://lists.swift.org/pipermail/swift-evolution/Week-of-TBD>
 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#motivation>Motivation

Swift setters and property observers supply predefined symbols that represent 
value arguments. These are newValue for set and willSet, and oldValue for 
didSet. These implicit names are always available -- you don't need to take any 
action to have access to them -- and they are instantly recognizable in context.

Swift allows you to override newValue and oldValue by supplying a name in 
parentheses after the set/willSet/didSet keyword, for example:

set(temperature) { 
   // use temperature instead of newValue
}
This feature is an attractive nuisance for the following reasons:

Preferring newValue and oldValue to custom names is consistent. Someone reading 
code needn't recognize a new and unfamiliar symbol in setter or observer 
context. 

Preferring newValue and oldValue to custom names avoids errors. Some developers 
prefer to name all mentioned values for the sake of consistency, clarity, and 
readability like this:

set(newValue) {...}
Developers who follow this rule may accidentally insert newValue or oldValue in 
the wrong observer. It is not that uncommon. (See this tweet 
<http://twitter.com/studobster/status/804064325715378176>, for example.) Swift 
does not check for name mismatches, specifically for the common error of using 
oldValue in place of newValue or vice versa.

 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#detailed-design>Detailed
 Design

Upon adopting this proposal:

Swift removes name overrides from the language.
Swift allows the current grammar to be used but disallows the mention of any 
mismatched name:
set { ... } // okay
willSet { ... } // okay
didSet { ... } // okay
set(newValue) { ... } // okay, self-documenting
set(oldValue) { ... } // compiler error
willSet(newValue) { ... } // okay, self-documenting
willSet(oldValue) { ... } // compiler error
didSet(oldValue) { ... } // okay, self-documenting
didSet(newValue) { ... } // compiler error
didSet(bob) { ... } // compiler error
 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#type-members>Type
 Members

As an optional extra, Swift could emit warnings for any type member named 
newValue or oldValue. 

var newValue: T { ... } // warning
A more extreme step would disallow the use of newValue and oldValue members, 
reserving those words for setters and observers. This proposal does not go so 
far since newValue and oldValue are reasonable property names for a generic 
ChangeSet<T> struct.

Although a warning could be limited to the presence of property observers and 
setters, this is not recommended. Deferring warnings until there's a name 
conflict might introduce the desire to rename members and break APIs when 
observers and setters are added at a later date. That outcome is undesirable.

Please note that Swift properly differentiates between members (self.newValue) 
and the newValue argument, as in the following example. 

struct Foo {
    var newValue: Int = 0
    var observedMember: Int {
        willSet {
            print(newValue)
            // newValue = 100 // error, `newValue` is immutable
            self.newValue = 100
        }
    }
}

var test = Foo(newValue: 0, observedMember: 50)
test.observedMember = 60 // prints 60
test.newValue // 100
 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#impact-on-existing-code>Impact
 on Existing Code

This proposal is breaking. The migrator will need to remove overrides and 
rename their mentions to newValue and oldValue.

 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#timeline>Timeline

This proposal is breaking so needs to be considered in Swift 4 Stage 1

 
<https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b#alternatives-considered>Alternatives
 Considered

If this proposal is not adopted, Swift could still warn or error on  
set(oldValue), willSet(oldValue), and didSet(newValue), since these can be 
considered to be always wrong.
Swift could entirely remove the parentheses syntax, although many developers 
prefer to explicitly mention the magic argument names.



_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to