FSF emacs - lemacs merge?

3 views
Skip to first unread message

Dave Gillespie

unread,
May 24, 1993, 9:23:07 PM5/24/93
to
[Various people listing reasons for not switching to lemacs...]

You might add horizontal scrolling and splitting to the list.

Several people have bashed GNU and RMS lately about their alleged
disregard for established precedent. Just to set the record straight,
the Lucid folks are no less guilty of this particular sin. Lucid
threw out RMS's event and keymap model, for example. Maybe Lucid's
approach was better (not entirely clear; each system has plusses and
minusses). But RMS was there first, and just because Lucid Emacs was
released earlier is no reason to fault RMS for sticking to his original
scheme.

GNU Emacs 19 makes a much greater attempt at backward compatibility.
One little thing I noticed recently is that the unread-command-char
variable is still supported, *as well as* an alternative that holds
events instead of chars. Lucid simply deleted the old variable,
and it was a giant pain for me to fix all the references to it in
Calc. I sure wish Lucid had put compatibility at a higher priority.

-- Dave

Jamie Zawinski

unread,
May 25, 1993, 8:43:30 PM5/25/93
to
Dave Gillespie wrote:
>
> Lucid threw out RMS's event and keymap model, for example. Maybe Lucid's
> approach was better (not entirely clear; each system has plusses and
> minusses).

What do you think is better about RMS's event and keymap model, beyond
the fact that it was there first (i.e., compatibility)?

> One little thing I noticed recently is that the unread-command-char
> variable is still supported, *as well as* an alternative that holds
> events instead of chars. Lucid simply deleted the old variable,
> and it was a giant pain for me to fix all the references to it in
> Calc. I sure wish Lucid had put compatibility at a higher priority.

The new event model in Lucid Emacs is a portability problem, to be sure.
I did what I could to remain compatible with the old model (keeping
last-command-char as the ASCII equivalent of last-command-event, for
example.) But I could not think of a way to keep unread-command-char
and still *make progress*.

My goal was to make emacs a better editor than it was before. Perhaps you
don't think that removing the restriction to the ASCII character set was
worth the pain; I think it was.

If you don't like the design decisions I made, please suggest better
ones. Converting to ASCII and back loses information. If a package were
to read and unread a character as ASCII, it could easily cause the wrong
command to be executed. I could put this hack in, and it would mostly
work most of the time, but it's the wrong thing. There are arguments in
favor of improving software by adding kludge on top of kludge instead of
stepping back and reevaluating the original decisions. I chose not to
take that approach. Maybe you disagree. But I gave you an editor more
than a year ago that I think was a vast improvement over what I started
with.

-- Jamie

Dave Gillespie

unread,
May 25, 1993, 10:24:04 PM5/25/93
to
Jamie Zawinski writes:
> What do you think is better about RMS's event and keymap model, beyond
> the fact that it was there first (i.e., compatibility)?

One: Simple keystroke events are represented the same as they were
before, which goes a long way toward compatibility with Emacs 18.
The mapping between strings and event vectors is much more natural,
leading GNU Emacs 19 to provide still more compatibility in that area.
Keymaps, while not backward-compatible, are fairly close.

Two: The most common events are atomic objects, which means he doesn't
need to resort to explicit memory management of event objects to keep
from garbage collecting all day long. The bulk of events don't need
to be collected because they're just symbols or integers.

Three: Events and keymaps are built from plain Lisp objects, which
makes them easier to examine during debugging, and easier to construct
and modify if necessary.

Four: Events are more usage-oriented, less X-oriented. This will
probably make for an easier transition to other window systems in
the future.

Those are the things inherent to the representation that I like. He
also has some features that you don't have, but that you could add
without losing your event model. The handling of down, up, and drag
events is nice. The Lucid model acts on the click, whereas RMS's
model usually acts on the release. This seems to work fine in
practice and allows him to generate drag events for the user.
(Although he doesn't yet, he could also generate double-click events
on the second of two consecutive clicks---hint hint, nudge nudge.)
It also fixes the stupid problem where mouse commands leave a
message behind only to have it erased when the release-event is
processed.

On the other hand, your method has its own advantages:

A: Keystroke events carry position and timestamp information, which
allows keys to emulate extra mouse buttons in a pinch.

B: All events have the same representation, which has a certain
elegance to it. (This elegance is muffled by the need to keep the
garbage collector away from event management, though.)

C: There was something else I liked, but I can't think of it offhand.
It will come back to me eventually.

Overall though, I seem to have found more items in RMS' favor.
Before I made the list, I was thinking of the two systems as about
equal in merits.

> But I could not think of a way to keep unread-command-char
> and still *make progress*.

GNU Emacs simply has both. If there is a character in unread-command-char,
it stuffs it into the input stream, and if there are events in
unread-command-events, it stuffs those, too. There is some order
of priority, but it doesn't really matter.

You could still have retained compatibility by using the name
"unread-command-char" instead of "unread-command-event" for your
current variable, and allowing it to contain integers as well as
event objects.

> My goal was to make emacs a better editor than it was before. Perhaps you
> don't think that removing the restriction to the ASCII character set was
> worth the pain; I think it was.

Maybe RMS' system has evolved since you first saw it. He represents
function keys as symbols, and he can also represent a full set of
modifier bits on printable keys. In terms of keys themselves, both
systems are equally expressive as far as I can see. Yours does
include time stamps, though, which could conceivably be handy. (Not
enough to choose them over the simplicity of RMS' model, though, in
my opinion.)

> If a package were
> to read and unread a character as ASCII, it could easily cause the wrong
> command to be executed.

Yes, but there are about a zillion places in Calc where I stuff an
event that I *know* is a printable character, and I had to change
every single one of these.

Your model does not detect incompatible code, either, because older
programs can simply go ahead and store something in "unread-command-char"
and then silently fail.

> But I gave you an editor more
> than a year ago that I think was a vast improvement over what I started
> with.

No question about it.

-- Dave

Jamie Zawinski

unread,
May 26, 1993, 1:23:02 AM5/26/93
to
Dave Gillespie wrote:
>
> Jamie Zawinski writes:
>> What do you think is better about RMS's event and keymap model, beyond
>> the fact that it was there first (i.e., compatibility)?
>
> One: Simple keystroke events are represented the same as they were
> before, which goes a long way toward compatibility with Emacs 18.

Yes, I realize this; that's why I said "beyond compatibility." I wanted
to know what you meant besides this.

> The mapping between strings and event vectors is much more natural,
> leading GNU Emacs 19 to provide still more compatibility in that area.

Keys and buffer-characters are not the same thing. Strings are made
of the stuff that buffers are made of. Keys are not. Show me how to
represent Control-Shift-A or Control-Backspace in a string.

> Two: The most common events are atomic objects, which means he doesn't
> need to resort to explicit memory management of event objects to keep
> from garbage collecting all day long.

You don't need to resort to explicit memory management. You can drop the
events on the floor and they will be garbage collected like any other lisp
object. It's simply more efficient to reuse them (this probably only
matters in one place in all of emacs: the single event that is reused by
the main command loop; and even there it hardly matters at all.)

It such a common misconception that you *need* to explicitly manage events
that I'm starting to regret that I made it possible at all...

> Three: Events and keymaps are built from plain Lisp objects, which
> makes them easier to examine during debugging, and easier to construct
> and modify if necessary.

And harder to programmatically tell apart from other things ("eventp" is
unpleasantly heuristic.) But perhaps they should be less opaque; give me
examples where you've wanted this.

> Four: Events are more usage-oriented, less X-oriented. This will
> probably make for an easier transition to other window systems in
> the future.

I very carefully designed the event structures to expose only those
components that emacs would need when running under *any* window system.
They are not X specific at all; why do you say they are?

> The Lucid model acts on the click, whereas RMS's model usually acts on
> the release.

Lucid delivers both up and down events, and you can bind commands to either.

> This seems to work fine in practice and allows him to generate drag events
> for the user. (Although he doesn't yet, he could also generate double-click
> events on the second of two consecutive clicks---hint hint, nudge nudge.)

Handling of double click and drag events is controverial and varies from
window system to window system. That's why I didn't build them into the
C substrate, but instead made them be processed up in lisp. (But this is
a tangential point; if you want to talk more about it, send me mail.)

> It also fixes the stupid problem where mouse commands leave a message
> behind only to have it erased when the release-event is processed.

Hey, this is just a *bug*, it has nothing to do with the event model per se...

> B: All events have the same representation, which has a certain
> elegance to it. (This elegance is muffled by the need to keep the
> garbage collector away from event management, though.)

See above.

> GNU Emacs simply has both. If there is a character in unread-command-char,
> it stuffs it into the input stream, and if there are events in
> unread-command-events, it stuffs those, too. There is some order
> of priority, but it doesn't really matter.
>
> You could still have retained compatibility by using the name
> "unread-command-char" instead of "unread-command-event" for your
> current variable, and allowing it to contain integers as well as
> event objects.

The reason I didn't do this is that the canonical use of unread-command-char
is something like this:

(let ((c (read-char)))
(if (= c 32)
(progn ... )
(setq unread-command-char c)))

If the user types some key with an unambiguous ASCII equivalent, this works
fine. But what if the user types Control-Shift-A or Shift-Linefeed, which
have no ASCII equivalent. Right now, lemacs's read-char signals an error when
C-Sh-A is typed, and returns 10 for Sh-LFD (the same as LFD). This means that
either this code would fail to work with many otherwise legitimate keystrokes,
or would unread LFD instead of Sh-LFD, which could have a different binding.
Likewise, when this code reads and unreads \010, we lose the distinction
between Control-h and Backspace.

Again, maybe you think that compatibility is more important than the feature
that BS and C-h aren't the same thing. That's a perfectly legitimate opinion.
But I can't think of a way to have both.

Using the FSF19 model, an int would be returned for C-a and an "event" would
be returned for C-Sh-A. But what about BS/C-h? Which one returns an event?
Both are equally bad choices.

> Maybe RMS' system has evolved since you first saw it. He represents
> function keys as symbols, and he can also represent a full set of modifier
> bits on printable keys. In terms of keys themselves, both systems are
> equally expressive as far as I can see.

The last time I checked, C-h, C-Shift-H, BS, C-BS, and C-Shift-BS were not
distinguishable in the FSF version. Has this changed?

> Yes, but there are about a zillion places in Calc where I stuff an
> event that I *know* is a printable character, and I had to change
> every single one of these.

I understand that you've had massive compatibility problems. But in my
defense, I think that Calc is about as atypical an emacs application as you
can find. Most packages just don't work that way; by far the most common
use of unread-command-char is to unread an arbitrary character read from
the user.

> Your model does not detect incompatible code, either, because older
> programs can simply go ahead and store something in "unread-command-char"
> and then silently fail.

Yes, this is true. However, it does issue a compilation warning. I could
make setq signal an error when storing into unread-command-char, but that
seems pretty perverse...

-- Jamie

Per Abrahamsen

unread,
May 26, 1993, 2:33:06 PM5/26/93
to

>>>>> On Tue, 25 May 1993 22:23:02 PDT, j...@lucid.com (Jamie Zawinski) said:

Jamie> The last time I checked, C-h, C-Shift-H, BS, C-BS, and
Jamie> C-Shift-BS were not distinguishable in the FSF version. Has
Jamie> this changed?

Yes.

The features provided by GNU Emacs 19.8 seem to be a superset of the
features provided Lucid Emacs 19.4 (I have not tried 19.6).

Dave Gillespie

unread,
May 26, 1993, 4:31:28 PM5/26/93
to
Jamie Zawinski writes:
> Keys and buffer-characters are not the same thing. Strings are made
> of the stuff that buffers are made of. Keys are not. Show me how to
> represent Control-Shift-A or Control-Backspace in a string.

But some keys are. In fact, statistically nearly all keys that are
actually typed are. Likewise, many key sequences dealt with by
programs are. It's silly not to incorporate this important fact
into a program's concept of events.

Lucid Emacs does this anyway, by allowing strings in some contexts
where event vectors are expected. But it's a kludge---only some
contexts allow this, where others require you to use "event-to-character"
and its inverse.

RMS' model represents all the key distinctions yours does, but the
subset of keys which are ASCII characters are represented by their
ASCII codes. It's very natural. All vector operations in Lisp apply
to strings as well, which can be thought of simply as special vectors
optimized to store only ASCII characters. So the relation between
strings and event vectors also becomes very natural in RMS' scheme.

It's not that your system doesn't have its own advantages; it's
just that I've seen some claims that your system is obviously
and completely superior, which is simply not the case.

> You don't need to resort to explicit memory management. You can drop the
> events on the floor and they will be garbage collected like any other lisp

> object. It's simply more efficient to reuse them [...]

I know, and that is commendable. It's purely a matter of efficiency,
and as you say it only matters in one point in the command loop. But
because of that one little thing, little uglies show up all over
the place in Lemacs' event functions. I'm thinking of "next-event",
which takes a blank event object to be filled in rather than simply
returning a new event object. That's inelegant and un-Lispish; it's
an expedient that isn't necessary in RMS' model.

> It such a common misconception that you *need* to explicitly manage events
> that I'm starting to regret that I made it possible at all...

I never misunderstood; I just interpreted your design as deriving
from a *need* to manage events in the command loop for performance
reasons. If this kludge had been hidden inside the command loop
it wouldn't have mattered, but in your design, "next-event" *must*
take an event to be filled in rather than consing one up itself,
"last-command-event" *must* be copied because it will be scribbled
on by the next input, and so on. Again, your event model is hardly
crippled by any of this, but it *is* inelegant in a system whose
main virtue, as you've argued, is its elegance. RMS' model neatly
sidesteps the whole issue. That, in its way, is elegant.

> And harder to programmatically tell apart from other things [...]

Lists are used for all kinds of things right now in Lisp, and it
doesn't seem to hurt anything. Lambda expressions can't be
distinguished from lists except by context, but that's okay because
context is enough. Likewise for events and keymaps. You know it's
an event because you got it from a place that has events in it.

> But perhaps they should be less opaque; give me
> examples where you've wanted this.

I'm tempted to, but I will resist---it misses the point. In some
contexts, like large object-oriented software systems, opaque
data types are a virtue. In others, flexibility and malleability
are the prime virtues. I think Emacs falls in the latter class.
For a system like that you don't want to wait for examples of why
it would be good to have access to a particular thing, you want to
give access to as much as possible *on the assumption* that some
ingenious soul will later find a way to use it.

That's why I worry a little bit about the fact that RMS' model
forgets the time stamps on keystroke events. I have only a vague
sense of when these would be useful, but I have absolute faith
that people, given this information, will be able to do cool things
with it. (I had misremembered your event model as storing mouse
positions in keystroke events, too, which could also be useful
though less portable between window systems.)

> I very carefully designed the event structures to expose only those
> components that emacs would need when running under *any* window system.
> They are not X specific at all; why do you say they are?

I went back and looked over your events, and, though they are X-like
in character, I agree that they are no more X-dependent than GNU's.

>> The Lucid model acts on the click, whereas RMS's model usually acts on
>> the release.
> Lucid delivers both up and down events, and you can bind commands to either.

Same in GNU Emacs 19, just that commands are now traditionally bound
to up instead of down. But the way the default bindings works sets
a pretty strong precedent for the way people will do their own
bindings.

>> It also fixes the stupid problem where mouse commands leave a message
>> behind only to have it erased when the release-event is processed.
> Hey, this is just a *bug*, it has nothing to do with the event model
> per se...

Not with the event model itself but with the decision to process on
up instead of down events. Emacs clears the echo area before processing
a command; if the down click is an active operation then the up click
acts like a null command with the side effect of clearing the last
message. Fixing the bug with active down-clicks would require a
kludge, but with active up-clicks the whole problem goes away.

>> You could still have retained compatibility by using the name

>> "unread-command-char" [etc...]


> The reason I didn't do this is that the canonical use of unread-command-char
> is something like this:

> [Reading a character and stuffing it back]

> Again, maybe you think that compatibility is more important than the feature
> that BS and C-h aren't the same thing. That's a perfectly legitimate opinion.
> But I can't think of a way to have both.

I understand that the "read-char"/"unread-command-char" idiom now loses
information. Nobody is asking you to forego an "unread-command-event"
feature, just that providing a backward-compatible feature *as well*
will allow code to hobble along until someone has time to fix it.
You don't have to give one up for the other. Just have both, and then
everybody is happy in both the short term and the long term.

> The last time I checked, C-h, C-Shift-H, BS, C-BS, and C-Shift-BS were not
> distinguishable in the FSF version. Has this changed?

Yes. They are all distinguishable.

> Using the FSF19 model, an int would be returned for C-a and an "event" would
> be returned for C-Sh-A. But what about BS/C-h? Which one returns an event?
> Both are equally bad choices.

The event for C-Sh-A is a number with a few high-end modifier bits set.
The event for C-h is 8, and the event for BS is the symbol "backspace".
This is rather like Lucid, where C-h is treated as a regular control
character and BS is treated as a function key. You both had to make
the choice, and you both happened to make the same choice.

RMS' model is more irregular in the way it handles modifier bits and
things. Lucid Emacs is much more orthogonal there, which is nice.
But I expect the two systems will be equally convenient to deal with
in practice.

> I could
> make setq signal an error when storing into unread-command-char, but that
> seems pretty perverse...

I'll second that! I thought of it, too, but I didn't want to suggest
it in public. :-)

-- Dave

Richard Mlynarik

unread,
May 26, 1993, 5:55:22 PM5/26/93
to
> And harder to programmatically tell apart from other things [...]

Lists are used for all kinds of things right now in Lisp, and it
doesn't seem to hurt anything. Lambda expressions can't be
distinguished from lists except by context, but that's okay because
context is enough. Likewise for events and keymaps. You know it's
an event because you got it from a place that has events in it.

I don't think you'll find much anybody involved in the Lisp world
(apart from those with their tastes set in concrete circa 1972) who
believe that the ad-hoc mess of "vectors of length 259 of lists whose
first element is the symbol `indirect' and whose tail is an alist of
conses whose ..." is any substitute for actual structure objects (of
varous degrees of opacity.)

It is one thing to argue that such perversions might make sense for
some reason of compatibility, but quite another to claim that
representing hash-tables and keymaps and events and so forth in terms
of conses and vectors and symbols is in any way a feature. (Why
aren't windows and processes and window configurations represented in
such a way in FSFmacs anyway?)

By the way, FSFmacs doesn't allow "(fillarray (make-keymap))" any
more. This "incompatibly broke" a bunch of code I wrote.

Jamie Zawinski

unread,
May 26, 1993, 6:28:48 PM5/26/93
to
Dave Gillespie wrote:
>
> Lucid Emacs does this anyway, by allowing strings in some contexts
> where event vectors are expected. But it's a kludge---only some
> contexts allow this, where others require you to use "event-to-character"
> and its inverse.

I believe that all functions which take event vectors also take strings,
and all functions which take events also accept ASCII integers.

unread-command-event must be an event, not an ASCII integer. I have no
particular objection to making it able to take an integer as well, except
that I don't see it as particularly useful (and the event- accessor
functions would need to be modified to work on ASCII integers as well, or
all code which references unread-command-event would have to be modified to
check to see if it is really an integer, either of which I would consider
an ugly wart.)

All functions/variables which return a key or sequence of keys return
events or vectors of events. I think this is a good thing because of
uniformity: keys are events, not sometimes events and sometimes integers.
It makes less work for the programmer.

YES, it is incompatible. YES, it makes more work for people porting their
code. I'm talking about purity of design, not about compatibility with
existing code.

> RMS' model represents all the key distinctions yours does, but the
> subset of keys which are ASCII characters are represented by their
> ASCII codes. It's very natural.

It makes more work for the programmer because the type of the key changes.

> I know, and that is commendable. It's purely a matter of efficiency,
> and as you say it only matters in one point in the command loop. But
> because of that one little thing, little uglies show up all over
> the place in Lemacs' event functions. I'm thinking of "next-event",
> which takes a blank event object to be filled in rather than simply
> returning a new event object. That's inelegant and un-Lispish; it's
> an expedient that isn't necessary in RMS' model.

You're right; the arg to next-event should be optional.

> Lists are used for all kinds of things right now in Lisp, and it
> doesn't seem to hurt anything.

(Mly's reply said exactly what I would have said to this.)

> For a system like that you don't want to wait for examples of why
> it would be good to have access to a particular thing, you want to
> give access to as much as possible *on the assumption* that some
> ingenious soul will later find a way to use it.

This is far from clear to me. The fact that "everybody knows keymaps are
just alists/vectors" was a big problem. Lots of code got written that used
aset and fillarray instead of the "advertised" interface of define-key,
making it harder to add power to keymaps (in both lemacs and FSFmacs.)

>>> It also fixes the stupid problem where mouse commands leave a message
>>> behind only to have it erased when the release-event is processed.
>> Hey, this is just a *bug*, it has nothing to do with the event model
>> per se...
>
> Not with the event model itself but with the decision to process on
> up instead of down events. Emacs clears the echo area before processing
> a command; if the down click is an active operation then the up click
> acts like a null command with the side effect of clearing the last
> message. Fixing the bug with active down-clicks would require a
> kludge, but with active up-clicks the whole problem goes away.

Well I really think we're getting off the track here, but it is my opinion
that if one *does* choose to bind a command to a downstroke (whether that's
the prescedent or not), and there is no command on the upstroke, then the
upstroke should not cause the minibuffer to be cleared. This used to work
in lemacs, but it's broken right now.

> I understand that the "read-char"/"unread-command-char" idiom now loses
> information. Nobody is asking you to forego an "unread-command-event"
> feature, just that providing a backward-compatible feature *as well*
> will allow code to hobble along until someone has time to fix it.
> You don't have to give one up for the other. Just have both, and then
> everybody is happy in both the short term and the long term.

I think that having existing code hobble along in way that sometimes
loses information is not a good solution. I have never subscribed to the
Unixlike idea that "mostly working most of the time" is good enough. I
think it's better for incompatible changes to cause code to not work at
all than to lose in obscure ways. Otherwise it will never get fixed.

If I could see a way to cause existing code to work 100% without
compromising the design, I would do it. If I thought that compatibility
with v18 was important enough to compromise the design, I would do it.

> The event for C-Sh-A is a number with a few high-end modifier bits set.
> The event for C-h is 8, and the event for BS is the symbol "backspace".

Then in FSF19, there are really *three* representations of events: ASCII
codes; ASCII-like codes with bits beyond #7 set; and symbols. In lemacs,
there is but a single representation (with strings allowed as well in the
interest of compatibility). The FSF model is good for compatibility, but
I think my model is a cleaner (and "more Lispy") way of doing things.

-- Jamie

Dave Gillespie

unread,
May 26, 1993, 7:33:03 PM5/26/93
to
Richard Mlynarik writes:
> It is one thing to argue that such perversions might make sense for
> some reason of compatibility, but quite another to claim that
> representing hash-tables and keymaps and events and so forth in terms
> of conses and vectors and symbols is in any way a feature.

GNU Emacs doesn't have hash-tables of any sort, as far as I can tell.
If it did you're right that they would work better as primitive Lisp
objects. It remains to be seen whether GNU Emacs 19 will suffer from
using alists instead of hash tables to store function key and mouse
maps. If the maps get big enough, it will.

The GNU keymaps are admittedly pretty baroque.

> (Why aren't windows and processes and window configurations represented in
> such a way in FSFmacs anyway?)

Windows and processes probably contain data that is more conveniently
dealt with on strictly a C level. There might also be funny business
in there with the garbage collector; there certainly is with buffers
and markers.

I've often wondered why window configurations are opaque. It has
occasionally been frustrating that they were.

> By the way, FSFmacs doesn't allow "(fillarray (make-keymap))" any
> more. This "incompatibly broke" a bunch of code I wrote.

Very true. I see why they had to do it, but it's still a shame that
keymaps couldn't be 100% backward compatible.

-- Dave

Dave Gillespie

unread,
May 26, 1993, 7:33:05 PM5/26/93
to
Jamie Zawinski writes:
> I believe that all functions which take event vectors also take strings,
> and all functions which take events also accept ASCII integers.

I just did "(setq unread-command-event ?a)" and it gave an error.

> unread-command-event must be an event, not an ASCII integer. I have no
> particular objection to making it able to take an integer as well, except

> that I don't see it as particularly useful [...]

Nor do I, on its own terms. My suggestion was that, if the variable
allowed this and still retained the name "unread-command-char", then
existing Lisp code would be able to function more or less. Not
perfectly, but it would work until the various authors had time to
redo it properly.

> I'm talking about purity of design, not about compatibility with
> existing code.

And I appreciate the purity of your design. It would be kludge for
Lucid Emacs to return strings from "this-command-keys" sometimes.
But it's not a kludge in GNU Emacs, because a vector of ASCII events
in GNU Emacs would be a vector of byte-sized integers, for which
strings can serve as functional substitutes.

There is a kludge for meta characters in the GNU system, though.
I can see it possibly coming back to haunt them some day.

> It makes more work for the programmer because the type of the key changes.

Could be, although I think it's rarely going to matter much. GNU
Emacs 19 does provide a few accessors for getting at things like the
modifiers of any key.

> Lots of code got written that used
> aset and fillarray instead of the "advertised" interface of define-key,
> making it harder to add power to keymaps (in both lemacs and FSFmacs.)

True, and I've certainly been guilty of that myself.

Honestly, I think the balance of merits is a lot more interesting
on the issue of events than on keymaps. Lucid's keymap model works
perfectly well, and even I, as devil's advocate, only managed to
come up with half-hearted arguments in favor of vectors and conses.
But RMS' event model has a nice feel to it. It still could be nice
to add extra stuff to events in the future, which his model can do
for mouse events but not for keystrokes. But there are other
advantages that weigh against it.

> I think it's better for incompatible changes to cause code to not work at
> all than to lose in obscure ways. Otherwise it will never get fixed.

Then perhaps Lucid's command loop should yell if it sees that
unread-command-char has been bound to anything.

-- Dave

Richard Mlynarik

unread,
May 26, 1993, 8:06:22 PM5/26/93
to
> It is one thing to argue that such perversions might make sense for
> some reason of compatibility, but quite another to claim that
> representing hash-tables and keymaps and events and so forth in terms
> of conses and vectors and symbols is in any way a feature.

GNU Emacs doesn't have hash-tables of any sort, as far as I can tell.

"intern".

(lemacs has more general (non-string-keyed) tables.)

Jamie Zawinski

unread,
May 26, 1993, 8:27:06 PM5/26/93
to
Dave Gillespie wrote:
>
>> I believe that all functions which take event vectors also take strings,
>> and all functions which take events also accept ASCII integers.
>
> I just did "(setq unread-command-event ?a)" and it gave an error.

That's a variable. (And I explained in my last message why I didn't make
it able to take integers: because, being a variable, it "returns" a value
as well as taking an "argument", and I don't want integers to be "returned"
for events.)

> Nor do I, on its own terms. My suggestion was that, if the variable
> allowed this and still retained the name "unread-command-char", then
> existing Lisp code would be able to function more or less. Not
> perfectly, but it would work until the various authors had time to
> redo it properly.

I understand. And my argument against this was the such code would only
work most of the time, and the existing bug would be obscured.

>> It makes more work for the programmer because the type of the key changes.
>
> Could be, although I think it's rarely going to matter much.

It may well be that the existing code will only fail in rare cases, that most
users don't encounter. But I don't think that's a good thing. For code which
uses read-char and unread-command-whatever to be *correct* in the FSF model,
it must accept that events can be integers or symbols. Existing code which
assumes they are integers will work if all you type is keys which are
represented integrally, and those are the majority. But the code is still
incorrect, and will lead to obscure errors that are unlikely to be noticed for
a long time.

>> I think it's better for incompatible changes to cause code to not work at
>> all than to lose in obscure ways. Otherwise it will never get fixed.
>
> Then perhaps Lucid's command loop should yell if it sees that
> unread-command-char has been bound to anything.

(I guess you mean "set", not "bound.") Yes, I think that's a good idea.

-- Jamie

Martin Boyer

unread,
May 26, 1993, 8:47:43 PM5/26/93
to
>>>>> Dave Gillespie writes:

>[...] I worry a little bit about the fact that RMS' model


>forgets the time stamps on keystroke events. I have only a vague
>sense of when these would be useful,

How about double-clicking on some keys (the space bar, for instance)?
If it is useful with the mouse, I can see it being useful on a
mouseless terminal

--
Martin Boyer mbo...@ireq-robot.hydro.qc.ca
Institut de recherche d'Hydro-Quebec mbo...@ireq-robot.uucp
Varennes, QC, Canada J3X 1S1
+1 514 652-8412

Per Abrahamsen

unread,
May 26, 1993, 10:01:33 PM5/26/93
to

>>>>> On Wed, 26 May 1993 14:55:22 PDT, m...@adoc.xerox.com (Richard
>>>>> Mlynarik) said:

Richard> I don't think you'll find much anybody involved in the Lisp world
Richard> (apart from those with their tastes set in concrete circa 1972) who
Richard> believe that the ad-hoc mess of "vectors of length 259 of lists whose
Richard> first element is the symbol `indirect' and whose tail is an alist of
Richard> conses whose ..." is any substitute for actual structure objects (of
Richard> varous degrees of opacity.)

No, they went ahead and implemented monster lisp environments that
collapsed under their own weight during the 80'ties. The techniques
needed to survive in those environments are not the same as for a lean
and mean lisp environment such as GNU Emacs.

Apart from that, I would agree that Jamie Zawinski's event model is
better. It is just that the benefit of having a `clean' event model
is much smaller than the problems of having two different event
models. Keymaps are not a problem, since GNU emacs can emulate
Lucid's interface.

Dave Gillespie

unread,
May 26, 1993, 9:00:52 PM5/26/93
to
>>> I believe that all functions which take event vectors also take strings [...]

>> I just did "(setq unread-command-event ?a)" and it gave an error.
> That's a variable.

.. which was my point: Unless the symmetry between events and
characters is carried all the way through, there will always be
something that slips through the cracks. Even if the functions can
all be fixed, there will be variables that break and can't easily
be fixed (for the reasons you stated).

>> Then perhaps Lucid's command loop should yell if it sees that
>> unread-command-char has been bound to anything.
> (I guess you mean "set", not "bound.") Yes, I think that's a good idea.

I was thinking "boundp", but yes, I suppose "set" is the right word.

-- Dave

Jamie Zawinski

unread,
May 26, 1993, 9:29:00 PM5/26/93
to
Dave Gillespie wrote:
>
> ... which was my point: Unless the symmetry between events and

> characters is carried all the way through, there will always be
> something that slips through the cracks. Even if the functions can
> all be fixed, there will be variables that break and can't easily
> be fixed (for the reasons you stated).

Rather than seeing this as an omission of the design, which "slips through
the cracks" implies, I see this as a piece of backward compatibility which
is simply not provided. Lemacs uses strings and ASCII codes only for
compatibility; if I could get away with it without breaking every .emacs
file that has ever existed, lemacs wouldn't use them at all. The backward
compatibility is there in places where it wouldn't adversely affect the core
of the design, which I think is clean and consistent. The compatibility
kludges are not complete, because I don't think they are worth the price.

-- Jamie

Dave Gillespie

unread,
May 26, 1993, 8:43:19 PM5/26/93
to
>> GNU Emacs doesn't have hash-tables of any sort, as far as I can tell.
> "intern".
> (lemacs has more general (non-string-keyed) tables.)

Sigh. :-] Well, I was referring to general-purpose hash tables,
with any sort of implementation, in GNU's version of Emacs 19.
Not that it really matters...

-- Dave

Richard Mlynarik

unread,
May 26, 1993, 11:38:19 PM5/26/93
to
Richard> I don't think you'll find much anybody involved in the
Richard> Lisp world (apart from those with their tastes set in
Richard> concrete circa 1972) who believe that the ad-hoc mess of
Richard> "vectors of length 259 of lists whose first element is the
Richard> symbol `indirect' and whose tail is an alist of conses
Richard> whose ..." is any substitute for actual structure objects
Richard> (of varous degrees of opacity.)


No, they went ahead and implemented monster lisp environments that
collapsed under their own weight during the 80'ties. The techniques
needed to survive in those environments are not the same as for a lean
and mean lisp environment such as GNU Emacs.

How stupid of me to forget.

PS I hope you never use "struct" in your C code.

Jim Blandy

unread,
May 27, 1993, 5:03:42 AM5/27/93
to

I personally find it very difficult to argue in favor of the GNU
keymap structure. It seems to me that building keymaps using the
simple types has the following arguments in its favor:

1) It requires no changes to allocation code or GC code - things do break.
2) It requires no new read syntax or printed representation.
3) You don't need to worry about thinking of all the necessary
primitives beforehand, since people can roll their own.
4) It's obvious, just by looking at the structure, how they work.
5) You get leverage from the ability to apply existing routines (assq,
etcetera) to them.

But those are kind of stretched.

1) Is is really that hard to write allocation, parsing, and unparsing
code? ("Are we not hackers?" :-) )
2) Come on, it's not hard to come up with a good set of primitives. A
keymap is a function mapping events onto commands. How many things
do you need to do with that?
3) It's *not* obvious how to use them any more! Did you know that a
binding for t in an GNU keymap structure acts like a default,
catch-all binding, providing the only way to create a keymap that
catches *all* events? And exactly what does it mean to nconc one
keymap onto another? Are you *sure*?
4) You can no longer effectively apply existing utility routines like
assq to an GNU keymap. assq doesn't know about the vectors. The
keymaps are too hairy to be operated on by anything but code which
knows it's dealing with a keymap.
5) It's a pain to upgrade. The keymap changes are probably the
largest source of broken a lot of code in GNU 19. Anyone who
thinks it's not going to happen again is a doodyhead.
6) It restricts your implementation. If you expect people to poke
around in the data structure in the raw, this discourages you from
making reasonable improvements, like the Lucid reverse indices.

I have yet to hear a single mildly persuasive argument from anyone in
favor of the GNU keymap structure.

RMS is this great programmer. He's got GCC. He's got Emacs. He's
got the MacArthur. He's got this luxurious pad on the fourth floor of
posh NE43. I go to work for him, hoping some of that will rub off.
It turns out that the single most common theme in his thought is,
"That's too much work." "That's going to take too long." "Don't
bother."

Is that what it takes? Is this the punchline of my lifelong pursuit
of hackerdom? I'm apprenticing myself to a blacksmith, just in case.
:-)

Reply all
Reply to author
Forward
0 new messages