ThoughtStorms Wiki

Context: LispLanguage

Quora Answer : What are some things that LISP programmers know, but others don't?

Feb 1, 2016

The cost of syntax.

If you're a non Lisp programmer (and I was, for many years) then you tend to judge syntax on a number of aesthetic and practical criteria. Can I understand it? Is it elegant? Is it concise? Readable? Beautiful?

You can certainly cultivate "good taste" in syntax. And your taste will probably develop over time. But you won't question the necessity of syntax. And Lisp's claim to be without syntax will look nonsensical.

To an extent, of course, Lisp DOES have syntax. But when you accustom to Lisp's minimal syntax you suddenly get the point. Syntax, even the nicest, is lumpy and indigestible. Lisp's syntax is maximally homogenized. So that everything looks and works the same. What this means is that it's "compressible". Any regularity in any part of your program can be factored out to eliminate redundancy. Either as a straight function or a higher order function or a macro, etc.

This goes hand-in-hand with homoiconicity. People tend to talk about how homoiconicity makes it easier for the program to operate on itself. And it does. But more than that, it makes your program a kind of self-executing data-structure.

Other programming languages, even FP ones, you feel that you are writing code that's pushing and pulling data-around, laboriously pounding and kneading it into the shape you want. A Lisp program, OTOH, often feels like you are in a declarative language, like HTML, simply telling the computer the shape you want your final data to be.

For example, Python programmers may be familiar with comprehensions. Eg. to get the first ten square numbers :

[x*x for x in range(10)]

They know that this is code in the shape of a data-structure. It can be dropped in to a context as if it were a data-structure :

for y in [x*x for x in range(10)] :


But outside this special case, you are back to laboriously pushing the data around again. Whereas in Lisp, it's often the case that ALL of your program is like this. Just larger and larger declarations of data-structures whose values are calculated from embedded snippets of code

A web-page may contain a header, a two column template, of which one is the main body text and the side-bar contains social tools like chat, updates, etc.

In Lisp, such a page-generation program would look very like the page it's trying to assemble.

(make-page (header)
      (list (main-body item))
         (list (contact-list (id user)) 
         (latest-news date (id user)))
       ) )

Declaring the function to make a page like that is nothing more than wrapping it in a function-making structure.

(defn main-page [user] 
   (make-page (header)
         (list (main-body (latest-item user)))
           (list (contact-list (id user))
           (latest-news date (id user)) ))))

Your program can continue to get bigger and more complex but it never seems to lose its isomorphism with the data-structures you actually want out of it. Once you get used to this, all other syntaxes, however nice they look, start to look like awkward obstacles, getting in the way of expressing your application as nothing but a declaration of the structure you want as your final result.