3 ms·
I don’t know how Swift and Koka handle things, but I’ve written a lot of Tcl that uses the same CoW reference-counting trick. (Tcl is an under-appreciated FP la
by nmadden 2y ago
I don’t know how Swift and Koka handle things, but I’ve written a lot of Tcl that uses the same CoW reference-counting trick. (Tcl is an under-appreciated FP language: everything is a string, and strings are immutable, so it has had efficient purely declarative data structures for decades).
The downside in Tcl is that if you refactor some code suddenly you can add a new reference and drop into accidentally quadratic territory because now everything is being copied. This leads to some cute/ugly hacks that are only explainable in terms of interpreter implementation details, purely to reduce a refcount in the right spot.
- plorkyeran 2y agoIn Swift you occasionally have to introduce a temporary local variable to avoid accidentally quadratic behavior, but I've never seen it require anything complicated or hard to explain.
- burntcaramel 2y agoCurious about an example of this in Swift? Is it a variable holding a collection like an Array?
- plorkyeran 2y agoA really simple example: class Foo { var foo = [Int]() var bar: [Int] { get { foo } set { foo = newValue } } } let obj = Foo() Calling `obj.foo.append(i)` in a loop takes linear time, while `obj.bar.append(1)` is quadratic time. `obj.foo.append()` does a borrow operation resulting in there never being more than one reference at a time, while `obj.bar.append()` does a get followed by a set, meaning that there's always two references to the array and every append does a copy on write. `let bar = obj.bar; for i = 0..<max { bar.append(i) }; obj.bar = bar` would do just a single CoW. Usually of course your computed properties actually do something so this difference feels less surprising. Swift does offer the undocumented `_modify` property accessor to let computed operations do borrows, but making it an official feature is waiting for noncopyable types to be finalized.
- nmadden 2y agoIn Tcl there is an idiom to do things like some_func $value[set value “”] where the [set value “”] bit reduces the refcount. There’s also a fairly widespread idiom of using the K combinator for this[1]: some_func [K $value [set value “”]] It’s one of those things that has become second-nature to people in-the-know, but is a total headscratcher otherwise. [1]: https://wiki.tcl-lang.org/page/K#c2a6014c2d129837889d8a8000d05e5c3b44e8f6b46cab777c04df8a927bfad2 https://wiki.tcl-lang.org/page/K#c2a6014c2d129837889d8a8000d...