Opened 14 years ago
Closed 13 years ago
#201 closed defect (fixed)
&WHOLE broken in DEFINE-METHOD-COMBINATION
| Reported by: | Greg | Owned by: | somebody | 
|---|---|---|---|
| Priority: | minor | Milestone: | 1.1.0 | 
| Component: | CLOS | Version: | 1.1.0-dev | 
| Keywords: | ansi-conformance | Cc: | |
| Parent Tickets: | 
Description
I get an error whenever I call a function that uses the simple method combination shown here.
CL-USER> (define-method-combination progn-with-whole ()
           ((methods ()))
           (:arguments &whole whole)
           `(progn (format nil "using ~a" ,whole)
                   ,@(mapcar (lambda (method) `(call-method ,method))
                             methods)))
PROGN-WITH-WHOLE
CL-USER> (defgeneric test-&whole (x)
           (:method-combination progn-with-whole)
           (:method (x) x))
#<STANDARD-GENERIC-FUNCTION TEST-&WHOLE {34315D04}>
CL-USER> (test-&whole 4)
Here is the error:
The value 4 is not of type LIST.
   [Condition of type TYPE-ERROR]
Restarts:
 0: [RETRY] Retry SLIME REPL evaluation request.
 1: [*ABORT] Return to SLIME's top level.
 2: [ABORT] Abort thread.
Backtrace:
  0: (#<FUNCTION {C69203}> #<TYPE-ERROR {FE85ADF}> #<FUNCTION {C69203}>)
  1: (APPLY #<FUNCTION {C69203}> (#<TYPE-ERROR {FE85ADF}> #<FUNCTION {C69203}>))
  2: (SYSTEM::RUN-HOOK SYSTEM::*INVOKE-DEBUGGER-HOOK* #<TYPE-ERROR {FE85ADF}> #<FUNCTION {C69203}>)
  3: (INVOKE-DEBUGGER #<TYPE-ERROR {FE85ADF}>)
  4: org.armedbear.lisp.Lisp.error(Lisp.java:379)
  5: org.armedbear.lisp.Lisp.type_error(Lisp.java:420)
  6: org.armedbear.lisp.LispObject.car(LispObject.java:156)
  7: org.armedbear.lisp.Lisp.eval(Lisp.java:520)
  8: org.armedbear.lisp.Lisp.evalCall(Lisp.java:559)
  9: org.armedbear.lisp.Lisp.eval(Lisp.java:515)
 10: org.armedbear.lisp.Lisp.progn(Lisp.java:684)
 11: org.armedbear.lisp.SpecialOperators$sf_progn.execute(SpecialOperators.java:275)
 12: org.armedbear.lisp.Lisp.eval(Lisp.java:505)
 13: org.armedbear.lisp.Lisp.progn(Lisp.java:684)
 14: org.armedbear.lisp.Primitives$sf_macrolet.execute(Primitives.java:3641)
 15: ((LAMBDA (#:G13665) (MACROLET (#) (PROGN # #))) (4))
 16: (FUNCALL (LAMBDA (#:G13665) (MACROLET (#) (PROGN # #))) (4))
 17: (#<STANDARD-GENERIC-FUNCTION TEST-&WHOLE {34315D04}> 4)
 18: (APPLY #<STANDARD-GENERIC-FUNCTION TEST-&WHOLE {34315D04}> (4))
 19: (MOP::INITIAL-DISCRIMINATING-FUNCTION #<STANDARD-GENERIC-FUNCTION TEST-&WHOLE {34315D04}> (4))
 20: (#<STANDARD-GENERIC-FUNCTION TEST-&WHOLE {34315D04}> 4)
    Change History (5)
comment:1 Changed 14 years ago by
| Milestone: | → 1.1.0 | 
|---|
comment:2 Changed 14 years ago by
| Keywords: | ansi-conformance added | 
|---|
comment:3 Changed 13 years ago by
| Resolution: | → invalid | 
|---|---|
| Status: | new → closed | 
comment:4 Changed 13 years ago by
| Resolution: | invalid | 
|---|---|
| Status: | closed → reopened | 
Reopening. On re-reading, the WHOLE variable should have been bound to a form evaluating to (4), so the ticket is valid and I need to figure out how to do this.
comment:5 Changed 13 years ago by
| Resolution: | → fixed | 
|---|---|
| Status: | reopened → closed | 
Note: See
        TracTickets for help on using
        tickets.
    

Well, of course the error can be improved, but the code provided is in error. The backquote form should have read:
`(progn (format nil "using ~a" ',whole))
Note the quote before the unquote. The difference being that the new code evaluates to
(progn (format nil "using ~a" '(4))
which takes (4) as a constant while the old code does to
(progn (format nil "using ~a" (4))
Which tries to evaluate a function by the name 4.
Resolving as invalid. Although I appreciate the fact that the error could be better, I don't see how at this time. (The problem being that LispObject.car() raises a type error "This is not a LIST", while the outer code knows which error *should* have been generated, but has no way to communicate that to inner code without presumed-large performance impact.