Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

If I understand you correctly Swift does that. Only objects (defined as classes) are mutable reference types as far as semantics go.

Declaring constants with let has the effect you are talking about for equality. If you want to you can stick to that.

Where you declare a variable to contain a struct, dictionary or array with var you can mutate it but it only affects your copy so it is equivalent to creating a new instance with the updated vale and assigning it back to the same variable.

With the copy on write behaviour if there are no other variables or constants pointing to the original instance it can skip the copy for efficiency without affecting the semantics.



Yeah that makes perfect sense. The notion I'm getting at is where you say "declare a variable to contain". If you have only immutable objects then you can dispense with the idea of containment and use only equivalence. As an equivalent semantics you can have containment and copy-on-write everywhere. Under immutability they are the same.

The trouble is that if you try to have both "name-equivalence" and "containment" and mutable things. At this point, copy-on-assign almost works uniformly. Except unless something like

    var a = x
    var b = a
does not refer to three separate containers, only at most two if x were immutable. At that point I feel like the explicit copy-on-assign might be better.


I'm not sure how the behaviour isn't uniform (unless you are getting on to classes).

Taking your example assuming x has been declared let x = [1,2,3] then the code you show will behave exactly as if the array had been copied but underneath it would actually be sharing a single bit of memory and have skipped/postponed the copies.

If the next line was b[0] = 5 then a copy would be made so x and a would still be [1,2,3] and b would be a separate array [5,2,3].

The behaviour will be exactly the same as copy on assign. You might be able to identify that it hasn't copied with the identity operator === but why would you need to know?


I'm assuming this is true

    var a = [1,2,3]
    var b = a
    b[0] = 10]

    > a
    [10,2,3]
and so copy-on-assign only applies when assigning an immutable reference to a mutable one.


No a has the value [1,2,3] still in that scenario. Copy on assign semantics is for constants and mutable variables.

Just tested in the playground:

  var a = [1,2,3]
  var b = a
  a == b        // true
  a === b       // true
  b[0] = 10
  a             // [1,2,3]
  b             // [10,2,3]
  b[0] = 1
  a == b        // true
  a === b       // false
  a             // [1,2,3]
  b             // [1,2,3]


Ah! Cool! My original point was always supposing that held. Being that it doesn't then I agree with Swift being consistent here.

Observing sharing using (===) is still dangerous, but presumably that can be saved by wrapping it in sufficient warning.


I wouldn't recommend using === in production (except for objects of classes) either but for this demonstration it let me show the copy on write without going to assembly.

Glad we've reached a common understanding, I wasn't quite sure that I hadn't missed something.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: