<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Since your backing buffer is copy-on-write, you can do the in-place mutation optimization in your immutable implementations, something like this:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">class C {</div><div class=""> var value: Int</div><div class=""> init(value: Int) { self.value = value }</div><div class="">}</div><div class=""><br class=""></div><div class="">struct S { var c: C }</div><div class=""><br class=""></div><div class="">func addInts(x: S, y: S) -> S {</div><div class=""> var tmp = x</div><div class=""> // Don't use x after this point so that it gets forwarded into tmp</div><div class=""> if isKnownUniquelyReferenced(&tmp.c) {</div><div class=""> tmp.c.value += y.c.value</div><div class=""> return tmp</div><div class=""> } else {</div><div class=""> return S(c: C(value: tmp.c.value + y.c.value))</div><div class=""> }</div><div class="">}</div></blockquote><div class=""><br class=""></div><div class="">which should let you get similar efficiency to the mutating formulation while using semantically immutable values.</div><div class=""><br class=""></div><div class="">-Joe</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class="">On Aug 5, 2016, at 2:35 PM, Fritz Anderson via swift-users <<a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a>> wrote:<br class=""><br class="">Swift 3 as of Xcode 8.0b4<br class=""><br class="">TL;DR: I have a struct value type backed by a copy-on-write mutable buffer. You use it to perform arithmetic on the buffers. The most expressive way to do this efficiently is to chain the arithmetic operators so each mutates the same buffer. Swift does not like to chain mutating operators — it treats the result of each step as immutable, so you can’t continue the chain. I can’t argue; the syntax apparently can't express anything else.<br class=""><br class="">All the alternatives I see are ugly-to-dangerous.<br class=""><br class="">Have I missed something, I hope? Please make a fool of me.<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>— F<br class=""><br class="">The details of my use case or implementation are off-topic; even if mine are ill-considered, surely apt ones exist. Unless you can demonstrate there are none.<br class=""><br class="">The vDSP_* functions in Apple’s Accelerate framework are declared in C to operate on naked float or double pointers. I decided to represent such Float buffers in Swift by a struct (call it ManagedFloatBuffer) containing a reference to a FloatBuffer, which is a final specialization of class ManagedBuffer<Int, Float>.<br class=""><br class="">(The names are a work-in-progress. Just remember: ManagedFloatBuffer is a value type that can copy-on-write to a reference to FloatBuffer, a backing store for a bunch of Floats.)<br class=""><br class="">The nonmutating funcs:<br class=""><br class=""> func subtract(_ other: ManagedFloatBuffer) -> ManagedFloatBuffer<br class=""> func subtract(_ scalar: Float) -> ManagedFloatBuffer<br class=""><br class="">are straightforward. They return new ManagedFloatBuffer values. You can chain further calls to simplify a complex calculation that is neither intricate nor tied up in temporaries:<br class=""><br class=""> let sum²OfResiduals = speeds<br class=""> .subtract(cameraSpeed.mean)<br class=""> .multiply(feetToMeters)<br class=""> .sumOfSquares<br class=""><br class="">Great. And vDSP gets you about a 40% boost. (The compiler itself seems to do a pretty good job of auto-vectorizing; the unoptimized code is a couple of orders of magnitude slower.) But as you chain the immutables, you generate new FloatBuffers to hold the intermediate results. For long chains, you end up allocating new buffers (which turns out to be expensive on the time scale of vectorized math) and copying large buffers into them that you are about to discard. I want my Swift code to be as performant as C, but safer and more expressive.<br class=""><br class="">So how about some mutating functions to change a ManagedFloatBuffer’s bytes in-place (copying-on-write as needed so you can preserve intermediate values)?<br class=""><br class=""> mutating func reduce(by other: ManagedFloatBuffer) -> ManagedFloatBuffer<br class=""> mutating func reduce(by scalar: Float) -> ManagedFloatBuffer<br class=""><br class="">These return self, because I’d hoped I could chain operators as I did with the non-mutating versions.<br class=""><br class="">The compiler doesn’t like this. It says reduce(by:) returns an immutable value, so you can’t chain mutating functions.<br class=""><br class="">(I can see an issue in that when the first func's self is copied as the return value that is used as the second func’s self, that could make two surviving references to the same buffer, so a buffer copy would happen when you mutate the second func’s self anyway. I’m not sure the compiler has to do that, but I can see how it might be hard to account for otherwise. Hey, it’s a tail call, right? SMOP, not source-breaking at all.)<br class=""><br class="">StackOverflow invites me to eat cake: Make the mutable operand inout to funcs I call one by one. Something like:<br class=""><br class=""> multiply(perspectiveCorrections, into: &pixelXes)<br class=""> sin(of: &pixelXes)<br class=""> multiply(pixelXes, into: &speeds)<br class=""> multiply(feetToMeters, into: &speeds)<br class=""> subtract(cameraSpeed.mean, from: &speeds)<br class=""> let sumSquaredOfResiduals = speeds.sumOfSquares<br class=""><br class=""> // grodiness deliberately enhanced for illustration<br class=""><br class="">I’d rather not. The thing to be calculated is named at the bottom of the paragraph. The intermediate steps must preserve names that change meaning line-by-line. You have to study the code to recognize it as a single arithmetic expression.<br class=""><br class="">And by the by, if a vector operand is itself the result of a mutating operation, the dependency graph becomes a nightmare to read — I can’t be sure the illustration even expresses a plausible calculation.<br class=""><br class="">Thinking up more reasons to hate this solution is a fun parlor game you and your family can play at home.<br class=""><br class="">Strictly speaking, the compiler is right: I don’t see any language construct that expresses that a returned value type that may be mutated by a chained func. Am I correct?<br class=""><br class="">I’m not at all happy with turning ManagedFloatBuffer into a class. Intuitively, this is a value type. Passing a packet of Floats into a func (or into another thread, as one does with math) and finding your Floats had changed in the mean time is… surprising.<br class=""><br class="">I’m not optimistic, but I have to ask: Is there a way to do this — to take mutability down an operator chain?<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>— F<br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class=""><br class="">_______________________________________________<br class="">swift-users mailing list<br class=""><a href="mailto:swift-users@swift.org" class="">swift-users@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-users<br class=""></blockquote><br class=""></div></body></html>