Live data from Hacker News

Lisp Machine Manual (1984)

hanshuebner.github.io

21–30 of 165 posts

Re: Lisp Machine Manual (1984)

#21
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

Asbestos suit on.

There are many positive things you can say about Lisp.

However, many day-to-day developers, and their managers, believe that Lisp's syntax creates nigh-unreadable programs. For example, there's no built-in infix syntax, as opposed to practically all other programming languages, and many modern programmers today expect infix as minimum table stakes for a language. Lisp syntax is extremely simple, but that doesn't mean the resulting code is easily read. Very smart people will disagree with that opinion - especially a number of people on Hacker News!! However, just look up phrases like "lots of irritating silly parentheses" and you'll see that this opinion is extremely widespread. Many people here will disagree with the sentiment, and that's fine, but it's a fact many people believe programs in Lisp syntax are hard to read.

A lot of people will reply that Lisp's syntax is simple, that real programs have been written in Lisp, that it has a kind of simplicity/elegance, and that Lisp syntax enables powerful facilities like Lisp macro processing. All of that is absolutely true. Lisp is quite powerful. But trying to convince people that Lisp is "advanced", even though it doesn't support basic capabilities like infix out of the box, is a losing battle. Forth is one of the few other languages that has an odd syntax and lacks support for infix, and it is also rarely used today.

Feel free to reply, but thoughtful responses preferred :-).

Re: Lisp Machine Manual (1984)

#22

The classic joke in here is that if you look up "fascism" in the index, it goes to the section about logging in. User authentication wasn't part of the dream, so having been forced to build it, they embedded a dig on it right in the manual. https://hanshuebner.github.io/lmman/files.xml#fascism I think there are a few other jokes in the index but I don't recall what they are.

That was probably Stallman's doing. He wrote most of the LISP machine code.

Re: Lisp Machine Manual (1984)

#23
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

It all comes back to the "worse is better" thing. Frequently enough the technologies in mainstream usage are not the best, technically speaking. Mainstream programming languages are still playing catch up on the features that the Lisp family of languages has had for decades. UNIX succeeded not because it was the best OS of the time (it wasn't, MIT made much better systems) but it had a killer feature: it ran on commo…

but it had a killer feature: it ran on commodity hardware, the PDP-11

That is not the essence of worse is better. UNIX won over the others because it was simple and regular, and was built from components that could be reassembled into more complex things. Pipes were a big part of that.

Re: Lisp Machine Manual (1984)

#24
post #7
post #6

Earlier quoted context omitted.

Are you saying that makes Lisp mainstream?

It's more mainstream than the $NEW-AWESOME-JAVASCRIPT-FRAMEWORK. Not being mainstream doesn't mean that something isn't awesome. There are lots of awesome discoveries trapped in research/academia because the overton window of the current technology community is shifted too far to "What I am used to", or because nobody cares to look. Eventually some of these ideas will get dislodged and fall down to us, but you can't…

>>> It's more mainstream than the $NEW-AWESOME-JAVASCRIPT-FRAMEWORK.

This sentence doesn't make any sense.

"Mainstream" means used alot - widespread acceptance.

Lisp is #33 on Tiobe after Cobol, Foxpro, Fortran and Ada. How you can compare that to the takeup of the latest JS nframeworks I don't really understand.

https://www.tiobe.com/tiobe-index/

21 SAS 1.372%

22 Dart 1.306%

23 D 1.103%

24 Transact-SQL 1.075%

25 ABAP 1.065%

26 COBOL 1.055%

27 (Visual) FoxPro 0.932%

28 Scala 0.923%

29 Fortran 0.879%

30 Ada 0.787%

31 Crystal 0.756%

32 Erlang 0.733%

33 Lisp 0.690%

34 Awk 0.662%

35 Lua 0.648%

Re: Lisp Machine Manual (1984)

#25
post #9
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

I don't see why language quality should have anything to do at all with mainstream usage. PHP can be considered a mainstream language today. Even COBOL in some parts of the industry. Are they any better because of that?

Well... for a language to succeed long-term, it needs to be either significantly better than the alternatives (at some particular kind of use), or else it needs to be entrenched in existing code.

When C began to spread, it was significantly better than alternatives for writing operating systems and associated tools on commodity hardware. Part of that "better" was cost - cost of the machines it ran on, cost of buying a compiler, and cost of implementing a compiler. (The mistake the anti-C people make in saying "but other languages were so much better!" is that they forget that cost was part of "better".)

C became entrenched in Unix and, later, Windows. But it didn't start entrenched. It started by being better.

If Lisp were significantly better, with everything considered, it should have won by now. I mean, yes, there are a lot of people chasing the current hotness. But the programming profession is not made up entirely of fools and sheep. Better languages get noticed, get used, acquire momentum. (Note well, however, that "better" again is "better with all things considered" - it doesn't equate to "better" as defined by theorists who about how much better their language is, even though it's a little-used language.)

Re: Lisp Machine Manual (1984)

#26
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

Asbestos suit on. There are many positive things you can say about Lisp. However, many day-to-day developers, and their managers, believe that Lisp's syntax creates nigh-unreadable programs. For example, there's no built-in infix syntax, as opposed to practically all other programming languages, and many modern programmers today expect infix as minimum table stakes for a language. Lisp syntax is extremely simple , bu…

I understand where you're coming from and agree to a large extent, but I think your hypothetical person's characterization of infix as a "basic capability" is a bit off. It's antithetical to Lisp's design to make use of infix notation. As far as Forth goes, I would say the same thing.

Re: Lisp Machine Manual (1984)

#27
post #23

Earlier quoted context omitted.

It all comes back to the "worse is better" thing. Frequently enough the technologies in mainstream usage are not the best, technically speaking. Mainstream programming languages are still playing catch up on the features that the Lisp family of languages has had for decades. UNIX succeeded not because it was the best OS of the time (it wasn't, MIT made much better systems) but it had a killer feature: it ran on commo…

but it had a killer feature: it ran on commodity hardware, the PDP-11 That is not the essence of worse is better . UNIX won over the others because it was simple and regular, and was built from components that could be reassembled into more complex things. Pipes were a big part of that.

UNIX had a weak design. It won not because it was good, but because it ran on more computers. There are many other OSes of that time period that had superior designs.

The Lisp Machine had way better composition primitives than UNIX's pipes passing plain text around.

Re: Lisp Machine Manual (1984)

#28
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

The future is long. Computers will be around for thousands of years. They've only been useful for the last ~60 years.

A programming language needs at least two things to succeed: a niche, and corporate backing. Almost every successful language has had both.

Lisp's benefit is that it is discoverable. Programmers hundreds of years from now will continue to stumble across the roots of lisp: http://www.paulgraham.com/rootsoflisp.html

http://ep.yimg.com/ty/cdn/paulgraham/jmc.lisp

The axioms are too simple not to discover by accident.

What are some promising niches for Lisp?

I think gamedev is a likely candidate. The whole gamedev industry still uses C++ / C#. But Lisp can be just as fast -- you can even make a statically-typed Lisp, which avoids any possibility that Lisp's performance will bite you.

The benefits for gamedev in particular are immense: http://all-things-andy-gavin.com/2011/03/12/making-crash-ban...

The reason this hasn't happened is because it takes a certain personality type to write languages. In 99% of cases, your language will fail. Meaning, if you spend 3 years on it, that's 3 years you didn't spend learning React or Vue or %salary-du-jour. You have to love it.

That love is quite the feeling. When you design your own language from the ground up, and break down all barriers of complexity, it stops mattering whether anyone else ever uses your language. Making it was reward enough.

In concrete terms, I think self-hosted Lisps are a promising way forward. It's simple to bootstrap a Lisp in almost any language: JS, Lua, Python, Ruby. Write a reader (you can use JSON to start), then write a compiler that steps through the tree of expressions and spits out the native language constructs. E.g.

  (%while true
    (print "she sells C shells by the C store"))
becomes C#:

  while (true) {
    Console.WriteLine("she sells C shells by the C store");
  }
or Python:

  while True:
    print("she sells C shells by the C store")
etc.

Then you can save the output code to disk and run it.

At this point you've written your compiler in Python, Ruby, or whatever. Now the trick:

Create a file "compiler.l" that sits alongside your "compiler.py" file. For each function in compiler.py, translate it into your Lisp language and save it into compiler.l.

E.g. if your compiler.py file has:

  def compile(x):
    if atom(x): return compile_atom(x)
    if special(x): return compile_special(x)
    return compile_call(x)
then in your compiler.l file, you should write:

  (define compile (x)
    (if (atom x) (return (compile_atom x)))
    (if (special x) (return (compile_special x)))
    (return (compile_call x)))
And hey presto -- your compiler.py file is now capable of reading in compiler.l and generating the exact same code. Meaning you no longer have to program in Python! (Or whatever language you're targeting.) At that point your language is fully self-hosted, and you can extend it however you like.

It's so incredibly easy to set up a self-hosted Lisp that it almost seems like a toy. But it's incredibly powerful. E.g. I'm currently building one on top of Racket so that I can write traditional unhygenic macros, completely sidestepping Racket's syntax transformer system.

You could imagine doing something similar for React, letting you write programs to generate React components -- a step toward the ultimate templating system.

Once you've done this, you'll notice that the entire language is extremely small. It's a thin wrapper around the host language. But that's the value -- that's why it's useful. E.g. in many Lisps, it's common to use the symbol 't for True and an empty list for False. In those systems, there is no such thing as a "boolean" type. Everything is either an empty list or not-an-empty-list. You could do that, which demonstrates just how powerful this technique is. Just modify the way you compile IF statements:

  (define compile_if (cond a b)
    (+ "if (" (compile cond) ") { "
           (compile a)
       " } else { "
           (compile b)
       " }\n"))
to

  (define compile_if (cond a b)
    (+ "if (yes(" (compile cond) ")) { "
           (compile a)
       " } else { "
           (compile b)
       " }\n"))
(i.e. wrap COND in a call to a YES function.)

Then you can define YES as:

  (define yes (x)
    (return (not (or (== x false) (empty_list x)))))

Now your compiler spits out "if (yes(x)) { a } else { b }" everywhere, and your YES function is your definition of truthiness.

So, you can do that, and it works, but at that point you'll discover that you start wrestling with the underlying language. If you change how IF behaves, then you'll need to change how AND and OR behave, too. Stuff like that.

I've found the best strategy is to make your Lisp as close to the target language's semantics as possible. When you do that, you end up with a tiny runtime. Clojure's runtime is gargantuan because it has to define in Java all of Clojure's semantics. But here, you're using the host language's semantics directly.

Now it might seem that this "isn't really a Lisp". But it turns out that it's just as powerful as any other Lisp. All you have to do is change your compiler from:

  (define compile-file (src)
    (compile (read-file src)))
to

  (define compile-file (src)
    (compile (expand (read-file src))))
Then define an EXPAND function that performs macroexpansion on the expressions you got from the reader.

At that point it's straightforward to introduce:

  (define-macro when (cond . body)
    (return `(if ,cond (do ,@body))))
which compiles to:

  def when_macro (cond, *body):
    return ["if", cond, ["do"] + body]

  environment["when"]["macro"] = when_macro
Your EXPAND function becomes dead simple:

  def expand(form):
    if atom(form): return form
    mac = environment[form[0]]["macro"]
    if mac: return apply(mac, form)
    return map(expand, form)
Finish it off by defining DEFINE-MACRO:

  def define_macro_macro(name, args, *body):
    f = eval(compile(["fn", args] + body))
    environment[name]["macro"] = f

  environment["define-macro"]["macro"] = define_macro_macro
Presto, now you can write

  (define-macro add1 (x) (return (list "+" x 1)))

  (print (add1 41))
and it compiles to print(41+1).

Scott Bell and Daniel Gackle pioneered the above technique, and I've spent the last couple of years implementing it across different languages, including Python, elisp, ruby, and racket.

You can try it out here:

https://github.com/sctb/lumen

That's Lumen, a Lisp for JS and Lua. One of the coolest aspects is that it compiles to both JS and Lua simultaneously, and runs in both.

If you want one for Python, you can try out my branch:

https://github.com/shawwn/lumen/tree/features/python

It compiles to JS, Lua, and Python simultaneously. So the same codebase runs on node, lua, luajit, torch, python2.7, python3, and pypy.

LuaJIT has a fantastic FFI library -- and since our lisp runs in Lua, that means we automatically get a fantastic FFI: https://github.com/sctb/motor/blob/master/pq.l

Imagine how much work it would be to write your own FFI! I think it's one of the best FFI's of any Lisp implementation.

So that's a rough outline of Lisp's unique power. It's so versatile that it feels like just a matter of time until someone decides to embed it in some popular system, like a game engine or an online store builder. Clojure might get some serious competition within the next decade.

Re: Lisp Machine Manual (1984)

#29
post #9
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

I don't see why language quality should have anything to do at all with mainstream usage. PHP can be considered a mainstream language today. Even COBOL in some parts of the industry. Are they any better because of that?

According to TIOBE, in 1987 only C was more popular than Lisp. Thirty years later, C is #2 and Lisp is #31. Lisp was mainstream and for some reason other languages overtook it. I think it's a good question.

Re: Lisp Machine Manual (1984)

#30
post #2

There seems to be plenty of people who think Lisp is awesome. If so, then why hasn't it become "mainstream"?

Asbestos suit on. There are many positive things you can say about Lisp. However, many day-to-day developers, and their managers, believe that Lisp's syntax creates nigh-unreadable programs. For example, there's no built-in infix syntax, as opposed to practically all other programming languages, and many modern programmers today expect infix as minimum table stakes for a language. Lisp syntax is extremely simple , bu…

I don't even disagree on the infix math point, really. I do find it awkward that it makes up a small fraction of what you actually do in most programs. Seems odd that such a minorly applicable point holds such high regard.

Sadly, I assert that this being the main irritation of LISP is one more of fashion than it is of actual applicability. Sad, because I do have pride in our communities to want them to be above fashion. Most people that "hate" LISP have never written a single line of it, ever. Nor will they ever do so.

Post reply on HN