Expression-based programming using this core form is trivially easy, and makes immutable data structures downright pleasurable to work with. It also makes code generation easy, though I've never taken full advantage of it; even so, a DSL made of runtime functions is not only possible, but a natural extension of anything you're already doing. Backing those homoiconic expression forms with typical high-performance data structures like arrays and hash maps, as Clojure and Janet do, is a winning formula for making complex tasks simple.
All the patterns of yesteryear for modeling problems begin to look quaint when your program eventually just becomes a pyramid of expression calls, with `main` at the top and database hits at the bottom. The organization of the stuff in between really just becomes a question of standardizing function signatures and organizing modules so humans can easily navigate them.
Ahem: can we discuss the word innovations and fundamentally above, and put two facts on the table:
LISP: 1959 C++: 1979
If they'd said "is not unique" I could agree. The innovation is a statement of origination. C++ did not originate this concept into a language system from 19 years prior to C++
For example, although this writer doesn't think macros are important, the Scheme (and especially Racket) branch of Lisp ran with macros, then with various other DSL support that take macros further (like Racket `#lang`). Racket also moved towards a strict definition of phases, and a very nice module system that works with that.
That might horrify some CL people, because it moves further away from the dynamic REPL live manipulation strength of CL, but others of us have found the tradeoffs very practical for our needs.
Maybe I'm confused but doesn't innovation mean doing something not done before?
C++ and even C are more recent than Lisp, they can't be used as counterexamples. Or am I missing something?
(Edit> other than that, I forgot to say: nice article.)
The "condition system" is niftier than i've seen elsewhere.
- some taste for minimalism (although CL/CLOS might feel different back in the days)
- human exploration oriented (repl, mop/updates)
- open homoiconicity, as a programmer lisp is an open box, makes you grow more in depth
- understanding of high and low levels in one place
- radical taste for innovation.. do whatever, you're near free
Really for most of these benefits you can reductively boil them down to “code is data” because serialization-of-code, first class functions, REPLs, etc all more or less follow from that single major innovation.
This single innovation has more far reaching effects than many people realize as once people figured out that code-is-data and AST serialization means little pieces of code (not full programs) could be transmitted and executed over a network, it has enabled massive improvements in data processing through things like MapReduce and distributed databases.
Consequently, we can manipulate a Lisp program as-is under almost any computing medium; as VMs for Turing machines and Quantum machines, as direct silicon hardware (Symbolics), under (paper-assisted) wetware (e.g. solve chapter 1 of SICP entirely by hand).
if so, that should really be considered its most pervasive innovation
Lambda: The Ultimate Imperative
Lambda: The Ultimate Declarative
Lambda: The Ultimate GOTO (Procedure Call Implementations Considered Harmful)
The Survival of LISP http://www-formal.stanford.edu/jmc/lisp20th/node2.html
He describes 15 innovations -- it is impressive that these were all innovations when he invented Lisp. He adds, "Of course, the above doesn't mention features that LISP has in common with most programming languages".
1. no part of the system off limits
2. pervasive interactivity