#:g1: defstructの紹介

Posted 2014-08-10 02:00:00 GMT

(LISP Library 365参加エントリ)

 LISP Library 365 の222日目です。

defstructとはなにか

 defstructは、Dorai Sitaram氏作のCommon LispのdefstructをScheme用に実現したものを、Felix Winkelmann氏がChickenに移植しPeter Bex氏が改良したものです。
元は、

パッケージ情報

パッケージ名defstruct
Chicken eggs:defstruct - The Chicken Scheme wiki

インストール方法

$ sudo chicken-install defstruct

すれば、

(use defstruct)

(require-extension defstruct)

試してみる

Common Lisp互換ということですが、Common Lispのように使い方が分からない程のオプションはなく、判定用述語、アクセサ、セッタ、alistとの相互変換の関数が定義時にまとめて作られます。

(defstruct tree height girth age leaf-shape leaf-color)
(list tree?
      tree-height
      tree-girth
      tree-age
      tree-leaf-shape
      tree-leaf-color
      update-tree
      set-tree!
      tree->alist
      alist->tree)
;=> (#<procedure (tree? x)> #<procedure (tree-height x)> #<procedure (tree-girth x)> #<procedure (tree-age x)> #<procedure (tree-leaf-shape x)> #<procedure (tree-leaf-color x)>)

 Common Lispだとセッタはsetfで定義されるところと、copy-がないところ、alistに変換する関数があるところが違っています。

 set-foo!とupdate-fooがありますが、updateの末尾に「!」がないことから分かるようにupdateの方は破壊的変更はせず、新しく値をアップデートして作り直したものを返します。と書いていて気付きましたが、新しい値を何も指定しなければコピー関数になりますね。

(let* ((a '((height . 1000) (girth . 100) (age . 60) (leaf-shape . acicular:) (leaf-color . green:)))
       (t1 (alist->tree a))
       (t2 (update-tree t1)))
  (set-tree! t2 age: 100)
  (equal? (tree->alist t1)
          (tree->alist t2)))
;=> #f

まとめ

 今回は、defstructを紹介してみました。
ChickenでDrai Sitaram氏の「Teach Yourself Scheme in Fixnum Days」を実習するのに丁度良いかなと思いましたが、生成されるアクセサの形式が微妙に違ってました。
まあ、「-」と「.」だけの違いではありますが。

comments powered by Disqus