Skip to content

Instantly share code, notes, and snippets.

@algal
Last active April 12, 2016 22:08
Show Gist options
  • Save algal/1ca25254e16504368c48 to your computer and use it in GitHub Desktop.
Save algal/1ca25254e16504368c48 to your computer and use it in GitHub Desktop.
Illustrates what is problematic about Swift's let-defined "constant" arrays actually being mutable
/*
This gist illustrates how Swift's "immutable" arrays are actually
mutable, and why that is sad. Load it into a playground to experiment.
"let"-defining an array should produce a truly immutable value. Instead, it
now produces a constant reference to a mutable, fixed-size array. This is like
C. So it is no better than C. And it's worse than Objective-C, where you
could produce a reliably constant array with code like:
NSArray * const ar = @[foo,bar,baz];
I reported this as a bug with <rdar://problem/17181951>.
Fuller discussion at <https://devforums.apple.com/message/976600#976600>.
*/
import Cocoa
//
// 1. non-constant arrays produce unnecessary aliasing problems:
//
// w is a constant array
let w:Int[] = [10,10]
// v is a constant array
let v = [w,w]
v // => [[10,10],[10,10]]
// but I am plainly allowed to mutate their contents!
v[0][0]=20
// and now I've mistakenly mutated two slots in my 2d array, because of
// the aliasing problems associated with mutability:
v // => [[20,10],[20,10]]
//
// 2. non-constant arrays undermine the purpose of the inout parameter
//
// this func takes a non-inout parameter, so I would think it cannot mutate its arguments
func mutateFirstParam(arr:Int[]) -> () {
arr[0] = 20
}
let Z:Int[] = [10,10]
Z
mutateFirstParam(Z)
Z // => surprise! Z has been changed. It was not a pure function.
//
// 3. non-constant arrays are inconsistent with Swift's constant dictionaries
//
// this dictionary is a variable, so I get to mutate it
var D = ["a":1]
D["a"]=2
D
// this dictionary is a constant, so I do not
let d = ["a":1, "b":2, "c":3]
d
d["a"] = 5 // this line produces an error, as it should
@algal
Copy link
Author

algal commented Jun 8, 2014

I'm surprised your code above works, where you call unshare() on s3, since the Swift Programming Language says:

“You ensure the uniqueness of an array reference by calling the unshare method on a variable of array type. (The unshare method cannot be called on a constant array.)”

Excerpt From: Inc, Apple. “The Swift Programming Language.” Apple Inc., 2014-05-27T07:00:00Z. iBooks.
This material may be protected by copyright.

Check out this book on the iBooks Store: https://itunes.apple.com/WebObjects/MZStore.woa/wa/viewBook?id=881256329

@dwarfland
Copy link

FWIW, i filed a radar at: radar://17229960 "Inconsistent immutability of arrays in Swift"
and also got this tweet stream going: https://twitter.com/dwarfland/status/476310789763395584

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment