4 ms·
But those are lists of args. The macros happens to be processing the lists in a non-linear way, but they're still just lists.
by eurleif 3y ago
But those are lists of args. The macros happens to be processing the lists in a non-linear way, but they're still just lists.
- lispm 3y agoMost people assume that args are restricted to Lisp syntax and that args are evaluated, like in function calls. But inside a macro form this is not the case: the macro can implement a whole new syntax and semantic -> then to say the enclosed items are 'args' is misleading: it's source code in a new sublanguage with a different syntax/semantics. Technically the macro gets called with arguments, but only as part of the process of code transformation. For the user there can be a different syntax and semantics. The enclosed code then may have a different syntax where the (operator . args) syntax is extended or no longer used. That also means that the simple (foo . args) pattern is now no longer valid inside the macro form and analyzing the source code of a macro form can be arbitrarily complex. > The macros happens to be processing the lists in a non-linear way Macros are code transformers. They get code as lists and return new code as a list. This generated code then is evaluated. Different from functions, macros are not processing normal arguments and returning an evaluation result, but they are code transformers. The resulting transformed code is then run and it returns a value. Thus we have two (interleaved) phases of execution, instead of one: * the code transformation phase * the evaluation of the code
- StackOverlord 3y ago> the macro can implement a whole new syntax and semantic -> then to say the enclosed items are 'args' is misleading: it's source code in a new sublanguage with a different syntax/semantics. Not exactly. It still needs to conform to something the Lisp Reader can absorb, i.e. something that looks like lisp. Then there are reader macros. That's where the true extensibility resides (and in addition to the new syntax elements, you'll need to reserve boundary keywords for that syntax).
- lispm 3y ago> Not exactly. That is exactly the point. Lisp syntax works differently. s-expressions are a data language and the Lisp syntax is not defined over characters, but over s-expressions. > i.e. something that looks like lisp. No, it would just look like s-expressions. You could define a completely different syntax and semantics on top of s-expressions: Logic (like Prolog), Postfix, ... No one says that s-expression need to have the operator first. That's what Lisp defines as syntax. But you could write a postfix in s-expressions_ ((3 4 +) 9 (pi sin) pi) 2 *) Above is a valid s-expression, but it is not valid Lisp. As such it does not look like Lisp, but it looks like a postfix language encoded on top of s-expressions. If a reader would reverse all expressions, then it could be executed as Lisp. You could also define a syntax where parentheses are replaced by significant indentation. s-expressions are not Lisp syntax, they are a data syntax which is used to encode Lisp. Historically s-expression were also defined only for data and Lisp code used m-expressions for programs and s-expressions for data. CADR would be written similar to: cadr[A]=car[cdr[A]] The function would then be called on data: cadr[(1,2)] -> 2 That's would Lisp code might look like, if it were not found out that one could als represent the code as s-expressions and that this would have interesting effects. Lisp designers tried to get away from this syntax several times. ML switched [] and (): similar to: fun cadr (l) = car ( cdr (l)) called then similar to cadr([1,2]) (read) reads every s-expression. Not just Lisp code. It knows nothing about the syntax of the Lisp constructs: DEFUN, LET, DEFCLASS, UNWIND-PROTECT, DOTIMES, ... When then EVAL gets called the s-expression external syntax is gone. EVAL gets Lisp code as Lisp data, not as characters or strings.