Lispy Days

趣味で Lisp な日々 (index) (weblog) (view) (edit) (help)

CLISP CVS 版で Meta Object Protocol サポート

久しぶりに cvs update したらファイルが増えてたので気になって impnote を読んだ. Meta Object Protocol のサポートが追加されたらしい.

pcase - 確率分岐

某掲示板で出ていた確率分岐のネタ.

(defmacro pcase (&rest lst)
  "確率分岐"
  (let (($p (gensym)))
    `(let ((,$p (random 1.0)))
      (cond ,@(do* ((forms nil)
                    (p 0)
                    (e lst (cdr e)))
                  ((null e) (nreverse forms))
                  (when (consp (car e))
                    (push `(,(if (member (caar e) '(t else))
                                t
                                `(<= ,$p ,(+ p (caar e))))
                            ,@(cdar e))
                          forms)
                    (when (numberp (caar e))
                      (incf p (caar e)))
                    (assert (<= p 1.0))))))))
CL-USER> (macroexpand-1 '(pcase (0.1 1) (0.2 2) (0.3 3) (t 4)))
(let ((#:g5493 (random 1.0)))
  (cond ((<= #:g5493 0.1)
          1)
        ((<= #:g5493 0.3)
          2)
        ((<= #:g5493 0.6)
          3)
        (t
          4)))

でもこれだと 1/3 とかやるときに困りそう.1.0 とか固定じゃなくて ユーザーが指定できたほうが良いような気がする.整数で

(random-case 3
  (1 ...)
  (1 ...)
  (1 ...))

とかいうように.