新エディタ Shiki を作る日記 (6)
&rest 引数の使い方が微妙にわかったので,Lisp の format 形式のメッセージをポップアップダイアログに表示する msgbox API を作ってみた.
なぜか xyzzy は返り値に :ok というシンボルを返す (symbolp で確認済み) という仕様だったので,一応再現してみた.まぁ,3 byte だし… (intern とかいろいろコストはかかるけど)
Format が使えるのは,scheme の世界からはすごく便利なんだけど,やっぱり C からは使いにくい.というわけで,C では同名の,printf 形式の可変長引数を取るように定義しなおした方が良いかもしれない.
こうしてみると,実は C API でガリガリ書いた方が,部分式がコンパイルされずに何度も何度も実行時に動的に intern やアロケートなどが繰り返されるため,場合によっては読み込み時にバイトコンパイルされる Scheme よりも遅くなるのかもしれない.
う〜ん,C にもコンパイルタイムマクロが欲しいのう (無理).
gcc とか,まっとうなコンパイラなら,共通する (部分文字列も ?) 文字列定数は,全部コンパイル時にインターンされて静的領域に置かれて共有されるはず.SCM_INTERN_STATIC_CONST とか,なんかそんな感じで何とかならないのかねぇ ? (たぶんならない)
まぁ,そんなに神経質にならなくても,二回目以降は無視できる程度なのかな… (src/symbol.c)
う〜ん,xyzzy が思いっきり Lisp でエディタの大部分を書いてるのは,やっぱりコンパイル (たぶんバイトコンパイル ?) に強い CL だから,ってのがあるのだろうか ?
よく LL の人とかが,「開発効率の方が重要,本当にクリティカルな部分は C で書けばいいじゃん云々」 みたいなことを言うけど,C で書いたら早くなるってもんでも無いと思う.そこらへん,本当にわかってそういう発言してるのかねぇ ?
# いや,速度を気にするような人は,そもそも LL なんて使ってないよな,普通.すいませんでした.以下全部ヨタです.
というか,むしろ C って,言語仕様的には,一番コンパイルには向いてない言語なんじゃないか ?
抽象度も中途半端だし.移植性にしろ,マシンへの近さにしろ,非常にどっちつかずで中途半端.そのせいで autotools みたいな,バッドノウハウがバッドノウハウを呼ぶという悲惨な事態が.そのくせ処理系依存のインラインアセンブラ使わないと,肝心なことは何もできないし.
なんたって,(言語仕様的には) 入出力すらライブラリなんだから.コンパイラは預り知らぬブラックボックスの領域に行っちゃう.
まぁ,gcc なんかだと,たとえば printf あたりは全部ビルトインで持ってて,型チェックやフォーマットの中身のコンパイルみたいなことも一応はやってくれるけど.それは非常に限定された形に過ぎない.
その点 CL なんかは,あの莫大なライブラリ全てが言語仕様の範疇だから,原理的にはありとあらゆる部分にコンパイラによる最適化がかかる可能性が生まれてくる.それこそ静的に確定してる正規表現の中身のネイティブコンパイルまで.
現時点で,そこまでできるマンパワーと力強い (ダーティな) 言語仕様を持った言語ってのは,おそらく Common Lisp と C++ しか無い (いや,ML もポテンシャルは凄そうだけど… いかんせん,アカデミックオンリーだからなぁ.企業のマンパワーが足りない気が) と思う.
いや,確かに 80:20 の法則を考えれば,そんなことに拘るのは無意味というのは,全くの正論なんですけど.
普段はダラダラインタプリタとかで Edit-Compile-Testループを素早く何度も何度も回して開発効率を上げられるし,いざとなったら,コンパイラに本気出してもらって,システム全体をまるごと 3 日 3 晩くらいかけて極限まで最適化することもできる.そんな言語,あったら良いと思わないかい ? (Joel 口調)
ちょっと書きやすかったり読みやすかったりするけど,ちょっとシステムが大きくなると全体を書き直さないと使い者にならなくなるような,15 分だけ時代を先取りした言語 では,オモチャは書けても,本物のシステムなんて書けっこないし,そもそも書かれないだろう. そういう意味で,僕は (少なくとも現在の) LL に未来は無い,という持論があったり.
# いや,もちろん,小粋な web API をちょちょいと使って,マッシュアップとかハイカラな言葉を並べて 30 年前の技術を飾り立てるのがアナタの 「未来」 だって言うならば,話は別だけど.
とかいう話はどうでも良いな.
う〜ん,なんの話だっけ.
そうそう,gauche にもバイトコードコンパイルが欲しいのう.という話だった (そうだっけ ?
まぁ,gauche の目的を考えれば,それはオカド違いな願望なんだろうね.
UNIX と C ってのは,やっぱり最悪のコンピュータウィルスだな.この 2 老害のせいで,計算機科学の発達は 20 年遅れた.こいつらのバッドノウハウにそそぎこまれた,莫大な量の不毛なマンパワーが,もしもっと他のことに正しく向けられていたら… (C はさらに, C++ という素晴らしい後継者にも恵まれたしね)
とか,たまには暴言吐いてみる (笑)
■[C]Cが使われる理由
(via ときどきの雑記帖 リターンズ ■_ 自分で自分を記述する)
# 2006/12/14 追記 : なにやらいろいろなところからリンクして頂いているようなので,遅ればせながら補足.上記は私のオリジナルではなく,The Rise of ``Worse is Better'' 「 Unix and C are the ultimate computer viruses.」 が元ネタです.念のため.
まぁ,いけるところまで gauche と C でがんばろう.どうしても速度や開発効率が気になってきたら,ネイティブコンパイル可能な Common Lisp 処理系も考えるかもしれない.
ただ,現状では,utf8 がそれなりに扱えるのは,バイトコンパイラの clisp ぐらいなんだよなぁ.たぶん.cmucl とかだったら,むしろ全部 CL で書いても良いかもしれないんだけど.xyzzy との親和性も高そうなのに.おしい.
# ついでに追記.SBCL という CMUCL のブランチは,Unicode を扱えます.ただ,CL から gtk を使うやり方がよくわからなかった… wxCL も微妙だったし.
なんかエディタと全然関係無い話になってしまった… orz
いちおう MinGW で出た警告は直したつもり.あと,たぶん charconv がコケても,システムロケール (Windows なら,たぶん sjis.Linux とかなら,だいたい euc-jp ?) と UTF8 の文章ならば,たぶんなんとかなるはず.
# 今 Windows 環境が無いからニントモカントモ… あと,真面目にエラー処理を書くのは,0.8.8 以降に上げてからだと思う.まだ Debian/testing は 0.8.7.
しっかし,スタブのエラーハンドリングがテキトーすぎるな.
C 言語で定義するから,「未定義」 っていう値が表現できないんだな,これが.
だから,Scm_Error が発動してるのに,一見それっぽい値 (gboolean を返す関数とか) が返ってきたり… いちおう正整数を返すやつとかは,適当に -1 とか返してるけど (そもそも Gtk,なんで明らかに正の数しか取らないところに,いっつも gint なんだ ? 謎過ぎる.なんか内部的には,負の数に特別な意味を持たせてるとか ?).
Lisp だったら,#t でも #f でも無くて,# とか nil とか,ナンカてきとぅーに返しときゃいいんだけど.
いや,面倒くさがらずに,返り値を にしておけば良いのか.自動 Boxing されないから全部手動なのはかなりきついけど.
う〜ん,xyzzy lisp には仕様書とか無いからな.何を返しておけば良いのか良くわからん.
ねむい.そもそも Scheme には,nil って概念無いし (いや,nil はあるけど… 単なるシンボル).
(define-cproc msgbox (format::&rest args)
(body
" ScmObj os = Scm_MakeOutputStringPort(TRUE);
GtkWidget *dialog;
Scm_Format(SCM_PORT(os), format, args, FALSE);
dialog = gtk_message_dialog_new(GTK_WINDOW(Shiki_EDITOR_WINDOW),
GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK,
Scm_GetString(SCM_STRING(Scm_GetOutputString(SCM_PORT(os)))));
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
SCM_RESULT = SCM_SYMBOL(SCM_INTERN(\":ok\"));"))
(msgbox "current buffer is ~A." (selected-buffer)) ;; ここで C-j
:ok
なぜか xyzzy は返り値に :ok というシンボルを返す (symbolp で確認済み) という仕様だったので,一応再現してみた.まぁ,3 byte だし… (intern とかいろいろコストはかかるけど)
Format が使えるのは,scheme の世界からはすごく便利なんだけど,やっぱり C からは使いにくい.というわけで,C では同名の,printf 形式の可変長引数を取るように定義しなおした方が良いかもしれない.
こうしてみると,実は C API でガリガリ書いた方が,部分式がコンパイルされずに何度も何度も実行時に動的に intern やアロケートなどが繰り返されるため,場合によっては読み込み時にバイトコンパイルされる Scheme よりも遅くなるのかもしれない.
う〜ん,C にもコンパイルタイムマクロが欲しいのう (無理).
gcc とか,まっとうなコンパイラなら,共通する (部分文字列も ?) 文字列定数は,全部コンパイル時にインターンされて静的領域に置かれて共有されるはず.SCM_INTERN_STATIC_CONST とか,なんかそんな感じで何とかならないのかねぇ ? (たぶんならない)
まぁ,そんなに神経質にならなくても,二回目以降は無視できる程度なのかな… (src/symbol.c)
ScmObj Scm_Intern(ScmString *name)
{
ScmHashEntry *e = Scm_HashTableGet(obtable, SCM_OBJ(name));
if (e) return e->value;
else {
ScmObj n = Scm_CopyStringWithFlags(name, SCM_STRING_IMMUTABLE,
SCM_STRING_IMMUTABLE);
ScmSymbol *sym;
INITSYM(sym, n);
Scm_HashTablePut(obtable, n, SCM_OBJ(sym));
return SCM_OBJ(sym);
}
}
う〜ん,xyzzy が思いっきり Lisp でエディタの大部分を書いてるのは,やっぱりコンパイル (たぶんバイトコンパイル ?) に強い CL だから,ってのがあるのだろうか ?
よく LL の人とかが,「開発効率の方が重要,本当にクリティカルな部分は C で書けばいいじゃん云々」 みたいなことを言うけど,C で書いたら早くなるってもんでも無いと思う.そこらへん,本当にわかってそういう発言してるのかねぇ ?
# いや,速度を気にするような人は,そもそも LL なんて使ってないよな,普通.すいませんでした.以下全部ヨタです.
というか,むしろ C って,言語仕様的には,一番コンパイルには向いてない言語なんじゃないか ?
抽象度も中途半端だし.移植性にしろ,マシンへの近さにしろ,非常にどっちつかずで中途半端.そのせいで autotools みたいな,バッドノウハウがバッドノウハウを呼ぶという悲惨な事態が.そのくせ処理系依存のインラインアセンブラ使わないと,肝心なことは何もできないし.
なんたって,(言語仕様的には) 入出力すらライブラリなんだから.コンパイラは預り知らぬブラックボックスの領域に行っちゃう.
まぁ,gcc なんかだと,たとえば printf あたりは全部ビルトインで持ってて,型チェックやフォーマットの中身のコンパイルみたいなことも一応はやってくれるけど.それは非常に限定された形に過ぎない.
その点 CL なんかは,あの莫大なライブラリ全てが言語仕様の範疇だから,原理的にはありとあらゆる部分にコンパイラによる最適化がかかる可能性が生まれてくる.それこそ静的に確定してる正規表現の中身のネイティブコンパイルまで.
現時点で,そこまでできるマンパワーと力強い (ダーティな) 言語仕様を持った言語ってのは,おそらく Common Lisp と C++ しか無い (いや,ML もポテンシャルは凄そうだけど… いかんせん,アカデミックオンリーだからなぁ.企業のマンパワーが足りない気が) と思う.
いや,確かに 80:20 の法則を考えれば,そんなことに拘るのは無意味というのは,全くの正論なんですけど.
普段はダラダラインタプリタとかで Edit-Compile-Testループを素早く何度も何度も回して開発効率を上げられるし,いざとなったら,コンパイラに本気出してもらって,システム全体をまるごと 3 日 3 晩くらいかけて極限まで最適化することもできる.そんな言語,あったら良いと思わないかい ? (Joel 口調)
ちょっと書きやすかったり読みやすかったりするけど,ちょっとシステムが大きくなると全体を書き直さないと使い者にならなくなるような,15 分だけ時代を先取りした言語 では,オモチャは書けても,本物のシステムなんて書けっこないし,そもそも書かれないだろう. そういう意味で,僕は (少なくとも現在の) LL に未来は無い,という持論があったり.
# いや,もちろん,小粋な web API をちょちょいと使って,マッシュアップとかハイカラな言葉を並べて 30 年前の技術を飾り立てるのがアナタの 「未来」 だって言うならば,話は別だけど.
とかいう話はどうでも良いな.
う〜ん,なんの話だっけ.
そうそう,gauche にもバイトコードコンパイルが欲しいのう.という話だった (そうだっけ ?
まぁ,gauche の目的を考えれば,それはオカド違いな願望なんだろうね.
UNIX と C ってのは,やっぱり最悪のコンピュータウィルスだな.この 2 老害のせいで,計算機科学の発達は 20 年遅れた.こいつらのバッドノウハウにそそぎこまれた,莫大な量の不毛なマンパワーが,もしもっと他のことに正しく向けられていたら… (C はさらに, C++ という素晴らしい後継者にも恵まれたしね)
とか,たまには暴言吐いてみる (笑)
■[C]Cが使われる理由
(via ときどきの雑記帖 リターンズ ■_ 自分で自分を記述する)
# 2006/12/14 追記 : なにやらいろいろなところからリンクして頂いているようなので,遅ればせながら補足.上記は私のオリジナルではなく,The Rise of ``Worse is Better'' 「 Unix and C are the ultimate computer viruses.」 が元ネタです.念のため.
まぁ,いけるところまで gauche と C でがんばろう.どうしても速度や開発効率が気になってきたら,ネイティブコンパイル可能な Common Lisp 処理系も考えるかもしれない.
ただ,現状では,utf8 がそれなりに扱えるのは,バイトコンパイラの clisp ぐらいなんだよなぁ.たぶん.cmucl とかだったら,むしろ全部 CL で書いても良いかもしれないんだけど.xyzzy との親和性も高そうなのに.おしい.
# ついでに追記.SBCL という CMUCL のブランチは,Unicode を扱えます.ただ,CL から gtk を使うやり方がよくわからなかった… wxCL も微妙だったし.
なんかエディタと全然関係無い話になってしまった… orz
いちおう MinGW で出た警告は直したつもり.あと,たぶん charconv がコケても,システムロケール (Windows なら,たぶん sjis.Linux とかなら,だいたい euc-jp ?) と UTF8 の文章ならば,たぶんなんとかなるはず.
# 今 Windows 環境が無いからニントモカントモ… あと,真面目にエラー処理を書くのは,0.8.8 以降に上げてからだと思う.まだ Debian/testing は 0.8.7.
しっかし,スタブのエラーハンドリングがテキトーすぎるな.
C 言語で定義するから,「未定義」 っていう値が表現できないんだな,これが.
だから,Scm_Error が発動してるのに,一見それっぽい値 (gboolean を返す関数とか) が返ってきたり… いちおう正整数を返すやつとかは,適当に -1 とか返してるけど (そもそも Gtk,なんで明らかに正の数しか取らないところに,いっつも gint なんだ ? 謎過ぎる.なんか内部的には,負の数に特別な意味を持たせてるとか ?).
Lisp だったら,#t でも #f でも無くて,#
いや,面倒くさがらずに,返り値を
う〜ん,xyzzy lisp には仕様書とか無いからな.何を返しておけば良いのか良くわからん.
ねむい.そもそも Scheme には,nil って概念無いし (いや,nil はあるけど… 単なるシンボル).
