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

Vladimir.S svabox at gmail.com
Fri Apr 22 02:18:41 CDT 2016


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<T>(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
>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> 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 <mailto: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