[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: symbols are not generic functions



   in reference to ensure-generic-function, Moon says:
   
       I don't completely understand.  Suppose symbol-function of the
   symbol
       is already a generic function, but it is of a different class than
   the
       kind that you get by default, because someone is using
   generic-function
       meta-objects.  Would ensure-generic-function accept that generic
       function, signal an error, or clobber it with a generic function of
       the default kind?
   
   Well, the short lazy answer is ensure-generic-function does whatever
   add-method was going to do.

This function is giong to be used for get-method and remove-method, its
behavior needs to be different for those because if there is no generic
function fbound to the symbol, we can't create one.
   
   The long answer is we need to figure this out.
   
   1. perhaps ensure-generic-function should take a second argument which
   would be the class of the generic function to make if there isn't one.
   
   2. There is a part of the meta-object protocol which deals with whether
   or not is is permissible to change the class of a generic function, that
   part of the protocol should be called here when there is already a
   generic function but its the wrong class.
I agree
   
   3. Perhaps ensure-generic-function should take another argument which
   could be used to specify that if there is a function in the place, but
   its not a generic-function, it should become the default method for the
   new generic function.
   
       Also, does ensure-generic-function ever alter the symbol-function of
       a symbol, or is it just a side-effect free coercion?  If the latter,
       it might be cleaner to use the existing COERCE function, thus
       (add-method (coerce <arg> 'generic-function) <method>).
   
   I am not sure about this given what I said above.

I think this is a summary of what we can encounter:
 
 Fboundp = nil: (error) 
                | (fdefine symbol (make-instance desired-type))
	        | (make-instance desired-type)

	 = t:

 	   generic-function-p = nil: (error) 
                                     | (replace-without-default
                                         (make-instance desired-type))
	                             |(make-instance desired-type)
                                     | (replace-with-default
	                                 (make-instance desired-type))
                                     |(add-method 
                                        (make-instance desired-type)
	                                .... old-function)

                              = t: (subtypep generic-function-type
                                            desired-type) = t:  generic-function
	
                                                          = nil: (error) 
                                                               |(change-class)  
                                                               |(make-instance desired-type)
To cover all the cases, we could have an arglist like this:

ensure-generic-function function-name &optional generic-function-type 
                        &key :error-if-not-fboundp 
                             :error-if-not-generic 
                             :error-if-not-subtypep
                             :side-effect-p 

If side-effect-p is nil, the old function-object is not changed and left
in the symbol-function slot of the symbol.

If side-effect-p is true, the old function-object is changed. If one has
to be created, it is put in the symbol-function of the symbol.

It would be useful for the function to return a second values to tell if 
the symbol-function was returned, changed or if a new generic-function
was created. (Like INTERN).

Patrick.