Live data from Hacker News

Swift 5 Exclusivity Enforcement

swift.org

31–40 of 63 posts

Re: Swift 5 Exclusivity Enforcement

#31

Earlier quoted context omitted.

Rust can use its own bovine superpowers here https://doc.rust-lang.org/std/borrow/enum.Cow.html to enable developers to write code that's invariant over whether it's dealing with a fresh copy of something, or just a borrowed reference. So, it's not quite correct to say that Swift's use of copy-on-write gives it better performance. Rust can express the exact same pattern quite easily, and do it with far more generalit…

Are you sure that code expresses the same pattern? It looks like Rust's COW can only transition from Borrowed to Owned by making a copy. Swift's COW works by dynamically inspecting the reference count.

Right, unless I'm mistaken, what you want is `Rc` with `Rc::make_mut`[0], not `Cow`.

[0]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#metho...

Re: Swift 5 Exclusivity Enforcement

#32
post #24

Earlier quoted context omitted.

Dynamic linking isn't a problem. Rust's checking is local, and doesn't require checking things in other functions, just their signatures. Swift is the same. There are some cases were dynamic checks are required (e.g. with reference counting/shared ownership: class in Swift, Rc/Arc in Rust). Swift will automatically insert checks in these cases, whereas they have to be manually written into Rust code (via tools like R…

That's the point: with dynamic linking the static signature encodes too much. In Rust sometimes you need to switch from FnOnce to Fn, or from Rc to Arc. These changes are binary incompatible. You have to recompile every client. Swift can't tolerate that restriction. UIKit doesn't want to have to pick from among Fn/FnOnce/etc for every function parameter, and commit to it forever. Swift types and functions need to evo…

This doesn't sound like a very good example. Fn inherits FnMut inherits FnOnce, so a library should just ask for the freest one it can support. Usually that just falls out of the meaning of the function. For example, a callback should only be called once, so you ask for an FnOnce, or maybe some function will be called in parallel, so you ask for an Fn. And with Rc, RefCell, Arc, etc. a dynamic approach is also pretty well-supported.

Re: Swift 5 Exclusivity Enforcement

#34
post #30
post #7

Earlier quoted context omitted.

But how many times the problem truly happened? Is in my experience so rare that the experience is alike with a GC.

It depends on your domain. Any data structure that has links in both directions becomes a pain, and it's pretty common to have trees like that. It's usually solved by having parents own the children but not vice versa, but then you run into cases where you want the whole thing to live so long as someone holds an owning reference to a child.

Agree. Is similar on rust, where circular links are also hard to do. Easy graphs is a killer feature of a GC.

But also, is a localized problem. I have more issues with obj-c in the past, some ergonomic of swift make it even rarer.

However, certainly suck for the ones that hit this!. I'm building a relational lang in rust and damm, I miss a GC!

Re: Swift 5 Exclusivity Enforcement

#35
post #4

I put Swift into the category of "almost memory managed" languages and it's never fully clicked in my brain. Thinking about strong/weak/unowned references is more difficult in my opinion than when to malloc/free something. Following the examples in the article just reinforced that maybe Swift's approach is a little too complex.

Right. This is one of the things I don't like about automatic reference counting, that it's almost a complete solution, but cycles require more thought (but less cases) to deal with than manual memory management itself.

You can add a cycle collector on top of a reference-counted language. It's been discussed for Swift, but there are downsides which might make it not worth adding.

Re: Swift 5 Exclusivity Enforcement

#36
post #24

Earlier quoted context omitted.

Dynamic linking isn't a problem. Rust's checking is local, and doesn't require checking things in other functions, just their signatures. Swift is the same. There are some cases were dynamic checks are required (e.g. with reference counting/shared ownership: class in Swift, Rc/Arc in Rust). Swift will automatically insert checks in these cases, whereas they have to be manually written into Rust code (via tools like R…

That's the point: with dynamic linking the static signature encodes too much. In Rust sometimes you need to switch from FnOnce to Fn, or from Rc to Arc. These changes are binary incompatible. You have to recompile every client. Swift can't tolerate that restriction. UIKit doesn't want to have to pick from among Fn/FnOnce/etc for every function parameter, and commit to it forever. Swift types and functions need to evo…

No, Swift needs the static signature of the library for dynamic linking too, by default.

You are correct that Swift wants to be able to change signatures without recompiling clients ("resilience"), but this is very limited, especially for changes that would affect the `inout` checking (e.g. one cannot change an argument to be inout): https://github.com/apple/swift/blob/master/docs/LibraryEvolu... (note the list of non-permitted changes includes changing types).

Re: Swift 5 Exclusivity Enforcement

#37

Earlier quoted context omitted.

That's the point: with dynamic linking the static signature encodes too much. In Rust sometimes you need to switch from FnOnce to Fn, or from Rc to Arc. These changes are binary incompatible. You have to recompile every client. Swift can't tolerate that restriction. UIKit doesn't want to have to pick from among Fn/FnOnce/etc for every function parameter, and commit to it forever. Swift types and functions need to evo…

This doesn't sound like a very good example. Fn inherits FnMut inherits FnOnce, so a library should just ask for the freest one it can support. Usually that just falls out of the meaning of the function. For example, a callback should only be called once, so you ask for an FnOnce, or maybe some function will be called in parallel, so you ask for an Fn. And with Rc, RefCell, Arc, etc. a dynamic approach is also pretty…

Apple's APIs last for years, in some cases decades. In this world, properties like "this object can only have one reference" and "this function can only be called once" become arbitrary constraints on the future.

Think about instances where you've refactored a RefCell to an Rc or a FnOnce to a FnMut, and consider what it would be like if you were unable to make that change because it would break the interface. It would be profoundly limiting.

Re: Swift 5 Exclusivity Enforcement

#38
post #30
post #7

Earlier quoted context omitted.

But how many times the problem truly happened? Is in my experience so rare that the experience is alike with a GC.

It depends on your domain. Any data structure that has links in both directions becomes a pain, and it's pretty common to have trees like that. It's usually solved by having parents own the children but not vice versa, but then you run into cases where you want the whole thing to live so long as someone holds an owning reference to a child.

When would you want the graph to exist due to some leaf more being retained but you wouldn’t know about it enough to maintain a ref to the root mode?

Re: Swift 5 Exclusivity Enforcement

#39
post #7

Earlier quoted context omitted.

But how many times the problem truly happened? Is in my experience so rare that the experience is alike with a GC.

- Doubly linked lists. - Cocoa delegates that keep references to some parent of the objects that they're delegates of. - Some event listeners (in the same way as delegates). I wouldn't say it's "rare". It popped up pretty often for me when I was writing Objective C.

What’s not solved with weak refs?

Re: Swift 5 Exclusivity Enforcement

#40

Earlier quoted context omitted.

- Doubly linked lists. - Cocoa delegates that keep references to some parent of the objects that they're delegates of. - Some event listeners (in the same way as delegates). I wouldn't say it's "rare". It popped up pretty often for me when I was writing Objective C.

What’s not solved with weak refs?

It can always be solved with weak references.
Post reply on HN