> On May 27, 2016, at 5:12 PM, Brent Royal-Gordon via swift-evolution
> <[email protected]> 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
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution