Smalltalk(2)

『図解 流体工学のキホン』(Softbank Creative)なんて本を読んでみた。たまには、異業種の 文化に触れてみるのも悪くないと思ったからだ。

そしたら、流体理論にもキルヒホッフの法則が有る事を知った。流体の量は分岐しても保存 されます。(但し、途中で漏水してる場合を除く。そういえば、最近古くなった水道管を新しく してますなんて言われて、田舎でも時々道路が渋滞してんな。)ベルヌーイの定理って言うらしい。

水だけで動くポンプが紹介されてて、びっくりしたよ。最初、錬金術のたぐいかと思っちゃったぞ。 水撃ポンプ と言うそうな。考えた人、頭いいなあ。

流体素子による、 流体コンピュータなんてのも考えられていたらしい。リレー回路を組み合わせた演算器を 作って喜んでいた人は知ってるけど、流体でも出来るとは。。。

まあ、NAND回路(AND + NOT)が実現出来れば、それを元に、フリップ・フリップ回路、それを 組み合わせて、カウンター回路等が容易に実現出来るからね。おいらが、昔初めてICに触れた 時、NORゲートが2つ入ったチップとJK-FFが一個入ったチップの2品種しか無かったからなあ。 でも、それを組み合わせて、周波数カウンターを実現してたな。カウンターの1桁が1枚の ボードで出来てたよ。懐かしい。

基本のものだけで機能を実現するってすがすがしい思いだ。そういう方針を標榜してたSchemeも 時代の趨勢と共に、太ってきてるな。まあ、いいんだけどね。

VisualWorks

本家Smalltalk-80の流れを汲むsqueakがforkしてPharoになり、元祖ってのも有ってそれがvisualworks らしい。昔々のLispと同じだな。んでもって、元祖の方も入れてやろうとしたんだ。でも、使うには 登録が必要らしい。登録したら、コマーシャルメッセージが頻繁に飛んで来るんかね? そんなのヤダな。

それなら、FreeBSDのportsから入れてしまえばいいんでないかい、って、悪魔の囁きをする自分が います。

tar玉5つは、何の文句も言われずに落とせました。厳しい所だと、tar玉は自分で登録してから 落としてこいって言われるんですが、そこは何とか無事にクリアー出来ました。インストールしようとしたら、 今度はFedora10のエミュレータを入れろと迫ってきましたよ。入れてもいいんだけど、ちゃんとした Linux環境がすでにあるからなあ。 そんな訳で、tar玉はArchLinuxの所へ持って行って動かす 事にしよう。運が良ければ動くだろう。動かなかったら、元祖には縁が無かったって事で。

事前に情報収集と言っては大げさですが、FreeBSD上のMakefileを覗いておきます。何たってレシピ ですからね。post-installに

 @${ECHO_MSG} " --------------------------- Please note: ---------------------------"
 @${ECHO_MSG} " "
 @${ECHO_MSG} "  To start using VisualWorks, copy the default image to your"
 @${ECHO_MSG} "  home directory:"
 @${ECHO_MSG} "    # ${CP} ${DATADIR}/image/visualnc.im ~"
 @${ECHO_MSG} "  Make it writeable:"
 @${ECHO_MSG} "    # ${CHMOD} u+w ~/visualnc.im"
 @${ECHO_MSG} "  Then run it using:"
 @${ECHO_MSG} "    # visual ~/visualnc.im"
 @${ECHO_MSG} " "
 @${ECHO_MSG} " -------------------- Thanks for your attention! --------------------"

ふーん、image/visualnc.imを自分の手元に持ってきて、書き込み可にしておけとな。コマンドは、visual って名前か。了解しましただ。

dirを掘って、その中で展開しましたよ。こうしておけば、ポィするのも簡単だからね。展開したら、 Install.pdfなんてもが出てきたけど、面倒だから飛ばして、binの中に潜って行くと、linux86な んていうdirが出てきた。その中は

[sakae@arch linux86]$ ls -l
合計 5208
drwxr-xr-x 2 sakae sakae    4096  3月  4  2008 assert
drwxr-xr-x 2 sakae sakae    4096  3月  4  2008 debug
-r-xr-xr-x 3 sakae sakae   59629  2月 15  2008 herald.so
-r--r--r-- 1 sakae sakae     820  2月 15  2008 readme.txt
drwxr-xr-x 2 sakae sakae    4096  3月  4  2008 userprim
-r-xr-xr-x 1 sakae sakae  681600  2月 15  2008 visual
-r-xr-xr-x 1 sakae sakae 1860223  2月 15  2008 vwlinux86
-r-xr-xr-x 1 sakae sakae 2228914  2月 15  2008 vwlinux86gui
-r-xr-xr-x 1 sakae sakae  472230  2月 15  2008 vwlinux86gui.so

おお、目指すコマンドが有ったわい。こやつArchLinuxに馴染んでくれるかな? 一応確認。

[sakae@arch linux86]$ file visual
visual: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, stripped
[sakae@arch linux86]$ ldd ./visual
        linux-gate.so.1 (0xb7756000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0xb7726000)
        librt.so.1 => /usr/lib/librt.so.1 (0xb771d000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0xb7718000)
        libX11.so.6 => /usr/lib/libX11.so.6 (0xb75e2000)
        libm.so.6 => /usr/lib/libm.so.6 (0xb759f000)
        libz.so.1 => /usr/lib/libz.so.1 (0xb7587000)
        libc.so.6 => /usr/lib/libc.so.6 (0xb73d6000)
        /lib/ld-linux.so.2 (0xb7757000)
        libxcb.so.1 => /usr/lib/libxcb.so.1 (0xb73b4000)
        libXau.so.6 => /usr/lib/libXau.so.6 (0xb73b0000)
        libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0xb73a9000)

一応動きそう。

[sakae@arch linux86]$ ./visual ../../image/visualnc.im
VisualWorks(R) 7.5 Non-Commercial Mar 3, 2008
Fatal error: Unable to connect to X11 server.

ははは、visualって言うだけあって、visualな環境で動かせとな。Xの上で起動したら、何の問題 もなく動いたよ。ああ、一つ問題が有った。システムブラウザーを使ってる時、時々エラーメッセージが 出てくるんだ。内容はvisualなんで、ここに貼れない(から、visual環境は好きではない)けど、 $VISUAL/visual.sou が見当たらんって事からすると、環境変数を指定しとけって事だろうな。

フーリエ変換

図解雑学フーリエ変換(ナツメ社)なんて本も読んでいる。中学校で倣う数学で理解出来るように 平易に解説しました、なんてキャッチャーな言葉が並んでいたからだ。それが、どうしてどうして、 途中から行列は出てくる、常微分方程式、偏微分方程式まで出て来るっていう、てんこ盛りに 圧倒されましただ。で、少々疲れてしまったので、smalltalkでFFT出来るか、ちょいと探って みましたよ。そしたら、こんな親切なのが見つかりました。

| fft sndSamples sndData snd fftSize fftSizeOrder |
"-(1)Waveファイル読み込み."
snd := SampledSound fromWaveFileNamed:'o.wav'.
"-(2)Waveファイル再生."
snd play.
"-(3)FFTの次数計算"
fftSizeOrder := (snd samples size log: 2) asInteger.
"-(4)FFTのサンプリング数計算"
fftSize := 2 bitShift: fftSizeOrder-1.
"-(5)Waveファイルの実サンプル点数"
sndSamples := snd samples.
"-(6)FFT計算のためWaveデータ(16bit整数)を実数に変換"
sndData := FloatArray new:fftSize.
1 to:fftSize do:[:i |
	sndData at: i put:(sndSamples at: i) asFloat.
].
"-(6)--------------------------------------------------"
"-(7)FFT計算:"
Display restoreAfter: [
	"-(8)FFTインスタンス生成"
	fft := ([[FFT]] new nu:fftSizeOrder).
	"-(9)FFTデータ設定"
	fft realData: sndData.
	"-(10)入力データ描画"
	fft plot: fft realData in: (100@20 extent: 256@60).
	"-(11)FFT実行"
	fft transformForward: true.
	"-(12)FFT結果描画"
	"--実部"
	fft plot: fft realData in: (100@100 extent: 256@60).
	"--虚部"
	fft plot: fft imagData in: (100@180 extent: 256@60).
].

実部は振幅、虚部は位相を表すって事は、上記雑学本には出てこなかったなあ。

サンプル品を試す

gstのtar玉にはサンプル品が添付されてた。その中に青木先生作のLispが入っていたので試して みる。FileStreamオブジェクトにキーワード付きのメッセージfileInを送信して、スクリプトを 取り込む。面倒ちゃ面倒なこったな。 そして、例題10を実行。無い例題をやろうとすると、勿論Stack traceを振りまいて怒ってくる。 debiggerを起動して欲しいな。

[sakae@secd ~/work/smalltalk-3.2.4/examples]$ gst
GNU Smalltalk ready

st> FileStream fileIn: 'Lisp.st'.
FileStream
st> LispInterpreter example10.
"Global garbage collection... done"
600
st> LispInterpreter example19.
Object: LispInterpreter error: did not understand #example19
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
LispInterpreter class(Object)>>doesNotUnderstand: #example19 (SysExcept.st:1407)
UndefinedObject>>executeStatements (a String:1)
nil

ああ。例題10って、こんなのね。

example10
    "LispInterpreter example10."

    | aList |
    aList := LispInterpreter evaluateFrom: '

    (progn
        (setq x 100)
        (setq y 200 z 300)
        (+ x y z))

    '.
    ^aList!

S式が文字列として埋め込まれていた。他にも面白そうなものとして、plolog.stとかqueen.st とか有ったよ。でも、読み込むの面倒くせぇー!

gst のオプションも試す

おいしいのが有ったんで試してみた。

[sakae@secd ~/MINE/share/smalltalk/examples]$ gst -D Lisp.st
  :
  class LispInterpreter, selector #subrTerpri
  Allocated stack slots 1
    0:  source line 2692
    4:  source line 2
        push Instance Variable[4]
    6:  send special message #nl
    8:  source line 3
        pop stack top
   10:  push Literal[0] = #t
        return stack top

これ、ソースがどんなVMコードになったかの確認ね。次は、実行時のVMコードダンプ。じっと見て いると、gstの考え方が分かるかも。

st> a _ 1234
    0:  source line 1
    2:  push 1234
    6:  store into Global Variable[0] = a
         :
        push Instance Variable[1]
    4:  return stack top
   20:  return stack top
   10:  return stack top
    0:  source line 0
    2:  terminate interpreter
1234

ここに出てきた アンダーバーは、昔のバインド記号、左矢印の代わりだそうだ。今は普通に、a := 1234 と書くらしい。昔の名残でまごつかないようにしないとな。

emacs for gst

gstを裸の状態で使うのは中学生までです。smalltalkは上で見たようにvisualが基本なんですから。 そこでGNUお得意のemacsです。これってCUI界の標準ツールなんですから。GNU製品には、emacsへの バインディングとInfoで書かれたマニュアルが付く事になってます。

例えば、gst関係のInfoとして

* Smalltalk: (gst).             The GNU Smalltalk user's guide.
* Smalltalk base classes: (gst-base).   The GNU Smalltalk base classes.
* Smalltalk libraries: (gst-libs).      The GNU Smalltalk class libraries.

全クラスの説明が載ってました。squekなんかも全クラスの説明書ってあるのかしらん? ざっと探した限りでは見つからなかったぞ。入門書には勘を働かしてツールを使って探せなんて 書いてあったな。使ってるうちに勘が働くようになるかな。余談はさておき、 そんな訳なんで、emacsからgstを使えるように、.emacsを設定しました。

(setq auto-mode-alist
           (append  '(("\\.st\\'" . smalltalk-mode))
                    auto-mode-alist))
(autoload 'smalltalk-mode "smalltalk-mode.el" "" t)

smalltalk-mode.elの最後で、gst-mode.elを呼ぶなんて事をしてて、gst-modeが隠れちゃって ますがね。で、 C-x C-f Lisp.stして、ファイルを眺めようとしたら、こんなつれないエラーが。

File mode specification error: (void-variable inhibit-first-line-modes-regexps)

M-x smalltalk-modeして、認識するかなと思ったら、

Symbol's value as variable is void: inhibit-first-line-modes-regexps

やはりエラー発現。調べてみると、emacs24で、切捨てられたみたいです。emacsは割りと気軽に 後方う互換性を棄ててくれるんで困ったものですと文句の一つも垂れておこう。 で、smalltalk-mode.elを下記のように修正しました。

(push "\\.star\\'" inhibit-local-variables-regexps)
;;(push "\\.star\\'" inhibit-first-line-modes-regexps)

ここに出て来る .star って、かっこいいサフィックスだなあ。スモールトーク・アーカイブの 略で、狙って付けられる名前じゃないですよ。実体は、世界共通のZIPファイルなんですけどね。 まあ、gstの核の部分を占めているんで、普通の人には用が無いか。

上の修正を施して、やっと動くようになりました。C-c m すると、画面が割れて、gstが 動き出しましたよ。そして、C-c f して、ファイルをロードすると、かかった時間等を表示して くれてます。この報告がうざいって人は、gst-mode.elの中のgst起動オプション、-V を外せば いいです。

GNU Smalltalk ready

st>
2889 byte codes executed
which took 0.041 seconds (0.003s user+0.037s sys)
110 primitives, percent 3.81
self returns 8, inst var returns 0, literal returns 0
103 method cache lookups since last cleanup, percent 3.57
33 method cache hits, 70 misses, 32.04 percent hits
returned value is FileStream
st> LispInterpreter example10
"Global garbage collection... done"
269830 byte codes executed
which took 0.024 seconds (0.007s user+0.013s sys)
17780 primitives, percent 6.59
self returns 561, inst var returns 0, literal returns 0
41529 method cache lookups since last cleanup, percent 15.39
40910 method cache hits, 619 misses, 98.51 percent hits
returned value is 600
st>

サンプル品も簡単に読み込めるので、Queen.stを試してみる。

st> Amazon test: 10
  :
 ___________________
|_|_|_|_|_|_|_|*|_|_|
|_|_|_|_|*|_|_|_|_|_|
|_|*|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|_|*|
|_|_|_|_|_|_|*|_|_|_|
|_|_|_|*|_|_|_|_|_|_|
|*|_|_|_|_|_|_|_|_|_|
|_|_|_|_|_|_|_|_|*|_|
|_|_|_|_|_|*|_|_|_|_|
|_|_|*|_|_|_|_|_|_|_|

540485 byte codes executed
which took 0.010 seconds (0.011s user+0.000s sys)
2180 primitives, percent 0.40
self returns 6, inst var returns 0, literal returns 0
88414 method cache lookups since last cleanup, percent 16.36
88306 method cache hits, 108 misses, 99.88 percent hits
returned value is 4

どんな風にやってるか、ソース嫁かな。

最後に、やっぱり気になる、*.star の中身。どうなってるんかな? emacs使って調べてみた。 ArchLinuxの場合、/usr/share/smalltalkの中あたりに、梱包したものがたくさん置いてあるんで、 dir-modeで、まず閲覧。見たいものに照準を合せてバーンとリターンを叩く。今回は、DBD-MySQL.starが生贄。

M Filemode      Length  Date         Time      File
- ----------  --------  -----------  --------  ------------------
  -rw-r--r--       629  20-Dec-2012  20:42:34  package.xml
  -rw-r--r--      2721   5-Feb-2011  16:23:56  Statement.st
  -rw-r--r--      1888   5-Feb-2011  16:23:56  Extensions.st
  -rw-r--r--     19942   5-Feb-2011  16:23:56  MySQLTests.st
  -rw-r--r--      1022   5-Feb-2011  16:23:56  ChangeLog
  -rw-r--r--     13912   5-Feb-2011  16:23:56  Column.st
  -rw-r--r--      3655   5-Feb-2011  16:23:56  Row.st
  -rw-r--r--      1987   5-Feb-2011  16:23:56  Table.st
  -rw-r--r--     19998   5-Feb-2011  16:23:56  Connection.st
  -rw-r--r--      4618   5-Feb-2011  16:23:56  ResultSet.st
  -rw-r--r--      2393   5-Feb-2011  16:23:56  TableColumnInfo.st
- ----------  --------  -----------  --------  ------------------
                 72765                         11 files

なんか、この表、どこかで見たようなスタイルのだな。思い出したよ、unzipした時のやつだ。 そう言えば、gst作る時、やれgawkを入れろだとかInfoZipが(アプリに見当たらん)無いとか 文句言われたな。解凍専用のunzipはかろうじて入れていたけど、梱包を作るZipは入れて なかったんだ。

で、表によると、去年の12月20日に梱包されたんだな。 肝心の中身は、2011年の2月製造品か。 詳細は、パッケージリスト(package.xml)を見ろとな。それぞれは、dired-modeと同じ操作で見れるのね。

<<package>
  <name>DBD-MySQL</name>
  <namespace>DBI.MySQL</namespace>
  <test>
    <namespace>DBI.MySQL</namespace>
    <prereq>DBD-MySQL</prereq>
    <prereq>SUnit</prereq>
    <sunit>DBI.MySQL.DBIMySQLTestSuite</sunit>
    <filein>MySQLTests.st</filein>
  </test>
  <prereq>DBI</prereq>
  <prereq>Digest</prereq>
  <prereq>Sockets</prereq>

  <filein>Column.st</filein>
  <filein>Connection.st</filein>
  <filein>Extensions.st</filein>
  <filein>ResultSet.st</filein>
  <filein>Row.st</filein>
  <filein>Statement.st</filein>
  <filein>Table.st</filein>
  <filein>TableColumnInfo.st</filein>
  <file>ChangeLog</file>
</package>

何となく、言わんとしてる事が分かるね。これって、コンピュータ言語が理解出来るインボイスだな。 DBD-MySQLを使う時はDigestなんてパッケージも要るんか。そんな事初めて知ったよ。