ラベル CommonLispはじめました の投稿を表示しています。 すべての投稿を表示
ラベル CommonLispはじめました の投稿を表示しています。 すべての投稿を表示

2018年7月28日土曜日

slime-scratch

 REPLって便利なんだけど、Emacsのscratchバッファになれているせいか、どうも使いづらい。scratshバッファは平面だけど、REPLは一次元ということがあるのだろう。
 ダミーのlispファイルをひらいてそのバッファでコードを書いて——実際の動作はREPLで確認、ということをやっていた。
 slimeの関数を眺めていたらslime-scratchというのを見つけた。
 おっ。

2018年7月26日木曜日

スターン数列とフィボナッチ数

スターン数列は,f(0)=0、f(1)=1と二つの再帰的関係f(2n)=f(n)およびf(2n+1)=f(n)+f(n+1)で定義される.これを計算すると,数列は0,1,1,2,1,3,2,1,4,3,5,2,5,3,4と続く.

マーク・チャンバーランド「ひとけたの数に魅せられて」 P11

 何をいっているのか、わからない。

 スターン数列でググってみたけれど、ヒットしたサイトは本の説明をくりかえしているだけで何のとっかかりにもならなかった。日本語のwikiも見当たらない。
 まぁ、f(0)とf(1)はわかる。でもf(2n)=f(n)って何だ? イコールじゃないじゃないか。
 しばし、じっと見つめる。
 あれ?
 もしかしたらf(2n)って偶数のことじゃないか?
 すると、f(2n+1)は奇数か。
 じゃ、コードはこうか?

(require 'cl)

(defun wrk(n)
  (cond ((= n 0) 0)
 ((= n 1) 1)
 ((evenp n)(wrk (/ n 2)))
 ((oddp n)(+ (wrk (/ n 2))(wrk (+ (/ n 2) 1))))))

(mapcar 'wrk '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
(0 1 1 2 1 3 2 3 1 4 3 5 2 5 3 4)

 おっ、正しいみたいだぞ1。
 プログラミングができてよかった。
 エレン、マフラーを巻いてくれてありがとうって気分だ。

 そういえば、フィボナッチ数のコードはよく見かけるけど2、実際に自分で組んでみたことはなかった。たしか、こんな感じ?

(defun wrk(n)
  (cond ((= n 0) 0)
 ((= n 1) 1)
 (t (+ (wrk (- n 1))(wrk (- n 2))))))

(mapcar 'wrk '(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15))
(0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610)

 0から15ぐらいならすぐだけど、0から100までにしたら延々、もどってこない……。

Footnotes:

1

by elisp

2

再帰の例題としては定番。

2018年7月24日火曜日

竹内郁雄「初めての人のためのLISP」

 もっと早くに読んでおくべきだった。
 交互リストによるplistのことも書かれているし、keywordについても——CommonLispをはじめていろいろ疑問に思ったことの答えが書かれていた。
 もっともずっと以前に読んでいたらこれらのことは気づかずにふーんとスルーしていたにちがいないけど。

2018年7月22日日曜日

setf

 setfではassocを使えないんだね1。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (assoc 3 wrk) 123)
; Evaluation aborted on #<UNDEFINED-FUNCTION (SETF ASSOC) {1003D452D3}>.
CL-USER>

 でもこうすると、中身を変更できるんだ。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (cadr (assoc 3 wrk)) 99)
99
CL-USER> wrk
((1 2) (3 99) (5 6))
CL-USER>

 これまた、RDBっぽい。
 ちなみにまちがって下記のように書いたらSBCLは即エラーになったけれど、ABCLは永久ループにはまりこんでしまった。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setf (cadr (assoc 3 wrk)) wrk)

 elispはどうだろう。

(setf wrk '((1 2)(3 4)(5 6)))
((1 2) (3 4) (5 6))
(setf (cadr (assoc 3 wrk)) wrk)
((1 2) (3 #0) (5 6))
wrk
((1 2) (3 #0) (5 6))

 なんじゃ?

Footnotes:

1

setfできるassocがalexandriaにあるらしい。

2018年7月20日金曜日

delete

 listを操作する関数で破壊的なものはあまり使う気になれなかった。意外なところに影響がでたりするからだ。でもsetfは便利だな、と思っていて、そういえば、listの一部だけ削除するにはどうしたらいいんだろう。
 deleteを見つけて色々、試してみて思った。
 これってassocと組み合わせるとすごくね?

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (delete (assoc 3 wrk) wrk)
((1 2) (5 6))
CL-USER> wrk
((1 2) (5 6))
CL-USER>

 RDBみたいじゃん。
 deleteのような破壊的関数ではなく、removeというのもあった。

CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> (setq wrk2 (remove (nth 1 wrk) wrk))
((1 2) (5 6))
CL-USER> wrk
((1 2) (3 4) (5 6))
CL-USER> wrk2
((1 2) (5 6))
CL-USER>

 もしかしたら、と思って試してみたら。
 wrkとwrk2の要素は共有されていた。

CL-USER> (setf (caar wrk2) 123)
123
CL-USER> wrk
((123 2) (3 4) (5 6))
CL-USER> wrk2
((123 2) (5 6))

 おもしろい。
 elispでも同じことができるけど、deleteの比較はequalだった。eqのものはdelq。CommonLispはどうやらeqらしい。:testで変更できるけど。

2018年7月17日火曜日

slime-eval

 CommonLispを使うようになってelispをプログラミングする気力がなくなってしまった。
 別にLisp四天王でelispが一番、最弱だから、というわけではなく、CommonLisp——SBCL——のレスポンスが速くてelispを使う気がしなくなってしまったのがひとつ。もうひとつは別プロセスで動くので、Emacsがかたまるということがない。こっちの方が理由としては大きいかもしれない。
 ただ、やはりエンドユーザとのインターフェイスをもっているというのは大きくてなんだかんだと選択肢はelispということになってしまう。
 じゃあバックグランドでCommonLispを動かしてしまえば、いいじゃん。
 S式でやりとりできるだろうし。
 roswellスクリプトをshell-commandで起動して……とか、考えて面倒くさっ、と思ってしまった。もっと簡単にできないものか。

 そもそもEmacsとCommonLispでやりとりしているわけだし。
 ——slimeに何か、あるんじゃね?
 そう思ってつらつらslimeのソースをながめていたら。
 「slime-eval」というものを見つけた。
 slimeを動かして*scratch*で——。

(slime-eval `(cl-user::+ 1 2 3))
6

 おおっ。
 eval自体はSWANK-IO-PACKAGEの中で動いているらしく、packageをフル指定しなければ、ならなかったけれど。
 listだって返ってくる。

(setq wrk (slime-eval `(cl-user::list 1 2 3)))
(1 2 3)
(car wrk)
1

 elispとシームレスにやりとりできるじゃないか!
 しかも非同期バージョンと思しき、「slime-eval-async」もある。
 「asdf::load-system」だってelispから動かせる。

 しかし、elispの変数の中身をわたすには——。

(setq wrk 4)
4
(setq wrk (slime-eval `(cl-user::list 1 2 3 ,wrk)))
(1 2 3 4)

 こうか。
 それにしてもこのやり方ってlispにしか、できない芸当だよなぁ1。

Footnotes:

1

shellもできるか……。

2018年7月15日日曜日

(unintern 'function)

 けっこうdefmethodが好きだ。
 引数の型によって処理をディスパッチできるので同じ名称をつけることができる。ただ、REPLでdefunで定義したものをあらためてdefmethodにしようとするエラーになってしまう1。いちいち、restartさせなければ、ならず……ああ?
 まてよ、所詮、シンボル。
 もしかしたら。

(unintern 'function)

 で、いけるんじゃね?
 defmethodで定義できるようになるんじゃね?
 ——いけた2。

Footnotes:

1

SBCLだけ?

2

追記。いけたと思っていたのだけど、だめなケースもあるみたいで
方法を探してみたところ

(fmakunbound 'function)

で、できるらしい。

2018年7月13日金曜日

nilってほんとうにNULLなのか!

 けっこうdefmethodが好きだ。
 というのも引数によって処理を分岐する関数をつくることが多いから。
 たとえば(下記はelispだけど)。

(defun y-string-to(x)
  "stringへ変換"
  (cond ((null x) "")
 ((listp x)(y-string-to (car x)))
 ((symbolp x)(y-string-to (symbol-name x)))
 ((stringp x) x)
 ((numberp x) (number-to-string x))
 ((vectorp x)(y-string-to (aref x 0)))))

 とか。
 defmethodを使えば、これらは全部、分けられる。

(defmethod y-string-to((x string))
      x)

(defmethod y-string-to((x number))
      (format nil "~D" x))

 とか。でもstringでもnumberでもないnilのときはどうすれば、いいねん、と思っていたら定義できるのだった。

(defmethod y-string-to((x null))
      "")

 nilってNULLってタイプなのか!

DEF> (type-of nil)
NULL
DEF>

2018年7月11日水曜日

Lispに型はないと思っていたら

 どうしてか、Lispには型がないとばかり思っていた。
 さすがに文字列と数値とかはあるだろうけど、と。

DEF> (type-of :ABC)
KEYWORD
DEF>

 ってやってみて驚いた。
 「:」付きってkeywordという型をなのか。
 あるじゃないか。型。
 以前からよくわからなかった「:」はkeywordという型指定ということになるのか、つまり。もしかしたらリーダーマクロで実装されているんだろうか?

 というか、根本的に勘違いしているじゃないか。

Lispはプログラムの実行時まで呼び出すべき変数のデータ型や関数の実体が決まらない動的束縛(late bindingともいう)の言語である。

竹内郁雄「初めての人のためのLisp [増補改訂版]」

2018年7月9日月曜日

みたび、package

 たとえば、次のようなpackageとclassを定義したとする。

(in-package :cl-user)

(defpackage abc
  (:use :cl)
  (:export :<abc>))

(in-package :abc)

(defclass <abc> ()
  ((abc :initarg :abc
  :reader get-abc
  :documentation "abc")))

(in-package :cl-user)
(defpackage def
  (:use :cl
 :abc))

(in-package :def)

(defclass <def> (<abc>)
  ((def :initarg :def
  :reader get-def
  :documentation "def")))

 で、defの中でinstanceを作成。

DEF> (setq wrk (make-instance '<def> :abc "111" :def "222"))

 まぁ、WARNINGは多少でるけれど、中身は設定されている。

DEF> (get-def wrk)
"222"
DEF>

 get-abcが効かないのは関数をexportしていないのでDEFから見えていないからだろう。

DEF> (get-abc wrk)
; in: GET-ABC WRK
;     (DEF::GET-ABC DEF::WRK)
; 
; caught STYLE-WARNING:
;   undefined function: GET-ABC
; 
; caught WARNING:
;   undefined variable: WRK
; 
; compilation unit finished
;   Undefined function:
;     GET-ABC
;   Undefined variable:
;     WRK
;   caught 1 WARNING condition
;   caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNDEFINED-FUNCTION GET-ABC {1003F36EE3}>.
DEF>

 ところがslot-valueでabcの中身を見にいってもエラーになる。

DEF> (slot-value wrk 'def)
"222"
DEF> (slot-value wrk 'abc)
; Evaluation aborted on #<SIMPLE-ERROR "~@<When attempting to ~A, the slot ~S is missing from the ~
   object ~S.~@:>" {10040EC8D3}>.
DEF>

 これがしばらく理解できなかった。
 というのもelispのEIEIOではうまくいくからだ。
 HyperSpecのdefpackageの説明を見ていてexportしているのはsymbol-nameだと気づいた。functionじゃないんだ……。つまりClassの中で定義しているslot-nameもexportしなければ、いけない。
 それならこれでも動くはず。

DEF> (slot-value wrk 'abc::abc)
"111"
DEF>

 実際にexportしてやっても動いた。

(defpackage abc
  (:use :cl)
  (:export :<abc>
    :abc))
DEF> (slot-value wrk 'abc)
"111"
DEF>

 EIEIOで動いていていたのはpackageがないからか……。
 でもslot-nameなんてばりばり競合してしまうでaccessorをexportするのが、吉なんだろうな……。accessorならmethodなので同じ名前が存在しても競合する可能性はきわめて低いから。

2018年6月29日金曜日

なんとEmacsが使える!

 重い処理をSLIMEからCommonLispをやらせていてちょっと感動した。
 なんとEmacsが使えるのだ1。
 elispにやらせていたときはなーんもできんようになっていたのに。処理自体も全然、速いし。これからはelispではなく、CommonLispを使うようになるかも。

Footnotes:

1

よくよく考えたら当たり前

2018年6月27日水曜日

とりあえず、データ変換

 とりあえず、データを加工してごっそり変換するプログラムをつくった。
 DBに格納しておいてそれをあとで利用しようというわけ。
 ところが変換中、元々残りわずかだったMacBookAirのディスクスペースが満杯になってしまった。あわてて中断したけれど、いかんじゃないか、これは。
 まいった。
 あれだな、これはPostgreSQLを別のパソコンに持っていくのが吉か。
 そう思って全然、使っていないBeelink S1のUbuntuにPostgreSQLをインストールした。psqlも。基本になるデータをpg_dumpでつっこんでリモートアクセスできるように設定して。
 動かした。
 MacBookAirのCommonLispから。20年分近いデータだ。時間がかかるだろうなぁ、と思っていたらBeelink S1が固まった——固まったと思った。terminalが反応しなくなったのだ。
 これだから安物は。
 熱暴走か——Beelink S1は熱が溜りやすいとか、なんとかいう噂を耳にしていたのだ。たしかに筐体は熱くなっていた。けれど、何度か、試してみているうちに、原因はBeelink S1ではないことに気づいた。
 topコマンドでみると、「kswapd0」というプロセスで固まっている——ように見える。「kswapd0」とはなんぞ。ググってみてページングプロセスらしいことがわかる。そうやってtopコマンドの出力を見直してみると、たしかにswapメモリが0になっていた。Linuxのせいかよ!
 いやこんなに簡単に固まるようじゃ、世間様が使うわけはない1。
 固まっているように見えるが、実は非常にレスポンスが悪くなっているだけで——何もできないけど。もしかしたら自分のせいじゃね?
 組んだプログラムが悪いんじゃね?
 でも。
 毎回、commitするようにしても固まるし。
 毎回、connectしなおすようにしたらsocketを取得できなくなってCommonLisp側がハングアップしてしまうし。
 あかんじゃないか。
 そりゃあ、プログラムを動かさなければ、固まらないさ。それじゃ、意味がない。swapを拡張しても1年分ほどで固まっているから問題の解決にはならんだろうし。

 たぶん状況から考えてリモート接続していると、PostgreSQLがメモリを食い潰しているのだろう(ローカルで動かしたpg_dumpはうまくいっているのだから)。そこでUbuntuにCommonLispの環境をつくってローカル接続からデータ変換するようにしたところ。
 うまくいった。
 swapメモリはまったく消費せずに2。

Footnotes:

1

一瞬、FreeBSDをインストールしなおそうか、とは思ったけど。

2

腹立たしいことにそのあと、MacBookAirに変換したデータをつっこんでもディスクが満杯になるようなことはなかった。

2018年6月23日土曜日

HyperSpecをローカルで

 hyperspecのデータをどこぞからもってきてローカルの保存して「common-lisp-hyperspec-root」に場所を定義すれば、よいらしい。

common-lisp-hyperspec-root is a variable defined in ‘hyperspec.el’.
Its value is "http://www.lispworks.com/reference/HyperSpec/"

Documentation:
The root of the Common Lisp HyperSpec URL.
If you copy the HyperSpec to your local system, set this variable to
something like "file://usr/local/doc/HyperSpec/".

 となっていたのだけれど、ewwだと「file://usr/local/doc/HyperSpec/」にしていると、うまくいかなかった。ftpで接続へ行ってしまう。
 なので色々、試した結果。

"file:/usr/local/doc/HyperSpec/"

 「//」を「/」にした。

2018年6月21日木曜日

packageふたたび

 ソースを見ると、cl-dbiはdbiというpackageだった。

(defpackage dbi
  (:use :cl
 :dbi.error)
  (:nicknames :cl-dbi)
  (:import-from :dbi.driver
  :list-all-drivers
CL-USER> (cl-dbi::select "123")

; in: DBI::SELECT "123"
;     (DBI::SELECT "123")
; 
; caught STYLE-WARNING:
;   undefined function: DBI::SELECT
; 
; compilation unit finished
;   Undefined function:
;     DBI::SELECT
;   caught 1 STYLE-WARNING condition
; Evaluation aborted on #<UNDEFINED-FUNCTION SELECT {10065F6893}>.

 それに気づかずに、自分もdbiというpackageにしたら。

CL-USER> (defpackage dbi
  (:use :cl
 :cl-dbi)
  (:nicknames :keiba-dbi))

(in-package :keiba-dbi)

(defun select(sql)
  sql)
WARNING: DBI also uses the following packages:
  (DBI.ERROR)

【割愛】

  The ANSI Standard, Macro DEFPACKAGE
  The SBCL Manual, Variable *ON-PACKAGE-VARIANCE*
SELECT

 cl-cbiにselectが定義されてしまった。

DBI> (cl-dbi::select "123")
"123"
DBI>

 うわっ。
 これってcl-dbiを拡張してしまったってこと?1

 関数とか、conflictしたらどうするのよ、CommonLispって変、と一瞬、思ったのだけど2、よくよく考えたらC言語とかでも関数名がかぶったら片方が有効になるだけだった。
 そう思うと、javaの、あのディレクトリ構成にマップされた命名規則はconflictを避けるためのものなんだなぁ、といまさらながら。3。

Footnotes:

1

プロンプトを見ると、何が起きたか、一目瞭然だった。

2

なんとなく、Lispってレキシカルって思った。

3

完全に避けることは不可能だろうけど。

2018年6月19日火曜日

ふぉー、まっと

 sql文を組み立てるため、formatを使った。
 CommonLispのformatは全然、ちがうというのは知っていたのだけれど、まぁ、「~S」が文字列だろう、と簡単に考えたら全然、ちがっていた。

CL-USER> (format t "あああ~Sかかか" "ABC")
あああ"ABC"かかか
NIL

 まさか「"」付きになるとは。

CL-USER> (format t "あああ~Aかかか" "ABC")
あああABCかかか
NIL

 「~A」か。
 しかも第一引数で出力先を指定している。nilでは標準出力になる。tで変数へ出力できる。まるでprintf()とsprintf()みたいだ。でもformatの構文は全然、ちがう。

2018年6月17日日曜日

あっ、ぷらい

 cl-dbiで返ってきたデータにはめんくらってしまったのだけど。
 こんなデータ。

(:|date| 3281472000 :|place| "A7")

 DBのカラム名と値が交互にならんでいる。
 きっと何か、うまくやる方法があるんだとは思っていた。値をひっぱりだすのにgetfを使うというのは了解した。

CL-USER> (setq wrk '(:|date| 3281472000 :|place| "A7"))
(:|date| 3281472000 :|place| "A7")
CL-USER> wrk
(:|date| 3281472000 :|place| "A7")
CL-USER> (getf wrk :|date|)
3281472000

 きっとkeyとしても使えるにちがいない。それがよくわからなかった。applyかな、とは思っていたのだけど、うまく動かない。

CL-USER> (defclass <wrk> ()
    ((date :initarg :date)
     (place :initarg :place)))

#<STANDARD-CLASS COMMON-LISP-USER::<WRK>>
CL-USER> (apply #'make-instance '<wrk> wrk)
; Evaluation aborted on #<SB-PCL::INITARG-ERROR {10048A9723}>.
CL-USER>

 ふと気づく。

CL-USER> (defclass <wrk> ()
    ((date :initarg :|date|)
     (place :initarg :|place|)))

#<STANDARD-CLASS COMMON-LISP-USER::<WRK>>
CL-USER> (apply #'make-instance '<wrk> wrk)
#<<WRK> {1004641BE3}>
CL-USER>

 そっか。
 defclassの定義で「:date」としていたのが、まちがいだったのだ。
 CommonLispのsymbol名は基本、大文字小文字の区別がないのだけれど、「|」付の場合は区別しているという意味だった(それは一応は知っていた)。「|」付で定義すると、区別あり、と定義できるのだった(これには気づいてなかった)。DBのカラム名は普通、大文字小文字の区別があるのでこうなっているのだろう。

 これでcl-dbiからの返却値を一気にクラスに流しこむことができる。
 この「apply」を使うやり方に気づいてから一気にコード量が減った。ちまちまと値を設定しているところがごっそりなくなったので。
 applyって凄い1。

 それにしても「:」付のsymbolってどうやってつくるんだろう?
 単純にinternしてもだめなんだよなぁ。

CL-USER> (intern "date")
|date|
:INTERNAL
CL-USER>

Footnotes:

1

いや、listが凄いのかも。

2018年6月16日土曜日

defclass

 データのかたまりはやはりstructか、classにした方がいいよな。
 EIEIOを使ったのときはクラスを定義した。
 あれが丸々、使えるんじゃね?
 そう思ってコピったところ、エラーになる。しかもdefclassのところ。何でよ。同じじゃないの。目を皿にしてようやく気づいた。EIEIOでは「:docment」だけど、CLOSでは「:documentation」だ……。

2018年6月15日金曜日

cl-project

 「~/.roswell/」の下をつらつら見ていると、「local-projects」というフォルダがあった。二カ所。

~/.roswell/local-projects/
~/.roswell/lisp/quicklisp/local-projects/

 ああ、ここの下に自分がつくりたいプログラムをいれておけば、いいんだな、と見当をつけてとりあえず、「cl-project」でprojectを作成した。

CL-USER> (cl-project:make-project #p"~/.roswell/local-projects/keiba/"
  :author 名前
  :email メールアドレス
  :license ライセンス
  :depends-on '(:cl-dbi :cl-ppcre))
writing ~/.roswell/local-projects/keiba/keiba.asd
writing ~/.roswell/local-projects/keiba/keiba-test.asd
writing ~/.roswell/local-projects/keiba/README.org
writing ~/.roswell/local-projects/keiba/README.markdown
writing ~/.roswell/local-projects/keiba/.gitignore
writing ~/.roswell/local-projects/keiba/src/keiba.lisp
writing ~/.roswell/local-projects/keiba/t/keiba.lisp
T

 (asdf:load-system :keiba)でsystemをロードすると、cl-dbiもロードされる模様。ふむ。なるほど。

CL-USER> (asdf:load-system :keiba)

; compiling file "/Users/yamada/.roswell/local-projects/keiba/src/keiba.lisp" (written 10 JUN 2018 09:29:31 AM):
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFPACKAGE KEIBA ...)
; compiling (IN-PACKAGE :KEIBA)

; /Users/yamada/.cache/common-lisp/sbcl-1.3.11-macosx-x64/Users/yamada/.roswell/local-projects/keiba/src/keiba-TMP.fasl written
; compilation finished in 0:00:00.005
T

 (ros::load-system "keiba")でも同じみたいだ。
 わからないのは

CL-USER> asdf:*central-registry*
(#P"/Users/yamada/.roswell/lisp/quicklisp/quicklisp/")

 なのに、#p"~/.roswell/local-projects/keiba/"をasdfが認識していること。qlが下記のようになっているのでRoswellはわからなくもないけど。

CL-USER> ql:*local-project-directories*
(#P"/Users/yamada/.roswell/local-projects/"
 #P"/Users/yamada/.roswell/lisp/quicklisp/local-projects/")

 不思議。

2018年6月13日水曜日

環境

 当たり前の話だけれど、REPLを立ち上げなおしたら1今までの作業がきれいさっぱり消えてしまった。あらためてちまちまとloadしなおさなければ、いけないとは思えず、たとえば、Emacsでいえば、load-pathみたいな仕組みがどこかにあるんじゃなかろうか?
 どうやらASDFとか、quicklispとかがその仕組みらしいのだけれど。

require, ASDF, quicklispを正しく使う

第6回 Common Lispライブラリを書く

 上記以外にもあちらこちらのサイトを読んで考えこんでしまった。なんか、情報が錯綜している。頭の中がごちゃごちゃになってしまった。defsystemってなんぞ2。そこで「SBCL」とか、「asdf」のinfoを読みなおしながら自分の環境のパス構成を確認。なんか、おかしい。
 「~/.sbclrc」とか、「~/common-lisp/」とか、見当たらない。
 それを作成して設定すれば、いいのか? でもなんか、根本で道を誤っているような気がする。
 あっ。
 思い出した。
 下記のサイトを見てRoswellを使ってsetupしたんだった。

Common Lispとリアル・ワールドを繋ぐ「Roswell」の紹介

 ということはそもそもRoswellを調べなきゃ、いかんのと、ちゃう3?

Footnotes:

1

(slime-restart-inferior-lisp)

2

asdfが提供している何かですかね

3

manがあった。

2018年6月11日月曜日

plistなんて知らんがな

 それにしてもcl-dbiで返ってきたデータにはめんくらった。
 こんな感じのlistになっていたからだ。

(:|date| 3281472000 :|place| "A7" :|count| 3 :|day| 7 :|raceno| 1 :|umano| 1 :|name| "アドマイヤマドンナ" :|sex| "牝" :|age| 2 :|time| 1137/10 :|umaorder| 13 :|odds| 502/5 :|ninki| 13 :|stable| "南井 克巳" :|weight| 54 :|forecast| :NULL)

 中身のことは別にどうでもいい1。
 「:|date|」の部分はテーブルのカラム名なのだろう、ということはわかるけれど、「:」と「|」には何か、意味があるのか? そもそもこんな形式で? mapcarで舐めてdateの次のものを値とあつかうなんて面倒じゃないか?
 たとえば、pg.elだと((data . 3281472000)(place . "A7")….)みたいな感じで返却されてきていた。alistというらしいが、これならassoc2で簡単に値を求めることができる。それがなんでまたこんな形式に?
 alistに変換する関数を書くか、と考えながらあちらこちら調べていたらgetf? 何、それ? おいしいの?
 返却されてきたlistは実はplistというものらしい。
 (getf list :|date|)
 で、値を求めることができた。
 getfは素のelispにはなく、cl.elに定義されていた。

 でも「:」と「|」の謎は解けていないのだった。

すこしわかった。

Footnotes:

1

競馬のデータだ。

2

(nth 1 (assoc 'date list))みたいな感じで。