Arguably, the s-expr syntax is what enables the rich code-as-data metaprogramming that you find in Lisps. Working with full macros in a sexpr language is already complex enough, the an extra layer of complexity that non-sexpr language add really breaks that camel in half. The point is, you really need code == AST parity to make a powerful macro system workable. You don't necessarily need the parans, but complaining about parens is really missing the point.
Without that, it's certainly doable, but the result looks nothing like your non-macro code in that language.
Of course, s-expressions have a big advantage: homoiconicity. Homoiconicity enables the metaprogramming that is such a powerful and relatively unique capability of the Lisp family. But it's possible to add additional abbreviations to s-expressions to make the notation much easier to read by most software developers. Indeed, the original Lisp didn't have "quote", but no one would be happy today if you had to write (quote a) instead of 'a. (See the "LISP 1.5 Programmer's Manual" by McCarthy et al. of 1962 at http://www.softwarepreservation.org/projects/LISP/book/LISP%... ... and note that it has only QUOTE.) I think adding a few more abbreviations to the s-expression reader can make a big difference in the readability (and acceptability) of Lisps. E.g., "{a + b}" as an abbreviation for "(+ a b)" retains homoiconicity, while making code significantly easier to read for most people. For more information, see: https://readable.sourceforge.io/
Superfluous parens: Do not assume that the parentheses are superfluous, they are an excellent way to write down and communicate a tree-like structures. Code happens to be such a structure.
With regard to the readability, this probably reveals an initial training in an Algol-syntax language. It is really not self-evident that s-expr are harder to read, and find it hard to believe that is true. Most likely, if it is the case for you, it more likely means it is not leveraging years of brain-training on Algol/C style notation. Do not mistake this for anything intrinsic about s-expr.
To grab to personal experience: I have thought both Lispy and Alogly languages to complete programming virgins and have anecdotally seen less syntax-related mistakes in the former. The benefit of pre-learned infix semantics from mathematics courses is vanishingly small compared to the complexity of learning how to program. Unless your domain is actual mathematics (R, Matlab, ...), only a very small set of expressions in any program actually leverage that familiarity. The benefit in teaching/learning S-expr syntax is that is comparably uniform: whitespace breaks with paren ends. Infix languages introduce a set of context-dependent symbols. For example, a good portion of the errors I saw first timers make in class is mixing commas versus semicolon breaks. Even Python does this in the form of complex line breaking rules mixed with symbol-breaks (semicolon expression seperators, colon in conditionals, etc). It isn't hard when you are already familiar, but you definitely notice the complexity when holding the hand of a first-timer.
In short, the 'not seeing parens' is akin to not 'seeing commas, semicolons, colons, braces, parens, backspaces, ...' in Algol-syntax languages.
But honestly, things that are different should look different. Leveraging familiarity is a vital tool when designing a consumer-facing interface, but avoiding faulty preconceptions and ambiguities is more important for the professional tool that is a serious programming language. I personally think in C when handling low-level memory, Lisp when doing metaprogramming, Prolog when doing logic programming and something APL-like when doing linear algebra.
Actually, the people saying "you won't see the parentheses after a while" are a significant subset of advocates of Lisp, who know the language well! Here's a quote from the old Common Lisp FAQ: "After you've written and read enough Lisp, you stop seeing the parentheses. (Reports vary from a few days to a few weeks.) They don't disappear in some magical way, but you start to see the structure of the code rather than just "lots of fingernail clippings".
We all agree that it's important to be able to see the structure of code. But if your goal is to not see the only marker with important information, then there's a problem.
> Infix languages introduce a set of context-dependent symbols.
That is not required at all. That conflates infix with precedence. What developers want is infix, not necessarily precedence. In practice many developers avoid using precedence, in fact, a large percentage don't understand the precedence rules of the language they're using all. In Algol-like languages, they just use parens to force all evaluation orders even when they are not necessary.
If your infix system doesn't support a built-in precedence, there are no context-dependent symbols. For example, in curly-infix, {2 + 3 + 4} => (+ 2 3 4), but there is nothing special about "+". The expression {2 qwe 3 qwe 4} => (qwe 2 3 4). If you want precedence, you use another pair of curly braces to directly express it, just like you would in an Algol-like language: {2 + {3 * 4}} => (+ 2 (* 3 4)), while {{2 + 3} * 4} => (* (+ 2 3) 4). As a result, there's no dependence on context-dependent symbols, and you DO get infix.
SRFI-105, at <https://srfi.schemers.org/srfi-105/srfi-105.html>, quotes research about precedence use in "Developer beliefs about binary operator precedence" by Derek M. Jones <http://www.knosof.co.uk/cbook/accu06.html>. Some key points:
"They first measured the visible source code of a number of large C programs... only 1.9% of all expressions had at least two binary operators (where precedence would make a difference)... In those cases where precedence could have been used (the 1.9% of all expressions), 67% (102,822/154,575) of the operator pairs were explicitly parenthesized (making any precedence rule moot)."
"The authors then described a survey of developers at the 2006 ACCU conference to determine if they correctly applied the precedence and associativity of the binary operators common to C, C++, C#, Java, Perl, and PHP. In this experiment only 66.7% of the answers were correct (standard deviation 8.8, poorest performer 45.2% correct, best performer 80.5% correct); this was not much better than random chance (50%). Even many widely-used operator pairs had relatively poor results... (only) 69% when they combined / and +. These were far short of the 100% one might expect. These developers ranged from 5 to 25 years of professional experience, and the more-experienced developers did not do better (!). ... these results clearly suggest that precedence rules may harm, instead of help, the process of developing correct code."
It is, and infix notations have been added many times, going back at least to Vaughan Pratt's CGOL in the 1970s. Yet none of these notations have ever caught on very much among Lisp programmers.
I understand that the syntax is a barrier to newcomers, but there's no point in arguing that it should be changed, because one really does get used to it, and even to like it. You might as well tell the Mexicans (or Indians, or Thai, or Chinese, etc.) not to make their food so spicy. Yes, it takes some getting used to, but to change it would be to ruin it.
I feel like this helped me understand the power of "everything is/as a function" to the point of wanting to go back and try lisp again.
Sibling post suggest making Python-esq DSL on top of lisp, and I really like that idea.
Julia-lang: Hold my beer. [1]
[1] https://docs.julialang.org/en/latest/devdocs/ast/#Surface-sy...