> On May 27, 2016, at 5:12 PM, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote: > >>> Just mentioning it as to end up... with the proper name for this new >>> function. >> >> Naming can always be bikeshedded. > > One possibility is to split `with` in two:
I much prefer this direction. > > - A plain `with` whose closure parameter is not mutable and which is marked > `@discardableResult`. I would like to see this version restricted to AnyObject. It has extremely limited utility with value types. It would usually be a mistake to call it with a value type. If we want a non-copying version that works with value types it should look like this: @discardableResult public func with<T>(_ item: inout T, use: @noescape (inout T) throws -> Void) rethrows { try use(&item) } That said, I am not convinced these non-copying functions would be worth having after method cascades are introduced. Are there any use cases left for them in that future? > > - A `withVar` whose parameter *is* mutable and which is *not* marked > `@discardableResult`. (This would help with the fact that our use of > `@discardableResult` is a little dangerous, in that people might expect > mutations to affect the original variable even if it's a value type.) > > `withVar` does, I think, make it pretty clear that you're working with a copy > of the variable. One thing to consider in choosing a name here is the cases where this function would still be useful in a future that includes method cascades. The one thing this function does that method cascades don’t is make a copy of the value before operating on it and returning it. With that in mind, I think it is worthwhile to consider the name `withCopy` and make the closure argument optional. public func withCopy<T>(_ item: T, update: (@noescape (inout T) throws -> Void)?) rethrows -> T { var this = item try update?(&this) return this } This function would be more clear and useful in conjunction with method cascades: let bar = withCopy(foo) ..cascaded = “value" ..operations() ..onFoo() > > /// Returns `item` after calling `use` to inspect it. > /// > /// If `T` is a value type, `use` is unable to mutate `item`. > /// If `T` is a reference type, `use` may use members which > /// change `item`, but cannot assign a different instance. > @discardableResult > public func with<T>(_ item: T, use: @noescape (T) throws -> Void) > rethrows -> T { > try use(item) > return item > } > > /// Returns `item` after calling `update` to inspect and possibly > /// modify it. > /// > /// If `T` is a value type, `update` uses an independent copy > /// of `item`. If `T` is a reference type, `update` uses the > /// same instance passed in, but it can substitute a different > /// instance by setting its parameter to a new value. > public func withVar<T>(_ item: T, update: @noescape (inout T) throws -> > Void) rethrows -> T { > var this = item > try update(&this) > return this > } > > -- > Brent Royal-Gordon > Architechies > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution