[Top][All Lists]

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

Re: Kickstarter for Emacs

From: Phil Hagelberg
Subject: Re: Kickstarter for Emacs
Date: Sun, 22 Apr 2012 22:17:22 -0700

On Fri, Apr 20, 2012 at 7:46 PM, Stefan Monnier
<address@hidden> wrote:
> My own local hacked version of Emacs has aset signal an error when
> called on a string (and subst-char-in-string also signals as error when
> called with `inplace').  I rarely bump into problems because of
> this change.
> But note that strings include text-properties, and I still allow those
> to be changed.  Making them immutable would break more code (since
> until `propertize' was added, all the text-properties were manipulated
> by side-effects).

Very interesting! Now that I think of it I haven't actually seen any
code that destructively updates strings other than text-properties as
you say. But given that equality already doesn't take these into
account, this is probably OK. In fact, Baker's paper addresses this
notion directly: "Obviously, material properties--being
contingent--cannot contribute to an object's identity, while formal
properties--being necessary--are an inherent part of an object's

I'd be interested in trying this patch if you could share it. Are you
fairly sure that those are the only existing functions which can
change the value of a string?

> For `cons' cells, side-effects are used much too often in Elisp,
> I wouldn't hold much hope for making them immutable.  So immutable cells
> would have to be a new type (and car/cdr could be made to work with
> them as well) with a new constructor (maybe named `icons' or `pair').

Indeed; this is a stickier issue. While I wouldn't expect it to be
feasible to change the default, the availability of a separate type of
cons cell upon which destructive operations could not act would be
wonderful provided the nondestructive list operations would still
work. I wonder if it wouldn't be possible to set a file-local variable
that could make the reader return immutable lists while loading that
file, much like the way lexical scoping was introduced in an opt-in
way to reduce breakage.

> The problem still remains: what would be the benefit?

I must confess this is difficult for me to express, simply because
it's something I've taken for granted for so long; it's like being
asked why I like garbage collection. Anyhow, the most obvious benefit
would be that you have a chance at writing code that you know will
function correctly while run concurrently. =)

But while the reduced complexity of referentially transparent
functions is subtler (and more difficult to explain without trying it
for yourself), I think it's no less compelling. The idea that you can
hand an argument to a function and not have to consider whether it's
going to change relieves you of a fair amount of needless mental
overhead while coding and makes certain classes of bugs impossible.
Essentially you can eliminate the difference between call-by-value and
call-by-reference. You can't write referentially transparent functions
that treat mutable objects as equivalent, because these functions will
not always return the same value when called with the same arguments
at different times.

The other benefit of immutable objects is that it allows you to do
away with the confusing eq/eql/equal distinction. This is the main
point of Baker's paper. He makes a compelling case that the usefulness
of hash tables in CL (and Elisp by extension) are severely limited by
having to pick a test function up-front. If you pick a test that is
too fine-grained (like eq or eql), then you are unable to use things
like strings as keys, but if you pick a test that is too coarse like
equal, then you will have false positives when you pass in a different
list that happens to have the same value at the time of the call. The
presence of immutable values allows you to define an equality
predicate that works in terms of operational equivalence, which is far
more useful.

Of course, in a way this amounts to turning Elisp into a functional
language, or possibly a language in which "mostly functional"
programming is encouraged. You could argue that it would be turning
Elisp into something that it isn't; perhaps this is fair. (I can just
go back to writing my Clojure code, but I really like Emacs as a
runtime.) Maybe I should just wait for Guile to gain the capability to
run Elisp, since that would be another way to achieve this goal. I'm
not sure it's the right thing for Emacs given the constraints of
legacy code and the limited time of its developers, but I am fairly
convinced it's a better design for languages in general.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]