On Scheme

Thoughts on Scheme and teaching Scheme

Improving Lisp Syntax Is Harder Than It Looks

Posted by Peter on March 17, 2006

One of the biggest complaints I hear (by biggest I mean most often) is that Lisp syntax is ugly. One common issue is that people from a mathematical background would like to invoke functions as name(parameters) instead of (name parameters). This kind of change wouldn’t be hard to make, and yet few lisp versions, except some of the very early variants and TwinLisp implement it.

The real motivation for leaving Lisp syntax as it is comes from macros. Under the current syntax macros can treat the code as a series of nested lists, which makes it easy to write intuitive looking macro expansions, for example if a macro expands into '(display "text") it is pretty obvious what it does. Although in theory you could keep this macro system with a new Lisp syntax it would look strange, and basically force users of the language to know both the old syntax and the new syntax. Thus we would expect the macros to read in the function call under this kind of syntax as some new kind of object, with one operation returning the function symbol, and another operation returning the list of parameters. Thus a macro expansion would have to look something like this: build-call('display '("text")). Not only does this expansion fail to visually look the same it also is much more complicated. One could try to get around this by altering the quasiquote operator, as in TwinLisp, so that the expansion becomes `display("text"), but then we have sacrificed the simplicity of the quasiquote, which no longer operates on lists. No matter how you solve the problem you end up in a bit of a bind.

Another disadvantage to this change of syntax is that it makes functional programming much more odd looking. Lets say you have a list containing functions and you want to call the first one. In Scheme you write ((car lst) params) and in Common Lisp (funcall (car lst) params). However in our new syntax it looks like: car(lst)(params) and funcall(car(lst) (params)). Neither of these is very elegant, and it only gets worse if that call in turn returns a function, which would look like: car(lst)(params)(params2) and funcall(funcall(car(lst) (params)) (params2)).

So changing lisp’s syntax, at least to make it more conventional in terms of function calls, is not really a win, although the average cases look slightly more “normal” more complicated operations become more convoluted. Of course that doesn’t necessarily mean that we can’t improve Lisp’s syntax at all, in a future post I will discuss the benefits and disadvantages of adding a block structure to Lisp (as proposed in Arc, TwinLisp, ect).

6 Responses to “Improving Lisp Syntax Is Harder Than It Looks”

  1. I cannot agree with the following:
    “””
    One could try to get around this by altering the quasiquote operator, as in TwinLisp, so that the expansion becomes `display(“text”), but then we have sacrificed the simplicity of the quasiquote, which no longer operates on lists.
    “””

    Quoting works in TwinLisp just like it in lisp. Let’s do an example with a backquote:

    $ tlisp
    TwinLisp interpreter.
    Typing “Ctrl-D” or “exit” quits interpreter.
    >>> a=1

    1
    >>> `~(a,b,$a)

    (A B 1)
    >>>

    So, quotes act on lists *exactly* like in lisp, because all expansions of quotes are performed by lisp itself (CLisp in our example). It amazes me how much of lisp can be left the same while introducing a syntax.

  2. In reply to
    “””
    Another disadvantage to this change of syntax is that it makes functional programming much more odd looking. Lets say you have a list containing functions and you want to call the first one. In Scheme you write ((car lst) params) and in Common Lisp (funcall (car lst) params). However in our new syntax it looks like: car(lst)(params) and funcall(car(lst) (params)). Neither of these is very elegant, and it only gets worse if that call in turn returns a function, which would look like: car(lst)(params)(params2) and funcall(funcall(car(lst) (params)) (params2)).
    “””

    Want to give TwinLisp version of (funcall (car lst) params). Here it is:

    lst.car().funcall(params)

    and with further funcall, if the first one returns a function:

    lst.car().funcall(params).funcall(params2)

    TwinLisp gives flexibility (choice) to write the same thing almost as you showed it above:
    funcall(funcall(car(lst),params),params2)

  3. Main problem with f(x) syntax is that it is unnatural if it represents the list which is not meant to be function call. For example 1(2,3,4) is really odd. And of course, compiler cannot know whether some list is meant to be function call, or it is just list.

  4. I agree that improving Lisp syntax is harder than it looks, but I think it’s possible. And I think the “problems” you note above are solveable or not really problems. Take a peek at our work on http://readable.sourceforge.net – we’ve got an approach towards readable Lisp that makes things better. If you’re interested, please join us!

    • that absolutely verifies to me what I was thinking about how clear syntax is often personal.. see that looks confusing to me, lisp is confusing to me, but removing brackets and then adding braces to get around the problem caused is more confusing looking to me.

      so you have basically removed what made lisp look interesting, so no function inside the (function x)… so u made it f(x) same as most people… that’s the standard c thinking and might miss the whole point of the syntax…

      your function, like python has no outer enclosing, but your “if” statement does have {}….. okay if and functions should look the same this is sort of given… why would functions an ifs require different parenthesis

      also you use braces for the ifs check… okay so curious do you have a = or == cos that is bloody confusing, having input in {}, and not () for absolutely no reason

      so I think my final diagnosis is you want IFs and Functions one to look like one language one like another

  5. Natalie said

    I was just looking at your Improving Lisp Syntax Is Harder Than It Looks « On Scheme site and see that your website has the potential to become very popular. I just want to tell you, In case you didn’t already know… There is a website service which already has more than 16 million users, and the majority of the users are looking for websites like yours. By getting your site on this network you have a chance to get your site more visitors than you can imagine. It is free to sign up and you can find out more about it here: http://mariowelte.de/26zz – Now, let me ask you… Do you need your website to be successful to maintain your way of life? Do you need targeted traffic who are interested in the services and products you offer? Are looking for exposure, to increase sales, and to quickly develop awareness for your website? If your answer is YES, you can achieve these things only if you get your website on the network I am describing. This traffic network advertises you to thousands, while also giving you a chance to test the network before paying anything. All the popular websites are using this service to boost their traffic and ad revenue! Why aren’t you? And what is better than traffic? It’s recurring traffic! That’s how running a successful site works… Here’s to your success! Read more here: http://i7n.co/249si

Leave a comment