Why Immutability and Pass-by-Value?

Immutability and pass-by-value are inherently useful, and inherently related (in fact an immutable pass-by-reference type is essentially indistinguishable from a pass-by-value type). I didn’t really get this at first, so let me paraphrase the best explanations I’ve gotten so far here.

For these reasons and more, the Swift standard library strongly prefers pass-by-value (structs and enums) rather than pass by reference (classes). String, Array, Set, Dictionary, etc... are all value types, and all support being declared immutable by using let.

Given the usefulness of these concepts, why aren’t we using them more already? My guess is that the answer lies in the fact that mutability is really convenient, and switching to immutability requires changing the way we think about programming. Let's walk through the conceptual leap from a simple mutable loop to the equivalent immutable code.

Thinking Immutably

Start by considering this code:
var randoms = [Int]()
for i in 1...1000 {
  randoms.append(Int.random(in: 1..<100))
}
Nothing after this code modifies randoms, so we’d like to make it immutable
let randoms = [Int]() //no error
for i in 1...1000 {
  randoms.append(Int.random(in: 1..<100)) //error
}
In both cases we’re assigning a value to randoms, but only one of them works. The key distinction here is that initialization is an expression, while mutation is a statement. So, we need a way to write a loop as an expression returning a value. Let’s imagine such a thing:
let randoms = for i in 1...1000 {
  /*
   well, this doesn’t make sense anymore, 
   since what we really want is for it to be appending to an array internal to the loop, 
   which we’ll initialize our array constant with
  */
  randoms.append(Int.random(in: 1..<100)) 
}
We’ll encapsulate the mutability of that loop-private array by making a function that runs the loop, and passing a closure as the loop body:
func for(range:Range<Int>, body:(Int)->Int) -> [Int] {
  var tempArray = [Int]()
  for i in range {
    tempArray.append(body(i))
  }
  return tempArray
}

...

let randoms = for(1...1000) { _ in 
  Int.random(in: 1..<100)
}
Now the mutability is encapsulated away in its own tiny function and it even still looks almost identical to a regular loop thanks to Swift’s syntax sugar, but at the cost of making a tiny function for each loop we have like this. Let’s generalize that function to be applicable to any loop that initializes an array by running the body of the loop once per element.
func for<S:Sequence, R>(sequence: S, body: (S.Element)->R) -> [R] {
  var tempArray = [R]()
  for i in sequence {
    tempArray.append(body(i))
  }
  return tempArray
}

...

let randoms = for(1...1000) { _ in 
  Int.random(in: 1..<100) 
}

let squares = for(1...1000) { x in 
  x * x 
}

let repeatedLetters = for(["a", "b", "c"]) { letter in 
  letter + letter 
}
Now we can use our new expression-form loop to initialize any array. One final simplification remains: delete the function! The standard library already contains it under a different name!
let randoms = (1...1000).map { _ in 
  Int.random(in: 1..<100) 
}

let squares = (1...1000).map { x in 
  x * x 
}

let repeatedLetters = ["a", "b", "c"].map { letter in 
  letter + letter 
}

We’ve now derived the existence of one of functional programming’s mainstays, the map operation, simply from the existence of immutability in the language.

Part 2
Other writing about programming