#:g1: alternativesの紹介

Posted 2014-12-02 15:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の337日目です。

alternativesとはなにか

 alternativesは、Patrick Stein氏作のコードの開発用のユーティリティです。

パッケージ情報

パッケージ名alternatives
Quicklisp
プロジェクトページnklein/alternatives · GitHub
参考ドキュメントCode That Tells You Why :: nklein software

インストール方法

 現在のところQuicklispには収録されていないのでリポジトリから取得してQuicklispのlocal-projectsに置けば、

(ql:quickload :alternatives)

でロード可能です。

試してみる

 使い方と仕組みは単純で、alternativesというマクロは、最後の節だけコードが活きるという単純なマクロです。

(defun fib (n)
  (alternatives
    (slow
     (if (< n 2)
         n
         (+ (fib (1- n))
            (fib (- n 2)))))
    (fast
     (labels ((fib (n a1 a2)
                (cond ((zerop n) a2)
                      ((= 1 n) a1)
                      (T (fib (1- n) (+ a1 a2) a1)))))
       (fib n 1 0)))))
;===>
(DEFUN FIB (N)
  (PROGN
   (LABELS ((FIB (N A1 A2)
              (IF (ZEROP N)
                  (PROGN A2)
                  (IF (= 1 N)
                      (PROGN A1)
                      (THE T (PROGN (FIB (1- N) (+ A1 A2) A1)))))))
     (FIB N 1 0))))

のように展開されますが、***という印を付けると最後以外の節が有効になります。
節の名前が、finalもしくはblessedの場合も同様。

(defun fib (n)
  (alternatives
    ***
    (slow
     (if (< n 2)
         n
         (+ (fib (1- n))
            (fib (- n 2)))))
    (fast
     (labels ((fib (n a1 a2)
                (cond ((zerop n) a2)
                      ((= 1 n) a1)
                      (T (fib (1- n) (+ a1 a2) a1)))))
       (fib n 1 0)))))
;===>
(DEFUN FIB (N)
  (PROGN
   (IF (< N 2)
       N
       (+ (FIB (1- N)) (FIB (- N 2))))))

 これが、どんな風に使われることを意図しているかというと、

(defun sum-i^2 (n)
  (alternatives
    (i-wanted-to-do-this
     (loop :for i :to n :summing (* i i)))

(my-first-attempt-was-something-like-this (do ((i 0 (1+ i)) (sum 0 (+ sum (* i i)))) ((> i n) sum)))

(but-i-could-not-do-that-because "Some people find a do-loop to hard to read (and 'too' too hard to spell, apparently).")

(now-i-know-better-and-can-do-this (/ (* n (1+ n) (1+ (+ n n)) 6)))))

 こんな風に開発時の試行錯誤を残しておくのに使います。
単なるコメントと違って代替コードが実行できるというのが味噌でしょうか。

まとめ

 今回は、alternativesを紹介してみました。
ブログでのライブラリ解説のエントリーのコメント欄でも賛否両論ではありますが、コードを後から読む場合には助けになりそうです。
代替コードからテスト用の検証コードを生成する機能があっても良さそう。

comments powered by Disqus