[swift-evolution] Proposal: Add replace(_:with:) function to the stdlib

Kevin Ballard kevin at sb.org
Mon Dec 14 02:30:59 CST 2015


Your versions throw away the whole point of the function, which is to make common patterns easier, not more awkward. Adding an unnecessary scope there just makes it impossible to use the function in otherwise-valid circumstances. You're also focusing on the one example I gave, which is tearing down an old value (which cannot be done in property observers if it should only happen sometimes).

I'll grant you that it's uncommon to have functions with both side-effects and return values, but it's certainly not unheard-of. Heck, that's how Generators work!

-Kevin Ballard

On Dec 13, 2015, 11:36 PM -0800, ilya<ilya.nikokoshev at gmail.com>, wrote:
> That's a useful pattern, but the implementation above creates a function that has both a return value and a side effect, which is likely to be unexpected for many readers.
> 
> public func replace<T>(inout a: T?, with b: T?, andCleanOldValue clean:T->()) { ... }
> 
> replace(&prop, with: newValue) { oldValue in
> oldValue.clean()
> }
> 
> As a bonus one can automatically unwrap nil.
> 
> Although in real life I tend to move this logic to property accessors, e.g.
> 
> // Currently executing task. This property manages task state.
> 
> var task: NSURLSessionTask? {
> willSet { task?.cancel() }
> didSet { task?.resume() }
> }
> 
> 
> On Mon, Dec 14, 2015 at 7:59 AM, Dave Abrahams via swift-evolution<swift-evolution at swift.org(mailto:swift-evolution at swift.org)>wrote:
> > 
> > > On Dec 13, 2015, at 2:21 PM, Kevin Ballard via swift-evolution<swift-evolution at swift.org(mailto:swift-evolution at swift.org)>wrote:
> > > A function I find myself defining in a lot of my projects looks like the following:
> > > /// Replace the value of `a` with `b` and return the old value.
> > > public func replace<T>(inout a: T, with b: T) ->T {
> > > var value = b
> > > swap(&a,&value)
> > > return value
> > > }
> > > This is a pretty simple function, and useful in a wide variety of circumstances, so I'd love to get it into the standard library. It doesn't actually enable any behavior that wasn't previously possible, but it does shrink some common code patterns, and I find the shorter code easier to read.
> > > An example of a place where I use it often is in replacing an optional property with a new value (or with nil) and cleaning up the previous value. Assuming a property like
> > > var task: NSURLSessionTask?
> > > This replaces
> > > if let task = self.task {
> > > task.cancel()
> > > }
> > > task = nil
> > > with
> > > replace(&task, with: nil)?.cancel()
> > > Or sometimes I use it like
> > > if let value = replace(&prop, with: newValue) {
> > > // multi-line cleanup
> > > }
> > > This is particularly nice if it's a COW value that I want to mutate, as it means I don't have to worry about getting unwanted copies due to the property still holding the old value while I muck with it.
> > 
> > This is a generalization of the postincrement pattern (mutate a value and return the original) and given that we're moving away from that I'm not sure it's something we want to enshrine in the standard library. That said, here's a question: looking at your use cases, how many of them are using something other than nil (or some moral equivalent) as the second argument?If this is effectively a non-destructive move in nearly all cases, I'd rather support that more directly.
> > 
> > If cases other than "nondestructive move" are commonenough, I'd consider something like this syntax instead:
> > 
> > (task<- nil).cancel()
> > 
> > But I strongly suspect this isn't a common enough pattern to warrant introducing an operator.
> > 
> > > Question: For trivial backwards-compatible API changes like this, does a proposal PR need to be submitted to the swift-evolution repo, or is discussion on this ML sufficient before submitting a patch?
> > A proposal is needed for all new/changed API.
> > 
> > -Dave
> > _______________________________________________
> > swift-evolution mailing list
> > swift-evolution at swift.org(mailto:swift-evolution at swift.org)
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> > 
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151214/1959aef5/attachment.html>


More information about the swift-evolution mailing list