[swift-evolution] [Pitch] Circling back to `with`

Matthew Johnson matthew at anandabits.com
Wed May 25 15:55:05 CDT 2016

> On May 25, 2016, at 3:48 PM, Jacob Bandes-Storch via swift-evolution <swift-evolution at swift.org> wrote:
> I like this pretty well, and I think "with()" makes sense as a peer of "withUnsafePointer()", "withExtendedLifetime()", etc.
> I'd also be okay with waiting for a comprehensive method-cascading solution. I don't find this issue particularly urgent, because it's pretty easily solvable with an extension or just using closures.

+1.  I’ve been playing around with it in my own code a little bit.  I’m still uncertain about when I think it is good style and when I think it is best avoided.  I would certainly feel more comfortable using it if it was in the standard library.  

At the same time, I think we can and should do better in the future.  If that is the plan, do we really want `with` in the standard library?  I don’t mind waiting for a better solution, especially if it means a better solution is more likely to happen and / or we aren’t left with an unnecessary and duplicative function in the standard library.

So I’m on the fence here.  

> On Wed, May 25, 2016 at 11:28 AM, Erica Sadun via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> Over the past couple of days, the Twitters have discovered some work I'd done on closure-based setup. 
> It's clear that a demand is out there and strong for this kind of behavior, even without implicit `self` as 
> part of the mix or cascading. In that light, I've put together the following:
> https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae>
> If the community demand is this high, I think we should re-consider pushing it before 3. 
> Feedback as always welcome, including criticism.
> -- E
> Introducing with to the Standard Library
> Proposal: TBD
> Author: Erica Sadun <https://github.com/erica>
> Status: TBD
> Review manager: TBD
>  <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae#introduction>Introduction
> This proposal introduces a with function to the standard library to simplify the initialization and modification of constants and Foundation-sourced complex objects.
> Swift-evolution thread: What about a VBA style with Statement? <http://thread.gmane.org/gmane.comp.lang.swift.evolution/14384>
>  <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae#motivation>Motivation
> Closure-based initialization enables clean and highly directed set-up in Swift code. Numerous variations on the theme have been introduced on the Swift Evolution list and in third party github repositories. Although you can build solutions natively without functions, current Swift technology has drawbacks:
> let questionLabel: UILabel = {
>     $0.textAlignment = .Center
>     $0.font =  UIFont(name:"DnealianManuscript", size: 72)
>     $0.text = questionText
>     $0.numberOfLines = 0
>     return $0
> }(UILabel())
> let mySwitch : UISwitch = {
>     view.addSubview($0)
>     CenterViewInSuperview($0, horizontal: true, vertical: true)
>     $0.addTarget(self, action: "action", forControlEvents: .TouchUpInside)
>     return $0
> }(UISwitch())
> Assignment must be explicitly typed.
> The source item must be postpended to the set-up closure.
> The closure must return the item.
> This approach is better suited to setting up Foundation objects than modifying Swift constants. When duplicating and modifying a constant, the closure must create a var copy and modify that copy.
> While the implementation is imperfect, the wins are notable. Code naturally groups into a clear set-up sequence. The scoped setup avoids clumpy redundant lines where the same variable is accessed over and over. 
> let questionLabel = UILabel()
> questionLabel.textAlignment = .Center
> questionLabel.font =  UIFont(name:"DnealianManuscript", size: 72)
> questionLabel.text = questionText
> questionLabel.numberOfLines = 0
> In the case of non-reference types, a constant's fields may be set-up sequentially without forcing the constant to be a variable.
>  <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae#detailed-design>Detailed Design
> This proposal introduces a with function that enables modification and use of an instance using positional references. It's not quite as clean as a solution with implicit self but it offers sufficient utility that a vast swath of Swift developers have adopted this function in some form or another.
> @discardableResult
> public func with<T>(_ item: T, update: @noescape (inout T) throws -> Void) rethrows -> T {
>     var this = item; try update(&this); return this
> }
> In use:
> struct Person { var name: String, favoriteColor: UIColor }
> let john = Person(name: "John", favoriteColor: .blueColor())
> let jane = with(john){ $0.name = "Jane" }
> print(jane) // Person(name: "Jane", favoriteColor: UIDeviceRGBColorSpace 0 0 1 1)
> struct Point { var (x, y) : (Double, Double) }
> let p1 = Point(x: 2, y: 3)
> let p2 = with(p1){ $0.y = 4 }
> print(p1, p2) // Point(x: 2.0, y: 3.0) Point(x: 2.0, y: 4.0)
>  <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae#impact-on-existing-code>Impact on Existing Code
> This proposal is purely additive and has no impact on existing code
>  <https://gist.github.com/erica/96d9c5bb4eaa3ed3b2ff82dc35aa8dae#alternatives-considered>Alternatives Considered
> Not adopting this proposal
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto: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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160525/bcad2678/attachment.html>

More information about the swift-evolution mailing list