> That is exactly what a simple AST is: A tree structure representing the semantics of the code you wrote with no syntax info.

That what I say: the s-expression does not represent the semantics. It does not know much about Lisp: no syntax and no semantics. It mainly uses similar data structures for the code: lists, symbols, numbers, etc.

See this for an AST: https://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Ab...

In Lisp the s-expression does not say that 'a' is a variable name. We don't know that '>' is a compare op.

(+ 1 a) would be written as an AST maybe like:

(function-call :operator (built-in-variadic-function cl:+)
:arguments ((numeric-constant 1)
(variable a)))

> As I said above, macros accept runtime data.

No, macros are also expanded before runtime.

> Macros are runtime code executed during the parser stage.

The s-expression is unparsed. The macro has to do the parsing.

> Other languages execute macros the same way.

No, in most languages macros get an AST, where syntax is represented and pre-parsed. For example the macro gets pre-parsed code, where the syntactic categories are determined. + is an operator. In Lisp + is just a symbol and that is no specific syntactic category. Thus most macro systems in languages, the code is pre-parsed and the result is given to the macro expansion. That means a use of the identifier + is an infix function. Not so in Lisp. + is just a symbol and we don't know yet what it is: data, operator, variable, lexical variable, etc.

> You can define different semantics to the same S-expression.

And also syntax. (+ + +) -> is that postfix, prefix or infix? Lisp does have prefix syntax, but the macro can assume anything.

> However for the S-expression to be interpreted as Lisp you need to use the Lisp semantics to run it.

And the syntax.

> A typical AST for Lisp would have the following semantics categories:
List, Symbol, Integer, Float, String.

That does not describe Lisp, that describes S-expressions. S-expressions are not Lisp, they are just a syntax for data. The Lisp program has simply a different notation in the form of s-expressions, but no syntactically or semantically representation. An AST would be already representing syntactical information like the syntactical categories of the identifiers present.

1 + 1 is just another notation, like (+ 1 1) is another one. It's not yet the a new quality. The main difference is that in the case of Lisp, s-expressions are backed by a simple data structure, nested lists, which provides some hierarchy, but no representation of syntax. I would think of it as a token tree output of some kind of lexer.

If I have (let ((a (+ b 10))) (* a b)), then in Lisp LET is a special operator, A is a lexical variable, b is a variable, 10 is an integer constant, * is a built-in function, etc.

The syntax for above LET is:

let ({var | (var [init-form])}*) declaration* form*

> That’s exactly what I mean when I say that the Lisp syntax directly represents the AST. And no other language does. That is the one feature that makes Lisp unique.

Yeah, but that's wrong. The Lisp syntax is on top of s-expressions. You seem to believe that s-expressions represent Lisp syntax. They can't s-expressions is a format to represent data, not a specific programming language. Thus they have no idea of syntactic categories or anything like the information which would be in an Abstract Syntax Tree.