There's a fascination in the Lisp world for cons cells. Specifically the cell aspect. If you represent lists as:
l = [x, [y, [z]]]
Then you can implement car as l[0] and cdr as l[1].If you require mutable cons cells, that's pretty much the only way to do it. Because if you want to set the car of cdr(l), how do you do it? You can just do
cdr(l)[0] = t
Because that's the same as l[1][0] = t
Which of course makes the list become l = [x, [t, [z]]]
But this sucks. It's always sucked, and Lispers go out of their way to ignore the fact that it sucks. I wince at having such a dismissive attitude here, but it's been the source of years of frustrations.It's a frustration because if Lisp had been implemented using vectors and hash tables instead, it'd be in a far stronger position today. Everyone uses vectors. Vectors are [1, 2, 3, 4] ... Plain old arrays! In fact, I used vectors in the above examples, and didn't even have to explain what they were. Everyone knows and understands arrays.
Lisp can work fine with vectors, if you drop the requirement of mutable cons cells. Because l becomes:
l = [x, y, z]
And cdr(l) becomes l[1:], so cdr(l) returns [y, z] -- an entirely new vector containing y and z.This might seem like nonsense, but in practice it's not. In practice, you're rarely building lists containing hundreds of thousands of elements. Usually it's much smaller lists contained in other structures, like hash tables.
And when the lists are small, you really don't care about creating new lists. The fact that cdr(l) returns a copy of l minus the first element is inconsequential. You'll ~never experience a slowdown.
And the gains are massive. You get to interface with all your native libraries using lisp algorithms. You don't have to convert from "lisp lists" to "python lists" or "javascript lists" or anything else. They're just arrays.