One way I've come to answer "why Lisp syntax" is through the following proxy question:
> If you want extensible syntax, what should the base syntax be?
The regularity and austerity of Lisp syntax comes from this idea. If Lisp, by default, were loaded up with all sorts of syntactic constructs [1] many of us take for granted today (which may in and of themselves be good!), then it leaves less room for the programmer to extend it in their own way. It turns out that the syntaxes we take for granted today—like for(;;){} loops or pipe | operators—are perfectly serviceable in their S-expression-equivalent form to the working Lisp programmer.
The author is right about why Common Lisp's syntax extension facilities (macros) work; the language is in a sort of syntactic Goldilocks zone.
[1] To properly discuss Lisp, we really ought to distinguish meta-syntax (the parentheses) and syntax (the grammar of symbols and lists). Common Lisp has lots of syntax, like
All of this is different syntax! These are different rules about how symbols etc. are allowed to be arranged to produce a semantically meaningful program. But they wear the same clothes of meta-syntax, which is relatively small, mostly based off of the fundamental idea of S-expressions:
Ordinary macros allow extension of the former class of syntax, while reader macros allow extension of the latter class of syntax. When talking about "macros" unqualified, we usually mean the former, but Common Lisp supports both.
It is used by Agda and Maude and is quite versatile.
Note that one of examples above is if_then_else_ function which implements a typical language construct, but in Agda, due to lasiness, it is just an ordinary function.
I think the reason it really works so good is that most people follow the already established conventions when writing their own macros.
Binding constructs look like let (ITER, rackets for loops, BB, my looping construct: https://git.sr.ht/~bjoli/goof-loop which pushes the limits of what can be comfortably done without breaking hygiene). Derived conditional constructs look like cond (trivia, match, case).
After some time you get a taste for how things are supposed to work to integrate (and to some extent compose) with the rest of the system. The discussions in the SRFI mailing lists can sometimes obsess over small details that, when finished, always seems to come together in a nice way.
> If you want extensible syntax, what should the base syntax be?
The regularity and austerity of Lisp syntax comes from this idea. If Lisp, by default, were loaded up with all sorts of syntactic constructs [1] many of us take for granted today (which may in and of themselves be good!), then it leaves less room for the programmer to extend it in their own way. It turns out that the syntaxes we take for granted today—like for(;;){} loops or pipe | operators—are perfectly serviceable in their S-expression-equivalent form to the working Lisp programmer.
The author is right about why Common Lisp's syntax extension facilities (macros) work; the language is in a sort of syntactic Goldilocks zone.
[1] To properly discuss Lisp, we really ought to distinguish meta-syntax (the parentheses) and syntax (the grammar of symbols and lists). Common Lisp has lots of syntax, like
All of this is different syntax! These are different rules about how symbols etc. are allowed to be arranged to produce a semantically meaningful program. But they wear the same clothes of meta-syntax, which is relatively small, mostly based off of the fundamental idea of S-expressions: Ordinary macros allow extension of the former class of syntax, while reader macros allow extension of the latter class of syntax. When talking about "macros" unqualified, we usually mean the former, but Common Lisp supports both.