From: James Y K. <fo...@fu...> - 2005-11-15 21:35:49
|
With the following code: (defun foobar (n) (* n 2)) (define-compiler-macro foobar (n) `(* ,n 3)) (defun test1 (n) (foobar n)) (defun test2 (n) (funcall #'foobar n)) (test1 2) => 6 (test2 2) => 4 test1 uses the compiler-macro, and test2 does not. This isn't what I hoped for, but the CLHS doesn't ever require that compiler-macros must be evaluated, so this can't properly be called a bug, just a wish. However, it does seem that CLHS _implies_ that they should be evaluated in that case, because of the following requirement: "* The &whole argument is bound to the form argument that is passed to the compiler macro function. The remaining lambda-list parameters are specified as if this form contained the function name in the car and the actual arguments in the cdr, but if the car of the actual form is the symbol funcall, then the destructuring of the arguments is actually performed using its cddr instead." This is where the actual bug comes in: (funcall (compiler-macro-function 'foobar) '(foobar x) nil) => '(* x 3) but, (funcall (compiler-macro-function 'foobar) '(funcall #'foobar x) nil) debugger invoked on a SB-KERNEL::ARG-COUNT-ERROR: error while parsing arguments to DEFINE-COMPILER-MACRO FOOBAR: invalid number of elements in (#'FOOBAR X) to satisfy lambda list (N): exactly 1 expected, but 2 found It looks like the special handling for funcall isn't being done. James |
From: Nikodemus S. <nik...@ra...> - 2005-11-15 21:51:05
|
On Tue, 15 Nov 2005, James Y Knight wrote: > This is where the actual bug comes in: > (funcall (compiler-macro-function 'foobar) '(foobar x) nil) => '(* x 3) > but, > (funcall (compiler-macro-function 'foobar) '(funcall #'foobar x) nil) Wierd. I though I had fixed this. Will look into this. Cheers, -- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." |
From: James Y K. <fo...@fu...> - 2005-11-16 01:01:45
|
On Nov 15, 2005, at 4:50 PM, Nikodemus Siivola wrote: > On Tue, 15 Nov 2005, James Y Knight wrote: > > >> This is where the actual bug comes in: >> (funcall (compiler-macro-function 'foobar) '(foobar x) nil) => >> '(* x 3) >> but, >> (funcall (compiler-macro-function 'foobar) '(funcall #'foobar x) >> nil) >> > > Wierd. I though I had fixed this. Will look into this. Looks like you only fixed it for the case where the compiler-macro has a &whole. And the fix is, at least from my reading, wrong in that case as well. I read the spec as saying the &whole really should contain the whole thing: '(funcall #'foobar x), whereas your fix makes &whole in that case only contain '(#'foobar x), but it does at least make the rest of the parsing succeed. :) James |
From: James Y K. <fo...@fu...> - 2006-01-09 23:16:13
|
On Nov 15, 2005, at 8:01 PM, James Y Knight wrote: > > On Nov 15, 2005, at 4:50 PM, Nikodemus Siivola wrote: > > >> On Tue, 15 Nov 2005, James Y Knight wrote: >> >> >> >>> This is where the actual bug comes in: >>> (funcall (compiler-macro-function 'foobar) '(foobar x) nil) => >>> '(* x 3) >>> but, >>> (funcall (compiler-macro-function 'foobar) '(funcall #'foobar x) >>> nil) >>> >>> >> >> Wierd. I though I had fixed this. Will look into this. >> > > Looks like you only fixed it for the case where the compiler-macro > has a &whole. And the fix is, at least from my reading, wrong in > that case as well. I read the spec as saying the &whole really > should contain the whole thing: '(funcall #'foobar x), whereas your > fix makes &whole in that case only contain '(#'foobar x), but it > does at least make the rest of the parsing succeed. :) Here's some test cases for the end of define-compiler- macro.impure.lisp. The first and second assert will currently fail because of incorrect compiler-macro funcall expression parsing. The fourth will fail because SBCL does not currently expand compiler macros of funcalls (which is remedied by the patch I sent a few months back). James (assert (equal '(funcall #'square (square y z)) (funcall (compiler-macro-function 'square) '(funcall #'square (square y z)) nil))) (defun test (x) (* x 2)) (define-compiler-macro test (x) `(* ,x 3)) (assert (equal '(funcall #'test (test x)) (funcall (compiler-macro-function 'test) '(funcall #'test x) nil))) ;; compiler-macros are not guaranteed to be expanded per CLHS, but ;; SBCL should do so. Test that it does. (assert (eql 9 (test 3))) (assert (eql 9 (funcall #'test 3))) |
From: James Y K. <fo...@fu...> - 2005-11-16 20:27:25
Attachments:
cm.diff
|
Here's a patch that allows compiler-macros to be expanded on funcall forms. It might even be right. It doesn't fix the parsing bug in define-compiler-macro; until that is fixed, it isn't usable without putting an extra &whole in your macro definition. Also I think this lets the warning in (define-compiler-macro (setf ..) ..) be removed. James |
From: Nikodemus S. <nik...@ra...> - 2006-08-11 08:11:04
|
James Y Knight <fo...@fu...> writes: > This is where the actual bug comes in: > (funcall (compiler-macro-function 'foobar) '(foobar x) nil) => '(* > x 3) > but, > (funcall (compiler-macro-function 'foobar) '(funcall #'foobar x) nil) Fixed in 0.9.15.26, thanks for the report! (Only the lambda-list parsing, not expansion of FUNCALL forms -- yet.) Cheers, -- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." |
From: Nikodemus S. <nik...@ra...> - 2006-08-11 13:41:53
|
James Y Knight <fo...@fu...> writes: > Here's a patch that allows compiler-macros to be expanded on funcall > forms. It might even be right. It doesn't fix the parsing bug in > define-compiler-macro; until that is fixed, it isn't usable without I ended up taking a bit different route, but 0.9.15.27 is able to expand compiler-macros for FUNCALL forms, and also fixes a few bugs that affected compiler-macros. Cheers, -- Nikodemus Schemer: "Buddha is small, clean, and serious." Lispnik: "Buddha is big, has hairy armpits, and laughs." |