nfunato

舟渡(nfunato at acm dot org) と申します。

本業はエンベディッドシステムの開発(だった)ですが、最近すっかり 御無沙汰のロートルです。

Cコンパイラのリンカーを書いてCを覚え、Blue Book のPart Fourを 読んでSmalltalk に馴染み、PCL(Portable Common Loops)のソースを 読みながらCommonLispを覚え、Orbit(T compiler)の論文とoaklisp の ソースを読みながらScheme を覚え、…といった言語遍歴です。

どうにも実装から入るという悪しきめぐりあわせです(自称「変格派」)。

Macintosh CL とoaklisp が一番のお気に入りでした。といっても、 そのまま本業のアウトプットにはならないので、専らプロトタイプか 内製ツールとしてですが。



(2009/09/26 22:44:57 PDT)

(Shiro 2009/09/25 プログラミング言語の進化)より:

全くShiroさんに同意ですね。

あと、言語の進化がベストプラクティスをサポートするためにあるのはそうなんでしょうが、プログラマとしては特定の言語がプログラマの考え方を強制する罠に陥らないように注意が必要なんでしょう。

言語に対しては、ShiroさんのMELの話(2004/06/26)にあったように「……が出来ない」という風にはして欲しくないわけですが、例えば「エラー処理必ずしも大域脱出にあらず」という考え方は、プリミティブなCでは(面倒であっても)実現可能なのが、C++のように言語サポートに含まれて ライブラリが追従してしまうことで、逆に難しくなってしまうという現象が起こるかもしれないのです。

気軽に言語の方を変えるには Lispはお勧めですが、頭の方も柔軟に保っとかないといけません。

なんか、久しぶりに書きたくなってしまいました。

"Lisp is a programmable programming language."

  • John Foderaro, CACM, September 1991

(2009/04/24 19:47:12 PDT) PLOT: Programming Language for Old Timers by David Moon, 2006-2008.

introductionによれば、

Programming Language for Old Timers (PLOT) is a new dialect of Lisp designed by Dave Moon in February 2006, and thoroughly revised and simplified November 2007 and March 2008. I have been developing PLOT as a hobby, with the idea of for once having a programming language which does everything the right way.

ということなので、Lisp:読み物

nfunato: http://people.csail.mit.edu/jrb/Projects/dexprs.pdf にもDylanマクロシステムの紹介があります(jrb氏はJava Syntax Extenderなんてのも書いてます)。昔話で恐縮ですが、Acknowledgementsに名を出すDavid Moonの書いたマクロシステムのドラフトは、1994頃 ftp.apple.com のトップにさりげなく置いてあって、もっと細かくASTの操作について書いてました。arcへのコメントでも、Moon氏はS式反対の立場なんですよね。

と書いたとき(2006/09/28)には、既に原型があったわけですね。
in a right way でなく、the right way というところに、mit approach のコダワリを感じてしまう。

最初に出てくる実装が良いFFIを持っているといいですね。言語仕様がすごく大事なことは承知のうえで、インターネット時代の昨今は、実装の数よりも良いライブラリが付くかどうか重要だし、枯れたライブラリにはCやFortranで書かれているものもあるから。
最近、身の周りのことをするときにPythonを使っているが、それはscipynumpymatplotlibを日常使わせてもらっていることによるもので、言語の"仕様"に不満がないわけではないのである。

32-bit windows で使える Clozure CLも出たし、Old Timer Lisperには春から縁起がいい?


(2009/01/03 16:52:48 PST)

帰省中、つかのまにネットサーフィンしていて、Eliot Miranda氏のblogに行き着いた。お名前は存じあげていたが、このような情報(jit compilerを含むcroquetのVM?)に触れられるようになったのは興味深い。既に自分の手におさまる話題ではないと知りつつ、文庫本の代わりに「あとで詠む」と思って、一部を保存する。しばらくネット接続もままならないので楽しめそう。

それにしても、Miranda氏にせよ Weinreb氏にせよ、私と変わらない世代だと思うが、ある種の尖がったソフトウェア領域でのアメリカの強みは、こういったノウハウを蓄積しながら前線に居続ける人の多さにあるのではないか。


(2008/07/25 08:37:45 PDT)

Scheme:なぜSchemeにはreturnが無いのかより: 

本題とは外れるので、こちらにて。

実際、Cのsetjmp/longjmpと継続とは非常に近い関係がある。ただ、Schemeの場合、オブジェクトのエクステント(有効範囲)は原則として無限だ。 setjmpで捕まえたjmp_bufは、それより下位の関数呼び出しの中でしか使えないけれども、 Schemeの継続にはそういう制限がない。まあ、言ってしまえば違いはそれだけさ。

"それより下位の関数呼び出しの中でしか使えない" というのは意味論の上での要請で、実際には 巻き戻されて無効になった筈の jmp_bufにlongjmp することが出来ます :-)

C言語とsetjmp/longjmpだけを使って non-preemptive thread を作ったことがありました。初期化ルーチンの中で、何重にも再帰呼び出しをしていって、ある回数の呼び出しごとに setjmp を呼び出して、stack areaと同時に jmp_buf というか TCB(Task Control Block)を確保していきます。所定の数のTCBを確保したら、一番最初に確保したjmp_bufまでlongjmpして、初期化ルーチンは終わり。以後は task schedulerを動作させればよい。
task schedulerは、巻き戻されていようがいまいが、特定のTCBのjmp_bufにlongjmpすることで、その context に switch 出来ます。

厳密にはOS依存な筈なんですけどね。例えば、巻き戻したstack segmentのpage割り当てが適当なタイミングで解放される場合は、core dump します。また、コーディングをする上では、volatile とか使用するなどして、種々のコンパイラの最適化を避ける必要があった。が、某Unixと複数のバージョンのgccで動作していました。

"初期化ルーチンやcontext switch"の部分をそんな下品な方法で行う必要は何処にも無いんだが、真の目的は 組み込み機器で動作する embedded preemptive kernel の初期デバッグをホスト上で行うことだったので、ターゲットでは別コードに置き換えられる上記の部分を一番短く作る方法でした。

もちろん、動的に継続を生成したり、closure変数を作ったりすることは簡単ではない。そんなことをしたら、Lisp:GreenspunsTenthRuleになってしまうに違いない。


(2008/03/29 17:53:55 PDT)

Daniel Weinreb 氏の blogに、 CL condition systemについてのpost(What Conditions (Exceptions) are Really About) があり、下記を含む Dave Moon氏のreplyがあったりして、ゆるゆると議論が行われている。

I believe the distinction (between condition and error) was intended to be that the function that signals an error is incapable of continuing execution, while the function that signals a non-error condition is capable of continuing execution if the exception handler does not unwind the stack. This depends on Common Lisp’s separation of exception signalling from stack unwinding, two distinct concepts that other languages have conflated. However, the Common Lisp standard is not entirely consistent about this, so it is easy to become confused about the intended model.

CLのように exception signaling と stack unwinding を分離したエラー処理機構には、signaler の stackで caller側で定義された handlerの実行を可能にする function closure が 欲しくなる。

実用上は、cacading signaling や error handling による 再帰呼び出しの過程でもスタックをあまり消費しないための proper tail recursion や、プログラミングし易いように application oriented な error type を mixin する機能も 欲しいかもしれない。

GC に付随して、closure が言語機能として一般的になってきても、上記の分離が一般的になってきたように見えないのは、両者の使い分けがあまり有用ではないと思われているのだろうか? つまり、実行時に起こり得る "unusual condition" で 継続可能なものというのが、それほどないのだろうか?

いずれにしても、両者の使い分けは 難しいものであるらしい。

私自身は、CL condition system の仕様を知っていたおかげで、メモリの少ない組み込み機器に、setjmp と longjmp に皮を被せた アプリケーション依存な special adhoc error system を組み込んで、コーディングを随分「楽」、つまり小さくかつ不具合の出にくいものにできた経験がある。

また、KCL (AKCL + ilisp) で プログラムしていたときは、デバッグ時の関数定義は、専ら break-loop の中でしていた。人間handler ですね。KCLインタプリタのデバッガは、いい意味でナイーブで、手を入れるのも容易でした。

続きがありそうなので、ちょっと期待して見守っています。

毎度 scheme な話でなくてすみません。


(2007/12/07 02:51:09 PST)

sasagawa:思いつき?(Lisp処理系の作成)より。

中西正和先生は、1つならずLisp処理系を作っておられるでしょうが、私がお世話になったのは、Apple Lisp (Apple II Lispだったかも ?)。これは6502アセンブラで書いてあったということになります。同名の記事が古いbit誌に出ており、大学の研究室にあったLisp 1.5のマニュアルと共に読みましたが、だいたい同じような仕様でした。Joy Stickで操作するスクリーンエディタが組み込まれていました。

記事に、I/Oの部分が完成するとだいたいLispは出来たような気になる、って書いてあったようなおぼろげな記憶があります。

I/Oが大変という観点からいうと、とりあえずLispを動かすのに最も手が抜ける言語は、Lisp自身ということになりますかね (最近は良いParser Generatorもあるから、ちょっと嘘臭いか)。上に書いてますが、私が読んだ TやOaklispは、この手合いでした。

Common Lispを含めて、しっかりしたnamespace機能のある Lisp言語族なら、てっとり早く動かしてみるところから、序々に機能を追加する形に持っていけそうです。 仕様がしっかりしたものというと、CLあたりになってしまい、その仕様に馴染むこと自体が大変なのが難点 :-)

Oaklisp(第1回だかのOOPSLAに論文が出てます)も、Symbolics上でbootstrapしていって、ターゲットであるMacintosh上の仮想マシンで動くようにして、最終形のVMコードコンパイラ込みで単独マシン上でセルフビルド可能な形にしたようです。

今も、昔のソースを著者の一人(アイルランドの大学の先生)が公開していますが、2人の著者がソースコードのコメント上で会話しているのが楽しかったですね。Hey Kevin ! とかいう感じで…


(2007/10/12 05:33:39 PDT)

最近、info-MCL ML のトラヒックが上がっていると思っていたら、何とMCL PPCは5.2からopen source になるんだそうです (まだ ML archiveには出てないけど)。

むぅ…

(2007/10/12 16:09:30 PDT)

12日の Planet Lisp でもここがポイントされていました。

MCL was a cutting-edge GUI Common Lisp environment for the Mac. It is second only to Lisp Machine environments at inspiring its aging users to sneer at the idiot Lispers who think command-line tools and terminal-based editors and Tk bindings are cool.

68kの頃からでも使えるのは、GUIの下の interactive native code compiler の存在が大きいんではないかと思っているのですが、cmuclのhemlockとかと比べると、MCLはずっと軽快なんですよね、これが。(speed を考えるときに、memory footprintとかも考えてしまうのが aging user の証しかもしれないんだが…)

(2007/10/16 08:24:09 PDT)

Archiveは、こっち移ってたみたいです。10月が大変なことになっている。


(2007/09/18 06:21:12 PDT)

 末尾再帰とループ問題

これを拝見するまで、Common Lispのloopマクロがtail recursiveでない理由に気づかないなんてどうかしてますね。

それにしても、special binding という open end な仕様を、何の制約もなくシステムが使いまくっているってことで、threadを重たくして stack groupを3本スタックにするとか、condition system に (Dylanと違って) 壁を作るとか、実装や仕様に散々な影響があるんですなぁ。。

Schemeでは、この辺は綺麗に成熟していくんでしょうか。


(2007/05/11 09:34:33 PDT)

 Method Cache Hacking (← まつもとさんのところ)

こういうの好きです。

組み込み稼業でしたので、それに加えて、こういうコンパイラがクロスでできないか考えてしまう。Java Beansが出る前ですが、Apple Dylanはターゲット実行プロセスにattach/dettach可能なIDEのデモをWWDCでやっていました。そんでもってついでにThumbをターゲットにしてしまうなんていかがでしょう。S60にPythonが載るご時世ですし、PC上のVMもThumb Simulatorにするのです。PPCや純正ARMに比べて、レジスタは少ないし色気に欠けるかもしれないが、ケータイの市場は大きいのですよ。既にheteroなmulti-core(DSPやUMTS)ですから、そのうちアプリもmulti-core ! (ほんまかいな)

SchemeはCLに比べて仕様が未完故に、この辺りに可能性があるように感じます。CLのpackage仕様を必須とすると、重装備のセルフ環境が想定されちゃいますから。(しかし、年配者に時間はないのである…)

(2007/07/20 07:37:49 PDT)

5/23リリースのLLVM2.0 (← やはり まつもとさんのところ)には、Thumbサポートが加わったんですね。いつもお世話になってます。1年程ごぶさたのC++を眺めてみるか。(しかし、でっかいシステムだ…)


(2006/09/09 09:26:03 PDT)

PCLって、Portable Common Loopsではなくって、最近はPractical Common Lisp のことだったとは。知らんかった。

 Another classic macro-writing MACRO: ONCE-ONLY

これは、どっちのPCLにも出てて、十分Schemeでも使えそう。ただ、gensymに慣れた自分には、どうやってhygienicに書くのかパッと浮かばない…


(2006/08/04 22:11:09 PDT)

お盆休みを前に、部屋の本を*本当に*久しぶりに整理していたら、本棚の奥からAMOPやCompiling with Continuations (ちなみに 私はこれでSMLを覚えました :-)、Simon Peyton Jonesの本なんかに混じって、Dylan -- An object-oriented dynamic language (1992)というのが出て来ました。

ごれは、94年くらいにJavaの攻勢にあってAlgol syntaxに戦略転換する前の、S式構文時代のDylanのReference本です。

ついパラパラと眺めています。

Larry Teslerの前文に「欲しいものを探していて Eiffel, Self, Beta, Oaklispなどは興味深かったが、我々の要求を満たさなかった」などと書いてあって、当時Gaucheが存在していたら… などと思わず考えてしまいました。

ところで、Dylanでは特定のcollection型に対して6つのメソッドを定義すれば(iteration protocol)、CLtL2のloopマクロに相当するものが使えるというストーリーでした。なおかつ、根がOOなんで、CLみたいにlistとarrayでprefix keywordが異なったりしないんです。

Shiroさんの以前の話(2006/01/10 23:54:26 PST)に、CLのloopマクロは副作用の悪を教えるSteeleの親心とありましたが、公式にtail recursiveでないからですかね。Dylanのは、ちゃんと再帰のsemanticsになってました。

loopマクロはある種パターン化を導入することで、読み易さを向上させると思うんだけど、Dylanみたいなことしたらコンパイラの最適化は面倒になるのかしら。。。

(2006/08/05 17:37:45 PDT)

自己フォローです。Rich Taubeさんが、Common Musicの中で CL loop macro を実装されているようですね。

http://article.gmane.org/gmane.lisp.scheme.gauche/583

 > If you come from a common lisp backgound its pretty
 > indispensible but of course it will probably make a real schemer puke. 

言った手前、自分でも使ってみようと思います。とりあえず、自分が Real Schemer でないことがわかりました (-o-)。という以前に自分でもの(コード)を創らねばね。


(2004/03/10 02:36:18 JST)

この一年ばかり自分では殆どプログラムしてない状態ですが、数日前からGaucheを使わせていただいて、リハビリに励んでいます。

ところで使っているうちに、CommonLispのdestructuring-bind 相当の機能が何度か恋しくなったのですが、これって今のSchemeやGaucheにはないものなんでしょうか?

いにしえのPCL(CLtL1時代!)やoaklispには、わざわざ自前で定義してありましたから、便利に感じる人はいると思うんですが、ひょっとして、何でも加えるのはSchemeの思想に反する?ということで、採用されていないのでしょうか?

私が見落としているだけかもしれないのと、他力本願でWishlistに書いてしまうのも正しくないような気がするので、どなたかこっそり教えてください (^^;)


(2003/03/20 23:48:37 PST)

実は、最初フリーフォーマットの日本語の文章を含む入力デー タをWiki+dbm に放り込んでおいて、後からPostgresに持っていく、 なんてツールを書くのに WiLiKi やGauche が使えないか考えている ので、ここに出てきました。

最終的にはRDBが不適というわけではなく、ひとまとまりのデータも 数100件くらいなんだが、データを入力している間は正確なスキーマ の細部を決定しにくい(入力データを分析してみて分かる部分がある)、 という感じです。

まだ思いつきの段階で、具体的に問題にぶつかったとかいう訳では ないのですが、似たような経験や事例を御存知の方はおられるで しょうか?

More ...