[swift-evolution] Reconsidering SE-0003 Removing var from Function Parameters and Pattern Matching

J. Cheyo Jimenez cheyo at masters3d.com
Wed Jan 27 22:45:33 CST 2016


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 at 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 at 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 at 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 at swift.org> wrote:
>
>>
>> on Tue Jan 26 2016, Tian Zhang <swift-evolution at 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 at swift.org
>> > https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> --
>> -Dave
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160127/c4d65a49/attachment.html>


More information about the swift-evolution mailing list