
Impressions of Rust as a Swift Developer: Memory Management - skohan
https://blog.spencerkohan.com/impressions-of-rust-as-a-swift-developer-2/
======
twic
> In Swift, value types have what's called "copy-on-write" behavior, which
> means every time a value type is written to a new variable, or passed to a
> function, a copy is made.

That isn't copy-on-write, that's just copy.

Does "copy-on-write" mean that Swift behaves _as if_ it is doing this, but
actually defers copies where it can, passing references to the original until
a function needs to modify its 'copy'?

Rust lets you do this explicitly via the Cow smart pointer:

[https://doc.rust-lang.org/std/borrow/enum.Cow.html](https://doc.rust-
lang.org/std/borrow/enum.Cow.html)

But it's not transparent, and it's not used a lot in practice.

~~~
monocularvision
The author is wrong in their description. Some value types in Swift (like the
standard library collection types like Array<T>) are value types with copy-on-
write behavior. Until modified, copies of the Array are not made.

That copy-on-write functionality must be purposely implemented in the type and
is not something provided automatically in Swift.

~~~
skohan
Thanks for the feedback, I was conflating copying with copy-on-write. I have
made a correction in the article.

------
kd5bjo
> In Rust it's also possible to copy values as a way to silence borrow
> checking errors, but this does add visual noise as copies have to be
> explicitly specified.

This statement isn't quite accurate. Types that can be safely duplicated by
memcopy generally implement the Copy trait, which allows the compiler to do
the same kind of silent copying that the author describes for Swift.

Cloning, on the other hand, must be explicitly specified; the difference here
is that it may involve some amount of computation to make the logical copy in
addition to simply copying the bytes.

~~~
csomar
> Value types, by contrast, are stack-allocated in general, and their memory
> is managed statically. However, the behavior of value types in Swift is much
> different to how Rust handles memory.

Yep. The only difference in that article is that it says that they are stack-
allocated _in general_. I would be more interested to know the difference
between what can be _copy_ in Rust vs. the a _Value_ type is swift.

~~~
pornel
In Rust user-defined types are copyable only if they explicitly opt-in. Even
trivial tiny structs can't be copied unless they have `derive(Copy, Clone)` in
their declaration.

This is very helpful, because you know you can't copy something expensive by
accident.

It comes handy in libraries. Zero-sized non-copyable objects with destructors
can be used as lock guards/handles that control exclusive access to a shared
resource.

~~~
twic
> In Rust user-defined types are copyable only if they explicitly opt-in. Even
> trivial tiny structs can't be copied unless they have `derive(Copy, Clone)`
> in their declaration.

This is true, but it's only half the story, and i think it's the less
interesting half.

As you can say, you can make a type copy by asking the compiler to
derive(Copy). But the compiler will only do this if all the fields in the
struct are themselves Copy [1].

Primitives (integers, floats, booleans, chars) are Copy; shared (aka
immutable) references are copy; tuples and arrays containing only Copy types
are Copy. Structs and enums declared to be Copy are Copy (as long as they only
contain Copy fields).

But exclusive (aka mutable) references are _not_ copy: Rust's safety
guarantees depend on there only being one instance of an exclusive pointer to
something (hence the name). Unique, which wraps a raw pointer, is also not
Copy, because the whole point of it is to mark a pointer as unique. Unique
underlies Box, Vec, and String, so those are also not Copy.

So, user-defined types are copyable only if they explicitly opt-in _and it is
actually safe to copy them_.

As an aside, smart pointer types like Rc are also not Copy, but not for
structural reasons: the one field in a Rc is Copy. But Rc itself being Copy
would defeat the object of actually counting references, so it is not declared
Copy.

[1] [https://doc.rust-lang.org/std/marker/trait.Copy.html#when-
ca...](https://doc.rust-lang.org/std/marker/trait.Copy.html#when-can-my-type-
be-copy)

------
benmmurphy
A good example is a function like map() that applies a closure over the
elements of a collection. In rust the compiler will prevent you from modifying
the collection from the closure. In swift the collection author has to make
the implementation do something intelligent if the collection changes. This
'intelligent' thing usually means a slower implementation. For example in Rust
map() for Vector can load the address of the buffer into a register and length
into a register and assume they won't change. In the swift implementation it
would have to reload the pointer to the buffer and the length every time the
user code returned because the Array might have been modified.

~~~
ridiculous_fish
Swift arrays are value types, how would you modify the array from inside map?

~~~
benmmurphy

        var x = [1, 2, 3];
    
        let y = x.map( { v -> Int in
          print("got \(v)")
          x.removeAll()
          return 1
        })
    
        print("x: \(x)")
        print("y: \(y)")
    
    
        got 1
        got 2
        got 3
        x: []
        y: [1, 1, 1]
    

I don't know much about swift but this shows the closure is able to mutate the
Array. I guess value types are captured by reference by a closure.

------
mark_l_watson
I think the author has it right, Swift makes things easy, Rust is more
challenging but better for high efficiency, embedded, etc.

I spent many evenings playing with Rust early last year, and more or less
liked it, but I didn’t have a use case for really getting into it.

I have been switching prototyping between Swift and Common Lisp for a product
idea I am exploring. I am used to effortless development with Lisp languages,
and once I started hacking around with Swift, I found that it has few pain
points and is generally a nice language. Two big advantages of Swift are the
free Apple dev tools and TensorFlow for Swift keeps getting better.
Additionally, Apples newest CoreML is really good.

------
elo3210
blog is down, web archive link:
[http://web.archive.org/web/20200311092731/https://blog.spenc...](http://web.archive.org/web/20200311092731/https://blog.spencerkohan.com/impressions-
of-rust-as-a-swift-developer-2/)

------
dbetteridge
webserver seems to be down

Mirror:
[https://web.archive.org/web/20200311092731/https://blog.spen...](https://web.archive.org/web/20200311092731/https://blog.spencerkohan.com/impressions-
of-rust-as-a-swift-developer-2/)

~~~
dochtman
In addition to the OP being down, it seems the mirror is also unavailable for
me now.

~~~
nijaru
The mirror is currently working for me.

------
neonate
[https://archive.md/CsSE8](https://archive.md/CsSE8)

