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

J. Cheyo Jimenez cheyo at masters3d.com
Fri Jan 22 12:10:47 CST 2016


+1

I had filed SR-534 to add shadow variables so that code would compile. The
problem is more apparent when the code uses structs heavily, in my
mind, forcing only let binding, might even encourage the use of classes so
that the let binding works for mutation. In an if let binding I already use
the same name for the binding and adding a shadow variable makes code sort
of ugly and repetitive for value optional types.

If let foo = foo, bar = bar {
    var foo = foo // don't need for classes
    var bar = bar //
         foo.mutare()
         bar.mutate()
}



On Friday, January 22, 2016, David Farler via swift-evolution <
swift-evolution at swift.org> 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 <javascript:;>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160122/1f59769c/attachment.html>


More information about the swift-evolution mailing list