4 ms·
Lisp syntax is pretty rough if you want to prioritize maintainability. I can look at blurry C code and know generally what things are and what’s going on witho
by jimbob45 4y ago
Lisp syntax is pretty rough if you want to prioritize maintainability. I can look at blurry C code and know generally what things are and what’s going on without a single character being legible. Lisps don’t typically have the same convenience. Given that code maintenance is usually about poring through thousands of lines of code quickly, I’d say this is a significant advantage for C.
However, Lisps have unparalleled macro flexibility. It’s a clear trade-off that Lispers often have trouble admitting is a trade-off.
- deleted 4y ago[deleted]
- xscott 4y ago> I can look at blurry C code [...] I'm kind of curious how much of this is the problem with parens, and how much of this is the conventions that Lisp programmers seem to mostly adopt. For instance, here's the concise 99-bottles from Rosetta Code for Racket: (define (sing bottles) (define (plural n) (~a n " bottle" (if (= n 1) "" "s"))) (printf "~a of beer on the wall\n~a of beer\n~ Take one down, pass it around\n~a of beer on the wall\n\n" (plural bottles) (plural bottles) (plural (sub1 bottles))) (unless (= 1 bottles) (sing (sub1 bottles)))) (sing 99) And even with a snippet this short, it's not quick for me to scan. Lispers generally like hanging parens, the indentation varies depending on what construct you're in, and that example uses recursion instead of a for-loop [0]. Ok, so let's turn the concise Python one into a hypothetical Lisp: (for i in (range 99 0 -1) (let b = "bottles of beer") (let w = "{b} on the wall") (print "{i} {w}, {i} {b}\n") (print "Take one down and pass it around, {(- i 1)} {w}.\n") ) I think you could "know generally what things are" with that version even if it was blurry. And of course, this "hypothetical lisp" is legal Racket/Scheme after implementing a few macros. [0] I know Racket has for loops, but they didn't choose to use them in that example. Which is my point.
- deleted 4y ago[deleted]
- kazinator 4y agoMore or less idiomatic TXR Lisp: 1> (defun bottles-verse (n) (flet ((bottles (:match) ((0) "No bottles") ((1) "1 bottle") ((@x) `@x bottles`))) (put-line `@(bottles n) of beer on the wall\n\ @(bottles n) of beer\n\ Take one down; pass it around\n\ @(bottles (pred n)) of beer on the wall\n`))) bottles-verse 2> [mapdo bottles-verse 5..1] 4 bottles of beer on the wall 4 bottles of beer Take one down; pass it around 3 bottles of beer on the wall 3 bottles of beer on the wall 3 bottles of beer Take one down; pass it around 2 bottles of beer on the wall 2 bottles of beer on the wall 2 bottles of beer Take one down; pass it around 1 bottle of beer on the wall 1 bottle of beer on the wall 1 bottle of beer Take one down; pass it around No bottles of beer on the wall nil 3> Why does 5..1 go from 4 to 1? Because 1..5 goes from 1 to 4; it's a half-open interval. 5..1 goes over the same values in reverse. :match is a "parameter list macro", which is something I invented. flet knows nothing about pattern matching; it transforms to a lambda, which also knows nothing about pattern matching, but :match takes the parameter list and body, transforming the code using the pattern expander logic. String literals and quasiliterals can go across multiple lines, but with the permission granted by a continuing backslash. Being explicit about this lets us catch errors when a literal is left open accidentally. All unescaped whitespace before a continuing backslash, and leading whitespace at the start of the next line is deleted: "abcd \ efgh" -> "abcdefgh" "abcd \ \ efgh" -> "abcd efgh" ;; escaped space counts "abcd\ \ efgh" -> "abcd efgh" ;; on either side of \
- xscott 4y agoI think I must be really bad at communicating, because you aren't responding to any point I was trying to make. Let me try again :-) I think Racket, Scheme, and some Lisps are conceptually elegant, but they don't read well to people like me (or apparently the poster above). In particular, your snippet of code has 3 different indentation strategies, and you hang your closing parens the way almost all Lisp programmers do. To me, it all looks so organic and arbitrary. So, for those of us who don't like to read other people's Lisp - is it because of the parens? Or is it because the conventional Lisp style is alienating to us? I really think it's the style. I'd rather read your example like: (defun bottles-verse (n) (flet ((bottles (:match) ((0) "No bottles") ((1) "1 bottle") ((@x) `@x bottles`) )) (put-line `@(bottles n) of beer on the wall\n\ @(bottles n) of beer\n\ Take one down; pass it around\n\ @(bottles (pred n)) of beer on the wall\n` ) ) ) That's still not quite as nice as I'd like, but maybe you can see where I'm coming from. I think most Lispers would say, "You get used to it." But, well we don't get used to it because we just stay with whatever our curly braced or indentation language is instead.