Opened 6 years ago

Closed 6 years ago

#1092 closed defect (invalid)

Method on t causes error when it should not

Reported by: gnp Owned by:
Priority: minor Milestone:
Component: ANSI CL Compliance Version: trunk
Keywords: Cc:

Description

The following code signals an error about the :sign keyword argument. The culprit seems to be the method on T, which prevents the method on list to run. If I omit the method on T, or I define it e.g. on built-in-class, the error is gone.

(defgeneric render (obj &rest args))

(defmethod render ((obj t) &key)
  (print obj))

(defmethod render ((obj list) &rest args)
  (mapc (lambda (item)
          (apply #'render item args))
        obj))

(defmethod render ((obj number) &key sign)
  (print (* sign obj)))

(render (list 1 2 3 4) :sign -1)

According to my reading of CLHS (7.6.4 & 7.6.5), no error should be signaled. Indeed, I have tested this with SBCL and it runs just fine.

Change History (1)

comment:1 Changed 6 years ago by gb

  • Resolution set to invalid
  • Status changed from new to closed

My reading of 7.6.5 is that "an error should be signaled" in this case. The fact that a method is defined on the class T doesn't seem to be relevant, but the fact that that method is defined to accept an empty set of keyword arguments seems to be.

That section says "the specific set of keyword arguments accepted by the generic function varies according to the applicable methods." The applicable methods in your example are the methods specialized to LIST and to T.

An applicable method that has &rest but not &key (like the method on LIST) doesn't affect the set of acceptable keyword arguments for a call to the GF; in this case, that set is empty (determined by the keyword args accepted by the method on T.)

The spec says that an error "should be signaled" in the case where CCL (and LispWorks, which is the only other implementation that I checked) do so. This terminology means that you can only count on the error being signaled in code compiled with (DECLARE (OPTIMIZE (SAFETY 3))) in effect; if an implementation doesn't signal an error, that doesn't mean that the code is correct or that other implementations are wrong in doing so.

Note: See TracTickets for help on using tickets.