Reconstruction or Eviction
on
GNU Emacs 21
·
· Score: 1
From winter@sch.bme.hu Mon Oct 22 20:48:03 2001
Date: Mon, 22 Oct 2001 20:47:31 +0200 (MEST)
From: Nagy Lajos Pal
To: Nagy Lajos Pal
Subject: emacs
Some people may not like it but the truth is that Emacs has reached its
technological limits and its extinction is almost inevitable without a
serious overhaul. I like Emacs but I want to express my fears about its
future.
First, a little background info about me. When I first got into touch
with *nix systems I started to use vim. I was amazed by its richness of
features. (I liked those infamous keystrokes too.) Later a friend of
mine introduced GNU/Emacs and tried to convince me of its superiority.
It was a hard task. I was used to my way of writing vim macros for
everything and jumping around the screen/file with only a handful of
keystrokes. He finally succeeded. Some of the features that seduced me:
support for various languages and file formats (Java, Lisp,
Python,...)
everything-a-function which results in easy
extension of the functionality
lot of support packages
pre-installed or downloadable
I fell in love. I read all the tutorials. And do not forget the 800+
pages Emacs Lisp Reference. I spent my time fabricating functions,
browsing the sources, debugging. I was amazed again. I felt that every
part of Emacs follows a well-designed pattern of technology and that the
whole editor shows a faint sense of synergy. (Zen, some would argue.)
The problems started to show up when I wanted to implement more serious
functionality.
Failure 1 - better forward-statement in Java
I was thinking of some new motion commands in Java/JDE
mode like forward-statement, mark-statement, finish-statement. Yes, I
know there are commands whose name implies this functionality.
Unfortunately in reality they are almost useless because their
interpretation of 'statement' is not what one would expect after reading
the grammar of the Java language. In short I wanted functions that know
more about the content of the file. It turned out soon that implementing
these functions may well include parsing the file and that would imply
serious programming in Lisp (or interfacing an external parser). I spent
some time trying but gave up later.
Failure 2 - mix iswitchb and imenu
Ok then. I am not prepared for writing serious extensions for Emacs yet.
But how about a smaller one? I like the iswitchb package very much.
(For those who do not know it: it eases the pain of using C-x b or
switch-to-buffer by adding incremental search and history to the selection
of buffers, much like the functionality used in the location part of IE
and other browsers.) My idea was to mix iswitchb and imenu (which gives
you the ability to jump to semantic elements in a java file like methods,
inner classes and so on.) I thought that using the selection method of
iswitchb added to imenu would greatly improve my editing of Java files. I
tried very hard and got quite far away but then I had to give up. It
proved not to be easy to extract the selection functionality from iswitchb
and insert it into imenu. In its final state my code worked but it was
full of bugs.
(There were several other little features that I could implement, but more
advanced functions needed a lot of work to implement.)
These failed attempts forced me to stop for a while and think about the
possible causes. My first thought was that maybe it is me who is not
skilled enough for the task. Then I tried to analyze the problems I faced
during coding. I found that it was scarcely ever the case that I could
not design a solution for the problem at hand. The problems came when I
tried to implement and insert it into Emacs's envirnment.
Emacs badly needs a mature OO language
Emacs based on Lisp. Lisp is a functional language. Emacs badly needs
object-orientation even at the cost of abandoning Lisp.
Emacs has a lot of data structures with functions to modify them.
Buffers, frames, windows, points, marks, faces and so on. But the
functions are separate entities from their intimate data. Everything is a
list and you got a myriad of functions to manipulate those lists. You
have a buffer? You get buffer-name, get-buffer, rename-buffer,
buffer-file-name, and so on. I thing in OO this kind of function naming
is called 'data-envy'. All these functions should belong to the buffer
object and not to the global namespace.
Language features instead of conventions in packages
Two words: global namespace. Lack of a nice naming and packaging system
become more and more iritating as you want to do serious programming.
Besides Emacs should be separated into a couple of modules with
well-defined interfaces. Nowadays function-variables play the role of
interfaces. Unfortunately this method is not well-suited for defining
complex abstractions.
Lisp is used in a procedural way, anyway
While browsing the sources of several packages I had to realize that Lisp
was not being used as a functional language. It seems that most of us is
locked into procedural thinking and Lisp only changes the syntax not the
logic. The majority of functions in the majority of packages could be
translated into C/Java without seriously changing the general outline.
(I did some programming in ML and I know how different a functional
program can (and should) be.) Lisp became a burden which cannot be
dropped because of historical and emotional reasons.
Weak coupling should be enforced by the language not by conventions
Packages get into intimate relations with each other's hook functions,
global variables and inner workings. Let's take an example. Suppose you
have a strange obsession and want to fork a new Emacs strain which gets
rid of the evil transient-mark mode. What percentage of the code base
will be affected? Do you have any clues to identify those parts? (Maybe
grep, but I would not bet on it.) I had to sourly learn that this
functionality and references to it are scattered all over the place. I
often felt that I was working on a
Big Ball of Mud.
Mud results in low-quality packages
The base packages are fine. But if you look at other packages which claim
to have complex and advanced functionality you find sloppy software. And
this is due to the strong coupling of code and unclear interfaces in
Emacs. I think that most authors simply cannot cope with it after a
certain point. Most of them have a great idea at the beginning then they
implement some nice 'one-liners' to get a feel of it then they get stuck
when the real work begins. That is why there are so many half-finished,
low-quality packages. I think that with the current code base the price
of developing a sophisticated package is daunting.
Escape while you can
Emacs is bogged by its heritage of supporting a wide range of terminals
and systems while being unable to develop further because of the
aforementioned reasons. The only conceivable remedy would be a total
reconstruction preserving the basic ideas and design. Unfortunately this
is very unlikely.
First, a little background info about me. When I first got into touch with *nix systems I started to use vim. I was amazed by its richness of features. (I liked those infamous keystrokes too.) Later a friend of mine introduced GNU/Emacs and tried to convince me of its superiority. It was a hard task. I was used to my way of writing vim macros for everything and jumping around the screen/file with only a handful of keystrokes. He finally succeeded. Some of the features that seduced me:
- integration (ftp, file manager, news browser, cvs client,
...)
- support for various languages and file formats (Java, Lisp,
Python,
...)
- everything-a-function which results in easy
extension of the functionality
- lot of support packages
pre-installed or downloadable
I fell in love. I read all the tutorials. And do not forget the 800+ pages Emacs Lisp Reference. I spent my time fabricating functions, browsing the sources, debugging. I was amazed again. I felt that every part of Emacs follows a well-designed pattern of technology and that the whole editor shows a faint sense of synergy. (Zen, some would argue.)The problems started to show up when I wanted to implement more serious functionality.
Failure 1 - better forward-statement in Java
I was thinking of some new motion commands in Java/JDE mode like forward-statement, mark-statement, finish-statement. Yes, I know there are commands whose name implies this functionality. Unfortunately in reality they are almost useless because their interpretation of 'statement' is not what one would expect after reading the grammar of the Java language. In short I wanted functions that know more about the content of the file. It turned out soon that implementing these functions may well include parsing the file and that would imply serious programming in Lisp (or interfacing an external parser). I spent some time trying but gave up later.
Failure 2 - mix iswitchb and imenu
Ok then. I am not prepared for writing serious extensions for Emacs yet. But how about a smaller one? I like the iswitchb package very much. (For those who do not know it: it eases the pain of using C-x b or switch-to-buffer by adding incremental search and history to the selection of buffers, much like the functionality used in the location part of IE and other browsers.) My idea was to mix iswitchb and imenu (which gives you the ability to jump to semantic elements in a java file like methods, inner classes and so on.) I thought that using the selection method of iswitchb added to imenu would greatly improve my editing of Java files. I tried very hard and got quite far away but then I had to give up. It proved not to be easy to extract the selection functionality from iswitchb and insert it into imenu. In its final state my code worked but it was full of bugs.
(There were several other little features that I could implement, but more advanced functions needed a lot of work to implement.)
These failed attempts forced me to stop for a while and think about the possible causes. My first thought was that maybe it is me who is not skilled enough for the task. Then I tried to analyze the problems I faced during coding. I found that it was scarcely ever the case that I could not design a solution for the problem at hand. The problems came when I tried to implement and insert it into Emacs's envirnment.
Emacs badly needs a mature OO language Emacs based on Lisp. Lisp is a functional language. Emacs badly needs object-orientation even at the cost of abandoning Lisp. Emacs has a lot of data structures with functions to modify them. Buffers, frames, windows, points, marks, faces and so on. But the functions are separate entities from their intimate data. Everything is a list and you got a myriad of functions to manipulate those lists. You have a buffer? You get buffer-name, get-buffer, rename-buffer, buffer-file-name, and so on. I thing in OO this kind of function naming is called 'data-envy'. All these functions should belong to the buffer object and not to the global namespace.
Language features instead of conventions in packages
Two words: global namespace. Lack of a nice naming and packaging system become more and more iritating as you want to do serious programming. Besides Emacs should be separated into a couple of modules with well-defined interfaces. Nowadays function-variables play the role of interfaces. Unfortunately this method is not well-suited for defining complex abstractions.
Lisp is used in a procedural way, anyway
While browsing the sources of several packages I had to realize that Lisp was not being used as a functional language. It seems that most of us is locked into procedural thinking and Lisp only changes the syntax not the logic. The majority of functions in the majority of packages could be translated into C/Java without seriously changing the general outline. (I did some programming in ML and I know how different a functional program can (and should) be.) Lisp became a burden which cannot be dropped because of historical and emotional reasons.
Weak coupling should be enforced by the language not by conventions
Packages get into intimate relations with each other's hook functions, global variables and inner workings. Let's take an example. Suppose you have a strange obsession and want to fork a new Emacs strain which gets rid of the evil transient-mark mode. What percentage of the code base will be affected? Do you have any clues to identify those parts? (Maybe grep, but I would not bet on it.) I had to sourly learn that this functionality and references to it are scattered all over the place. I often felt that I was working on a Big Ball of Mud.
Mud results in low-quality packages
The base packages are fine. But if you look at other packages which claim to have complex and advanced functionality you find sloppy software. And this is due to the strong coupling of code and unclear interfaces in Emacs. I think that most authors simply cannot cope with it after a certain point. Most of them have a great idea at the beginning then they implement some nice 'one-liners' to get a feel of it then they get stuck when the real work begins. That is why there are so many half-finished, low-quality packages. I think that with the current code base the price of developing a sophisticated package is daunting.
Escape while you can
Emacs is bogged by its heritage of supporting a wide range of terminals and systems while being unable to develop further because of the aforementioned reasons. The only conceivable remedy would be a total reconstruction preserving the basic ideas and design. Unfortunately this is very unlikely.