| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#11
| |||
| |||
| Rainer Joswig <joswig@lisp.de> wrote: >> Same here: but just like with a declaration, right ? > > No. OK, fair enough. -- Resistance is futile. You will be jazzimilated. Scientific site: http://www.lrde.epita.fr/~didier Music (Jazz) site: http://www.didierverna.com EPITA/LRDE, 14-16 rue Voltaire, 94276 Le Kremlin-Bicêtre, France Tel. +33 (0)1 44 08 01 85 Fax. +33 (0)1 53 14 59 22 |
|
#12
| |||
| |||
| On 2008-08-22, Didier Verna <didier@lrde.epita.fr> wrote: > > Suppose you have a generic function func (arg1 arg2). Suppose > further that in your application, the dispatch might occur on arg1, but > arg2 will always be of the same type. > > How do you guys behave in that situation ? Please select one or several > options below. All choices must be properly justified. > > * Option 1 (well, I do nothing special): > (defmethod func ((arg1 type1) arg2) ...) > (defmethod func ((arg1 type2) arg2) ...) > etc. This is the best option. Just because some datum is currently observed to be of the same type all the time doesn't mean that this observation has to be enshrined in the form of a restriction. Suppose that FUNC does nothing with ARG2 other than pass it down to some other method which is capable of handling various types of ARG2. Adding premature restrictions into FUNC simply causes it to be less transparent. > * Option 2: > (defmethod func ((arg1 type1) (arg2 theonlytype)) ...) > (defmethod func ((arg1 type2) (arg2 theonlytype)) ...) > etc. Of course, here ARG2 may be not just exactly of THEONLYTYPE, but any subtype of that type. So you haven't closed the door against type variation. The only difference between option 1 and 2 is that 2 cuts a deeper, narrower slice of the class hierarchy for ARG2. What do you achieve by providing a single method of FUNC which specialized ARG2 to THEONLYTYPE? What you achieve is that dispatching FUNC won't work unless the second argument is in that subtree of the class hirearchy. What would be the reason for wanting do do that? The reason would be that FUNC does things with ARG2 that only work with that slice of the class hierarchy. Well, this is incorrect reasoning, because in Lisp, we can extend methods to work with anything we want at any time. Just because the methods used by FUNC to work with ARG2 currently don't work with anything other than THEONLYTYPE doesn't mean that they won't be able to do that in the future. We may in fact be able to make FUNC handle values of ARG2 which are outside of THEONLYTYPE, and we may be able to do this by changing only the generic functions called by FUNC, without touching FUNC itself. CLOS is not like the object system of some OO programming languages in which inheritance determines what methods are applicable to an object. Option 2 resembles Java or C++, where arg2 has to be statically declared to be something derived from TheOnlyType so that func can properly work with it as TheOnlyType. It can't simply be a of type Object, because the Object class doesn't have all of the the methods that are needed to operate on TheOnlyType. In Lisp, we don't have this problem. The object's type is known even in a method where it appears as a parameter specialized to T. Methods don't belong to a class, but to a generic function, etc. > * Option 3: > (defmethod func ((arg1 type1) arg2) (declare (type theonlytype arg2)) ...) > (defmethod func ((arg1 type2) arg2) (declare (type theonlytype arg2)) ...) > etc. Type declarations are largely pointless except when you're optimizing. Other than that, the only value is that a Lisp compiler may be able to give you a compile-time warning here that you have a type mismatch. Declarations are potentially dangerous, because you're telling the compiler that you promise that the object is of that type. If you reduce safety, the compiler may generate code which assumes that it's working on an object of that type. If you want to assert that some incoming parameter has a given type, try CHECK-TYPE. This is largely pointless in most CLOS code, because you can develop the methods to make any type work. It makes sense when the object is really some basic type dressed up as a class (string, number, cons ...) and the method's body uses non-generic functions to operate on it. E.g. dumb example: (defmethod associate-with-name ((object sometype) name) ;; name is a string or symbol (check-type name (or string symbol)) ...) Even here, I would suspect that it's premature to be doing such a check. |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.