#:g1: typedvarの紹介

Posted 2014-08-17 04:45:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の229日目です。

typedvarとはなにか

 typedvarは、CLISPの開発者で知られるBruno Haible氏作のCommon Lispの型宣言を楽に記述できるようにするCommon Lispの拡張です。

パッケージ情報

パッケージ名typedvar
プロジェクトサイト CLOCC - Common Lisp Open Code Collection / Hg / [e6b24a] /src/syntax/typedecl/typedvar.lisp

インストール方法

 CLOCCのプロジェクトサイトからダウンロードしてきて適当に導入します。

$ hg clone http://hg.code.sf.net/p/clocc/hg clocc-hg

で全体のソースも取得できます。
src/syntax/typedecl/typedvar.lisp が目的のソースです。
リードテーブルの[、]、#'を再定義するので予めリードテーブルを自前で定義しておいた方が良いかと思います。

試してみる

 letが一番分かり易いかと思いますが、

(LET ((X 42))
  (DECLARE (TYPE INTEGER X))
  X)

のようなものを

(let (([x integer] 42))
  x)

と書けるようにしようというものです。
再定義されている構文は、

あたりです。
記述例としては下記のような感じです。

(defmethod matu ([x integer])
  x)
;==>
(CL:DEFMETHOD MATU ((X INTEGER)) (DECLARE (TYPE INTEGER X)) X)

(matu 'a) ;!> There is no applicable method for the generic function

(loop for [n integer] from 0 to 9)

(defun dialma ([n number] [s symbol] [a atom]) [list] (list n s a)) ;==> (PROGN (DECLAIM (FTYPE (CL:FUNCTION (NUMBER SYMBOL ATOM) LIST) DIALMA)) (CL:DEFUN DIALMA (N S A) (DECLARE (TYPE NUMBER N) (TYPE SYMBOL S) (TYPE ATOM A)) (LIST N S A)))

(funcall (lambda ([x symbol]) x) 42) ;==> (FUNCALL (THE (CL:FUNCTION (SYMBOL) T) #'(CL:LAMBDA (X) (DECLARE (TYPE SYMBOL X)) X)) 42)

(do* (([n fixnum] 0 (1+ n)) ([ans list] (list nil)) ([tem list] ans)) ((= 10 n) (cdr ans)) (setf (cdr tem) (setq tem (list n)))) ;=> (0 1 2 3 4 5 6 7 8 9)

(dolist ([e integer] '(1 2 3 a)) e) ;!> The value A is not of type INTEGER.

(defun fib ([n fixnum]) [fixnum] (declare (optimize (speed 3) (safety 0) (debug 0))) (labels ((fib ([n fixnum]) [fixnum] (if (< n 2) n (the fixnum (+ (fib (1- n)) (fib (- n 2))))))) (declare (inline fib)) (fib n)))

 defun等関数の定義構文では、返り値の型も可能です。
また、こういう構文拡張にありがちな問題ですが、lambdaは、cl:lamdbaではないため

((lambda (x) x) 42)

とは書けず、funcallが必要になります。
さらに、説明では、loopでも

(loop :for [n integer] :in '(1 2 ...) ...)

のように書けるようなことが書いてありますが、ソースのコメントには #| TODO: (defmacro loop ...) |# とあるので未実装のようです。

まとめ

 今回は、typedvarを紹介してみました。
Common Lispの構文にDylanのような型指定の構文を導入しようという試みは割合にありますね。

comments powered by Disqus