[swift-evolution] [Discussion] "with" statement/method

Vladimir.S svabox at gmail.com
Fri Apr 22 05:27:24 CDT 2016


Personally, I don't feel like your suggestion is a replacement for "with" 
feature. "With" not just about mutating(it can be used to just get multiply 
props from "target" instance), it allows to call methods of instance, use a 
label of "target" instance (like $0) to be used as argument (like with 
someInstance { ...; callFunc($0); } etc.

Also, in your suggestion there is implicit "self" for the target instance 
(.firstName) and this will produce not obvious code (like .someColor = 
.colorRed - first belongs to target instance, second - enum value)

I believe you can start new [Discussion]/[Idea] about this "mutating" 
feature, in this thread I'd like to collect opinions regarding the "with" 
feature proposal.

On 22.04.2016 11:12, Patrick Smith wrote:
> I was wondering if all mutating and setters of a method could become a type
> (Typename.Mutation), say something similar to an enum.
>
> You’d use it like this:
>
> let alice = john mutating [
>   .firstName = "Alice",
>   .makeScottishClan
> ]
>
> See more here:
> https://gist.github.com/BurntCaramel/ba2ce9dfd49595dacce07394de579172
>
> Patrick
>
>
>
>
> On Fri, Apr 22, 2016 at 12:18 AM -0700, "Vladimir.S via swift-evolution"
> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>
>     Just wanted to summarize our opinions on this suggestion that we was
>     discussing earlier and check if someone is ready to crate an "official"
>     proposal for this feature.
>
>     There a number of questions regarding this feature we can discuss, for
>     example statement vs method, what could be a placeholder of target instance
>     inside the scope($0, $, _, .., nothing etc)
>
>     The main question, *do you support that we need "with" feature in some way
>     in Swift 3.0 out of the box* . And if so, what variant do you prefer.
>
>     * this proposal is for *explicit* "with", where it is clear what
>     method/property belongs to the "target" instance
>     * I believe that as such feature is really useful and handy, if it is
>     explicit and if it is clearly showing in code what we are doing - we want
>     to have this feature as part of language/standard lib rather than
>     possibility to use some workaround to implement it
>     * It is not about saving the space in code. It is about more readable and
>     (I insist) more stable(with less errors) code. Much less possibilities for
>     copy-paste errors. Wrong code completion suggestion(by editor) can not
>     produce error. It is explicit and clear, it has much less noise in code.
>     * Many of us already implemented and use such "with" construction in some way
>
>     There were 2 main suggestions :
>
>     1) Introduce "with" statement that can be used in for example in such way:
>
>     // set props just after creating
>     // similar to "if let.. " and "guard let.."
>     with let questionLabel = UILabel() {
>        //set props of created instance here
>        // here we can have:
>        // $0.prop = value
>        // or
>        // ..prop = value
>        // or
>        // .prop = value
>        // or
>        // _.prop = value
>        // or
>        // $.prop = value
>        // or ?
>     }
>     // questionLabel is available here
>
>
>     // works for structures
>     with var some = SomeStruct() {
>        //...
>     }
>
>     // just for some class/structure/enum
>     with questionLabel {
>        // ..
>     }
>
>     probably
>
>     with var src = someNamedInstance1,
>           let dst = someNamedInstance2 {
>         src.propA = dst.propB
>         dst.someMethod(src.propC)
>         src.someMehtod()
>     }
>
>     or
>     with someNamedInstance1, someNamedInstance2 {
>         $0.propA = $1.propB
>         $1.someMethod($0.propC)
>         $0.someMehtod()
>     }
>
>
>     2) Introduce .with method for each(?) class/struct, so we can use out-of-box:
>
>     let questionLabel = UILabel().with {
>        //set props of created instance here
>        $0.prop = value
>     }
>
>     var someStructInstance = SomeStruct().with {target in
>        target.prop = value
>     }
>
>     questionLabel.with {label in
>        label.prop = value
>     }
>
>     someNamedInstance1.with(someNamedInstance2) {src, dst in
>         src.propA = dst.propB
>         dst.someMethod(src.propC)
>         src.someMehtod()
>     }
>
>     Note that function like this :
>     func with(item:T, apply:(T)->Void) {  apply(item) }
>
>     Produces such kind of problems:
>     struct A {var x = 1}
>     let a1 = A() // constant
>     with (a1) { $0.x = 10 } // this will be compiled without errors/warnings
>
>
>     On 13.04.2016 17:17, Radosław Pietruszewski via swift-evolution wrote:
>     > It can be (more-or-less) solved in library code today:
>     >
>     >     extension NSObjectProtocol {
>     >         public func with(@noescape fn: Self -> Void) -> Self {
>     >             fn(self)
>     >             return self
>     >         }
>     >     }
>     >
>     >
>     > This way, you can do, on NSObjects:
>     >
>     >     textLabel.with {
>     >
>     >     $0.textAlignment = .Left
>     >
>     >     $0.textColor = .darkTextColor()
>     >
>     >     }
>     >
>     >
>     > I love this pattern.
>     >
>     > You can also make it a function to make it work with any value of any kind
>     > (it will then take form of `with(foo) { …}`).
>     >
>     > Ideally, if you could write a universal extension (something like
>     > `extension Any`), you could just add this behavior, with method syntax, to
>     > everything.
>     >
>     > — Radek
>     >
>     >> On 13 Apr 2016, at 15:15, 李海珍 via swift-evolution
>     >> > wrote:
>     >>
>     >> I recently learned some VBA and I found a very conveniently `with` statement.
>     >>
>     >> `with` statement can be helpful to set property for UIKit instance.
>     >>
>     >> for instance a UILabel instance `textLabel` ,with `with` statement we can
>     >> set UILabel property like this
>     >>
>     >>
>     >> ```swift
>     >>
>     >> with textLabel{
>     >>
>     >> .textAlignment= .Left
>     >>
>     >> .textColor= UIColor.darkTextColor()
>     >>
>     >> .font= UIFont.systemFontOfSize(15)
>     >>
>     >> }
>     >>
>     >> ```
>     >>
>     >> _______________________________________________
>     >> 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
>


More information about the swift-evolution mailing list