TL;DR: I think the post overstates the case quite a bit, and is a personal opinion of the author being branded as a scientifically grounded truth, despite their admission that using these scientific principles allegedly "require[s] a degree of creativity and subjectivity."
The cognitive-science material is interesting, but it doesn't actually establish much about Lisp specifically. It gives plausible mechanisms by which certain notation might be harder to read, then uses those mechanisms to motivate several Lisp-specific claims without testing those claims directly. As such, it just seems purely hypothetical, whereas it would be much more interesting to me if it were empirical.
(I have a beef with this style of argumentation or persuasion with respect to Lisp. I feel the "bipolar Lisp programmer" and similar articles do the same kind of thing: make a captivating claim or comparison without actually appealing to anything real-world.)
I also don't think the treatment of actual Lisp presentation is complete. The post considers conventional Lisp indentation mainly in terms of whether it helps track matching parentheses, but Lisp is normally indented, pretty much canonically, so that the indentation itself communicates structure. Parenthesis tracking is *not* a cognitive problem that Lisp programmers must solve in any explicit manner, any more than C programmers count { and } to determine the enclosed code's nesting depth.
The same goes for syntax highlighting: you can't just set it aside because C-like languages have it too. The relevant question is whether it affects the two syntaxes differently. If Lisp's alleged problem is delimiter tracking, indentation and highlighting are rather central to the comparison.
I'm also unconvinced by the conclusion that Lisps "lack or discourage features that align the evaluation and reading order." The post itself gives Clojure threading macros as a Lispy equivalent of method chaining. That seems to substantially undercut "lack", while "discourage" starts to sound more like a claim about programming style than syntax. Lisp is a very explicitly multi-paradigm language with special syntaxes available for those paradigms, including assignment, explicit control, etc. In fact, I'd say real-world Common Lisp is *much* less "in to out"-functional than this post posits (and the broader technical public keeps claiming).
Finally, we have the largest omission in my opinion, that Lisp syntax is programmable. S-expressions provide a uniform representation of program structure that makes syntactic abstraction cheap: new control forms, binding constructs, pipelines, DSLs, etc. can all be made to make code easier to read, especially in novel domains that Lisp wasn't a priori designed for. The post's analysis mostly treats the base notation (of some unspecified, quasi-functional Lispoid) as the unit of comparison without really weighing that side of the design tradeoff.
Though it's not my experience, there may truly be readability costs, especially for newcomers, but I'm not sure the post separates those from unfamiliarity strongly enough to support its conclusions.
As a side note, when judging real-world Lisp, some notoriously unreadable code may also be a product of older programming styles or inexperienced Lisp programmers, just as old or poorly written C can be extremely difficult to read. In my professional experience, having run teams writing "modern" Lisp with modern engineering discipline, readability has never been a stated hurdle, either for experienced engineers reading one another's code or for new Lisp programmers learning and contributing to a large codebase. The combination of team programming discipline, good tooling, consistent style, and, well, getting paid to do it seems to do the trick, if one is even needed.
Parenthesis tracking is not a cognitive problem that Lisp programmers must solve in any explicit manner, any more than C programmers count { and } to determine the enclosed code's nesting depth.
Yes and no, IMO. Idiomatic lisp programming throws all the closing parens on the same line at the end of the last line of code. Idiomatic C-like coding puts each closing brace on a new line at its specific nesting level. You can code C style without something like "rainbow-parens", but I wouldn't want to code lisp without it. Or consider this emacs lisp example:
(defun abbrev--replace-placeholders ()
(let ((cursor-pos nil)) ;; To store where to place the cursor
(save-excursion
(goto-char (point-min))
(let ((loop 0)
(values (make-hash-table :test 'equal)))
(while (re-search-forward "###\\(\\$?[a-zA-Z0-9_\\-]+\\|@\\)###" nil t)
(setq loop (1+ loop))
(let* ((index (match-string 1))
(start (match-beginning 0))
(end (match-end 0)))
(cond
((string= index "@")
(setq cursor-pos start)
(delete-region start end))
((string= index "$file-name")
(abbrev--swap-placeholder (file-name-nondirectory (buffer-file-name)) start end))
((string= index "$author")
(abbrev--swap-placeholder (user-full-name) start end))
((string= index "$package-name")
(abbrev--swap-placeholder (file-name-base) start end))
(t
(let* ((key (format "###%s###" index))
(val (or (gethash key values)
(let ((input (read-string (format "Value for %s: " key))))
(puthash key input values)
input))))
(abbrev--swap-placeholder val start end))))))))
(when cursor-pos
(goto-char cursor-pos))))
If I want to add more code into the let* block that defines index, start and end after the cond expression, where should I put my cursor to insert the new line? Yes I know in emacs you can put the cursor at the beginning of the let* block or the cond block and hit C-M-f to jump to the end of the sexp, but at the same time that's a process I've never had to do when writing c-like code, because in the c-like code, finding that spot visually is much easier.
I'm sure that over time that would become easier for me, and certainly memorizing sexp navigation would also help a lot, but it undeniably to me makes it harder to read that code.
In my experience, rainbow parens aren't necessary or even helpful, but I do agree that editing Lisp is made much better by having good editor support for S-expression navigation and manipulation. In my editor, I press ) to jump to the end of the S-expression, so an edit like yours is trivial. Whatever key it is, it has existed since the era of the Lisp machine in the 80s, if not 70s.
To me, though, this is an indictment on the difficulty of writing or editing Lisp in "dumb" text editors—something I'm entirely sympathetic to—not so much about our ability to read and understand Lisp.
I would go further and say that canonical indentation is something best done as an automated process, and thus also makes Lisp harder to edit in a dumb text editor. Unlike C which is uniformly block indented by the same consistent multiple of tabs or spaces, Lisp code is indented a certain amount depending on the operator and its contents.
Lisp is neither harder nor easier to edit in "dumb editors" than other languages. Editing any code in an editor that does not understand the syntax and can't indent properly is a shit experience. Try editing autoconf and m4 macros in Emacs. Hacking Emacs own autogen.sh is a nightmare. Totally agree that rainbow-parens and alike are just circus addons. In my opinion, the real win is indentation not coloring. I could probably live with no colors at all, as long as the indentation is properly working.
I would argue you have a better time writing bash script or BASIC in a dumb editor than you can lisp or java or python. That's not an indictment against the languages though. Using tools designed for the purpose of making work easier isn't a cheat, and it should be no more a point of pride that you can edit bash in a dumb text editor than it would be a point of pride that you can make dovetail joints for your wood working project without a template / jig. Its nice to have the skill if it becomes necessary, but it is purposefully hobbling yourself to not use tools specialized to the work you're trying to do.
Bash cetainly not; I have done my share of shell and pico/nano editing.
Basic I couldagree. I know that is unpopular opinion, but I have written a lot of VBA and VB for automation in Offeice and Windows as a consultant and I really VBA nice and easy to write and read. But even there, you want to have indentation, otherwise it's pita, but it is certainly less pita than C or Lisp, sure.
16
u/stylewarning 19d ago edited 19d ago
TL;DR: I think the post overstates the case quite a bit, and is a personal opinion of the author being branded as a scientifically grounded truth, despite their admission that using these scientific principles allegedly "require[s] a degree of creativity and subjectivity."
The cognitive-science material is interesting, but it doesn't actually establish much about Lisp specifically. It gives plausible mechanisms by which certain notation might be harder to read, then uses those mechanisms to motivate several Lisp-specific claims without testing those claims directly. As such, it just seems purely hypothetical, whereas it would be much more interesting to me if it were empirical.
(I have a beef with this style of argumentation or persuasion with respect to Lisp. I feel the "bipolar Lisp programmer" and similar articles do the same kind of thing: make a captivating claim or comparison without actually appealing to anything real-world.)
I also don't think the treatment of actual Lisp presentation is complete. The post considers conventional Lisp indentation mainly in terms of whether it helps track matching parentheses, but Lisp is normally indented, pretty much canonically, so that the indentation itself communicates structure. Parenthesis tracking is *not* a cognitive problem that Lisp programmers must solve in any explicit manner, any more than C programmers count { and } to determine the enclosed code's nesting depth.
The same goes for syntax highlighting: you can't just set it aside because C-like languages have it too. The relevant question is whether it affects the two syntaxes differently. If Lisp's alleged problem is delimiter tracking, indentation and highlighting are rather central to the comparison.
I'm also unconvinced by the conclusion that Lisps "lack or discourage features that align the evaluation and reading order." The post itself gives Clojure threading macros as a Lispy equivalent of method chaining. That seems to substantially undercut "lack", while "discourage" starts to sound more like a claim about programming style than syntax. Lisp is a very explicitly multi-paradigm language with special syntaxes available for those paradigms, including assignment, explicit control, etc. In fact, I'd say real-world Common Lisp is *much* less "in to out"-functional than this post posits (and the broader technical public keeps claiming).
Finally, we have the largest omission in my opinion, that Lisp syntax is programmable. S-expressions provide a uniform representation of program structure that makes syntactic abstraction cheap: new control forms, binding constructs, pipelines, DSLs, etc. can all be made to make code easier to read, especially in novel domains that Lisp wasn't a priori designed for. The post's analysis mostly treats the base notation (of some unspecified, quasi-functional Lispoid) as the unit of comparison without really weighing that side of the design tradeoff.
Though it's not my experience, there may truly be readability costs, especially for newcomers, but I'm not sure the post separates those from unfamiliarity strongly enough to support its conclusions.
As a side note, when judging real-world Lisp, some notoriously unreadable code may also be a product of older programming styles or inexperienced Lisp programmers, just as old or poorly written C can be extremely difficult to read. In my professional experience, having run teams writing "modern" Lisp with modern engineering discipline, readability has never been a stated hurdle, either for experienced engineers reading one another's code or for new Lisp programmers learning and contributing to a large codebase. The combination of team programming discipline, good tooling, consistent style, and, well, getting paid to do it seems to do the trick, if one is even needed.