Speculative Problems

Jean-Philippe Paradis tweeted the perfect answer to those who complain about “problems” with Lisp syntax. The tweet was apparently provoked by this post from John Cook that, while discussing symbols in programming languages, remarked that “Lisp’s typographical monotony makes it hard to skim for landmarks.” Paradis' tweet makes the point that supposed problems with s-expressions are speculative in that they tend to disappear once one becomes familiar with the syntax.

I'm with Paradis on this. Certainly Lisp has fewer symbols than APL and arguably fewer than Perl but I don't find it anymore typographically monotonous than, say, C, C++, Python or most of the other mainstream languages. I certainly don't have any more problem scanning it than I do the others. I think Paradis is exactly right: once you use it for a little while, the syntax or lack of it just disappears into the background.

What do the rest of you find? Do you think Lisp is typographically monotonous? If so, does that make it hard to scan for you? I don't think so but Cook, who is not a stranger to Lisp, seems to believe it is. Share your experience in the comments.

This entry was posted in General and tagged , . Bookmark the permalink.
  • http://xahlee.info/ Xah Lee

    yeah, i also think it's a problem. I think there are 2 opposite aspects, and whichever side one stands, there's a logical conclusion that lisp syntax have certain problem.

    first is the monotonic syntax problem. Nature isn't monotone, and i don't think we handle it well. You and other lispers believe it isn't a problem at all once used to, but i find it a problem, namely, not as good as if it had more syntax variations. (and i think quite a few lispers are on this side too. Many expert Common lispers expressed this criticism, as well as in discussion when Dylan switched to algor-like syntax.) One supporting evidence of this idea is that there are lots modes to help with the lisp syntax, yet they are almost hard to use, and semi-solutions, doesn't work well, and adopted only minor percentage of lisp coders. For example, the coloring paren mode, the paredit mode. Lisp syntax, given its regular nature, we really should have automatic formatter builtin, or real semantic based editor. I understand some editor has some of that feature to various degrees (hemlock, Climacs, Edwin, ...?), but not gnu emacs.

    the other aspect, which i haven't seen much mention, is that the lisp syntax isn't regular. The syntax for quote, the dot notation for cons pair, the comment syntax, the macro syntax. In my opinion, if we abide 100% regular lisp nested parens, it would make the language much more powerful, in the sense of macros but more importantly, the long-term direction of growth. If lisp syntax were 100% regular, i surmise that we would have automatic formatter or sematic-based editor long ago.

    • http://irreal.org jcs

      Thanks for your comments, Xah. I have to say that I don't get this "typographical monotony" thing. How is

      for (i=0; i<10; i++)
      a[i] = a[i] + i;

      less monotonous than

      (dotimes (i 10)
      (setf a (+ i (aref a))))
      Perhaps you could argue that the typical mapcar expression has a more uniform skyline than the corresponding, say, C statements but it's still a win because it expresses the whole operation in a single expression whose meaning is instantaneously recognizable.

      Many of the apparent irregularities in Lisp are really just shortcuts to save typing. For example '(a b c) is just a shortcut for (quote a b c). Similarly ("a" . 2) is just a handy way of setting a cons cell and could just as easily be written (cons "a" 2). One thing for sure, Lisp's syntax (or rather lack of it) is far more regular than most other languages. Part of what really makes programming hard for beginners is learning the syntax of the language.

      • http://xahlee.info/ Xah Lee

        hey Jon. I love to argue, and thanks for the post on this issue. Our opinions may differ, but i enjoy the discussion/argumentation.

        about the monotonic quality aspect you gave example of, the lisp case is harder to read. ( but am no fan of C-like syntax either, which is mostly syntax soup (between the two, i rather favor lisp syntax)) The example you gave is small, but when in large quantity, as in real world source code, i think the effect is there.
        e.g. this classic example:

        (-b + sqrt(b^2 - 4 * a * c))/(2*a)


        (/ (+ (- b) (sqrt (+ (^ b 2) (- (* 4 a c))))) (* 2 a))

        this is a artificial example, and involves math formula. But in my experience, the argument in this example applies to general lisp code.

        but then, one may argue that one should indent the code and it become even better than the infix. But that argument by itself indicates a weak quality of lisp syntax. Namely, it requires xyz, while the other syntax don't.

        about the irregularity of lisp code, i can't see how you are in favor of it. It seems a contradition of stance. If lisp touts its regularity of syntax, in its benefit of macros, it should go all the way.

        • http://www.hexstreamsoft.com/ Jean-Philippe Paradis

          (First time I tried posting this I got an error. Refreshing the page didn't show my comment so I tried posting it again, this time it said I "already posted that". Apologies in advance for any duplicates.)

          but then, one may argue that one should indent the code and it become even better than the infix. But that argument by itself indicates a weak quality of lisp syntax. Namely, it requires xyz, while the other syntax don’t.

          That's bullshit. Almost all computer language syntaxes REQUIRE at least some indentation to be properly human-readable beyond short samples.

          I won't recapitulate all the advantages of s-expressions here, but the lack of need for screwed up "precedence rules" is a notable advantage of prefix syntax for mathematical expressions.

  • http://foolsmate.net Alex Chamberlain

    (I tried posting this yesterday but didn't see it, so apologies if this is a double post.)

    I have to agree with Jean-Phillipe on both points. Xah's example of the quadratic formula is a bit of a straw man. I have no problem reading the Lisp version with prefix operators (probably due to a lifetime of using RPN on HP calculators). The benefits of Polish notation for easy parsing are well-known.

    But you'd never write a sexp like that (all on one line) in actual Lisp code; you'd indent it to show structure, just as C code is indented by convention even though its semantics are fully specified by non-whitespace delimiters (the curly braces, square brackets, etc.). If there's any proposal to improve the syntax of Lisp that makes sense IMHO, it's not the ones that call for adding more and varied punctuation--it's the proposal to get rid of parens and make whitespace semantically meaningful as in Python!

    • http://blog.puercopop.com Javier Olaechea

      On a sidenote: Python's whitespace doesn't allow for a readable anonymous functions.

    • Guest

      Just making whitespace significant isn't sufficient to make the language more readable. It's necessary, but not sufficient.

      In Python (oversimplifying slightly):

      * Whitespace is only significant to statements, not expressions. But there is a clear divide between statements and expressions.

      * Everything about the language and its stdlib is designed such that mutation almost always happens only once per statement, and only to the leftmost thing in the statement (the variable before the "=", or the object before the ".mutating_method()"). And the cult of pythonicity means that most third-party code follows the same idioms as the stdlib, so using third-party code preserves that property.

      * Various features and limitations of the language discourage you from writing too-complex expressions, from the simplicity and efficiency of transforming a list via a chain of "new_vals = (expr_with val for val in old_vals)" statements, to the fact that inline (lambda) functions can't contain statements.

      Put that all together, and the vertical flow and indentation of the program carry a lot of information, which you can pick up almost instinctively by skimming. Take all those away, and the significant whitespace provides a lot less benefit. (Sure, it gets rid of a bit of clutter from {} or BEGIN/END, and it means that the rare misleading-indentation bugs are easier to debug because they're syntax errors, but neither of those is a huge win.)

      There is probably a way to make significant whitespace work for expression-only languages and/or purely-immutable languages. As far as I know, nobody's yet come up with anything nearly as nice as Python, but I suspect that's just because not enough people have tried.

      Also, of course, Python got where it was largely by Guido's instincts (he can't explain any of the stuff above, but some part of him clearly knows it), partly by accident (nobody realized that generator expressions would allow a new style of programming until a couple years after they were added), and only a tiny amount by actually planning. Nowadays, people understand things better, at least within the Python community--changes between 3.5 and 3.6 are discussed much differently than those between 2.1 and 2.2, and people will argue about how a proposal would affect the flow of the source code, etc. Someone just needs to distill the right information into the right lessons. (Or someone needs to be as instinctive and/or lucky as Guido.)

      But someone should try. Whether by starting from Dylan or ML and figuring out how to Pythonize it, or by starting from Python and figuring out how to pure-functionalize it, or by starting from scratch.