総称関数の練習のために、Fizz-Buzz問題を総称関数を使って解いてみた。独自のメソッド結合まで使った、無駄に大掛かりな物になっている。
(defun strcat (&rest strings) (apply 'concatenate `(string ,@strings))) (define-method-combination strcat :identity-with-one-argument t) (defgeneric fizz-buzz-method (mod3 mod5) (:documentation "mod3が0ならFizz, mod5が0ならBuzz") (:method-combination strcat)) (defmethod fizz-buzz-method strcat ((mod3 (eql 0)) mod5) "Fizz") (defmethod fizz-buzz-method strcat (mod3 (mod5 (eql 0))) "Buzz") (defmethod fizz-buzz-method strcat (mod3 mod5) "") (defun empty-p (seq) (if (= 0 (length seq)) nil seq)) (defun fizz-buzz (n) (format t "~a~%" (or (empty-p (fizz-buzz-method (mod n 3) (mod n 5))) n)))
総称関数の使い勝手はHaskellやErlangのパターンマッチと似たところがあるが、マッチするメソッドが一度に全部手に入り、それらを結合できるところが決定的に違う。