← Back to context

Comment by shasta

15 years ago

Or the explanation could be that Lisp just isn't that great. First of all, it doesn't even make much sense to talk about "Lisp" as if it's a language. The difference between the toy lisp you can write an interpreter for in a page of code and Clojure is night and day. And the other features are actually much more important than just being a Lisp. I'd be afraid to work with the "Haskell" that the smug Lisper of the article slaps out with macros. Not only would it probably not be as well designed as Haskell, unless they copied Haskell's hard work wholesale, but it wouldn't interop well with any other Lisp code.

Secondly, if you actually look at the defining feature of Lisp, S-Exprs and macros, it's not a good idea. Code generating S-exprssions may be more sane than generating C code through string manipulation, but it's still a bad idea and for the same reasons. Code is a human readable format (even if you force it to be S-expressions and pretend it isn't). Code shouldn't be generating other code, it should be generating more structured values. There are composability advantages to doing so and as an added benefit, you don't get stuck with S-expressions as syntax. I predict that in the not too distant future, languages will provide a better alternative to almost every current use of macros (we're already over half way there).

S-expressions are more readable than C-syntax to me. Readability is about familiarity.

The task of comparing English with Russian in terms of readability is not a clear task at all and it's hard to determine how such a judgement would be made.

I would argue that it's just as hard to genuinely judge the readability of S-expr vs. C-syntax.

People whose first language is in Russian obviously find the Cyrillic alphabet to be more readable and wonder why anyone would use anything else. To me Russian looks like scribbling.

  • Familiarity is probably the prime factor in readability. And it is indeed a subjective one.

    But there are also objective factors.

    Infix function application allows for easier visual parsing of the expression tree's components. There's a reason mathematicians have been using infix notation for centuries before we had arbitrary other constraints for choosing notation.

    In fact, if you look at mathematicians' notation, you will see that not only is it horizontally infix (arguments left and right of the function), it is also vertically infix, and arguments are placed above and below (Sigma, Integrals, etc.).

    • People have come up with many rationalizations, but really, anything that doesn't have a mostly C/Java-style syntax just pisses off the majority of programmers.

      When you look at languages that actually, consistently use infix and mathematical notation (http://nsl.com/k/ray/rayq.k), they seem to give most programmers fits.

      Infix also only really works for unary and binary operators, of course.

    • since 99.9% of every language is in prefix notation i cant buy this.

      when mathematicians type f(x,y) they are using prefix notations.

      likewise when programmers type run(x, y);

      Anecdotally, most advanced mathematicians prefer Lisp because it is more conducive to a mathematical way of thinking. I am a very mathematical programmer and I prefer lisp specifically because I don't have to deal with operator precedence. Everytime you use infix notation you introduce a bunch of unnecessary complexity and often you complicate the ability to use simple recursion.

      Gregory Chaitin, eminent mathematician, writes his proofs in Lisp for a reason.

      Is it truly easier to write

         print(a + " " + b + " " + c + " "); 
      

      rather than

         (print a " " b " " c " ")
      

      ?

      I greatly prefer the latter. The first one is weighed down with unnecessary special cases, unnecessary complexity.

      The benefits of Polish notation are apparent with math as well. You don't need to reformulate the entire calculation and figure out messy operator precedence rules when you want to add a term. I think RPN lends itself to bug free code and easy modifiability.

      To each his own I suppose. C-syntax to me is completely nonsensical and I don't see what problem it is meant to solve. I'm sure Russians view the Latin alphabet in the same way though.

      3 replies →

I think that you're the only person in this thread who openly questions the cheer-leading of Lisp. I respect that. For that, I gave you an upvote. Heretic.

Sure, the pile of Lisp macros that recapitulates most of Haskell would be gnarly and nasty. But would that be due to the intrinsic bogosity of doing it through macros, or would it be due to it coming from a lone hacker who's following the scratch-an-itch school of design?

Code is a human readable format (even if you force it to be S-expressions and pretend it isn't). Here's something for which there's no accounting, as the Romans used to say. Plenty of smart people love S-expressions. Plenty of smart people can't stand them. John McCarthy thought that S-expressions would go away, but no one got around to that in more than half a century. Someone must find them readable.

Code shouldn't be generating other code, it should be generating more structured values. You must know more than me. Something more structured than code?

  • I think the reason that S-expressions haven't gone away is mostly because of the way they mesh with macros, but anyway the sub-optimality of S-expressions as a syntax wasn't a part of my argument there (I don't like them, but I don't hate them). In that quote, I meant there that all code, even S-expressions, is a human readable expression that defines the thing you're interested in.

    Note that it's considered poor form in Lisp to make a square macro that multiplies its parameter by itself. That should be a function. Why? Because numbers have the structure you want them to have. A function that takes a number and multiplies it by itself is just simpler than a function that takes an expression for a number, and pastes it together with an astericks and then returns that to be evaluated. And because the function has a better structure than a macro, it's more composable.

    The thing is that this same situation exists with most other uses of macros. In a language with staged computation and maybe a little well tamed syntax extension, I think there would be no place for macros. You can do better.

  • "Sure, the pile of Lisp macros that recapitulates most of Haskell would be gnarly and nasty."

    I don't think you can macro your way to Haskell. Haskell wants a guarantee that if some function takes a function of type Int -> Int, the passed-in function will absolutely positively not do anything in the universe except take an int and return an int, and if that isn't true and that closure can do something else, Haskell breaks. Even if you can macro your way towards restricting arbitrary closures like that, you don't have Lisp anymore; you've got Haskell. Or you don't have Haskell and you do have Lisp. The two are fundamentally opposed at a deep philosophical level.

> Code shouldn't be generating other code, it should be generating more structured values.

How is code not a structured value? Do you mean that instead of some properly typed AST you only have lists, symbols etc?