Languages involve a lot of apparent mystification, in part because the syntax tree and the semantics of the syntax tree are not the program you are writing. Who knows what "class X {}" actually does to the (virtual) machine?
By essentially providing a 1:1 correspondence between the "real" semantics and the "apparent" semantics, programming this way can seem magical compared to other languages.
With assembly you arent taking objects of the language and making them objects of a metalanguage, ie. you arent preserving semantics when you abstract. All you're doing is creating hacks on top of the basic semantics, so in effect, introducing a new language (of specialized jumps, etc.).
(If Lisp people want to start doing that though, I'd be happy. Prolog is great.)
So you'll have to modify your statement at minimum to "a single person other than Mark Tarver" ^_^.
I'll give Prolog a shot!
It took years to develop approaches to garbage collection (the earliest prototypes used bump allocators and crashed when they exhausted a heap), years to finalize the syntax of the language (you'll notice that the "maxwell's equations" are written using M-Expressions, a syntax for the language which was discarded for ease of implementation and later rationalized because homoiconicity can be handy), decades to realize how important lexical scope (versus dynamic) is to maintaining encapsulation. Modern Lisps are substantially different in syntax and semantics from these earliest ideas; we're just still calling them Lisp.
It's very easy to make Lisp look elegant when you brush all the implementation details under the rug.
Together these changes brush the computational complexities under the rug, and leave only the descriptive power of the laws:
* "the gradient of the electric field is proportional to the amount of electric charge"
* "the curl of an electric field is always zero"
* "the gradient of a magnetic field is always zero"
* "the curl of a magnetic field is proportional to the size of the electric current plus the amount of change in the electric field with respect to time".
As Wikipedia notes: "Mesopotamian, Indian and Chinese mathematicians are all known to have discovered the theorem independently and, in some cases, provide proofs for special cases."
An interesting take on "modern", meaning "the last 3 decades or so", which is like millenia in the IT industry...
Or are you referring to some other difference?
Work clothes, suits and hazmat wear also don't change their design every three months.
Like cycles in economics, climate, fashion, etc.
For example, John Shutt has developed a non-trivial theory of F-Expressions (vau-calculus)[1] and a language named Kernel that employs them[2]. Neither has received wide attention yet, but the Lisp renaissance of the past few years is still young...
[1] https://www.wpi.edu/Pubs/ETD/Available/etd-090110-124904/unr...
[2] ftp://ftp.cs.wpi.edu/pub/techreports/pdf/05-07.pdf
So it started an ideal until a student was foolish enough to actually program it. Yet this vaporous ideal was enough to write a symbolic differentiator. You don't have bytes nor integers but you can express non trivial mathematical concepts.
You had almost nothing yet you could do a lot, another fun fact. To me Lisp is like a linguistic library, on top of which you'll add primitive types as needed. The expressiveness is given by scope, lambdas, logic and recursion, the rest is secondary. Maybe my lambda calculus classes are making me biased though. McCarthy said he wasn't too inspired by LC even though I've read he was a student of A. Church.
ps: about scoping, I've read emails from Lisp users circa 59 who were discussing the addition of lexical scope, that was before Algol was publicly released.
More to the point, Lisp is nice because it's in a sweet spot of language complexity vs self-interpreter complexity, and lambda calculus is nice because it's a simple basis of computation. But there are many languages that make self-interpreters simple (assembly, Forth...) and many simple bases of computation (SKI calculus, rule 110...)
To call something the "Maxwell equations of software", IMO you need something more substantial. For example, Haskell folks can claim that lazy evaluation is provably superior (in termination and time complexity) to any other evaluation strategy. The dependent typing folks can claim that all valid programs correspond to valid proofs and vice versa, and that strict and lazy evaluation are equivalent w.r.t. termination. The guy behind Kernel can claim that the one true Lisp should allow you to mapcar a macro. There are many kinds of wonderful math that give you insight into computation!
E.g. does the additional math you're talking about stand on top of either of those? I don't know (By nature and calling I'm a scientist of the continuous world, not discrete, damnit! :-).
Of course, I'm moving the goalposts by using "Lisp" as a stand in for the lambda calculus (and I remember someone, maybe McCarthy, saying Lisp is what you get after you've read and only understand the first chapter of a book on it :-), which I don't even know at the poets level (but am maybe starting to correct that; don't know if the payoff is worth it to me at this point in my life).
To many people, Lisp is simply the most advanced language they know, so they view other languages as "Lisp plus some features that you could implement with macros". They might as well view other languages as "assembly plus some features that you could implement with assembly". It's just the blub paradox all over again.
To add insult to injury, many of today's advanced languages aren't even built on Lisp. They throw away the key idea of Lisp (easy equivalence between code and data) in order to achieve other things which are not achievable in Lisp (provability of certain classes of statements about all valid programs). To put it in an exaggerated but not entirely untrue way, these days Lisp seems like a dead end in terms of research. Most of the interesting stuff is coming from ML-like languages instead.
With that in mind, I would not want to learn a new language for every project I was a part of. I'd even go so far as to say: The majority of programmers cannot design a good language, and if Lisp gives them the opportunity to try then that's a BadThing™.
[1]http://blogs.msdn.com/b/peterhal/archive/2006/01/04/509302.a...
Even single-author projects have the person who wrote the code months ago and the person reading it today. :)
> is usually the time it takes to read and understand source code. Some estimates[1] claim that up to 78% of development time is spent just reading code.
Sure. This is a big deal.
I'm not sure the software-conservative approach of locking down the syntax and flexibility of expression is deeply helpful, though. My experience is that comprehending syntax (while it can be a barrier) isn't the biggest portion of that 78% you're talking about -- maybe 15%. Wrapping your head around the semantics of what a piece of code does is a much bigger portion.
The semantics of what the software does are the true language of the program you're writing, so in a sense the choice isn't whether or not you're going to have a DSL or not, it's just how concisely the syntax of the language will support the expression of it. And I've found that the less flexibility you have in syntax, the more likely it is over time that you'll have to type/read over larger amounts of code in order to capture the expression of a given semantic goal.
Well, you have to. Every new project comes with its own vocabulary and semantics. You have to learn those whether they're expressed in terms of data/function abstractions or syntactic abstractions. Sometimes—perhaps less often than many Lisp programmers appreciate, but sometimes nonetheless—those new concepts are simply easier to understand when expressed syntactically.
>The majority of programmers cannot design a good language, and if Lisp gives them the opportunity to try then that's a BadThing™
There are many programmers (I say "many" because I haven't actually met most programmers, but "most" might be true, too) who cannot design good data abstractions. Would you consider that [your favorite "OO" language here] allows one to form data abstractions to be a "bad thing?"
The risk is that Lisp is used to create a lousy language ill-suited for the task at hand. The benefits come when it is used to capture the ubiquitous language of a domain and used at the appropriate level of abstraction.
If it makes the code harder to reason about, then it's not the right level of abstraction. But poor code can be written in any language.
This takes Lisp as the machine language of a high-level machine (with READ as the assembler). You could do the same with C, but without a compiler stage it'd be absurd.
Deleted comment
Not that I know of, but only because of microcode errors. I was told "Sussman wasn't quite as smart as he thought he was" to tape it out without making really sure the microcode was correct.
In all fairness, at the time they had little in the way of available computer resources to e.g. simulate it, and it was all part of a very exciting time when MIT started doing Mead and Conway style VLSI, see https://en.wikipedia.org/wiki/Mead_%26_Conway_revolution and note the latter gave a famous course on it at MIT in 1978.