
Swift 5 Exclusivity Enforcement - return_0e
https://swift.org/blog/swift-5-exclusivity/
======
kris-s
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.

~~~
giornogiovanna
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.

~~~
dfgdghdf
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.

~~~
giornogiovanna
Rust doesn't just give you better guarantees. It gives you no runtime
checking, and potentially even better performance than naive C, because it can
automatically tell LLVM when there is no memory aliasing going on.[0] Also, it
gives you more confidence, because you can, for example, give out an array to
someone and be sure that it won't be modified. And usually that kind of
confidence is enough to write safe, race-free parallel code.

I don't think Swift's runtime exclusivity checks give you any of that.

[0]: [https://github.com/rust-lang/rust/pull/50744](https://github.com/rust-
lang/rust/pull/50744)

~~~
glhaynes
Swift arrays have pass-by-value semantics (under the cover, they use copy-on-
write to keep performance good) and are thus safe to pass to functions without
concern that they'll be modified. (Unless it's passed as an `inout` parameter,
which requires a prepended "&" at the call site.)

~~~
zozbot123
Rust can use its own bovine superpowers here [https://doc.rust-
lang.org/std/borrow/enum.Cow.html](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 generality.

~~~
millstone
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.

~~~
giornogiovanna
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...](https://doc.rust-
lang.org/stable/std/rc/struct.Rc.html#method.make_mut)

------
Teknoman117
And here I thought this was going to be something about enforcing some
exclusivity of swift to apple devices...

~~~
jake_the_third
With their recent attempt at patenting programming-language concepts, you'd be
excused to think so. I thought the same.

------
zaksoup
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?

~~~
saagarjha
> 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 disallow this and get the benefit
of clear behavior and better optimization opportunities, at the cost of
removing this somewhat uncommon and not-all-that-hard to-rewrite-for-clarity
pattern.

~~~
duneroadrunner
> 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.

~~~
saagarjha
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...](https://github.com/apple/swift-
evolution/blob/master/proposals/0176-enforce-exclusive-access-to-memory.md)

------
saagarjha
I'm assuming that -Ounchecked also removes the runtime diagnostic?

~~~
atrick6
Yes, it removes exclusivity checks and bounds checks.

------
hnbroseph
neat. maybe by swift 10 they will have windows builds and i can check it out.

------
Temasik
How do you use swift on ubuntu

~~~
saagarjha
You should be able to download a toolchain from here for your version of
Ubuntu and have it work:
[https://swift.org/download/](https://swift.org/download/)

