Reconsidering SE-0003 Removing var from Function Parameters and Pattern Matching


(Tian Zhang) #1

I’m also curious how most people fix “guard var” or “if var”? Especially for checking a class object for protocol conformation and set variable on the object?

like in this case,

if var vc = vc as? ControlPanelConfigurationProtocol {
        vc.servicePresentationObject = service
        vc.presentAsPanel = true
}

become

if let vc = vc as? ControlPanelConfigurationProtocol {
        var vc = vc

        vc.servicePresentationObject = service
        vc.presentAsPanel = true
}

I saw a few people suggest to create a method on the protocol like “configureObject(...)” with all potential args and have the object to figure it out but doing so I feel we’re losing the benefits offered by property observation for the underlying object. Using pattern “if let” with a “var” in the block just to make the property mutable again feels really strange.

Best Wishes,
Tian

···

An alternative would certainly be interesting but I would prefer to take it one step at a time and avoid being hasty so we can come up with something really great. What did most of your var fixes look like, by the way? Did you end up changing the layout of your value types or did you decide to add more vars?

David

> On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution <swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>
> -1
>
> Having already adopted the syntax in my projects in anticipation of 2.2,
> the increase in clarity at the expense of terseness is appreciated. A
> proposal should not be discussing an alternative, not a rollback.
>
> Cheers!
> Zachary Waldowski
> zach at waldowski.me <https://lists.swift.org/mailman/listinfo/swift-evolution>
>
> On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution > > wrote:
>> Hello everyone,
>>
>> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> change in its entirety. After collecting feedback since Swift's open
>> source launch, I no longer feel this is a good move and there are a few
>> reasons why.
>>
>> There are two main patterns that the removal penalizes:
>>
>> - Get-Modify-Reassign
>> - Get-Modify-Return
>>
>> I've found that many of the problems with this proposal stem from the
>> uses before and after the "Modify" part, before returning or reassigning
>> with the new value.
>>
>> I've seen a few common responses to the var removal. Consider a
>> `Rectangle` struct:
>>
>>
>> struct Rectangle {
>> var origin: (x: Double, y: Double)
>> var size: (width: Double, height: Double)
>> }
>>
>>
>> Even with mutable variables `origin` and `size`, this pattern would be
>> impossible:
>>
>>
>> var selection = getRectangularSelection()
>> if var rect = selection?.rect {
>> // Mutate `rect` ...
>> selection.rect = rect
>> }
>>
>>
>> So, one might shadow the variable, which is not ideal:
>>
>>
>> var selection = getRectangularSelection()
>> if let rect = selection?.rect {
>> var rect = rect // Not so great
>> // Mutate `rect` ...
>> selection.rect = rect
>> }
>>
>>
>> Or, you might make a transformation function on `Rect`:
>>
>>
>> struct Rectangle {
>> var origin: (x: Double, y: Double)
>> var size: (width: Double, height: Double)
>> func withOrigin(x: Double, y: Double) -> Rect {
>> var r = self
>> r.origin = (x, y)
>> return r
>> }
>> }
>>
>>
>> This is a much better solution than shadowing but you would need one of
>> these for any property that you want to mutate and I think you'll agree
>> that it doesn't scale with the language we have today. This response begs
>> for a kind of initializer that takes all of the fields of the original
>> struct except any that you want to override:
>>
>>
>> if let rect = selection?.rect.with(origin: newOrigin) {
>> // ...
>> }
>>
>>
>> Straw syntax, but maybe you'll see something along these lines on
>> swift-evolution in the future, which would provide a clear alternative to
>> direct mutation patterns. Even then, I think having complementary
>> patterns in the language isn't a bad thing.
>>
>> These problems come up with the other variable bindings but the one that
>> ended up bothering me the most was `guard var`:
>>
>>
>> func transform(selection: Rect?) {
>> guard let rect = selection else { return }
>> var _rect = rect
>> // Mutate `_rect` ...
>> }
>>
>>
>> One of the guard statement's main purposes is to conditionally bind a
>> value as a peer in its own scope, not an inner scope like if statements.
>> Not having var makes the guard statement much weaker.
>>
>> There is certainly a bit of confusion about the nuances between value and
>> reference semantics, who owns a value and when, how effects are
>> propagated back to values, but I think we can attack the problem with
>> more finesse.
>>
>> Value types are one of the attractive features of Swift – because of
>> their semantics, mutating algorithms are written in a familiar style but
>> keeping effects limited to your unique reference. I don't think we should
>> give that up now to address confusion about semantics, out of principle,
>> or in anticipation of new language features. I propose cancelling this
>> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> it occurs in Swift 2.2.
>>
>> Regards,
>> David
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 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>
> https://lists.swift.org/mailman/listinfo/swift-evolution


(Dave Abrahams) #2

I’m also curious how most people fix “guard var” or “if var”?
Especially for checking a class object for protocol conformation and
set variable on the object?

like in this case,

if var vc = vc as? ControlPanelConfigurationProtocol {
        vc.servicePresentationObject = service
        vc.presentAsPanel = true
}

become

if let vc = vc as? ControlPanelConfigurationProtocol {
        var vc = vc

        vc.servicePresentationObject = service
        vc.presentAsPanel = true
}

If vc has class type, you don't need the var at all.

···

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

I saw a few people suggest to create a method on the protocol like
“configureObject(...)” with all potential args and have the object to
figure it out but doing so I feel we’re losing the benefits offered by
property observation for the underlying object. Using pattern “if let”
with a “var” in the block just to make the property mutable again
feels really strange.

Best Wishes,
Tian

An alternative would certainly be interesting but I would prefer to
take it one step at a time and avoid being hasty so we can come up
with something really great. What did most of your var fixes look
like, by the way? Did you end up changing the layout of your value
types or did you decide to add more vars?

David

> On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >> > <swift-evolution at swift.org >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>
> -1
>
> Having already adopted the syntax in my projects in anticipation of 2.2,
> the increase in clarity at the expense of terseness is appreciated. A
> proposal should not be discussing an alternative, not a rollback.
>
> Cheers!
> Zachary Waldowski
> zach at waldowski.me <https://lists.swift.org/mailman/listinfo/swift-evolution>
>
> On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >> > wrote:
>> Hello everyone,
>>
>> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> change in its entirety. After collecting feedback since Swift's open
>> source launch, I no longer feel this is a good move and there are a few
>> reasons why.
>>
>> There are two main patterns that the removal penalizes:
>>
>> - Get-Modify-Reassign
>> - Get-Modify-Return
>>
>> I've found that many of the problems with this proposal stem from the
>> uses before and after the "Modify" part, before returning or reassigning
>> with the new value.
>>
>> I've seen a few common responses to the var removal. Consider a
>> `Rectangle` struct:
>>
>>
>> struct Rectangle {
>> var origin: (x: Double, y: Double)
>> var size: (width: Double, height: Double)
>> }
>>
>>
>> Even with mutable variables `origin` and `size`, this pattern would be
>> impossible:
>>
>>
>> var selection = getRectangularSelection()
>> if var rect = selection?.rect {
>> // Mutate `rect` ...
>> selection.rect = rect
>> }
>>
>>
>> So, one might shadow the variable, which is not ideal:
>>
>>
>> var selection = getRectangularSelection()
>> if let rect = selection?.rect {
>> var rect = rect // Not so great
>> // Mutate `rect` ...
>> selection.rect = rect
>> }
>>
>>
>> Or, you might make a transformation function on `Rect`:
>>
>>
>> struct Rectangle {
>> var origin: (x: Double, y: Double)
>> var size: (width: Double, height: Double)
>> func withOrigin(x: Double, y: Double) -> Rect {
>> var r = self
>> r.origin = (x, y)
>> return r
>> }
>> }
>>
>>
>> This is a much better solution than shadowing but you would need one of
>> these for any property that you want to mutate and I think you'll agree
>> that it doesn't scale with the language we have today. This response begs
>> for a kind of initializer that takes all of the fields of the original
>> struct except any that you want to override:
>>
>>
>> if let rect = selection?.rect.with(origin: newOrigin) {
>> // ...
>> }
>>
>>
>> Straw syntax, but maybe you'll see something along these lines on
>> swift-evolution in the future, which would provide a clear alternative to
>> direct mutation patterns. Even then, I think having complementary
>> patterns in the language isn't a bad thing.
>>
>> These problems come up with the other variable bindings but the one that
>> ended up bothering me the most was `guard var`:
>>
>>
>> func transform(selection: Rect?) {
>> guard let rect = selection else { return }
>> var _rect = rect
>> // Mutate `_rect` ...
>> }
>>
>>
>> One of the guard statement's main purposes is to conditionally bind a
>> value as a peer in its own scope, not an inner scope like if statements.
>> Not having var makes the guard statement much weaker.
>>
>> There is certainly a bit of confusion about the nuances between value and
>> reference semantics, who owns a value and when, how effects are
>> propagated back to values, but I think we can attack the problem with
>> more finesse.
>>
>> Value types are one of the attractive features of Swift – because of
>> their semantics, mutating algorithms are written in a familiar style but
>> keeping effects limited to your unique reference. I don't think we should
>> give that up now to address confusion about semantics, out of principle,
>> or in anticipation of new language features. I propose cancelling this
>> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> it occurs in Swift 2.2.
>>
>> Regards,
>> David
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> <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>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

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

--
-Dave


(Chéyo Jiménez) #3

Would it be confusing if `guard var ` or `if var ` was only allowed for
value types?

···

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution < swift-evolution@swift.org> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org <javascript:;>> > wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution > >> > <swift-evolution at swift.org > >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of
2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution > >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a
few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from the
>> >> uses before and after the "Modify" part, before returning or
reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would
be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need one
of
>> >> these for any property that you want to mutate and I think you'll
agree
>> >> that it doesn't scale with the language we have today. This response
begs
>> >> for a kind of initializer that takes all of the fields of the
original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear
alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one
that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind a
>> >> value as a peer in its own scope, not an inner scope like if
statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between
value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar style
but
>> >> keeping effects limited to your unique reference. I don't think we
should
>> >> give that up now to address confusion about semantics, out of
principle,
>> >> or in anticipation of new language features. I propose cancelling
this
>> >> change for Swift 3 and continue to allow `var` in the grammar
everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

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


(Nate Birkholz) #4

Seems in line with other compiler warnings.

···

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution <swift-evolution@swift.org> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >> >> > <swift-evolution at swift.org >> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of 2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from the
>> >> uses before and after the "Modify" part, before returning or reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need one of
>> >> these for any property that you want to mutate and I think you'll agree
>> >> that it doesn't scale with the language we have today. This response begs
>> >> for a kind of initializer that takes all of the fields of the original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind a
>> >> value as a peer in its own scope, not an inner scope like if statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar style but
>> >> keeping effects limited to your unique reference. I don't think we should
>> >> give that up now to address confusion about semantics, out of principle,
>> >> or in anticipation of new language features. I propose cancelling this
>> >> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
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


(Jordan Rose) #5

That doesn't make sense to me. If it's sometimes necessary to reassign a struct containing a single reference, then surely it may be necessary to reassign a single reference not contained in a struct.

Jordan

···

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution <swift-evolution@swift.org> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org <javascript:;>> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >> >> > <swift-evolution at swift.org <http://swift.org/> >> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of 2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <http://waldowski.me/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from the
>> >> uses before and after the "Modify" part, before returning or reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need one of
>> >> these for any property that you want to mutate and I think you'll agree
>> >> that it doesn't scale with the language we have today. This response begs
>> >> for a kind of initializer that takes all of the fields of the original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind a
>> >> value as a peer in its own scope, not an inner scope like if statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar style but
>> >> keeping effects limited to your unique reference. I don't think we should
>> >> give that up now to address confusion about semantics, out of principle,
>> >> or in anticipation of new language features. I propose cancelling this
>> >> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <http://swift.org/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org <http://swift.org/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
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


(Chéyo Jiménez) #6

Reassigning of class objects probably occurs less than
mutations of structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK, is that
people get confuse about references. Perhaps just limiting their use for
value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to be
value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice
the `let`

···

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose <jordan_rose@apple.com> wrote:

That doesn't make sense to me. If it's sometimes necessary to reassign a
struct containing a single reference, then surely it may be necessary to
reassign a single reference not contained in a struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution < > swift-evolution@swift.org> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution < > swift-evolution@swift.org> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for
value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution < > swift-evolution@swift.org> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >> >> > <swift-evolution at swift.org >> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of
2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling
the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a
few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from
the
>> >> uses before and after the "Modify" part, before returning or
reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would
be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need
one of
>> >> these for any property that you want to mutate and I think you'll
agree
>> >> that it doesn't scale with the language we have today. This
response begs
>> >> for a kind of initializer that takes all of the fields of the
original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear
alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one
that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind
a
>> >> value as a peer in its own scope, not an inner scope like if
statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between
value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem
with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar
style but
>> >> keeping effects limited to your unique reference. I don't think we
should
>> >> give that up now to address confusion about semantics, out of
principle,
>> >> or in anticipation of new language features. I propose cancelling
this
>> >> change for Swift 3 and continue to allow `var` in the grammar
everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
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

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


(Jordan Rose) #7

I still don't understand how value types and reference types are different here. Here's a contrived "confusion" example (but we have seen similar real-world code):

for var element in array {
  if element.isNotUpToMyStandards {
    element = makeANewElement()
    // 'element' is not stored back into 'array', but was meant to be.
  }
}

This code, or rather the behavior the developer intended, is perfectly reasonable. But it's exactly the same code whether there's a value type or a reference type involved. I get that there are other examples where this is not the case, but I can't see how those would be any less confusing by adding this rule.

But maybe I'm just too familiar with Swift, and so have trouble putting myself in the shoes of a new learner.

Jordan

···

On Jan 27, 2016, at 20:45 , J. Cheyo Jimenez <cheyo@masters3d.com> wrote:

Reassigning of class objects probably occurs less than mutations of structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK, is that people get confuse about references. Perhaps just limiting their use for value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to be value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice the `let`

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:
That doesn't make sense to me. If it's sometimes necessary to reassign a struct containing a single reference, then surely it may be necessary to reassign a single reference not contained in a struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org <>> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >>> >> > <swift-evolution at swift.org <http://swift.org/> >>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of 2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <http://waldowski.me/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >>> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from the
>> >> uses before and after the "Modify" part, before returning or reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need one of
>> >> these for any property that you want to mutate and I think you'll agree
>> >> that it doesn't scale with the language we have today. This response begs
>> >> for a kind of initializer that takes all of the fields of the original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind a
>> >> value as a peer in its own scope, not an inner scope like if statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar style but
>> >> keeping effects limited to your unique reference. I don't think we should
>> >> give that up now to address confusion about semantics, out of principle,
>> >> or in anticipation of new language features. I propose cancelling this
>> >> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <http://swift.org/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org <http://swift.org/> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <>
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

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


(Howard Lovatt) #8

I am fine with eliminating var in constructs like if etc. I hardly use it
and if I need it it is easy to assign to a var. Likely to eliminate sill
cut and past errors also, in addition to genuine misunderstand of what is
happening.

···

On Thursday, 28 January 2016, J. Cheyo Jimenez via swift-evolution < swift-evolution@swift.org> wrote:

Reassigning of class objects probably occurs less than
mutations of structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK, is
that people get confuse about references. Perhaps just limiting their use
for value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to be
value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice
the `let`

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose <jordan_rose@apple.com > <javascript:_e(%7B%7D,'cvml','jordan_rose@apple.com');>> wrote:

That doesn't make sense to me. If it's sometimes necessary to reassign a
struct containing a single reference, then surely it may be necessary to
reassign a single reference not contained in a struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution < >> swift-evolution@swift.org >> <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org >> <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for
value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org >> <javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >>> >> > <swift-evolution at swift.org >>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of
2.2,
>> > the increase in clarity at the expense of terseness is appreciated.
A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >>> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling
the
>> >> change in its entirety. After collecting feedback since Swift's
open
>> >> source launch, I no longer feel this is a good move and there are
a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from
the
>> >> uses before and after the "Modify" part, before returning or
reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern
would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need
one of
>> >> these for any property that you want to mutate and I think you'll
agree
>> >> that it doesn't scale with the language we have today. This
response begs
>> >> for a kind of initializer that takes all of the fields of the
original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear
alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the
one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally
bind a
>> >> value as a peer in its own scope, not an inner scope like if
statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between
value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem
with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because
of
>> >> their semantics, mutating algorithms are written in a familiar
style but
>> >> keeping effects limited to your unique reference. I don't think we
should
>> >> give that up now to address confusion about semantics, out of
principle,
>> >> or in anticipation of new language features. I propose cancelling
this
>> >> change for Swift 3 and continue to allow `var` in the grammar
everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

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

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
<javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
<javascript:_e(%7B%7D,'cvml','swift-evolution@swift.org');>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
  -- Howard.


(Nate Birkholz) #9

Interestingly for me, my first "real" language was Swift (unless you count
fortran in the 80s) so the behaviors of Swift are "normal" to me, but I
still made the mistake of thinking var == object mutability when coming
back to Swift last month after a year of Objective-C. I get the confusion.
But I also think the removal of the expressiveness of "if var foo {}" is a
shame and would like to see an alternate plan.

I can live without var parameters because it's just a bit of a trick,
really, however convenient.

···

On Thu, Jan 28, 2016 at 10:05 AM, Jordan Rose via swift-evolution < swift-evolution@swift.org> wrote:

I *still* don't understand how value types and reference types are
different here. Here's a contrived "confusion" example (but we have seen
similar real-world code):

for var element in array {
  if element.isNotUpToMyStandards {
    element = makeANewElement()
    // 'element' is not stored back into 'array', but was meant to be.
  }
}

This code, or rather the behavior the developer intended, is perfectly
reasonable. But it's exactly the same code whether there's a value type or
a reference type involved. I get that there are other examples where this
is *not* the case, but I can't see how *those* would be any *less* confusing
by adding this rule.

But maybe I'm just too familiar with Swift, and so have trouble putting
myself in the shoes of a new learner.

Jordan

On Jan 27, 2016, at 20:45 , J. Cheyo Jimenez <cheyo@masters3d.com> wrote:

Reassigning of class objects probably occurs less than
mutations of structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK, is
that people get confuse about references. Perhaps just limiting their use
for value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to be
value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice
the `let`

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose <jordan_rose@apple.com> > wrote:

That doesn't make sense to me. If it's sometimes necessary to reassign a
struct containing a single reference, then surely it may be necessary to
reassign a single reference not contained in a struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution < >> swift-evolution@swift.org> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for
value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >>> >> > <swift-evolution at swift.org >>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of
2.2,
>> > the increase in clarity at the expense of terseness is appreciated.
A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >>> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling
the
>> >> change in its entirety. After collecting feedback since Swift's
open
>> >> source launch, I no longer feel this is a good move and there are
a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from
the
>> >> uses before and after the "Modify" part, before returning or
reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern
would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need
one of
>> >> these for any property that you want to mutate and I think you'll
agree
>> >> that it doesn't scale with the language we have today. This
response begs
>> >> for a kind of initializer that takes all of the fields of the
original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear
alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the
one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally
bind a
>> >> value as a peer in its own scope, not an inner scope like if
statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between
value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem
with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because
of
>> >> their semantics, mutating algorithms are written in a familiar
style but
>> >> keeping effects limited to your unique reference. I don't think we
should
>> >> give that up now to address confusion about semantics, out of
principle,
>> >> or in anticipation of new language features. I propose cancelling
this
>> >> change for Swift 3 and continue to allow `var` in the grammar
everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
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

_______________________________________________
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

--
Nate Birkholz


(Dave Abrahams) #10

I still don't understand how value types and reference types are
different here. Here's a contrived "confusion" example (but we have
seen similar real-world code):

for var element in array {
  if element.isNotUpToMyStandards {
    element = makeANewElement()
    // 'element' is not stored back into 'array', but was meant to be.
  }
}

This code, or rather the behavior the developer intended, is perfectly
reasonable. But it's exactly the same code whether there's a value
type or a reference type involved. I get that there are other examples
where this is not the case, but I can't see how those would be any
less confusing by adding this rule.

The difference between value types and reference types here is that in
many examples (but not this one), a reference type will hide the fact
that "var" doesn't produce writeback semantics, and the user who expects
writeback will only discover it much later.

[IMO this mis-expectation is better treated through education than
through language surface changes, FWIW]

···

on Thu Jan 28 2016, Jordan Rose <swift-evolution@swift.org> wrote:

But maybe I'm just too familiar with Swift, and so have trouble
putting myself in the shoes of a new learner.

Jordan

On Jan 27, 2016, at 20:45 , J. Cheyo Jimenez >> <cheyo@masters3d.com> wrote:

Reassigning of class objects probably occurs less than mutations of
structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK,
is that people get confuse about references. Perhaps just limiting
their use for value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to
be value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice the `let`

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose >> <jordan_rose@apple.com >> <mailto:jordan_rose@apple.com>> wrote:
That doesn't make sense to me. If it's sometimes necessary to
reassign a struct containing a single reference, then surely it may
be necessary to reassign a single reference not contained in a
struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution >>> <swift-evolution@swift.org >>> <mailto:swift-evolution@swift.org>> >>> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution >>>> <swift-evolution@swift.org >>>> <mailto:swift-evolution@swift.org>> >>>> wrote:

on Tue Jan 26 2016, Tian Zhang >>>> <swift-evolution@swift.org <>> >>>> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >>>> >> > <swift-evolution at swift.org <http://swift.org/> >>>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution >>>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>>> >>>> >> > wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of 2.2,
>> > the increase in clarity at the expense of terseness is appreciated. A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <http://waldowski.me/>
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >>>> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling the
>> >> change in its entirety. After collecting feedback since Swift's open
>> >> source launch, I no longer feel this is a good move and there are a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from the
>> >> uses before and after the "Modify" part, before returning or reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need one of
>> >> these for any property that you want to mutate and I think you'll agree
>> >> that it doesn't scale with the language we have today. This response begs
>> >> for a kind of initializer that takes all of the fields of the original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally bind a
>> >> value as a peer in its own scope, not an inner scope like if statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because of
>> >> their semantics, mutating algorithms are written in a familiar style but
>> >> keeping effects limited to your unique reference. I don't think we should
>> >> give that up now to address confusion about semantics, out of principle,
>> >> or in anticipation of new language features. I propose cancelling this
>> >> change for Swift 3 and continue to allow `var` in the grammar everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <http://swift.org/>
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>> > _______________________________________________
>> > swift-evolution mailing list
>> > swift-evolution at swift.org <http://swift.org/>
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org <>
> https://lists.swift.org/mailman/listinfo/swift-evolution
> <https://lists.swift.org/mailman/listinfo/swift-evolution>

--
-Dave

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

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

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

--
-Dave


(Chéyo Jiménez) #11

The curse of knowledge. :slight_smile:

I don't mind 'for var' to be gone or var in functions.
The suggestion of 'if bind' seems interesting but then I think it may
become a little too magical. A combination of the two ideas would
be something like:

let x:Int? = 1

if bind x {
    var x = x
    x += 2
    methodWithSideEffets(x)
}

same as :

if let x = x {
    var x = x
       x += 2
    methodWithSideEffets(x)
}

vs

if var x = x {
   x += 2
    methodWithSideEffets(x)
}

···

On Thursday, January 28, 2016, Jordan Rose <jordan_rose@apple.com <javascript:_e(%7B%7D,'cvml','jordan_rose@apple.com');>> wrote:

I *still* don't understand how value types and reference types are
different here. Here's a contrived "confusion" example (but we have seen
similar real-world code):

for var element in array {
  if element.isNotUpToMyStandards {
    element = makeANewElement()
    // 'element' is not stored back into 'array', but was meant to be.
  }
}

This code, or rather the behavior the developer intended, is perfectly
reasonable. But it's exactly the same code whether there's a value type or
a reference type involved. I get that there are other examples where this
is *not* the case, but I can't see how *those* would be any *less* confusing
by adding this rule.

But maybe I'm just too familiar with Swift, and so have trouble putting
myself in the shoes of a new learner.

Jordan

On Jan 27, 2016, at 20:45 , J. Cheyo Jimenez <cheyo@masters3d.com> wrote:

Reassigning of class objects probably occurs less than
mutations of structs inside `if var` or `guard var`.
The main reason for the removal of `if var` or `guard var`, AFAIK, is
that people get confuse about references. Perhaps just limiting their use
for value types could then clear up the confusion.
example of warning.
"'if var' is restricted to value types, did you mean 'if let'?"

One of the issues is that now all comma separated optionals need to be
value types or offer alternative syntax.

if var value1 = value1, ref1 = ref1 {} /// This would not work

if var value1 = value1, let ref1 = ref1 {} /// Possible solution, notice
the `let`

On Wed, Jan 27, 2016 at 8:05 PM, Jordan Rose <jordan_rose@apple.com> > wrote:

That doesn't make sense to me. If it's sometimes necessary to reassign a
struct containing a single reference, then surely it may be necessary to
reassign a single reference not contained in a struct.

Jordan

On Jan 26, 2016, at 20:37 , Nate Birkholz via swift-evolution < >> swift-evolution@swift.org> wrote:

Seems in line with other compiler warnings.

Sent from my iPhone, please excuse brevity and errors

On Jan 26, 2016, at 8:30 PM, J. Cheyo Jimenez via swift-evolution < >> swift-evolution@swift.org> wrote:

Would it be confusing if `guard var ` or `if var ` was only allowed for
value types?

On Tuesday, January 26, 2016, Dave Abrahams via swift-evolution < >> swift-evolution@swift.org> wrote:

on Tue Jan 26 2016, Tian Zhang <swift-evolution@swift.org> wrote:

> I’m also curious how most people fix “guard var” or “if var”?
> Especially for checking a class object for protocol conformation and
> set variable on the object?
>
> like in this case,
>
>> if var vc = vc as? ControlPanelConfigurationProtocol {
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }
>
> become
>
>> if let vc = vc as? ControlPanelConfigurationProtocol {
>> var vc = vc
>>
>> vc.servicePresentationObject = service
>> vc.presentAsPanel = true
>> }

If vc has class type, you don't need the var at all.

> I saw a few people suggest to create a method on the protocol like
> “configureObject(...)” with all potential args and have the object to
> figure it out but doing so I feel we’re losing the benefits offered by
> property observation for the underlying object. Using pattern “if let”
> with a “var” in the block just to make the property mutable again
> feels really strange.
>
> Best Wishes,
> Tian
>> An alternative would certainly be interesting but I would prefer to
>> take it one step at a time and avoid being hasty so we can come up
>> with something really great. What did most of your var fixes look
>> like, by the way? Did you end up changing the layout of your value
>> types or did you decide to add more vars?
>>
>> David
>>
>> > On Jan 24, 2016, at 7:19 PM, Zach Waldowski via swift-evolution >>> >> > <swift-evolution at swift.org >>> >> > <https://lists.swift.org/mailman/listinfo/swift-evolution>> wrote:
>> >
>> > -1
>> >
>> > Having already adopted the syntax in my projects in anticipation of
2.2,
>> > the increase in clarity at the expense of terseness is appreciated.
A
>> > proposal should not be discussing an alternative, not a rollback.
>> >
>> > Cheers!
>> > Zachary Waldowski
>> > zach at waldowski.me <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >
>> > On Fri, Jan 22, 2016, at 12:26 PM, David Farler via swift-evolution >>> >> > wrote:
>> >> Hello everyone,
>> >>
>> >> I'd like to reconsider SE-0003 for Swift 3 and propose cancelling
the
>> >> change in its entirety. After collecting feedback since Swift's
open
>> >> source launch, I no longer feel this is a good move and there are
a few
>> >> reasons why.
>> >>
>> >> There are two main patterns that the removal penalizes:
>> >>
>> >> - Get-Modify-Reassign
>> >> - Get-Modify-Return
>> >>
>> >> I've found that many of the problems with this proposal stem from
the
>> >> uses before and after the "Modify" part, before returning or
reassigning
>> >> with the new value.
>> >>
>> >> I've seen a few common responses to the var removal. Consider a
>> >> `Rectangle` struct:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> }
>> >>
>> >>
>> >> Even with mutable variables `origin` and `size`, this pattern
would be
>> >> impossible:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if var rect = selection?.rect {
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> So, one might shadow the variable, which is not ideal:
>> >>
>> >>
>> >> var selection = getRectangularSelection()
>> >> if let rect = selection?.rect {
>> >> var rect = rect // Not so great
>> >> // Mutate `rect` ...
>> >> selection.rect = rect
>> >> }
>> >>
>> >>
>> >> Or, you might make a transformation function on `Rect`:
>> >>
>> >>
>> >> struct Rectangle {
>> >> var origin: (x: Double, y: Double)
>> >> var size: (width: Double, height: Double)
>> >> func withOrigin(x: Double, y: Double) -> Rect {
>> >> var r = self
>> >> r.origin = (x, y)
>> >> return r
>> >> }
>> >> }
>> >>
>> >>
>> >> This is a much better solution than shadowing but you would need
one of
>> >> these for any property that you want to mutate and I think you'll
agree
>> >> that it doesn't scale with the language we have today. This
response begs
>> >> for a kind of initializer that takes all of the fields of the
original
>> >> struct except any that you want to override:
>> >>
>> >>
>> >> if let rect = selection?.rect.with(origin: newOrigin) {
>> >> // ...
>> >> }
>> >>
>> >>
>> >> Straw syntax, but maybe you'll see something along these lines on
>> >> swift-evolution in the future, which would provide a clear
alternative to
>> >> direct mutation patterns. Even then, I think having complementary
>> >> patterns in the language isn't a bad thing.
>> >>
>> >> These problems come up with the other variable bindings but the
one that
>> >> ended up bothering me the most was `guard var`:
>> >>
>> >>
>> >> func transform(selection: Rect?) {
>> >> guard let rect = selection else { return }
>> >> var _rect = rect
>> >> // Mutate `_rect` ...
>> >> }
>> >>
>> >>
>> >> One of the guard statement's main purposes is to conditionally
bind a
>> >> value as a peer in its own scope, not an inner scope like if
statements.
>> >> Not having var makes the guard statement much weaker.
>> >>
>> >> There is certainly a bit of confusion about the nuances between
value and
>> >> reference semantics, who owns a value and when, how effects are
>> >> propagated back to values, but I think we can attack the problem
with
>> >> more finesse.
>> >>
>> >> Value types are one of the attractive features of Swift – because
of
>> >> their semantics, mutating algorithms are written in a familiar
style but
>> >> keeping effects limited to your unique reference. I don't think we
should
>> >> give that up now to address confusion about semantics, out of
principle,
>> >> or in anticipation of new language features. I propose cancelling
this
>> >> change for Swift 3 and continue to allow `var` in the grammar
everywhere
>> >> it occurs in Swift 2.2.
>> >>
>> >> Regards,
>> >> David
>> >> _______________________________________________
>> >> swift-evolution mailing list
>> >> swift-evolution at swift.org <
https://lists.swift.org/mailman/listinfo/swift-evolution>
>> >> https://lists.swift.org/mailman/listinfo/swift-evolution
>> >> <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>
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>> > <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

--
-Dave

_______________________________________________
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

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