From: Hoehle, Joerg-C. <Joe...@t-...> - 2005-01-25 14:13:04
|
Hi, while we are at CLISP custom syntax uses, here's something Marco Baringer just reported as causing problems with Iterate (and code walkers, generally): ((setf foo) value other-args) CLISP does not document this syntax extension (probably nobody uses it directly). Yet it appears as a result of macroexpansion: [9]> (macroexpand-1'(setf (values-list (list a b c)) (foo))) (LET* ((#:G6359 (LIST A B C))) ((SETF VALUES-LIST) (FOO) #:G6359)) ; T I consider it impossible to add such an extension. The standard clearly says: ?3.1.2.1.2 A cons that is used as a form is called a compound form. If the car of the compound form is not a symbol, then that car must be a lambda expression, in which case the compound form is a lambda form. With ((setf ...) ...), the car is not a symbol, nor a lambda expression. It's not legal CL (and it's not a function form). Therefore, I believe CLISP must not use such special syntax, or it will cause trouble to any portable code walker. IMHO ((setf ...) ...) cannot be considered a function form, since the standard uses a discrimination tree to distinguish among the three categories: function, special and lambda forms. Nowhere does it say "a function form is a list starting with a function name or designator, and (setf ...) is a function designator" -- except in the glossary, so YMMV: "function form n. a form that is a list and that has a first element which is the name of a function to be called on arguments [...]" One may argue that the above example with (setf value-list) is specific to CLISP (impnotes ?5.1.5) and thus non-portable already. Well, it's just the first example I came up with after Marco Baringer reported the bug to the iterate-devel mailing list. I guess there are other such uses of illegal syntax in macroexpansions from CLISP for plain porable code. Suggestions are welcome! BTW, #'(setf values-list) *** - FUNCTION: undefined function (SETF VALUES-LIST) Same for #'(setf car), but I guess CL says nowhere that (setf car) is the name of a defined function. I presume it only applies to self-defined functions. Regards, Jorg Hohle. |
From: Bruno H. <br...@cl...> - 2005-01-25 14:58:01
|
Joerg-Cyril Hoehle wrote: > I consider it impossible to add such an extension. The standard clearly > says: ?3.1.2.1.2 > A cons that is used as a form is called a compound form. > If the car of the compound form is not a symbol, then that car must be a > lambda expression, in which case the compound form is a lambda form. The ANSI CL committee, when they voted down item 7 of issue <FUNCTION-NAME:LARGE>, voted for inconsistency. CLISP supports the consistent way of using function names, in DEFUN, in DECLARE INLINE, in DEFGENERIC, in DEFCLASS slot options, in FBOUNDP, in FUNCTION, _and_ also in the function call syntax. > glossary, so YMMV: > > "function form n. a form that is a list and that has a first element which > is the name of a function to be called on arguments [...]" Cool! You already found the paragraph that supports the extension! > Therefore, I believe CLISP must not use such special syntax, or it will > cause trouble to any portable code walker. Come on, get real: 1) There is no such thing as a portable code walker. You cannot expand (macrolet ((foo (a &environment env) ...)) (symbol-macrolet (x 5) (macrolet ((bar () (foo x))) (bar)))) in a portable way, because in order to do so, you would need to construct a macroexpansion environment 'env' that contains the symbol-macro binding for 'x' in the format that the implementation uses. You don't have the portable primitives for doing so. 2) If you are working on a semi-portable code walker, that anyway requires some adjustments for every Lisp implementation, then please do yourself a favour and replace (symbolp x) with (typep x '(or symbol (cons (eql setf) (cons symbol null)))) at the appropriate place. It's a one-line change. Bruno |