
History of Lisp Editing - lemming
https://github.com/shaunlebron/history-of-lisp-editing
======
gumby
D-Edit was already around when I got to PARC in late 1983. The first thing I
worked on was an Emacs in Interlisp-D.

I think ITS Emacs (written in TECO) had paren matching before the CADR Lisp
machines (what you call Zmacs, but it was EINE originally).

The first Emacs written in Lisp was Multics Emacs (written by Bernie
Greenberg) and it had paren matching when I used it but that was 81/82
timeframe.

What do you call paren matching by the way? Emacs always had structure
navigation (c-m-F/B and c-m-U etc) in which case that support went back into
the 1970s.

(BTW the first Emacs-like editor for the lispms was EINE (Eine Is Not Emacs);
it was replaced by ZWEI (Zwei Was Eine Initially). Look at a German dictionary
if that is not funny. IIRC Zmacs was a renaming by Symbolics as part of their
efforts to move beyond the AI lab implementation (While LMI/TI continued to
sync back to the AI lab sources).

~~~
lispm
EINE was the first Emacs written in Lisp. Actually Lisp Machine Lisp by the
then young Dan Weinreb at the age of 17. Dan passed away way too early a few
years ago.

[https://en.wikipedia.org/wiki/Daniel_Weinreb](https://en.wikipedia.org/wiki/Daniel_Weinreb)

------
timonoko
Teletype Lisp editor was really amazing experience. I got the idea I could do
something similar to natural languages. Especially Finnish Language, which
contains very long words, and the end of those words do not necessarily need
to be printed out to aid comprehension. So chapters and paragraphs and
sentences would be like S-expressions in Interlisp Editor, only first few
words showing and first few letters printed out in worlds. Unfortunately this
grand idea never came real, because they did not give me extra teletype time
in 1974.

------
linkmotif
Hah, fun:

> Debating Maclisp vs Interlisp (i.e. storing code as text vs structure)

This really puts "tabs vs. spaces" to shame.

~~~
AceJohnny2
I found this the most interesting. For one thing reminding me of Erik Naggum's
existence, insight, and causticity[1], and for another exploring what seems to
be a promising but dead branch of programming.

As we continue wishing we had "better ways to write programs", constantly re-
exploring visual programming (Scratch and its spinoffs), it's interesting to
me that the ALGOL-children (C and the like) have completely lost this way of
developing programs. What is there to learn, both from the technology itself
and from how we forget?

[1]
[https://en.wikiquote.org/wiki/Erik_Naggum](https://en.wikiquote.org/wiki/Erik_Naggum)

------
torrent-of-ions
I started to use paredit early in my Lisp career and never looked back. I
tried smartparens but found it annoying (I find it much harder to change my
tools these days).

Parinfer looks very clever, but I'm not afraid of "hotkeys" (I use emacs) and
I don't want to do manual indentation. Is there any benefit over paredit for
me?

~~~
lgas
I'm a paredit user too and I tried but couldn't make the switch to parinfer. I
think there's just too much muscle memory I'm fighting against. But I've heard
that parinfer was much easier to pick up from two separate people that were
just learning Clojure, for whatever that's worth.

------
Grue3
I don't use paredit or similar extensions to code Lisp. Just bare Emacs (with
SLIME, of course) is enough. The closing parens that I didn't type are
distracting. If there's so much parentheses in your code that you're tired of
closing them, maybe it needs a refactoring?

~~~
triclops200
> tired of closing them

This comment misses the point entirely. The point isn't to mitigate having to
type them, it's to help keep structural preservation. All of these structural
editors also do so much more than just close the parens. They allow you to
edit the code as the tree it is as well as navigate it as such. Without the
parens actually being there, you couldn't do that in a determininistic way,
thus the auto-closing of parens is more of a side effect than anything else.

~~~
breck
You actually don't need parentheses--you can use whitespace. You give up the
ability to add N arbitrary trees/nodes to one line, but in return you get
beautiful, geometric code that's easier to reason about at scale.

~~~
ohyes
I do this too. ctrl-meta-q is really all I need... Sometimes i'll do rainbow
parens if i'm feeling festive.

~~~
carapace
links to example code? (breck too)

~~~
breck
This:

    
    
      (+ 1 2 (x 3 4))
    

Can be written as:

    
    
      +
       1
       2
       x
        3
        4
    

Or:

    
    
      + 1 2
       x 3 4

------
white-flame
I'd like to find out how people tolerate ()[]{};,. in their programming, in
far greater quantities and in more complex interspersal than Lisp's parens.
)]];));}}};

~~~
munificent
You know, I think it's a fine argument to say, "Yes, Lisp has a lot of
parentheses but we _like_ how it looks." I don't think it makes sense to say,
"No, other languages have more punctuation characters than Lisp." The latter
is an objective statement that can be actually tested.

I went to Rosetta Code and grabbed the implementations of Conway's Game of
Life in Racket, Ruby, Python, and Java. For each one, I manually removed
comments and string literals. Then I wrote a little script. It looks at each
character in the file and groups them into categories:

    
    
        bracket: ()[]{}
        whitespace: space\t\r\n
        text: a-zA-Z01-9_
        punctuation: =,;<>-'!|?:#/*%+.
    

Then I looked at each file to see what fraction of non-whitespace characters
are brackets or punctuation (including brackets). Here's the results:

    
    
                  bracket   punctuation
        life.java  13.25%        27.52%
        life.py    13.27%        21.95%
        life.rb     9.56%        23.73%
        life.scm   22.29%        28.30%
    

The Racket implementation has roughly twice as many bracketing characters as
the other languages, and more of all kinds of punctuation than any of them. It
may be that the languages and example programs I chose aren't representative,
but I'd be surprised if another corpus was significantly different.

Most languages have multiple levels of precedence. The entire point of that is
to allow eliding explicit bracketing characters for commonly nested
subexpressions. You may _dislike_ that feature, which is reasonable. But I
don't think you can argue that it doesn't _exist_ and doesn't accomplish what
it intends to do. Consider:

    
    
        var isCloser = x1 * x1 + y1 * y1 < x2 * x2 + y2 * y2                  // 0 brackets
        (define is-closer (< (+ (* x1 x1) (* y1 y1)) (+ (* x2 x2) (* y2 y2)))) ; 16 brackets

~~~
yorwba
I think most of the non-bracket "punctuation" in Racket is caused by the
kebab-case identifiers and to a lesser degree by ? and ! in function names.

So in fact "Other languages have more punctuation characters than Lisp." is
not an objective statement at all, since it relies on the definition of
punctuation, which is subjective or at least language-specific.

~~~
munificent
Good point. I updated my little script to (roughly) take each language's
identifier rules into account. Now "?" is considered an identifier character
in Ruby and "-", "!", and "?" are punctuation in Racket. It gets a little
fuzzy, of course because ">" works like punctuation in "(> 1 2)" but less so
in "(number->string 123)".

    
    
                  bracket   punctuation
        life.java  13.25%        27.52%
        life.py    13.27%        21.95%
        life.rb     9.56%        23.29%
        life.scm   22.29%        24.81%
    

This gets Racket down to having similar levels of punctuation but note that,
of course, brackets are still significantly more common than other languages.

------
kgwgk
> I'd like to find out how people tolerated parens back in the golden days of
> Lisp.

Why is it so unimaginable that people can just live with all those
parentheses? The only parenthesis-related fragment in my .emacs is the
following:

    
    
        (keyboard-translate ?\( ?\[)
        (keyboard-translate ?\[ ?\()
        (keyboard-translate ?\) ?\])
        (keyboard-translate ?\] ?\))
    

I guess all the listed approaches may make things easier once you get used to
them, but I'm sure I'm not the only one writing parentheses one by one.

~~~
pjmlp
Apparently moving from

    
    
        puts("Hello")
    

to

    
    
        (puts "Hello")
    
    

Or for example

    
    
        if (i < x) {
           puts ("low");
        } else {
           puts ("high");
        }
    

to

    
    
        (if (< i x)
           (puts "low")
           (puts "high")
        )
    

Is very complex.

~~~
mpweiher
Yeah, actually it is. That despite the examples being seemingly somewhat
contrived and the comparison also not so good.

Prefix notation is hard, at least for people whose native language is S-V-O,
and not V-S-O.

So

    
    
       i < x 
    

reads naturally: "i is smaller than x". On the other hand:

    
    
       < i x 
    

reads unnaturally: "is smaller than i x". It's not a _huge_ deal individually,
but it does add up. And of course the extra level of parens is necessary(?) in
LISP.

"if" is interesting, because it seems to do fine in prefix notation, and
puts() is also a bit weird because its subject is missing/implied:

    
    
        stdout puts:"hello".
    

But in general I find it more surprising that prefix-y notation is as
acceptable as it is for most function calls, despite the fact that, when
offered, infix notation is considered more "natural" or even more "built-in",
than that applying it to even more situations is considered difficult.

~~~
Koshkin
> _infix notation is considered more "natural"_

Infix notation only works "naturally" for two operands.

~~~
TuringTest
> Infix notation only works "naturally" for two operands.

Or n operands where the operator is the same (think a + b + c + ... ).

The Readable Lisp project for Lisp without parentheses allows using infix
notation in Lisp for these two use cases.

~~~
Koshkin
But notice that in math, for example, they tend to switch to the _prefix_
sigma notation as soon as the number of operands grows beyond just a few.

------
escherize
I incorporated parinfer into my reagent live coding environment here[1], and
it's been working pretty well.

I have also used Atom with Parinfer to teach a nontechnical designer the
basics of clojure. Enough to build templates using hiccup for her resume, and
personal website. I don't think smartparens or paredit would be anywhere near
as easy for her to pick up.

If you're used to indentation being meaningful as some langs do, you should
probably try out clojure/script with parinfer.

[1]: [http://escherize.com/cljsfiddle](http://escherize.com/cljsfiddle)

~~~
hellofunk
Would be nice to see some examples on that page about how to actually use
parinfer commands. Or maybe you have that explained on a different page?

edit: I see, the point of parinfer is to not use commands or hot keys. I'm
going to play with your site and if the slurp/barf behavior is any better than
paredit.

------
cat199
no expert at all; was before my time -

But probably worth spending some time with ITS, TOPS-10, and TOPS-20 & digging
around with TECO and its descendants which came to be emacs, and probably
checking into 4.2/4.3BSD as well..

The former group is pretty much the platform for early LISP (when lisp was
still in caps :b ), and the latter, well, alot of good stuff happened here..
plus built in franz lisp and the lisp mode for (real) vi ..

------
anon1253
Very interesting! paredit + agressive-indent made my life so much easier. Now
I don't have to worry about parens OR indentation. Unless you work with people
who have different preferences of course, but for my own stuff I generally
stopped trying to fight agressive-indent (at least it's consistent).

------
MarkMMullin
kb-emacs should be on that list too, I would think

