まだ無名の風景たち

そしてその情景

Common Lispでリレーションの勉強 1.リレーションを作成する関数を作る

リレーションの勉強を兼ねて自分なりに何かプログラムを作ってみる。

Common Lispが好きなので、Lispでやる。

リレーションには、見出しと本体がある。

すなわち、リレーションは、

リレーション = 見出し + 本体

と考えてよいだろう。

これをLispで扱うとき、どのように表現すべきだろう。

Lispといえばリストなので、やはりリストでリレーションを表現するようにしたい。

直感的に、

(cons attribute body)

って表現すればいいんじゃない?って思う。

リストの図で表現するとこんな感じだろうか。

f:id:hitsuji123:20170722155059p:plain

「なんだ、簡単じゃん」と思って、下記のようなコードを書いてREPLで試してみる。

consの引数1に見出しのリストを、引数2に本体のリストを渡せばOKのはずだ。

CL-USER> (cons '(id name password) '( (1 "bob" "bob1234") (2 "alice" "0002")))
( (ID NAME PASSWORD) (1 "bob" "bob1234") (2 "alice" "0002"))

「あれ?思っていた結果と違う」

俺が欲しかったのはこんなリストだ。

( (ID NAME PASSWORD) ( (1 "bob" "bob123") (2 "alice" "0002")))

何か間違っているらしい。 

リスト( (ID NAME PASSWORD) ( 1 "bob" "bob1234") ( 2 "alice" "0002"))を図で表現すると、下記のようになる。

f:id:hitsuji123:20170722164327p:plain

 ふむ・・・。本来は下記の図のようになって欲しかった。

f:id:hitsuji123:20170722164655p:plain

このようにするには、

(cons attribute (cons body nil))

 とすれば良いのでは。実際にREPLで試してみる。

 CL-USER> (cons '(id name password) (cons '( ( 1 "bob" "bob123") ( 2 "alice" "0002")) nil))
( (ID NAME PASSWORD) ( (1 "bob" "bob123") (2 "alice" "0002")))

 OKだ。てなわけでリレーションを作る関数を定義する。

(defun make-relation (attribute body)
     (cons attribute (cons body nil)))

CL-USER> (make-relation '(id name password) '((1 "bob" "bob123") (2 "alice" "0002")))
((ID NAME PASSWORD) ((1 "bob" "bob123") (2 "alice" "0002"))) 

うん。シンプルだし、なかなか悪くないんじゃない?

てか、はてなLisp投稿するの面倒だな・・。