Just Another Victim of the Ambient Morality wrote: > Well, yeah, I got that. It's just that he spent this whole paragraph > on a rationale that wasn't true so I was wondering what he was really > trying to get at for his rationale... My rationale? Erm, the rationale stated by _others_ was that a matrix (as a value) is immutable, therefore the implementation of a matrix (as a data structure) should be immutable. But that makes no sense. r ---------- | n0 n1 n2 | n3 n4 n5 | n6 n7 n8 What makes n0-n... special and different from just plain old n = 1? Yes, r is a unit, but that just means that when n... is changed then r is now a new value unit; you don't need to do that by constructing a whole new matrix, you can do the same thing by changing members of r in place. The _value_ of r at any given time is immutable, the data structure that represents r need not be. Given r: r = [ [0, 1, 2], [3, 4, 5], [6, 7, 8] ] Which is better? def new_matrix(k, x, y, value) out = [] k.each_with_index { |m, row| out << [] m.each_with_index { |n, col| if row == x and col == y out[-1] << value else out[-1] << n end } } out end r = new_matrix(r, 2, 2, r[0][0]) r # => [[0, 1, 2], [3, 4, 5], [6, 7, 0]] Or: r[2][2] = r[0][0] r # => [[0, 1, 2], [3, 4, 5], [6, 7, 0]] Duh! The answer is obvious. I do like Dave's idea about having a named method to do the in place modification, though; that would make sure You Really Mean It and eliminate the typo where you meant == but actually wrote =. Ps. Paul gave another rationale: usefulness. That makes sense (though its truth was contested). Dave also gave another rationale: predictability. That makes sense too. But the immutability of the value of a matrix as a rationale for disallowing destructive assignment to members doesn't make sense.