2009/11/15 Karol Swietlicki <magotari@...>:
> Here goes, with a bit of a different syntax.
> (defmacro define-dispatch-function (name arglist dispatch-arg &body cases)
> (defun ,name ,arglist
> (etypecase ,dispatch-arg
> ,@(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.
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.