From: Nikodemus S. <nik...@ra...> - 2009-11-15 09:46:44
|
2009/11/15 Karol Swietlicki <mag...@gm...>: > Here goes, with a bit of a different syntax. > > (defmacro define-dispatch-function (name arglist dispatch-arg &body cases) > `(progn > (defun ,name ,arglist > (etypecase ,dispatch-arg > ,@cases)) > ,@(mapcar #'(lambda (case) > (let* ((pos (position dispatch-arg arglist)) > (list (make-list (length arglist) :initial-element t))) > (setf (elt list pos) (car case)) > `(sb-c:deftransform ,name ,(list arglist list) > ',@(cdr case)))) cases))) > > This seem to be working, but I have to defknown the function before I > deftransform it. I am reluctant to do so because I fear that it might > interfere with other optimizations. Thanks! It doesn't -- but the D-D-F syntax should probably also expose some DEFKNOWN attributes, and if a DEFKNOWN exists and matches these the new definition, it should not be overwritten. Also, I this this should really be able to dispatch on multiple arguments, ideally including &keys: DEFTRANSFORMS can handle that, so I think this too should. I'm willing to leave the constant-dispatch out from this, since at that point on _should_ be writing a deftransform instead, I think. (define-dispatch-function two-arg-+ (a b) ((fixnum fixnum) (+ a b)) ; compiler should deal with this ((fixnum bignum) (bignum+fixnum a b)) ((bignum fixnum) (bignum+fixnum b a)) ;; No, I don't seriously propose replacing number-dispatch macros from ;; numbers.lisp with this -- it just makes a good example. ...) Cheers, -- Nikodemus |