Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defstruct predicate-dispatch-method predicates function)
- (defun find-predicate-dispatch-method (name parameters)
- (dolist (method (get name 'predicate-dispatch-methods))
- (when (every (function funcall)
- (predicate-dispatch-method-predicates method)
- parameters)
- (return-from find-predicate-dispatch-method (predicate-dispatch-method-function method))))
- (lambda (&rest arguments)
- (error "Cannot find a method to dispatch on the arguments ~S of the function ~S"
- arguments name)))
- (defun set-predicate-dispatch-method (name predicates function)
- (push (make-predicate-dispatch-method :predicates predicates
- :function function)
- (get name 'predicate-dispatch-methods)))
- (defmacro define-predicate-dispatch-function (name (&rest parameters))
- `(progn
- (setf (get ',name 'predicate-dispatch-methods) '())
- (defun ,name (,@parameters)
- (funcall (find-predicate-dispatch-method ',name (list ,@parameters)) ,@parameters))))
- (defmacro define-predicate-dispatch-method (name (&rest parameters-and-predicates) &body body)
- `(set-predicate-dispatch-method ',name ',(mapcar (function second) parameters-and-predicates)
- (lambda (,@(mapcar (function first) parameters-and-predicates))
- (block ,name ,@body))))
- (define-predicate-dispatch-function foo (x y))
- (define-predicate-dispatch-method foo ((x stringp) (y numberp))
- (foo (read-from-string x) y))
- (define-predicate-dispatch-method foo ((x numberp) (y numberp))
- (+ x y))
- (foo "33" 42)
- ; --> 75
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement