[Discussion] "with" statement/method


(Thorsten Seitz) #1

@Thorsten, thank you for providing these functions and sample code.
Unfortunately personally I can’t check them now to find out if there is
some problems with them. (But will check later)

That would be great, thanks!

In any case. Let’s assume these functions are 100% fine and can be used in
almost any situation with no drawbacks.

Do you(and all other) agree that such functions should be a part of
standard library, so we’ll have this “with” feature out-of-box with correct
implementation (and so there will be no need to re-invent them for many of
us and to re-copy into each project) ?

Yes, I totally agree that such functions should be part of the standard library. I just think that we don’t need a language feature for this (if there should still be a problem with these functions we should think about how to fix this in a general way).

-Thorsten

···

Am 25. April 2016 um 15:43 schrieb “Vladimir.S via swift-evolution” swift-evolution@swift.org:

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

This works as expected (giving a compile error for let constant):

// for value types
funcwith(inoutitem: T, apply: (inoutT) throws-> Void) rethrows-> Void{
tryapply(&item)
}

// for reference types (classes)
funcwith<T: AnyObject>(item: T, apply: (T) throws-> Void) rethrows-> T{
tryapply(item)
returnitem
}

// value types

structA { varx = 1}

vara1 = A()
with(&a1) {
$0.x= 10
}
print(a1) // A(x: 10)

/*
let a2 = A()
with (&a2) { // error: cannot pass immutable value as inout argument: 'a2’
is a ‘let’ constant
$0.x = 10
}
print(a2)
*/

// reference types (classes)

classB : CustomDebugStringConvertible{
vary = 1
vardebugDescription: String{ return"B(y: (y))"}
}

varb1 = B()
with(b1) {
$0.y= 11
}
print(b1) // B(y: 11)

// reference types allow this pattern (value types don’t)
letb2 = with(B()) {
$0.y= 12
}
print(b2) // B(y: 12)

-Thorsten

Am 22.04.2016 um 09:18 schrieb Vladimir.S via swift-evolution
<swift-evolution@swift.org mailto:swift-evolution@swift.org>:

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()
}

  1. 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 > > > > > <swift-evolution@swift.org mailto:swift-evolution@swift.org > > > > > mailto:swift-evolution@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


with textLabel{

.textAlignment= .Left

.textColor= UIColor.darkTextColor()

.font= UIFont.systemFontOfSize(15)

}


swift-evolution mailing list
swift-evolution@swift.org mailto:swift-evolution@swift.org
mailto:swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


swift-evolution mailing list
swift-evolution@swift.org mailto:swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


swift-evolution mailing list
swift-evolution@swift.org mailto:swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

This is the main first question regarding this proposal.

On 23.04.2016 14:28, Thorsten Seitz wrote:


swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution