#:g1: incf-clの紹介

Posted 2014-06-21 11:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の172日目です。

incf-clとはなにか

 incf-clは、Juan M. Bello Rivas氏作のCommon Lispのユーティリティ集です。

パッケージ情報

パッケージ名incf-cl
Quicklisp
CLiKihttp://cliki.net/incf-cl
Quickdocshttp://quickdocs.org/incf-cl
CL Test Grid: ビルド状況incf-cl | CL Test Grid

インストール方法

(ql:quickload :incf-cl)

試してみる

 どんな関数があるかは、Quickdocsで確認できます。

 incf関係を拡張するユーティリティなのかと思ってインストールしてみましたが、incfの意図は、C系文化で良くあるCL++ということみたいです。

 ユーティリティの内容ですが、Haskell等で良く使われているユーティリティを模しているようです。

内包表記

 LOOPに展開されるマクロです。LOOPは元々内包表記っぽく書けますが、それを推し進めた感じです。

(lc x (<- x '(1 2 3 4)))
;=>  (1 2 3 4)

(lc (list x y) (<- x '(1 2 3 4)) (<- y '(1 2 3 4)))
;=>  ((1 1) (1 2) (1 3) (1 4) (2 1) (2 2) (2 3) (2 4) (3 1) (3 2) (3 3) (3 4) (4 1)
;     (4 2) (4 3) (4 4))

doctest

 最近の言語では良くあるドキュメントストリングにテストを書くというもの。

パッケージ名> 式 結果

と書くと、doctest関数でテスト可能です。パッケージ丸ごとという指定も可能

(defpackage katino 
  (:use :cl :incf-cl))

(cl:in-package :katino)

(defun fib (n) " KATINO> (fib 0) 0 KATINO> (fib 1) 1 KATINO> (fib 2) 1 KATINO> (fib 10) 55" (if (< n 2) n (+ (fib (1- n)) (fib (- n 2)))))

(doctest 'katino::fib) ;>> .... ;=> T

HaskellのPrelude

 HaskellのPreludeに含まれているものを模した関数もあります。

その他

 その他、関数合成の$、ネストしたリストを扱うnest関数、ハッシュテーブルのユーティリティ、unfold、文字列連結等があります。

(nest-list #'list 1 :max 10)
;=>  (1 (1) ((1)) (((1))) ((((1)))) (((((1))))) ((((((1)))))) (((((((1)))))))
;     ((((((((1)))))))) (((((((((1))))))))) ((((((((((1)))))))))))

(nest-list #'list '(1 1) :max 8) ;=> (1 1 (1 1) (1 (1 1)) ((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1)))) ; (((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1))))) ; (((1 (1 1)) ((1 1) (1 (1 1)))) ; (((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1)))))) ; ((((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1))))) ; (((1 (1 1)) ((1 1) (1 (1 1)))) ; (((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1))))))) ; ((((1 (1 1)) ((1 1) (1 (1 1)))) ; (((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1)))))) ; ((((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1))))) ; (((1 (1 1)) ((1 1) (1 (1 1)))) ; (((1 1) (1 (1 1))) ((1 (1 1)) ((1 1) (1 (1 1)))))))))

(nest-list #'+ '(1 1) :max 8) ;=> (1 1 2 3 5 8 13 21 34 55)

(nest #'+ '(1 1) :max 8) ;=> 55 (mapcar ($ #'list #'+) '(1 2 3 4) '(5 6 7 8)) ;=> ((6) (8) (10) (12))

(dohash (key value (*:alist-hash-table '((a . 1) (b . 2) (c . 3)))) (format t "~A => ~D~%" key value)) ;>> A => 1 ;>> B => 2 ;>> C => 3 ;>> ;=> NIL (string-join (list "foo" "bar") "") ;=> "foobar"

まとめ

 今回は、incf-clを紹介してみました。
incf-clは結構、利用頻度が高そうなものが揃っているので、なかなか使えそうですね。

comments powered by Disqus