[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: s-exprs + prototypes

Christopher Barber wrote:
> > At the moment, imperative programmers use mutation without
> > thinking about it, and they've mostly never learned any
> > other way to program.  Most use of mutation is gratuitous,
> > and simply arises from the design of imperative languages
> > which actively encourage & require it.  I don't think
> > eliminating these uses of mutation is in any way fundamentally
> > difficult for humans, as long as languages provide constructs
> > that support basic features like iteration and recursion in
> > ways that are comfortable to use.
> I disagree.  Not allowing objects to have mutable state would
> weaken the object metaphor to the point where the average
> programmer would find it hard to grasp.  The way humans
> perceive the real world, objects can and do have mutable state.

Philosophically, I don't know that I would concede anything about "the way
humans perceive the real world" - how much of that is training?  Humans used
to perceive all sorts of things very differently.  But, that's a side
argument and my ll1-discuss bandwidth usage is at dangerously high levels...

More to the point, I don't think that complete elimination of mutation is
necessarily desirable from the human perspective, although I admire
languages like Haskell for trying it.  I also think they're valuable for
exploring strategies for dealing with lack of mutation.

I think that it's possible for languages to support mutation in more
sophisticated ways than they currently do.  They should be able to
acknowledge and deal with the relationship of mutation to time, and take
into account and mitigate or encapsulate the costs of mutation.

For example, I don't see any reason why a language couldn't present mutable
objects as a view or interface to a series of immutable states, which are
managed automatically by the language.  In fact, you can view an ordinary OO
system as doing exactly this, except that the immutable states are currently
simply discarded and there's no support for dealing with them.

In the accounting transaction example I gave in an earlier message, if a
programmer wishes to treat an account as a series of immutable states (or
events), in most imperative languages, the programmer gets none of the
benefits - such as the ones John Clements has just described - from the fact
that this approach can easily avoid mutation.

A more trivial example of "mutation management" is the kind of thing done
with the static single assignment compiler optimization.  This:

  x = a;
  x = b;

...is of course transformable into:

  x1 = a;
  { x2 = b; ... }

...with appropriate substitutions of x1 and x2 for occurrences of x, in the
rest of the affected code.  Given this relatively trivial transform, in
suitably restricted situations there's no technical reason to impose on
users the need to avoid "mutating" the value of x, since these situations
don't have to incur the typical costs of mutation.  A language could be
designed to allow mutation in such situations where it has no appreciable
cost, but prevent it or manage it more carefully in other situations.  (I'm
assuming that for human-friendliness reasons, we want to avoid requiring
programmers to simply exercise more discipline in variable management.)

These kinds of strategies could result in languages that have the (alleged)
human-friendliness of imperative languages, combined with the useful
mathematical properties of functional languages, plus some additional
capabilities related to management of state over time which current
languages don't offer.  Done well, such languages might even qualify as
"lightweight" in the LL1 sense.