Live data from Hacker News

Swift 5 Exclusivity Enforcement

swift.org

41–50 of 63 posts

Re: Swift 5 Exclusivity Enforcement

#41
post #24

Earlier quoted context omitted.

Swift is designed to support dynamically linked code. If Rust had the same design goal, it would need a lot more dynamic checks too.

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…

> Dynamic linking isn't a problem.

Rust does not have a stable ABI at present, so practical use of dynamic linking would require falling back to some baseline ABI/FFI for everything that crosses shared-object boundaries (such as the C FFI), or lead to a requirement that a shared object must be compiled with the same compiler version and compile options as all of its users. This seems like it would be a severe pitfall.

Re: Swift 5 Exclusivity Enforcement

#42

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?

What's not solved with manual memory management? The point is not that you can't solve it, the point is that reference counting isn't the whole solution for garbage collection unlike a tracing gc for instance.

Re: Swift 5 Exclusivity Enforcement

#43
post #2

I'm not totally versed in Swift. In the example provided is it ambiguous because the closure captures `count` and count itself is being modified by the method calling the block? I don't understand why this is an example of an unsafe operation. Wouldn't clearly defined behavior of closures clarify the "3 or 4" question?

> I don't understand why this is an example of an unsafe operation. Wouldn't clearly defined behavior of closures clarify the "3 or 4" question? I believe that it's possible to specify this, and that's basically the behavior we had before SE-0176 was implemented. The issue with this is that it was slower for a dubious benefit (the semantics are obscure and non-obvious), so it was decided that it's just better to disa…

> it was slower for a dubious benefit

Isn't this kind of arguable? The benefit is that it avoids the need to make unnecessary copies in some cases, as is basically acknowledged in the article:

> The exclusivity violation can be avoided by copying any values that need to be available within the closure

Right? And in addition to the local cost of the extra copy, there's also the more ubiquitous cost of these run-time checks. Yes, there's the potential benefit of better optimization due to the non-aliasing guarantee, but I think it's far from clear that it's an overall performance win.

While I think it's reasonable to adopt a universal "exclusivity of mutable references" policy in order to achieve memory safety and address a fear of a (vaguely-defined) notion of "mutable state and action at a distance" (referred to in the article), particularly for a language like Swift, I think it would be improper to dismiss the associated costs, or even to imply that the costs are well understood at this point. Or to imply that this policy is, at this point, known to be an optimal solution for achieving memory (or any other kind of code) safety.

Re: Swift 5 Exclusivity Enforcement

#44
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…

> Dynamic linking isn't a problem. Rust does not have a stable ABI at present, so practical use of dynamic linking would require falling back to some baseline ABI/FFI for everything that crosses shared-object boundaries (such as the C FFI), or lead to a requirement that a shared object must be compiled with the same compiler version and compile options as all of its users. This seems like it would be a severe pitfall…

I'm referring only to the thing being discussed in this post. To expand for precision: dynamic linking doesn't force the Swift compiler to insert more dynamic checks for exclusivity enforcement.

Re: Swift 5 Exclusivity Enforcement

#45
post #34
post #30

Earlier quoted context omitted.

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!

Many people in the Rust community use some sort of ECS in cases where something like a GC is needed. The whole point of ECS is that they work a lot like an ordinary GC runtime or an in-memory database, the underlying representation ensures that the system knows about all the "entities" that it needs to, and can reliably trace linkages between them. It might be easier to just use Go in cases where tracing GC is needed, though.

Re: Swift 5 Exclusivity Enforcement

#46
post #7

Earlier quoted context omitted.

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.

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

Alike a tracing GC..,.

Re: Swift 5 Exclusivity Enforcement

#47
post #30

Earlier quoted context omitted.

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?

In a language with tracing GC, you'd use a strong reference in both directions, so anybody who holds the child can always walk their way to the root (if you expose those references). Without such GC, you basically have to pass the root around, because it's what's holding all those children alive.

Re: Swift 5 Exclusivity Enforcement

#48
post #9

Earlier quoted context omitted.

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.

It would be interesting to compare the cognitive load of the Swift way and the Rust way. Rust gives you better guarantees, but you must annotate your code.

The cognitive load is higher on Rust, not only do we have to annotate the code, to have the same semantics as Swift we have to write Rc> everywhere, which isn't that ergonomic.

On other side, as discussed recently at CCC regarding writing drivers in safe languages, Swift's GC as reference counting generates even less performant code than Go or .NET tracing GC, so there is also room to improvement there.

Re: Swift 5 Exclusivity Enforcement

#49

Earlier quoted context omitted.

What’s not solved with weak refs?

What's not solved with manual memory management? The point is not that you can't solve it, the point is that reference counting isn't the whole solution for garbage collection unlike a tracing gc for instance.

Weak reference counting is still reference counting.

Re: Swift 5 Exclusivity Enforcement

#50

Earlier quoted context omitted.

> I don't understand why this is an example of an unsafe operation. Wouldn't clearly defined behavior of closures clarify the "3 or 4" question? I believe that it's possible to specify this, and that's basically the behavior we had before SE-0176 was implemented. The issue with this is that it was slower for a dubious benefit (the semantics are obscure and non-obvious), so it was decided that it's just better to disa…

> it was slower for a dubious benefit Isn't this kind of arguable? The benefit is that it avoids the need to make unnecessary copies in some cases, as is basically acknowledged in the article: > The exclusivity violation can be avoided by copying any values that need to be available within the closure Right? And in addition to the local cost of the extra copy, there's also the more ubiquitous cost of these run-time c…

I'm going to refer you to the proposal, which explains the rationale behind the change better than I possibly could: https://github.com/apple/swift-evolution/blob/master/proposa...
Post reply on HN