Ice は冷たいのか, それとも 3文字なのか.


使用と引用

「凹み(へこみ)にはめる」と「凹は凸な図形ではない」 といったばあい, 同じ凹という文字だが, その使い方は異なっている. 前者は使用であり, 後者は引用だ. つまり, 最初の文章が文法的に正しいのなら 後の文章は文法的に誤りである.

最初の文章の文法を尊重して厳密さを期せば, あとの文章はこうなる. 「"凹" は凸な図形ではない」 というわけで, あの記号は引用符と呼ばれる.

シンボルと値の関連は任意で, そのありようは, 本来シンボルの使用者に委ねられている. でも, いちいち関連を宣言していたのではウザいので, 通常は 広く通用しているお約束というのがあり, みんなそれに従っているわけです. すると, ついそのシンボルと値の関連は自明なものであり, それ以外の選択肢はありえないかのように思われて来ます. しまいにシンボルと値は同一視されるに至ります.

引用と使用は, 文脈から明らかな事も多いので, 言語によっては区別しないこともありますが, シンボル一般が持っているこのような性質からすれば, これは言語のありようとしてかならずしも厳密であるとは言い切れません. あるいは, 一般的な原則を無視していると言っても良いかも知れませんね. たとえば, 数学では x=5 のとき x*2=10 なんて書きます. 最初の数式に出て来る "x" は引用で, あとの数式に出て来る "x" は使用ですな.

ええかげんな書き方をしても判ってもらえる天然知能相手の数学は こんなでたらめな表記で通りますが(数学は論理的だと信じている おめでたい人々に祝福のあらんことを. 笑), このへんは, プログラミング言語はさすがにちゃんとしてます.

たとえばシェル. 使用は $a で引用は普通に a と表記します. 使用の方が文字の数が多いってのは, どういうわけでしょうか? シンボルの使い方として普通なのは使用の方ですから, この仕様は若干謎ですな. 誰か由来をご存知ありませんかね?

LISP では, 使用は a で引用が 'a です. こっちは直観的に引用っぽい感じですね.

LISP の引用はシンボルとなる文字列の左側にしか無いっすね. 日常言語みたいに, なんで囲まないのでしょう? それは, 空白が来たら 引用終わりってことになってるからですな.

LISP オブジェクトには, シンボル, 数値, 文字列, 関数, その他イロイロ(emacs だとバッファとか)などがあります. このうち値を持ったりできるのはシンボルだけ. あとは操作不能な 単にそこに存在しているモノすなわち LISP オブジェクトです.

シンボルとオブジェクトだけからなる世界. それが LISP ワールド. こういう, 世界に関するスルドい洞察を厳密に徹底させた設計の言語. それが LISP . ビリビリ. あぁシビレルぅ.

ちゅうわけで, 本日の一つ目のお題. setq ですな. setq は set と quote をまとめた奴です. LISP で "a" といったらそれは "a" の値のこと. "a" に 5 を代入したかったら, "'a" と書かねばなりません. というわけで, シンボルと値の関連に関する上記の原則を徹底した書き方を すればこうなります.

(set 'a 5)

しかしながら, これを毎回やるのはウザいので, こういう書き方もできるように なりました

(setq a 5)

厳密に徹底させたといいつつ, イキナリ原則をぶち破った書き方を 許容してしまうところが LISP っておちゃめ. 笑.

LISP は実用的なプログラミング言語なので, シンボルの値は関数だったりもします. ところで関数って何じゃらほい.

関数ってのは, 要するに, 入口と出口のある箱ですな. 何か入れる. で, 箱をガガっと振ると出口から何か出て来る. そんなようなもんです. 何も入れなくても出て来ることもありますが. C なんかだと何も出て来ないのもありですが, LISP は必ず何か出て来ることに なってます.

シンボルの値が関数だったりするから, LISP は実用的なプログラミング言語として 存在しています. ところで, 関数をシンボルの値にするって言うけどそれって一体?

ま, そういうことができたと今は仮定しましょう. すると, emacs lisp でよくでてくる「でふん」の正体は, setq の正体をさっき見たように, 実はこうなんじゃねぇか?という気が してきますね?

(set '関数名 (よくわかんねぇけど関数の本体))

これができるのが scheme. できないのが LISP . もげー. ここはかなりややこしいぜ. すまんのう. LISP では, シンボルの値には 2 種類があるのじゃ. 一つは 変数としての値. もう一つは関数としての値じゃ. scehme では, そういう区別は無くなって統一されておる. そして, 単に "a" と言った場合, それは変数としての値にアクセスするのじゃ. 関数としての値にアクセスするのは, カッコの最初の中身になった時だけじゃ.

関数としての値をいじるには, emacs lisp では define-function というものを使ってくれっす. つまり, こうなるわけ

(define-function '関数名 (よくわかんねぇけど関数の本体))

関数の本体に, たとえば (* x x) とか書くとしましょう. 自乗する関数ってつもりでね. でも, これだと関数の本体じゃないのですよ. こりゃどうなるかというと, x の値がありませんということになるわけさ.

じゃあ x の値を決めときゃいいんじゃない?と思った人は甘いね. たとえば 10 にしたとするじゃないですか. そうすると, 関数の本体のはずが, 単に 100 という数値になっちゃうわけさ.

ここで, 関数に名前を付けるという特殊な関数を用意して (* x x) でオッケーな風に 作る, というインチキもありえるわけだが, それよりもずっとカッコイイ 設計を LISP の設計者達は選んだ. これは Haskel Curry や Kleene などの 計算論の偉い人々の遺産でもある.

シンボルの扱いの原則を破って関数を定義するための特殊な関数を用意するのではなく, これを守りつつ関数本体だけを取り出す関数を作る方を彼等は選んだのだ! さあ, 皆さん, ここで起立して拍手です!

それが本日二つめのお題. lambda です. これで, 変数から切り離して関数だけを取り出すわけさ. 専門用語で言えば, 関数抽象というやつです.

(define-function 'hoge (lambda (x) (* x x)))

そして再び. こういうのはいちいち書いてると面倒だから, まとめてこうなった.

(defun hoge (x) (* x x))

原則をほとんど原理主義的に守りつつ, 簡単な書き方も用意する LISP の寛容に栄光あれ. つうか, おかげでかえって解りにくいか. 笑.

買物

未だに ナマPnetium 150MHz に 56MBytes メモリなどという 低スペックのパソコンを使っている私でして, 元もとそういう方面の物慾にはとんと疎いのです. もっとも最近に自分用の買物をしたのは, 小さい光学マウス である.

それ以来, 3年ぶりくらいに, アキバ系の買物をしたよ. といっても, 新しいパソコンではない. またしても光学マウスです. Logitech のちょっとカワイイ形のやつ.

付けてみる. 机も焦げよとばかり, 高輝度の発光ダイオードが ビィムを発射しまくっておる. そう, 今日びの光学マウスは 座標不要なのだ. というか, 自分で座標を持っておるのだ. おお. ちゃんと動いた. すげぇぜ. 当り前か. ヒヒヒ. センサ部分を指でなぞると動くぞ. 当り前か. うを! X がバグった. 今, マウス関係が壮絶にバグってます! キーボードは生きてるな. 一回サスペンドしたら治った. ふう. うむー. けっこうこの光学マウスを使いこなすのはムズい?

判った. トラックボールとマウスを同時に動かすとおかしくなる. 結局, BIOS でトラックボールをオフにした.

ホイールも付いてるんで, せっかくだから設定してやろう. む. 動かん. ホイールもちゃんと動いてる清水に訊いてみた. それに従って, プロトコルを IMPS/2 にし, ZAxisMapping を設定してみる. xev でみると, 何らかの信号を Xサーバが受信している様子ではある. どうもこりゃ動きそうだ.

とりあえず動いた. こんな感じらしい. まず, ホイールをまわすと X サーバとしては Z 軸(ってどっちだ? 笑) 方向の移動ということになっているらしい. これを, ZAxisMapping というのでボタンの 4 と 5 に割り当てるのだそうだ. この割り当てが, 3ボタンエミュレートしてるとちゃんと動かない. XF86Config でこんな感じだ.

   Section "Pointer"
   Protocol        "IMPS/2"
   Device          "/dev/mouse"
   #   Emulate3Buttons
   Emulate3Timeout 250
   Buttons 5
   ZAxisMapping 4 5
   EndSection
  

あとは, ボタン 4 と 5 を何かに割り当てれば良い. たとえば emacs でスクロールさせるなら,

(define-key global-map [(button5)] 'scroll-up-command)
  

Gtk でできてるものは, 特に何もせんでも割り当てられているらしく, 勝手に適切に動いた.

んむー. 今さらですが, ホイールでスクロールできるのは, 便利じゃね. 今さらながら, Gtk も良い.


記事リストへ