kikkiiのブログ

ひきこもり

(ql:quickload :let-plus)

Common Lispが気になる。いつか「自分Common Lisp」をつくりたい。let-plusは便利だと思った。

効率がいいとか悪いとかそういうのはわからないが、この分配束縛系構文ライブラリを使ったら、ローカール変数やローカール関数わかりやすくなる気がする。

Common Lispだと、ローカール変数や関数を定義したいとき、次の4つを使い分けなければならない。

自分自身を呼べない系 自分自身を呼べる系
ローカール変数 let let*
ローカール関数 flet labels
;; 自分自身を呼べない系ローカール変数
(let ((aa 11))
  (* aa aa))
121

;; 自分自身を呼べる系ローカール変数
(let* ((aa 11)
       (bb aa))
  (* aa aa))
121

;; 自分自身を呼べない系ローカール関数
(flet ((ff (n) (* n n)))
  (ff 11))
121

;; 自分自身を呼べる系ローカール関数
(labels ((ff (n) (* n n))
     (fff (n) (* n (ff n))))
  (fff 11))
1331

こんなの煩わしいから、細かいことは気にせずlet+を使えばいいと思った。

(ql:quickload :let-plus)
(use-package :let-plus)

;;まとめて書けるのでいい
(let+ ((aa 11)
       (bb aa)
       ((&flet+ ff (n) (* n n)))
       ((&flet+ fff (n) (* n (ff aa)))))
  (fff bb))
1331

;; 再帰関数を使いたいときは&flet+では失敗する
;; &labels+を使わなければならないようだ
(let+ ((aa 1)
       (bb (+ 1 aa))
       ((&flet+ ff (n) (* n n)))
       ((&labels+ fib (n)
          (if (< n bb)
              n
              (+ (fib (- n (ff aa)))
                 (fib (- n bb)))))))
  (fib 11))
89