The Hidden Origins of Lisp (2015)
blog.lfe.io
blog.lfe.io
I suspect Lisp has incredible longevity because it is nearly impossible to simplify down from functions. The approach also seems to breed a certain level of flexibility that other languages struggle to match - I have seen software that does a better job of editing text than Emacs, but I have not seen software more capable of taking on any challenge. Even Excel doesn't have quite the same level plumbing-exposed openness that can be achieved with a raw stack of functions. But I think alien civilisations would also invent Common Lisp, although they might use square brackets or somesuch.
Not Scheme? Common Lisp seems a more arbitrary to me...
To understand what is calculated in Lisp, given that you understand what the syntax means, the evaluation is inside->out (that is, if the syntax is an ordinary expression made of nested function calls, and not something with a custom evaluation order).
That's no different from math. In any languages that have math-like nested expressions with bracketing, you have inside-out evaluation.
The alternative are catenative languages and such, which have never been mainstream.
There are assembly languages which go line by line.
Imperative languages with statements and expressions tend to have small expressions where evaluation is followed inside-out; the rest of the control flow is just top down, with some forward and backward skips.
Lisp has all of the above in it. Lisp can be assembly language. For instance, in this source file from Clozure Common Lisp:
https://github.com/Clozure/ccl/blob/master/level-0/ARM/arm-h...
(defarmlapfunction fast-mod-3 ((number arg_x) (divisor arg_y) (recip arg_z))
(mov imm0 (:lsr number (:$ arm::fixnumshift)))
(smull imm2 imm1 imm0 recip)
(mul imm0 imm1 divisor)
(sub number number imm0)
(sub number number divisor)
(mov imm0 (:asr number (:$ (1- arm::nbits-in-word))))
(and divisor divisor imm0)
(add arg_z number divisor)
(bx lr))
It's just ARM code, ending in a "bx lr" and everything.The Lisp can be anything requires a jump in intellectual maturity and mental flexibility. You have to approach everything you might see in an unfamiliar Lisp project with an open mind, prepared for anything.
Now that's true in any large system --- but not in a way where it is rolled into one unifying syntax.
If a non-Lisp project has ARM assembly in it, it might just be conventional syntax. So you are hit on the head with a hammer: "this is obviously not the Foo language; it looks totally different". Suppose you are some newbie and don't know what ARM assembly language is; you still know that the files are something special and different.
If you're a newbie not knowing what ARM assembly is and see that in Lisp code, you just think that it's just more indecipherable Lisp weirdness. You just barely learned car and cdr and now you have (bx lr) and smull. Man, Lisp is weird!
Suppose we replace ( with ^ and ) with $. The visual aesthetics is ruined. Or suppose we swap them: ) means ( and vice versa. Ditto.
Let's try it:
(let ((s nil))
(dotimes (i 16)
(setq s (rbt-insert (1+ i) s)))
(pp s))
^ is opening, $ is closing: ^let ^^s nil$$
^dotimes ^i 16$
^setq s ^rbt-insert ^1+ i$ s$$$
^pp s$$
) is opening, ( is closing: )let ))s nil((
)dotimes )i 16(
)setq s )rbt-insert )1+ i( s(((
)pp s((
the reversal is slightly better than using random glyphs, because we can pretend that ) ( is suggesting closure in a different way. I don't think I could get used to this no matter how much time I put into it.I can't escape the conclusion that the shape of the glyphs is important. The parens, being shaped the way they are, are making the code readable.
I think the author would agree with you. In the last post of the series (https://blog.lfe.io/excerpts/2015/03/27/1101-the-hidden-orig...):
> And here the answer arrives, not as some astounding epiphany, but again in humble simplicity: Lisp's fun and its beauty rest not only in its syntactic elegance but in its power of expression. This is specifically important for the adventurer: if you want to create something new, explore some new programmatic territory, you need tools at your fingertips which will allow you to do so flexibly and quickly, with as little overhead as possible. Otherwise the moment of inspiration can be to quickly lost, the creative process swallowed in a mire too heavy with infrastructure and process.
Sadly it looks like their effort to translate SICP to LFE stalled out a long time ago.
Lisp is the only language I have used where I didn't feel as if the language was fighting me. Smooth indeed.
I have been sort of following in its footsteps (at least philosophically) with my latest 3D project in CL.