[Pitch] Removing Setter/Observer Name Overrides


(Erica Sadun) #1

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.


(Sean Heber) #2

Perhaps an alternative would be to eliminate the newValue/oldValue magic names and require they be named in parens instead?

l8r
Sean

···

On Nov 30, 2016, at 4:40 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

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
  • Status: TBD
  • Review manager: TBD
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

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, for example.) Swift does not check for name mismatches, specifically for the common error of using oldValue in place of newValue or vice versa.

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
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
Impact on Existing Code

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

Timeline

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

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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Charles Srstka) #3

Dramatically source-breaking, dubious benefit.

-1.

Charles

···

On Nov 30, 2016, at 4:40 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Brandon Knope) #4

Breaking changes, at this point, have a high bar for acceptance. I am failing to see how the downsides presented here are enough to warrant a change.

Also:

Developers who follow this rule may accidentally insert newValue or oldValue in the wrong observer. It is not that uncommon

One example from a tweet doesn't seem convincing enough that this is not an uncommon problem. Are there more examples of people getting hurt by this?

Brandon

···

On Nov 30, 2016, at 5:40 PM, Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

Developers who follow this rule may accidentally insert newValue or oldValue in the wrong observer. It is not that uncommon


(Tino) #5

-1

I'm more or less neutral towards the change itself, but combined with the breaking effect, that's a clear "no".

None the less, I hope that the whole topic with all its magic words (willSet, didSet, newValue, oldValue…) will be reworked in the future, which would be another argument not to fiddle with it now*

- Tino

* https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003148.html


(Georgios Moschovitis) #6

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

I don’t agree with this proposal,

-1

-g.

PS: The first alternative might be useful though: “… Swift could still warn or error on set(oldValue), willSet(oldValue), and didSet(newValue), since these can be considered to be always wrong."


(Rick M) #7

-1.

I always name parameters to code blocks with an "in" or "out" prefix, and want to maintain my ability to change the name for set.

As to oldValue, isn't that the same as self.value? Does it even need to exist?

···

On Nov 30, 2016, at 14:40 , Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

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
  • Status: TBD
  • Review manager: TBD
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

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, for example.) Swift does not check for name mismatches, specifically for the common error of using oldValue in place of newValue or vice versa.

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
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
Impact on Existing Code

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

Timeline

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

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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Rick Mann
rmann@latencyzero.com


(Will Field-Thompson) #8

I'm also against this (though I like the first alternative about warning on
set(oldValue) etc.).

While I think there may be value in either preventing name overrides or
requiring them here, I don't believe it's worth a breaking change. Then
again, I have never personally encountered the problem (I tend not to
override names), so maybe those who have feel differently.

I also think that if this proposal goes through I would prefer not to allow
the current name overriding syntax, even in the self-documenting case. At
that point, the self-documenting case seems like unnecessary syntactic
noise. It makes sense for a team where observer names are frequently
overridden, but when that's disallowed, I feel that the self-documenting
case adds very little.

- Will

···

On Thu, Dec 1, 2016 at 3:40 AM Tino Heth via swift-evolution < swift-evolution@swift.org> wrote:

-1

I'm more or less neutral towards the change itself, but combined with the
breaking effect, that's a clear "no".

None the less, I hope that the whole topic with all its magic words
(willSet, didSet, newValue, oldValue…) will be reworked in the future,
which would be another argument not to fiddle with it now*

- Tino

*
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003148.html
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Saagar Jha) #9

oldValue is the value the property contained before didSet. self.value is the variable’s current value (i.e. newValue in willSet).

Saagar Jha

···

On Dec 3, 2016, at 9:34 PM, Rick Mann via swift-evolution <swift-evolution@swift.org> wrote:

-1.

I always name parameters to code blocks with an "in" or "out" prefix, and want to maintain my ability to change the name for set.

As to oldValue, isn't that the same as self.value? Does it even need to exist?

On Nov 30, 2016, at 14:40 , Erica Sadun via swift-evolution <swift-evolution@swift.org> wrote:

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
  • Status: TBD
  • Review manager: TBD
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

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, for example.) Swift does not check for name mismatches, specifically for the common error of using oldValue in place of newValue or vice versa.

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
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
Impact on Existing Code

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

Timeline

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

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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Derrick Ho) #10

I like this proposal!

+1

Oldvalue and newvalue have different meanings. I have witnesses programmers
overriding oldvalue with the name newvalue and vice versa.

Of course if you are good at reading the documentation then you would not
make the mistake.

Swift should be a language that prevents a programmer from making mistakes!

I am in favor of disallowing the name changes. Because it is much more
clear if it is an oldvalue or newvalue.

If a different name is desired there are two solutions, create a new
variable or add a capture list.

set (newValue: TheType) {
let temp = newValue
}

set { [temp = newValue] in

}

I think either of these would make this change easier to convert.

The second one would probably be easier to convert.

//current
set (temp) {

}

// Proposed and much more clear.
set { [temp = newValue] in

}

···

On Thu, Dec 1, 2016 at 3:01 PM Will Field-Thompson via swift-evolution < swift-evolution@swift.org> wrote:

I'm also against this (though I like the first alternative about warning
on set(oldValue) etc.).

While I think there may be value in either preventing name overrides or
requiring them here, I don't believe it's worth a breaking change. Then
again, I have never personally encountered the problem (I tend not to
override names), so maybe those who have feel differently.

I also think that if this proposal goes through I would prefer not to
allow the current name overriding syntax, even in the self-documenting
case. At that point, the self-documenting case seems like unnecessary
syntactic noise. It makes sense for a team where observer names are
frequently overridden, but when that's disallowed, I feel that the
self-documenting case adds very little.

- Will

On Thu, Dec 1, 2016 at 3:40 AM Tino Heth via swift-evolution < > swift-evolution@swift.org> wrote:

-1

I'm more or less neutral towards the change itself, but combined with the
breaking effect, that's a clear "no".

None the less, I hope that the whole topic with all its magic words
(willSet, didSet, newValue, oldValue…) will be reworked in the future,
which would be another argument not to fiddle with it now*

- Tino

*
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/003148.html
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Derrick Ho) #11

True, adding the type would be redundant. Here is my revised solution.
Which basically still allows you do use a different name besides
newValue/oldValue

set { let temperature = newValue
// do stuff
}

didSet { let temperature = oldValue
// do stuff
}

···

On Sun, Dec 4, 2016 at 12:47 AM Saagar Jha via swift-evolution < swift-evolution@swift.org> wrote:

oldValue is the value the property contained before didSet. self.value is
the variable’s current value (i.e. newValue in willSet).

Saagar Jha

On Dec 3, 2016, at 9:34 PM, Rick Mann via swift-evolution < > swift-evolution@swift.org> wrote:

-1.

I always name parameters to code blocks with an "in" or "out" prefix, and
want to maintain my ability to change the name for set.

As to oldValue, isn't that the same as self.value? Does it even need to
exist?

On Nov 30, 2016, at 14:40 , Erica Sadun via swift-evolution < > swift-evolution@swift.org> wrote:

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
• Status: TBD
• Review manager: TBD
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

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,
for example.) Swift does not check for name mismatches, specifically for
the common error of using oldValue in place of newValue or vice versa.

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
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
Impact on Existing Code

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

Timeline

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

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
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Erica Sadun) #12

[Original pitch: https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b]

GENERAL FEEDBACK

I received a gratifying amount of feedback about my pitch here, on Twitter,
through email, on several Slack channels, and on IRC. I wanted to summarize
the feedback, to start a new round of discussion.

* A majority of respondents believe the current feature is incorrectly designed
  and that this is our best opportunity to change it.
* A majority of respondents disagree on *how* it should be changed.

Before I commit to the (non-trivial) effort of pushing on this, I'd like to know if any
of the core team can chime in on the "preferred" design. Thank you.

BUG REPORT

The notion that the compiler should check for `set(oldValue)`, `willSet(oldValue)`,
and `didSet(newValue)` and emit warnings or errors had pretty much universal
support. I have submitted https://bugs.swift.org/browse/SR-3310 to address
this, regardless of whether the syntax changes or not.

MENTIONING NAMES

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

* The current system violates the principle of clarity.
* It adds too much magic (https://en.wikipedia.org/wiki/Magic_(programming)) <https://en.wikipedia.org/wiki/Magic_(programming))>
  at the point of use.
* It is inconsistent with the binding of variable names in closures.

My original design, which I chose to provide the least impact on the compiler and
existing code, was the least popular option.

PREFERRED DESIGN

The most popular design is that setters and property observers follow closures
syntax, namely that the old value and new value arguments be passed as $0,
and assignable using `name in`. Under this design, a setter looks like:

set { newValue in ... } // or
set { somethingElse in ... } // or
set { use $0 here }

Swift loses the "magic" newValue and oldValue, but any developer who
normally prefers to mention the name before use has a simple, visible
and easy way to retain that clarity.

* Mirrors closure syntax
* Easy to use
* Loses magic names
* Encourages documenting names in context

"NO CHANGE"

The second most popular design is "leave things as they are" (but implement the bug
report.) Developers with good style habits will use mandatory `newValue` and `oldValue`
names in their setter and observer declarations. No proposal is needed, and the bug
report guards against potential errors.

I would appreciate knowing whether the core team feels that the support for "no change",
even from a smaller group of developers, disqualifies this issue from the high bar of Phase 1.

(This group also included the most developers who self-reported that they did not
use the override feature.)

REMOVING OVERRIDES

A third design entirely loses the ability to override variables or mention their names.
This was in fact my *original* original design that I did not submit after sufficient
devs told me they wanted to always spell out magic argument names.

RIGHT NAMES ONLY

Finally, the least popular design is my original pitch. (Only allow the "right" names,
and allow them to be omitted.) This design has the least impact on the language,
causes the least breaking for most use-cases, and allows most pro coders to continue
using the "mention all names" approach.

UPDATING PROPOSAL

I am happy to update the proposal for the "closure-like" design. I believe there *was*
reasonable consensus that the current system is out of step with Swift's design goals
to push forward. However, I want this to go through another round of feedback.

Thank you in advance for your comments. If this does move forward to a proposal, it
must be discussed and decided in the first phase of Swift 4 as the change *is* breaking.

-- Erica

···

On Dec 1, 2016, at 10:22 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

I like this proposal!

+1


(Brent Royal-Gordon) #13

For what it's worth, I don't agree that the default names are a problem. I think they're a helpful convenience which, nevertheless, must occasionally be overridden because they conflict with the name of something else. The names are well-chosen and virtually always read correctly.

(Also FWIW, I'm not sure I've ever explicitly named the `oldValue`/`newValue` variable rather than using the implicit names.)

I think a warning on using `oldValue` instead of `newValue` or vice versa would be very helpful and address the parts of this proposal which aren't motivated by mere style complaints. The rest I think is a style issue, and I don't think that style issue is nearly universally-agreed-upon or serious enough to motivate a breaking change affecting tons of property setters, property observers, and subscript setters.

···

On Dec 3, 2016, at 7:06 PM, Erica Sadun <erica@ericasadun.com> wrote:

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

--
Brent Royal-Gordon
Architechies


(Derrick Ho) #14

I believe Erica's point about RIGHT NAMES ONLY is the most clear. While a
block-like syntax using $0 is nice, it fails to communicate whether it is a
newvalue or an oldvalue.

Therefore instead of following a block-like pattern it should follow a
delegate-function like pattern. This would remove the ambiguity that $0 or
name changing would present.

set (newValue: TheType) {
let a = newValue
}

didSet (oldValue: TheType) {
let b = oldValue
}

···

On Sat, Dec 3, 2016 at 10:06 PM Erica Sadun via swift-evolution < swift-evolution@swift.org> wrote:

[Original pitch:
https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b]

GENERAL FEEDBACK

I received a gratifying amount of feedback about my pitch here, on
Twitter,
through email, on several Slack channels, and on IRC. I wanted to
summarize
the feedback, to start a new round of discussion.

* A majority of respondents believe the current feature is incorrectly
designed
  and that this is our best opportunity to change it.
* A majority of respondents disagree on *how* it should be changed.

Before I commit to the (non-trivial) effort of pushing on this, I'd like
to know if any
of the core team can chime in on the "preferred" design. Thank you.

BUG REPORT

The notion that the compiler should check for `set(oldValue)`,
`willSet(oldValue)`,
and `didSet(newValue)` and emit warnings or errors had pretty much
universal
support. I have submitted https://bugs.swift.org/browse/SR-3310 to address
this, regardless of whether the syntax changes or not.

MENTIONING NAMES

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

* The current system violates the principle of clarity.
* It adds too much magic (
https://en.wikipedia.org/wiki/Magic_(programming))
  at the point of use.
* It is inconsistent with the binding of variable names in closures.

My original design, which I chose to provide the least impact on the
compiler and
existing code, was the least popular option.

PREFERRED DESIGN

The most popular design is that setters and property observers follow
closures
syntax, namely that the old value and new value arguments be passed as
$0,
and assignable using `name in`. Under this design, a setter looks like:

set { newValue in ... } // or
set { somethingElse in ... } // or
set { use $0 here }

Swift loses the "magic" newValue and oldValue, but any developer who
normally prefers to mention the name before use has a simple, visible
and easy way to retain that clarity.

* Mirrors closure syntax
* Easy to use
* Loses magic names
* Encourages documenting names in context

"NO CHANGE"

The second most popular design is "leave things as they are" (but
implement the bug
report.) Developers with good style habits will use mandatory `newValue`
and `oldValue`
names in their setter and observer declarations. No proposal is needed,
and the bug
report guards against potential errors.

I would appreciate knowing whether the core team feels that the support
for "no change",
even from a smaller group of developers, disqualifies this issue from the
high bar of Phase 1.

(This group also included the most developers who self-reported that they
did not
use the override feature.)

REMOVING OVERRIDES

A third design entirely loses the ability to override variables or mention
their names.
This was in fact my *original* original design that I did not submit after
sufficient
devs told me they wanted to always spell out magic argument names.

RIGHT NAMES ONLY

Finally, the least popular design is my original pitch. (Only allow the
"right" names,
and allow them to be omitted.) This design has the least impact on the
language,
causes the least breaking for most use-cases, and allows most pro coders
to continue
using the "mention all names" approach.

UPDATING PROPOSAL

I am happy to update the proposal for the "closure-like" design. I believe
there *was*
reasonable consensus that the current system is out of step with Swift's
design goals
to push forward. However, I want this to go through another round of
feedback.

Thank you in advance for your comments. If this does move forward to a
proposal, it
must be discussed and decided in the first phase of Swift 4 as the change
*is* breaking.

-- Erica

On Dec 1, 2016, at 10:22 PM, Derrick Ho <wh1pch81n@gmail.com> wrote:

I like this proposal!

+1

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jean-Daniel) #15

If you want to go to the side of consistency, why not just require the standard method syntax like any other place ?

set(foo newValue: valueType) {

}

So old/newValue will become a parameter label.

···

Le 4 déc. 2016 à 04:06, Erica Sadun via swift-evolution <swift-evolution@swift.org> a écrit :

[Original pitch: https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b]

GENERAL FEEDBACK

I received a gratifying amount of feedback about my pitch here, on Twitter,
through email, on several Slack channels, and on IRC. I wanted to summarize
the feedback, to start a new round of discussion.

* A majority of respondents believe the current feature is incorrectly designed
  and that this is our best opportunity to change it.
* A majority of respondents disagree on *how* it should be changed.

Before I commit to the (non-trivial) effort of pushing on this, I'd like to know if any
of the core team can chime in on the "preferred" design. Thank you.

BUG REPORT

The notion that the compiler should check for `set(oldValue)`, `willSet(oldValue)`,
and `didSet(newValue)` and emit warnings or errors had pretty much universal
support. I have submitted https://bugs.swift.org/browse/SR-3310 to address
this, regardless of whether the syntax changes or not.

MENTIONING NAMES

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

* The current system violates the principle of clarity.
* It adds too much magic (https://en.wikipedia.org/wiki/Magic_(programming)) <https://en.wikipedia.org/wiki/Magic_(programming))>
  at the point of use.
* It is inconsistent with the binding of variable names in closures.

My original design, which I chose to provide the least impact on the compiler and
existing code, was the least popular option.

PREFERRED DESIGN

The most popular design is that setters and property observers follow closures
syntax, namely that the old value and new value arguments be passed as $0,
and assignable using `name in`. Under this design, a setter looks like:

set { newValue in ... } // or
set { somethingElse in ... } // or
set { use $0 here }

Swift loses the "magic" newValue and oldValue, but any developer who
normally prefers to mention the name before use has a simple, visible
and easy way to retain that clarity.

* Mirrors closure syntax
* Easy to use
* Loses magic names
* Encourages documenting names in context

"NO CHANGE"

The second most popular design is "leave things as they are" (but implement the bug
report.) Developers with good style habits will use mandatory `newValue` and `oldValue`
names in their setter and observer declarations. No proposal is needed, and the bug
report guards against potential errors.

I would appreciate knowing whether the core team feels that the support for "no change",
even from a smaller group of developers, disqualifies this issue from the high bar of Phase 1.

(This group also included the most developers who self-reported that they did not
use the override feature.)

REMOVING OVERRIDES

A third design entirely loses the ability to override variables or mention their names.
This was in fact my *original* original design that I did not submit after sufficient
devs told me they wanted to always spell out magic argument names.

RIGHT NAMES ONLY

Finally, the least popular design is my original pitch. (Only allow the "right" names,
and allow them to be omitted.) This design has the least impact on the language,
causes the least breaking for most use-cases, and allows most pro coders to continue
using the "mention all names" approach.

UPDATING PROPOSAL

I am happy to update the proposal for the "closure-like" design. I believe there *was*
reasonable consensus that the current system is out of step with Swift's design goals
to push forward. However, I want this to go through another round of feedback.

Thank you in advance for your comments. If this does move forward to a proposal, it
must be discussed and decided in the first phase of Swift 4 as the change *is* breaking.

-- Erica

On Dec 1, 2016, at 10:22 PM, Derrick Ho <wh1pch81n@gmail.com <mailto:wh1pch81n@gmail.com>> wrote:

I like this proposal!

+1

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Saagar Jha) #16

I’m along the lines of keeping the old behavior+warnings if “oldValue” is used for “newValue” and vice versa. Nonbreaking, and removes the issue of accidentally swapping the two.

Saagar Jha

I believe Erica's point about RIGHT NAMES ONLY is the most clear. While a block-like syntax using $0 is nice, it fails to communicate whether it is a newvalue or an oldvalue.

Therefore instead of following a block-like pattern it should follow a delegate-function like pattern. This would remove the ambiguity that $0 or name changing would present.

set (newValue: TheType) {
let a = newValue
}

didSet (oldValue: TheType) {
let b = oldValue
}

Hmm, why do we need “TheType”? Is this not conveyed by the actual property’s declaration?

[Original pitch: https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b]

GENERAL FEEDBACK

I received a gratifying amount of feedback about my pitch here, on Twitter,
through email, on several Slack channels, and on IRC. I wanted to summarize
the feedback, to start a new round of discussion.

* A majority of respondents believe the current feature is incorrectly designed
  and that this is our best opportunity to change it.
* A majority of respondents disagree on *how* it should be changed.

Before I commit to the (non-trivial) effort of pushing on this, I'd like to know if any
of the core team can chime in on the "preferred" design. Thank you.

BUG REPORT

The notion that the compiler should check for `set(oldValue)`, `willSet(oldValue)`,
and `didSet(newValue)` and emit warnings or errors had pretty much universal
support. I have submitted https://bugs.swift.org/browse/SR-3310 to address
this, regardless of whether the syntax changes or not.

MENTIONING NAMES

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

* The current system violates the principle of clarity.
* It adds too much magic (https://en.wikipedia.org/wiki/Magic_(programming)) <https://en.wikipedia.org/wiki/Magic_(programming))>
  at the point of use.
* It is inconsistent with the binding of variable names in closures.

My original design, which I chose to provide the least impact on the compiler and
existing code, was the least popular option.

PREFERRED DESIGN

The most popular design is that setters and property observers follow closures
syntax, namely that the old value and new value arguments be passed as $0,
and assignable using `name in`. Under this design, a setter looks like:

set { newValue in ... } // or
set { somethingElse in ... } // or
set { use $0 here }

Swift loses the "magic" newValue and oldValue, but any developer who
normally prefers to mention the name before use has a simple, visible
and easy way to retain that clarity.

* Mirrors closure syntax
* Easy to use
* Loses magic names
* Encourages documenting names in context

Feels kind of “off”, since with closures the number represents a positional argument, but here the number has no value other than to match with closure syntax.

"NO CHANGE"

The second most popular design is "leave things as they are" (but implement the bug
report.) Developers with good style habits will use mandatory `newValue` and `oldValue`
names in their setter and observer declarations. No proposal is needed, and the bug
report guards against potential errors.

I would appreciate knowing whether the core team feels that the support for "no change",
even from a smaller group of developers, disqualifies this issue from the high bar of Phase 1.

(This group also included the most developers who self-reported that they did not
use the override feature.)

+1 provided bug report is considered.

REMOVING OVERRIDES

A third design entirely loses the ability to override variables or mention their names.
This was in fact my *original* original design that I did not submit after sufficient
devs told me they wanted to always spell out magic argument names.

-1, keeping “newValue” and “oldValue” is too restrictive, both in the case that there is another property with these names (causing potential confusion with self.newValue/self.oldValue), and in the case that the developer has a better description for the value.

RIGHT NAMES ONLY

Finally, the least popular design is my original pitch. (Only allow the "right" names,
and allow them to be omitted.) This design has the least impact on the language,
causes the least breaking for most use-cases, and allows most pro coders to continue
using the "mention all names" approach.

See above, but this design is a bit less source breaking, at the expense of being less consistent.

···

On Dec 3, 2016, at 7:33 PM, Derrick Ho via swift-evolution <swift-evolution@swift.org> wrote:
On Sat, Dec 3, 2016 at 10:06 PM Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

UPDATING PROPOSAL

I am happy to update the proposal for the "closure-like" design. I believe there *was*
reasonable consensus that the current system is out of step with Swift's design goals
to push forward. However, I want this to go through another round of feedback.

Thank you in advance for your comments. If this does move forward to a proposal, it
must be discussed and decided in the first phase of Swift 4 as the change *is* breaking.

-- Erica

On Dec 1, 2016, at 10:22 PM, Derrick Ho <wh1pch81n@gmail.com <mailto:wh1pch81n@gmail.com>> wrote:

I like this proposal!

+1

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matthew Johnson) #17

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

For what it's worth, I don't agree that the default names are a problem. I think they're a helpful convenience which, nevertheless, must occasionally be overridden because they conflict with the name of something else. The names are well-chosen and virtually always read correctly.

(Also FWIW, I'm not sure I've ever explicitly named the `oldValue`/`newValue` variable rather than using the implicit names.)

I think a warning on using `oldValue` instead of `newValue` or vice versa would be very helpful and address the parts of this proposal which aren't motivated by mere style complaints. The rest I think is a style issue, and I don't think that style issue is nearly universally-agreed-upon or serious enough to motivate a breaking change affecting tons of property setters, property observers, and subscript setters.

+1

···

Sent from my iPad
On Dec 4, 2016, at 4:31 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 3, 2016, at 7:06 PM, Erica Sadun <erica@ericasadun.com> wrote:

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Jean-Daniel) #18

Of course, I meaned

set(newValue foo: valueType) {

}

···

Le 4 déc. 2016 à 09:56, Jean-Daniel via swift-evolution <swift-evolution@swift.org> a écrit :

If you want to go to the side of consistency, why not just require the standard method syntax like any other place ?

set(foo newValue: valueType) {

}

So old/newValue will become a parameter label.

Le 4 déc. 2016 à 04:06, Erica Sadun via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :

[Original pitch: https://gist.github.com/erica/f5c58c689a6f479606c6158077c1962b]

GENERAL FEEDBACK

I received a gratifying amount of feedback about my pitch here, on Twitter,
through email, on several Slack channels, and on IRC. I wanted to summarize
the feedback, to start a new round of discussion.

* A majority of respondents believe the current feature is incorrectly designed
  and that this is our best opportunity to change it.
* A majority of respondents disagree on *how* it should be changed.

Before I commit to the (non-trivial) effort of pushing on this, I'd like to know if any
of the core team can chime in on the "preferred" design. Thank you.

BUG REPORT

The notion that the compiler should check for `set(oldValue)`, `willSet(oldValue)`,
and `didSet(newValue)` and emit warnings or errors had pretty much universal
support. I have submitted https://bugs.swift.org/browse/SR-3310 to address
this, regardless of whether the syntax changes or not.

MENTIONING NAMES

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

* The current system violates the principle of clarity.
* It adds too much magic (https://en.wikipedia.org/wiki/Magic_(programming)) <https://en.wikipedia.org/wiki/Magic_(programming))>
  at the point of use.
* It is inconsistent with the binding of variable names in closures.

My original design, which I chose to provide the least impact on the compiler and
existing code, was the least popular option.

PREFERRED DESIGN

The most popular design is that setters and property observers follow closures
syntax, namely that the old value and new value arguments be passed as $0,
and assignable using `name in`. Under this design, a setter looks like:

set { newValue in ... } // or
set { somethingElse in ... } // or
set { use $0 here }

Swift loses the "magic" newValue and oldValue, but any developer who
normally prefers to mention the name before use has a simple, visible
and easy way to retain that clarity.

* Mirrors closure syntax
* Easy to use
* Loses magic names
* Encourages documenting names in context

"NO CHANGE"

The second most popular design is "leave things as they are" (but implement the bug
report.) Developers with good style habits will use mandatory `newValue` and `oldValue`
names in their setter and observer declarations. No proposal is needed, and the bug
report guards against potential errors.

I would appreciate knowing whether the core team feels that the support for "no change",
even from a smaller group of developers, disqualifies this issue from the high bar of Phase 1.

(This group also included the most developers who self-reported that they did not
use the override feature.)

REMOVING OVERRIDES

A third design entirely loses the ability to override variables or mention their names.
This was in fact my *original* original design that I did not submit after sufficient
devs told me they wanted to always spell out magic argument names.

RIGHT NAMES ONLY

Finally, the least popular design is my original pitch. (Only allow the "right" names,
and allow them to be omitted.) This design has the least impact on the language,
causes the least breaking for most use-cases, and allows most pro coders to continue
using the "mention all names" approach.

UPDATING PROPOSAL

I am happy to update the proposal for the "closure-like" design. I believe there *was*
reasonable consensus that the current system is out of step with Swift's design goals
to push forward. However, I want this to go through another round of feedback.

Thank you in advance for your comments. If this does move forward to a proposal, it
must be discussed and decided in the first phase of Swift 4 as the change *is* breaking.

-- Erica

On Dec 1, 2016, at 10:22 PM, Derrick Ho <wh1pch81n@gmail.com <mailto:wh1pch81n@gmail.com>> wrote:

I like this proposal!

+1

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Chris Lattner) #19

Sent from my iPad

A majority of respondents prefer that argument names always be mentioned,
whether or not they *can* be omitted. Consensus is that it's unSwifty
to use pre-built `newValue` and `oldValue` arguments without mentioning
them first.

For what it's worth, I don't agree that the default names are a problem. I think they're a helpful convenience which, nevertheless, must occasionally be overridden because they conflict with the name of something else. The names are well-chosen and virtually always read correctly.

(Also FWIW, I'm not sure I've ever explicitly named the `oldValue`/`newValue` variable rather than using the implicit names.)

I think a warning on using `oldValue` instead of `newValue` or vice versa would be very helpful and address the parts of this proposal which aren't motivated by mere style complaints. The rest I think is a style issue, and I don't think that style issue is nearly universally-agreed-upon or serious enough to motivate a breaking change affecting tons of property setters, property observers, and subscript setters.

+1

Just MHO, not speaking for the core team: +1 to Brent's points.

-Chris

···

On Dec 4, 2016, at 5:32 AM, Matthew Johnson via swift-evolution <swift-evolution@swift.org> wrote:
On Dec 4, 2016, at 4:31 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

On Dec 3, 2016, at 7:06 PM, Erica Sadun <erica@ericasadun.com> wrote:

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution