ITコンサルの日常

ITコンサル会社に勤務する普通のITエンジニアの日常です。

「Ansi Common Lisp」7章読了

入出力に関する章。
普通のプログラミング言語の入門書なら、まず外せない内容でしょうね。
「ふつうのHaskellプログラミング」では、Wikiエンジンの開発の中で取り上げられていたみたいですが、ここ読んでないので結局標準入出力しか分かってないなあ。。

ストリーム

ファイルを書き込んでみる。

* (setf path (make-pathname :name "myfile"))
Warning:  Declaring PATH special.

#p"myfile"
* (setf str (open path :direction :output
                       :if-exists :supersede))

#<Stream for file "myfile">
* (format str "Something~%")

NIL
* (close str)

T
* 
taka@taka-desktop:~/lisp$ more myfile
Something
taka@taka-desktop:~/lisp$

ファイル名としていきなり文字列を与えるのではなく、パス名とかいうのを与えるらしい。原注に、

パス名の代わりにストリングを与えることもできるが、可搬性がない。

とあるので、一応やってみる。

* (setf str (open "myfile2" :direction :output))

#<Stream for file "myfile2">
* (format str "Hello, world!")

NIL
* (close str)

T
*
taka@taka-desktop:~/lisp$ more myfile2
Hello, world!
taka@taka-desktop:~/lisp$

普通に動くみたい。


今度はファイルを読んでみる。

* (setf in (open "myfile2" :direction :input))

Warning:  Declaring IN special.

#<Stream for file "myfile2">
* (read-line in)

"Hello, world!"
T
* (close in)

T
*

with-open-fileマクロを使うと、Rubyのブロック付きopenみたいなことが出来るらしい。(というか、Rubyのブロック付きopenが、Common Lispのwith-open-fileマクロみたいなもの。といった方がいいのかも。歴史的背景は良く分かりませんが。。)
つまり、読み込みとか書き込みに失敗しても、closeは保証されますよっていうことです。

* (with-open-file (str path :direction :output
                            :if-exists :supersede)
    (format str "Anything~%"))

NIL
*
taka@taka-desktop:~/lisp$ more myfile
Anything
taka@taka-desktop:~/lisp$

入力

readは、入力を解析してLispオブジェクトとして返す。

* (setf abc (read))

Warning:  Declaring ABC special.
(lambda (x) (* x 2))

(LAMBDA (X) (* X 2))
* abc
;
(LAMBDA (X) (* X 2))
* (eval abc)

#<Interpreted Function (LAMBDA (X) (* X 2)) {580BF109}>
* (funcall (eval abc) 2)
;
4
*

なんでevalしないと動かせないのだろうと思ったら、

* (inspect abc)

Object is a LIST of length 3.
0. LAMBDA
1. (X)
2. (* X 2)
>

単なるリストだからなのですね。

出力

出力といえばformat(printfみたいなもの)ばかり使ってきましたが、prin1、princ、printなどの関数も使えるようです。

* (prin1 "Hello")
"Hello"
"Hello"
* (princ "Hello")
Hello
"Hello"
* (print "Hello")

"Hello"
"Hello"
*

マクロ文字

マクロ文字(macro character)は、readが特別扱いする文字である。

とあるように、リストを作るための"("や")"、quoteの省略形"'"、functionの省略形"#'"とか。