Proposal: Local identifier for the newValue in didSet and willSet blocks

Just an idea.

I use didSet a lot, and it'd be nice to have a generic way to access the
newValue.

For UI modes:

var anonymousUserMode = false { didSet {
  if oldValue == anonymousUserMode { return }
  renderLoginOverlay(show: anonymousUserMode)
}}

For animated display strings:

var errorMessage: String? = nil { didSet {
  if oldValue == errorMessage { return }
  errorLabel.text = errorMessage
  // Do some sliding or hiding based on the new value
}}

Has the idea of using $0 / $1 or oldValue / newValue been considered?

I'd like to be able to write this as:

var anonymousUserMode = false { didSet {
  if oldValue == newValue { return }
  renderLoginOverlay(show: newValue)
}}

The newValue is already set in the property, so you just use that property. I don't see much benefit in having "newValue" instead of just accessing it:

var anonymousUserMode = false {
  didSet {
    if oldValue == self.anonymousUserMode {
      return
    }
    
    renderLoginOverlay(show: newValue)
  }
}

And the same goes for willSet, where you have newValue, but not "oldValue", since oldValue is still in the stored property...

···

On Aug 26, 2016, at 8:20 PM, Eric Miller via swift-evolution <swift-evolution@swift.org> wrote:

Just an idea.

I use didSet a lot, and it'd be nice to have a generic way to access the newValue.

For UI modes:

var anonymousUserMode = false { didSet {
  if oldValue == anonymousUserMode { return }
  renderLoginOverlay(show: anonymousUserMode)
}}

For animated display strings:

var errorMessage: String? = nil { didSet {
  if oldValue == errorMessage { return }
  errorLabel.text = errorMessage
  // Do some sliding or hiding based on the new value
}}

Has the idea of using $0 / $1 or oldValue / newValue been considered?

I'd like to be able to write this as:

var anonymousUserMode = false { didSet {
  if oldValue == newValue { return }
  renderLoginOverlay(show: newValue)
}}
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I believe this is just a ‘nice to have’ shortcut. I wouldn’t mind to have this:

willSet(newValue, oldValue)
didSet(newValue, oldValue)
$0 for newValue and $1 for oldValue
It’s nothing for phase one, so we’ll have to defer this until next year where we’ll start talking about sugar/additional features for Swift 4.

···

--
Adrian Zubarev
Sent with Airmail

Am 27. August 2016 um 08:47:38, Charlie Monroe via swift-evolution (swift-evolution@swift.org) schrieb:

The newValue is already set in the property, so you just use that property. I don't see much benefit in having "newValue" instead of just accessing it:

var anonymousUserMode = false {
didSet {
if oldValue == self.anonymousUserMode {
return
}

renderLoginOverlay(show: newValue)
}
}

And the same goes for willSet, where you have newValue, but not "oldValue", since oldValue is still in the stored property...

On Aug 26, 2016, at 8:20 PM, Eric Miller via swift-evolution <swift-evolution@swift.org> wrote:

Just an idea.

I use didSet a lot, and it'd be nice to have a generic way to access the newValue.

For UI modes:

var anonymousUserMode = false { didSet {
if oldValue == anonymousUserMode { return }
renderLoginOverlay(show: anonymousUserMode)
}}

For animated display strings:

var errorMessage: String? = nil { didSet {
if oldValue == errorMessage { return }
errorLabel.text = errorMessage
// Do some sliding or hiding based on the new value
}}

Has the idea of using $0 / $1 or oldValue / newValue been considered?

I'd like to be able to write this as:

var anonymousUserMode = false { didSet {
if oldValue == newValue { return }
renderLoginOverlay(show: newValue)
}}
_______________________________________________
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

The benefit I see is that the logic internal to didSet blocks is often
pretty generic in terms of how it deals with old VS new.

Eg:
* always bail if they match
* always render the new value
* always animate from the old value to the new value

The internal logic may repeat these names a lot, and it is unconcerned with
the often lengthy or descriptive name that may be exposed to the outside
world.

Often I rename the property, and have to rename 3 or 4 places inside the
didSet which should in my view be unnecessary.

Conceptually this is similar to the benefit of having different internal
and external parameter names for functions. In this case we have a great
default internal parameter name available.

I'm not sure whether some good examples or some other form of reasoning
best advances my point.

I'll try a sort of philosophical approach though. Why not have not didSet
and willSet always both have newValue and oldValue, since keeping the API
the same removes something the developer has to think about. In this way we
actually simplify the language, since all change observing blocks have the
same preconfigured variables available.

···

On Sat, Aug 27, 2016 at 12:47 AM Charlie Monroe <charlie@charliemonroe.net> wrote:

The newValue is already set in the property, so you just use that
property. I don't see much benefit in having "newValue" instead of just
accessing it:

var anonymousUserMode = false {
        didSet {
                if oldValue == self.anonymousUserMode {
                        return
                }

                renderLoginOverlay(show: newValue)
        }
}

And the same goes for willSet, where you have newValue, but not
"oldValue", since oldValue is still in the stored property...

> On Aug 26, 2016, at 8:20 PM, Eric Miller via swift-evolution < > swift-evolution@swift.org> wrote:
>
> Just an idea.
>
> I use didSet a lot, and it'd be nice to have a generic way to access the
newValue.
>
> For UI modes:
>
> var anonymousUserMode = false { didSet {
> if oldValue == anonymousUserMode { return }
> renderLoginOverlay(show: anonymousUserMode)
> }}
>
> For animated display strings:
>
> var errorMessage: String? = nil { didSet {
> if oldValue == errorMessage { return }
> errorLabel.text = errorMessage
> // Do some sliding or hiding based on the new value
> }}
>
> Has the idea of using $0 / $1 or oldValue / newValue been considered?
>
> I'd like to be able to write this as:
>
> var anonymousUserMode = false { didSet {
> if oldValue == newValue { return }
> renderLoginOverlay(show: newValue)
> }}
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

The benefit is pretty obvious to me. In addition to have consistently named variables that don't change inside didSet/willSet, using the oldValue/newValue would prevent the getter from being called.

That is what bugs me the most about this. I don't want to call the getter inside a setter, just give me the new value directly.