If you use language 'x', then using
mutation is wrong.
and recently, I've been thinking about the practically important but socially awkward question: What language is best for implementing
mutable state?
By which I don't mean: What language makes avoiding mutable
state impossible?
because given my skill set on some absolute scale that encompasses Knuth, I've got big fish to fry. Trying to maintain ideological purity is a distraction at best and an impediment at worst, if I am ever to see an [m42] and have a solid intuition about its solution.Even the most rousing chorus of 'Onward Christian Soldiers' isn't going to help me implement Hoare's Quicksort in Clojure. Consing and filtering are great, but they miss the idea of working in-place. Racket's built in O(log n)priority queue isn't a substitute for a traditional O(1) queue implementation:
+-------+
| | o-|------------------+
+-|-----+ |
| |
v v
+-------+ +-------+ +--------+
| | o-|--->| |o-|--->| | nil|
+-|-----+ +-|-----+ +-|------+
| | |
v v v
'a 'b 'c
The built in priority queue is mutable anyway.The illustration of queues in Racket isn't rendered from whole cloth. If one searches the Racket documentation (depth first is implied?) the only hit for 'queue is the priority queue which lives in the 'data library [and again, it's still mutable and not thread safe]. But the real problem is that providing Racket implementations on Rosetta code is one of those ways Racketeers are encouraged to give back, and the implementation of LIFO on Rosetta Code shows the priority queue, rather than an actual queue, in part because using 'mcons is considered taboo under functional programming mores. It's a socially acceptable answer, rather than a correct one.
Some things just have to be to be mutable in order to get built in a way that will be useful when dealing with large tables when the first test of usability is getting built in the first place. It's not that playing with dangerous objects ought to be encouraged, it's that it there's nothing wrong with a little dynamite now and then for removing stumps when the alternative is lifting the grinder to the top of the cliff with a crane. All that really matters is acting in accord with the fact that, yes, we're using dynamite.
There's a continuum between Coq and MMIX. A good functional programming language allows refactoring a solution from right to left. It doesn't pretend as if there isn't a right wing or that it doesn't matter politically.