August 3rd, 2024

Ask HN: Why do people say "Lisp has no syntax"? It has infinite syntax

The author discusses Lisp's syntax, highlighting its list-based structure and challenges with constructs like `cond`. They conclude that Lisp's complexity resembles other languages, despite its unique features.

Ask HN: Why do people say "Lisp has no syntax"? It has infinite syntax

The author reflects on the common belief that Lisp has no syntax, suggesting instead that its syntax is based on list expressions where the first element is a function and the rest are arguments. They describe their experience creating a Lisp-like language, initially using recursive descent parsing to interpret expressions. This method works well for basic function calls but raises challenges when introducing conditionals, such as the `cond` construct. The author notes that treating `cond` as a function is problematic because it does not behave consistently with the function definition; it evaluates conditions until one is true, which can lead to the same output for different inputs. This realization leads to the conclusion that while Lisp has a uniform structure of list expressions, the internal rules governing those expressions are varied and complex. The introduction of macros and reader macros further complicates the syntax, allowing for a broader range of expressions beyond simple list structures. Ultimately, the author feels that this understanding diminishes the perceived uniqueness of Lisp, likening it to other programming languages with multiple syntax rules. They express a continued appreciation for Lisp but acknowledge that practical computation requires deviating from the simple (function args) syntax, suggesting that only a pure lambda calculus could maintain such uniformity.

Link Icon 4 comments
By @al2o3cr - 6 months

    `cond` still returns the same output even though its input args 
    have changed. So `cond` is not a function anymore!
It sounds like you're holding the definition of "pure function" backwards: a pure function can't give a different OUTPUT for the same INPUT.

A feature like "cond" is usually implemented as a macro (since the arguments are only evaluated sometimes) but that's ultimately just a shorthand for a bunch of extra "quote" wrapping.

By @lispm - 6 months
> But this means that `cond` is not a function anymore because it could be that > A popular notion is that Lisp has no syntax. People also say Lisp's syntax is just the one rule: everything is a list expression whose first element is the function/operator and the rest are its args.

That's wrong. Lisp has functions, special operators (like IF) and macros. Also any data-object is also valid Lisp.

Valid Lisp examples:

    3          -> number
    "string"   ->
    hello      -> variable
    (print "hello world")  -> function call
special forms

    (if (> a 10) 1 0)      -> no more than three args,
                              arg 2 & 3 are evaluated depending on first argument value

    (let ((var1 20)        -> definition of local variables
          (var2 22))
      (+ var1 var2))

    (quote hello)          -> definition of a literal object
macros

    (defun foo (arg1 arg2)       -> defun is macro, which defines global functions
      (if (> arg1 arg2)
          1
          0))
> But this means that `cond` is not a function anymore because it could be that for two different inputs, it returns the same output.

A function can return the same output for different inputs.

    (defun foo (args)
      0)
Above returns 0 for all arguments. It's a valid function.

> So essentially, my understanding so far is that Lisp has list expressions, but what goes on inside those expressions is not necessarily following one unifying syntax rule—it actually follows many rules. And things get more complicated when we throw macros in the mix: Now we have the ability to have literally any syntax within the confines of the list expressions, infinite syntax!

That's true.

By @ofalkaed - 6 months
How I understand it is that Lisp has syntax but lacks a grammar, the syntax is just very simple. Essentially the same as Forth and Tcl, everything is either a command or data, a result of the simple single pass left right parsing. But I am not completely sure I have things right just yet.

Edit: What I am saying is that in lisp '(' is actually a command and everything after it is an argument to that command. The syntax is command - arguments; this is what gives these languages their power, the simple syntax and lack of grammar allows us to define our own grammar. Hopefully someone will correct me if I misunderstand, I could be seeing Tcl and Forth everywhere since I have been primarily working with them lately.

By @Tomte - 6 months
You‘re utterly confusing parsing and evaluation.