The Lisp and Scheme LANGUAGES don't limit mutability, though.  In Scheme you 
can literally mutate any cons cell, for instance.  It's the communities that 
have limited the mutation in their programs in part because the language makes 
it easy to do so.  In ML you can define any data structure to be based on 
mutable Refs, yet SMLers are especially keen on maintaining as much purity as 
they can, and OCamlers are mostly so (not entirely though, OCamlers frequently 
care more about efficiency than their SML brethren). 

The article you link only talks about LISP up to 1.5 or so.  It doesn't cover 
Common Lisp, which is the 800 pound gorilla of the Lisp family. I bring it up 
because a huge amount of Common Lisp code is deeply imperative: for some reason 
CLispers are less interested in the value of purity than Schemer's are, even 
thought their language is just about as suitable (ignoring the fact that the CL 
spec doesn't require tail call optmization since most CL implementations 
support it).  You may be right that it's concerns about efficiency, but I'm not 
entirely sure that's true since even at the small scale CLers tend to use loops 
where Schemers use (just as efficient) tail call recursion (yes, CL doesn't 
mandate TCO, but all the major implementations that I know of support it).

Look, I'm not arguing that uncontrolled side effects are "good."  What I am 
arguing is very simple: the definition of functional language, as applied to 
the vast majority of functional programming languages, does not imply any form 
of proof of purity.  Redefining it that way is just retronyming with no good 
purpose when there's already a perfectly useful phrase, "purely functional 
programming language," to cover the Mirandas, Haskells, Cleans, Agdas, and 
Epigrams of the world.

As for your comment about concurrency, it's a funny image, but it's false, or 
at least overstated. Erlang, for instance, does not put limits on effects 
except in the narrow sense that mutation is more awkward to express than in 
typical imperative languages.  Some people think that Erlang does not permit 
the sharing of mutable state, but that's not true at all. Erlang prevents the 
sharing of direct access to memory, but actors are (or at least can be) 
stateful and can be shared concurrently, and you can get exactly the same kinds 
of race conditions you get in more traditional "shared state" concurrency.  The 
difference in the Erlang model and locks/variables model is really more a 
matter of granularity and the programmers thought process.  I talk about the 
state model in Erlang here 
(http://james-iry.blogspot.com/2009/04/erlang-style-actors-are-all-about.html). 
 The article even ends with an implementation of sharable mutable "variables" 
with get and set operations, and I fol!
 low up in another article with an implementation of a mutex lock. 

If Erlang did not permit sharing of mutable entities then it would be too 
limited to be useful - concurrency (as opposed to simple parallelism) is a side 
effect.  There's a reason Haskell pushes all of its concurrency primitives 
(forkIO, MVars, STM commits) into the IO Monad while the less pernicious 
data-parallel extensions don't require effect tracking.

Now, again, limiting the scope of impurity and mutation in a concurrent setting 
is probably more win than not.  But that does not mean we need to change the 
definitions of "concurrent language" or "functional programming language" to 
preclude Erlang just because it has no such limitations.

Andrei Alexandrescu Wrote:

> On 03/10/2010 02:42 PM, James Iry wrote:
> > Andrei Alexandrescu Wrote:
> >
> > I don't disagree with you (except that you probably meant "first
> > class" rather than "first order").
> >
> > But that wasn't the question.   The question was "does a language
> > have to enforce purity in order to be a functional language" and the
> > answer is that historically that has not been the case.  The Lisp
> > family (especially Scheme) and the ML family both have a rich
> > tradition of purely functional programming without ever having the
> > purity enforced. They did not "adopt the functional window dressing";
> > they invented it.
> 
> Mutation has always been seen as an awkward concession to efficiency by 
> functional languages, and limited to the maximum extent possible. LISP 
> has commonly used a pure subset (see e.g. 
> http://www-formal.stanford.edu/jmc/history/lisp/node3.html) for proving 
> essentially everything there is to be proven regarding functional 
> programming.
> 
> There's one final nail in the coffin. In wake of concurrency, de jure 
> immutability becomes a necessity, not a useful and desirable de facto 
> convention. Adopting the window dressing but not the essence of FP by a 
> concurrent language evokes to me a scene in the Marx Brothers: an 
> otherwise impeccably-dressed gentleman who forgot to put his pants on.
> 
> 
> Andrei

Reply via email to