Archive for 7月, 2010

式Mのxをyに置き換える

土曜日, 7月 17th, 2010

λ計算だとか、数学よりの話をするときはよく、

式Mのxをyに置き換えたものを
M[x:=y]
で表す.

なんて定義が出てきます。
本によっては、まったく同じことを表すのに、
[y/x]M
だとか、
M[y/x]
といった記法も使います。

本日、このM, x, yの順番に、意味がある(かもしれない)ことに唐突に気づきました。

Mxyに置き換える
M[x:=y]

M[x:=y]は日本語表記と完全に一致するじゃないですか、
なんか読み易いと思ったらそういうことか。

それから、[y/x]Mは英語だと意味をなします。

Substitute y for all x in M.
[y/x]M

完全に一致。

しかし、そうなるとM[y/x]が浮いてしまうんですが、
これには何か意味があるんでしょうか。
謎です。

#+のちょっといい話

火曜日, 7月 13th, 2010

Lispでは式1個だけをコメントアウトしたいことがよくあります。

(list A B C)

このようなプログラムで、Bをコメントアウトするときに、
行コメントをつかうと非常に不格好になります。

(list A ;B
  C)

ブロックコメントコメント #| … |# を使えばもう少し奇麗に書けますが、面倒です。

(list A #|B|# C)

Schemeの場合、R6RSで式コメントが書けるようになりました。

(list A #;B C)

非常に簡潔です。素晴らしい。

Common Lispで同じことをする場合、#+を使います。
#+はCで言うところの#ifdefであり、環境に依存するコードを書くときによく使います。

(defun do-something-quickly()
  #+allegro ACL専用の処理
  #+sbcl SBCL専用の処理
  #+clisp CLISP専用の処理
  #-(and allegro sbcl clisp) (error "Use ACL, SBCL or CLISP.")
)

#+X Yと書くと、(member X *features*)が真であれば、Yがリードされ、
偽であればYは読み飛ばされます。
*feature*に含まれないシンボルXをわざと書けば、式コメントが実現できます。

;; 例1
(list A #+nil B C)
;; 例2
(list A #+ignore B C)
;; 例3
(list A #+comment B C)

多くの場合、上の3つの例はうまく動いてくれますが、
万が一、*feature*にnilやignoreやcommentが含まれている場合、Bがコメントアウトされません。

どうしたものかと思いつつ、ずっと #+nil を使い続けていたんですが、
どんな環境でも確実にうまくいく方法を見つけました。

(list A #+(or)B C)

#+(or)です。
#+(or X Y …) Zと書くと、
(or (member X *features*) (member Y *features*) …)
が真のときのみ、Zがリードされます。
つまり、orに引数を与えなければZは常にリードされません。
これで、*features*にnilが含まれていないか心配で眠れない夜ともおさらばです。