ecl (2)
日経Linuxあたりで、ラズパイとかを使って、温度監視システムを作りましょなんて、 電子工作を勧めている。多角経営に乗り出さないと、里奈だけじゃ食っていけないからだな。 毎度、Winを目の仇にして、里奈への勧誘だけじゃ、飽きられちゃうからね。
でも、電子工作の基本は、Lチカからだと思うんよ。このLEDチカチカは、Hardware界の Hello world だもの。
Lチカするなら、2石でマルチバイブレータを組むのが定石でしょう。それよか少し高級に なるとPICでしょう。
ARMの石もいいけど、pic funなんていう遊園地も楽しそうだぞ。 定番のPICを使った、 PIC12Fシリーズの製作例集なんてのもある。
アセンブラで頭の体操をするも良し、CCS-Cを使ってコンパイルしても良し。 ハードもソフトもメカも組み合わせれば、総合レジャーランドになるぞ。
あれが動くかな
前々回だかにやった、方程式を解くやつ。作者さんはCLISPでやっておられたけど、果たして eclでも動くのだろうか? 早速、互換性テスト実施
> (load "bidirection.lisp") ;;; Loading "/home/sakae/src/cl/bidirection.lisp" Condition of type: STREAM-DECODING-ERROR decoding error on stream #<input stream #P"/home/sakae/src/cl/bidirection.lisp"> (:EXTERNAL-FORMAT ... Available restarts: 1. (CONTINUE) Read next character 2. (USE-VALUE) Replace the bogus sequence with a character 3. (RESTART-TOPLEVEL) Go back to Top-Level REPL.
いきなりのエラーだよ。CLの場合、何かあると盛大にえらーだぞ、どうする? って聞いて 来るんで、この流儀に慣れないと、気持ちが萎えてしまうぞ。
でも、ちゃんと原因を報告してきてるから、まずは気持ちを落ち着けるんだ。デコードエラー って言ってきてるな。ソースファイルの文字コードが不味いんだろうな。確認してみる。
sakae@uB:~/src/cl$ nkf -g bidirection.lisp Shift_JIS sakae@uB:~/src/cl$ nkf -w bidirection.lisp > a.lisp
文字コードが、島国根性丸出しになってたんで、国際コードに変換したよ。され、これで 動くかな?
> (load "a.lisp") ;;; Loading "/home/sakae/src/cl/a.lisp" #P"/home/sakae/src/cl/a.lisp" > (fc -h) (- (* 5.0 (- F 32.0)) (* 9.0 C)) > (fc c 20) 68.0
そして、気温20度C を、アメリカ版、気温に変換してみたぞ。全く、アメリカって困った国 だのう。誰か、長さ、重さ、容量の変換コードを書かないかな。
eclの内部観察
ソースを自前でコンパイルして動かしている手前、内部がどう動いているか、観察したく なりませんか? そういう時は、gdbが使えるように
make ECL_DEBUG=1
しておきます。いきなりeclに当たろうとしても無理なんで、build/ecl_min に当たるのが吉。 build 配下には、.gdbinitとかTAGSまで用意されてますから。(TAGSって事は、emacsを準強要 されるって事です)
;*** Lisp core booted **** ECL (Embeddable Common Lisp)
ecl_minを起動してプロンプトが出てきた所で、Ctrl-Cした時、gdbが立ち上がり、そこで btしてみた。
#0 0xb7fdd424 in __kernel_vsyscall () #1 0xb7eece1b in read () at ../sysdeps/unix/syscall-template.S:81 #2 0x0806714d in read (__nbytes=1, __buf=0xbffff487, __fd=0) at /usr/include/i386-linux-gnu/bits/unistd.h:44 #3 io_file_read_byte8 (strm=0x84d7e70, c=0xbffff487 "\267", n=1) at /home/sakae/ecl-13.5.1/src/c/file.d:2652 : #11 0x0807062e in cl_read (narg=narg@entry=3) at /home/sakae/ecl-13.5.1/src/c/read.d:1518 #12 0x0804c3a4 in si_simple_toplevel () at /home/sakae/ecl-13.5.1/src/c/cinit.d:170 #13 0x0807fc15 in dispatch0 (narg=0) at /home/sakae/ecl-13.5.1/src/c/cfun_dispatch.d:10 #14 0x0804c18e in main (argc=1, args=0xbffff704) at /home/sakae/ecl-13.5.1/src/c/cinit.d:203
もう一つやってみる。carした時breakさせてみる。ソース上では、c/cons.d/の中にある、ecl_carが 相当するようだ。
(gdb) bt #0 ecl_car (x=x@entry=0x81d6c39) at /home/sakae/ecl-13.5.1/src/c/cons.d:371 #1 0x08053ad7 in cl_car (x=x@entry=0x81d6c39) at /home/sakae/ecl-13.5.1/src/c/cons.d:818 #2 0x080a39fc in si_pathname_translations (narg=narg@entry=2, host=0x84d2fd8, host@entry=0x81621fc <str_sys_data>) at /home/sakae/ecl-13.5.1/src/c/pathname.d:1566 #3 0x0804de1a in cl_boot (argc=argc@entry=1, argv=argv@entry=0xbffff704) at /home/sakae/ecl-13.5.1/src/c/main.d:676 #4 0x0804c0b9 in main (argc=1, args=0xbffff704) at /home/sakae/ecl-13.5.1/src/c/cinit.d:185
なお、ecl_car とは別に、c_car なんてのもあるようだ。(TAGSをgrepしたら出てきた) このc_carは、ecl_minのプロンプトから呼び出した時に使われるようで、compiler.dの中に 定義されてる。btの結果は
(gdb) bt #0 c_car (env=0xb7fda000, args=0x81d6581, flags=2) at /home/sakae/ecl-13.5.1/src/c/compiler.d:2549 #1 0x0805ca22 in compile_form (env=env@entry=0xb7fda000, stmt=stmt@entry=0x81d65e1, flags=flags@entry=2) at /home/sakae/ecl-13.5.1/src/c/compiler.d:2292 #2 0x0805d25d in compile_with_load_time_forms (env=env@entry=0xb7fda000, form=form@entry=0x81d65e1, flags=flags@entry=2) at /home/sakae/ecl-13.5.1/src/c/compiler.d:2445 #3 0x0805d525 in eval_nontrivial_form (form=0x81d65e1, env=0xb7fda000) at /home/sakae/ecl-13.5.1/src/c/compiler.d:2370 #4 eval_form (env=env@entry=0xb7fda000, form=form@entry=0x81d65e1) at /home/sakae/ecl-13.5.1/src/c/compiler.d:2388 #5 0x0805fd10 in si_eval_with_env (narg=narg@entry=1, form=0x81d65e1) at /home/sakae/ecl-13.5.1/src/c/compiler.d:3129 #6 0x0804c360 in si_simple_toplevel () at /home/sakae/ecl-13.5.1/src/c/cinit.d:173 #7 0x0807fc15 in dispatch0 (narg=0) at /home/sakae/ecl-13.5.1/src/c/cfun_dispatch.d:10 #8 0x0804c18e in main (argc=1, args=0xbffff704) at /home/sakae/ecl-13.5.1/src/c/cinit.d:203
対応するコード部分
static int c_car(cl_env_ptr env, cl_object args, int flags) B { n cl_object list = pop(&args); if (args != ECL_NIL) { FEprogram_error_noreturn("CAR: Too many arguments", 0); } compile_form(env, list, FLAG_REG0); => asm_op(env, OP_CAR); return FLAG_REG0; }
おお、matzさん得意の仮想マシンかな。上のトレースを眺めると、ソースの土地勘が出て くるな。次は、src/h/bytecodes.h あたりを見て、おくかな。で、開いてみたら、 src/c/interpreter.d も見ると吉って、お勧めされてた。ちょいと覗き見したら、スレテッドなんて 言葉が出てきたけど、 トークンスレッデッドコードマシン とかも関係するのかしらん。
profile
通過儀式って事で、profile出来ないか調べてみる。するとcontribに入っていたよ。
;;;; This software is part of the SBCL system. See the README file for ;;;; more information. ;;;; ;;;; This software is derived from the CMU CL system, which was ;;;; written at Carnegie Mellon University and released into the ;;;; public domain. The software is in the public domain and is ;;;; provided with absolutely no warranty. See the COPYING and CREDITS ;;;; files for more information. (eval-when (:compile-toplevel :load-toplevel) (defpackage "PROFILE" (:nicknames "PROF" "SB-PROFILE") (:export "PROFILE" "REPORT" "RESET" "UNPROFILE" "UNPROFILE-ALL")) ) (in-package "PROFILE")
profile.lispの冒頭部分。仰せに従って、鉄鋼銀行Lispの説明を見る。 どうも、この説明と、このファイルの実体は違うようだ。だって、外から見えるように してくれてる、exportされてる関数が微妙に違うから。 で、原典になったという、カーネギーメロン大学の方の Profiling を見る。どうもこちらのようだ。
使い方は、profileマクロを使って、観察したい関数を登録。後は、関数を適当に実行。 それからreportしてね。結果は累積されてくんで、クリアする場合、resetを発行するとな。 監視を止める場合は、unprofileって事だな。
> (package-name *package*) "COMMON-LISP-USER" > (use-package 'profile) Condition of type: SIMPLE-PACKAGE-ERROR There exists no package with name PROFILE
ポール本の210ページからパッケージの使い方がさらっと書いてある。噂によるとポールは、 余りパッケージシステムが好きでは無いようだ。だから、ちからが入らないんだな。彼が 好きなのはマクロ。マクロ専門本 On Lispなんてのを書いてるぐらいだから。 そんなものだろうね。今では、マクロがLispのアドバンテージだもの。
オイラー並みにパッケージを理解すると、パッケージってディレクトリーなんだな。 今居る場所は、Unixならpwdで確認するけど、CLだとpackage-nameコマンドで確認。
別Dirになってるのを参照するには、UnixだとPATHを通すって操作をするけど、CLだとuse-package なんだな。指定したDirへ行くには、Unixだとcdだけど、CLだと、in-packageになるんか。 mkdirの対応品は、あれれ? そういう時は、CLに聞いてみるのが手っ取り早い。
> :apropos package *PACKAGE* has value: #<"COMMON-LISP-USER" package> : LIST-ALL-PACKAGES Function MAKE-PACKAGE Function USE-PACKAGE Function WITH-PACKAGE-ITERATOR Macro
色々と出てきたな。どんなパッケージが有るかも確認出来るんか。
> (LIST-ALL-PACKAGES) (#<"ECL-CDB" package> #<"FFI" package> #<"GRAY" package> #<"MP" package> #<"CLOS" package> #<"C" package> #<"SI" package> #<"EXT" package> #<"KEYWORD" package> #<"COMMON-LISP-USER" package> #<"COMMON-LISP" package>)
あれ? お目当てのprofileが無いぞ。これって、ひょっとして隠しパッケージなのかなと unix-userは思ってしまうのでした。
こういう時は、Lispの総合開発環境、emacs+slimeに任せてみるのも手かも知れません。 Slimeのキーバインド なんてのを参照してみました。そしたら、ちゃんと有るじゃないですか。profileメニューが。
実験材料を用意しました。
sakae@uB:~/src/cl$ cat z.lisp (defun tak (x y z) (if (<= x y ) z (tak (tak (- x 1) y z) (tak (- y 1) z x) (tak (- z 1) x y)))) (defun fact (n) (if (zerop n) 1 (* n (fact (- n 1))))) (defun add1 (n) (1+ n)) (defun sq (n) (* n n))
tak,fact,add1,sqなんてのを定義。
CL-USER> (load "/home/sakae/src/cl/z.lisp") #P"/home/sakae/src/cl/z.lisp" CL-USER> (fact 10) 3628800 CL-USER> (tak 12 6 0) measuring PROFILE overhead..done seconds | consed | calls | sec/call | name -------------------------------------------------------- 0.000 | 4,581,360 | 63,609 | 0.000000 | TAK 0.000 | 0 | 11 | 0.000000 | FACT -------------------------------------------------------- 0.000 | 4,581,360 | 63,620 | | Total estimated total profiling overhead: 0.14 seconds overhead estimation parameters: 4.e-8s/call, 2.256e-6s total profiling, 8.4e-7s internal profiling These functions were not called: ADD1 SQ
実験材料を読み込んでおいてから、CL-USERってパッケージ内の全てをプロファイルしてねって指示。 それから、お目当てを実行。そして結果表示。 親切な事に、まだ試験してない関数も有るよって教えてくれています。
でも、ちょっと結果が変だぞ。実行時間が取れていない。使い方の間違いも無さそうだし、 どうしたものかな? そんなの聞くまでも無い、ソース嫁。
その前に、別の手法でプロファイルしてみる。cmuclのwebに紹介されてたやつ。
time
まずは、素直に使ってみる。
> (time (tak 18 9 0)) real time : 10.470 secs run time : 10.213 secs gc count : 102 times consed : 759824144 bytes 9
何回も回す場合は、loopの魔界を使うか
> (time (loop repeat 100 do (fact 1000))) real time : 0.161 secs run time : 0.120 secs gc count : 7 times consed : 58299976 bytes NIL
易しい繰り返しを使うのが、素直かつ脳内負荷の低減に役立ちます。
> (time (dotimes (i 100) (fact 1000))) real time : 0.149 secs run time : 0.152 secs gc count : 5 times consed : 936758312 bytes
この時点で、profileのBUG確定ですな。timeマクロで、ちゃんと時間計測出来ているんですから! こういうトラブルが有ると、生きた勉強になりそう。 その前に
slimeでは?
ちゃんと、profileを見つけて動かしてくれた。これってどゆ事? 変な疑問、もとえまっとうな 疑問が湧いてきましたなあ。slimeのコードも嫁ってか。
まてまて、emacsの裏bufferに*slime-events*という監視カメラが有ってだなあ。それに オイラーとeclとのやり取りがみーんな記録されてるんよ。そいつを見れば、どんな要求を 突きつけたか一発だわい。
(:emacs-rex (swank:list-all-package-names t) "COMMON-LISP-USER" :repl-thread 12) (:return (:ok ("SWANK-IO-PACKAGE" "SWANK" "SWANK-RPC" "SWANK-MATCH" "SERVE-EVENT" "PROFILE"\ "SB-PROFILE" "PROF" "SB-BSD-SOCKETS" "SWANK-MOP" "SWANK-BACKEND" "SWANK-LOADER\ " "ASDF/FOOTER" "ASDF/USER" "ASDF-USER" "ASDF/INTERFACE" "ASDF" "ASDF-UTILITIES\ " "ASDF/SOURCE-REGISTRY" "ASDF/BACKWARD-INTERFACE" ...)) 12) (:emacs-rex (swank:profile-package "CL-USER" t t) "COMMON-LISP-USER" :repl-thread 13) (:return (:ok nil) 13) : (:emacs-rex (swank:profile-report) "COMMON-LISP-USER" :repl-thread 31) (:write-string "measuring PROFILE overhead..done\n") (:write-string " seconds | consed | calls | sec/call | name \n-------\ :
デカ長さん(刑事物の凝ってるんで使ってみたのさ)の分析によると、eclに向かって、オイラーの 代理人(slime)が、お前、どんなサービスしてくれるん?
で、いろいろと答えが返ってきました。そなら、profile-packageってのが有るはずだから、 そいつを頼むわ。
そんでもって、結果を返せとな。このやり取りを裏で支えているのにswankってやつが想像 出来るけど、ここでは尻尾を出していません。まあ、多分そんな事でっしゃろう。
念の為、裏取りって事で、slime/swank-ecl.lispの中を覗いてみたら
(defimplementation profile (fname) (when fname (eval `(profile:profile ,fname)))) :
こんなのに出くわした。これって、slimeのコマンドを、ecl側のパッケージに結び付けて いるんだな。このファイルには、emacs側と通信する為のサーバーを立てる処理も書いて あったよ。で、これが翻訳された結果であるswank-ecl.fasがecl側で起動してた。 以下、その証拠を入手。slimeでeclを起動した後の状態
sakae@uB:~$ lsof -c ecl| awk '{print $9}' | grep sakae | cut -f15 -d '/' swank.fas swank-rpc.fas swank-match.fas swank-gray.fas swank-ecl.fas swank-source-file-cache.fas swank-backend.fas swank-source-path-parser.fas
基本、lsof -c eclだけで良いんだけど、出力がごちゃごちゃしてたんで、パイプを通して 洗浄してます。
でもどうやって、emacsからeclを起動してんの? こっそりemacsを尾行してみるかな。
sakae@uB:~/t$ strace emacs &> LOGemacs sakae@uB:~/t$ strace -f emacs &> LOGecl
上段は親側のemacsの挙動追跡。これだと煙に巻かれてしまって肝心な所が察知出来ない。 だって、emacsがeclって子共を生むんだけど、子の追跡はしてくれないのよ。
そんな訳で、生まれた子共もしっかり追跡出来るように、オプションを追加しました。 家にある唯一のsyscall解説書を、あわてて参照したよ。そしたら、子共を生む方法が 書いてあった。
親(emacs)が、vforkして、うり二つのプロセスを生成する。生まれた子供をexecveを使って eclに変身させる。親は子が死ぬのをじっと観察してて、死んだら、wait4で葬式を出してやる。 子供が死んでしまっても、親はまだまだ生き続ける(のが普通)。
たまたま親が先に死んだ後に子が死ぬと、葬式を出してもらえないので、子はゾンビになる。 みかねた神様のinit様が、ゾンビを成仏させてあげる。こういう世界なんだな。目の前で 動いているOSは。
sakae@deb:~/t$ grep execve LOGecl execve("/usr/bin/emacs", ["emacs"], [/* 19 vars */]) = 0 [pid 2803] execve("/usr/local/bin/ecl", ["/usr/local/bin/ecl"], [/* 22 vars */] <unfinished ...> [pid 2803] <... execve resumed> ) = 0
emacsが引数無しで起動され、そこからeclと言う子供が生まれたとな。子供の背番号は2803って 事が分かる。最後は子供を看取って、成仏した事を確認してるな。教科書通りの世界だ。
sakae@deb:~/t$ grep open LOGecl | grep slime : open("/home/sakae/.emacs.d/slime/slime.el", O_RDONLY|O_LARGEFILE) = 4 open("/home/sakae/.emacs.d/slime/contrib/slime-repl.el", O_RDONLY|O_LARGEFILE) = 5 : [pid 2803] open("/home/sakae/.emacs.d/slime/swank-loader.lisp", O_RDONLY|O_LARGEFILE) = 6 [pid 2803] open("/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-backend.fas", O_RDONLY) = 6 :
一方、こちらはslime関係の利用状況。slime.elとその関係者を親のemacsがまず利用。 子供の方は元気よく生まれたら、swan-loader.lispなんてのを呼び出すんだな。その力を 借りて、ecl側の環境を整え、親と交信出来るようにチャンネルを開くんか。
大まかには、上記の説明で良いだろうけど、おぎゃーと生まれたeclがどうやってswank-loader.lispを 嗅ぎ付けて、呼び出すの? そこが不思議。単独で起動したeclは、勿論swank-loader.lisp なんて呼び出さないし。。。
ニュートン誌で、新生児の誕生の仕組みが解説されてた。母体から分離(出産の事ね)した 時、心臓の大工事を行い血液の流れを変える事や、肺の自動起動の仕組みが解説されてて 、生命の不思議さに心を打たれましたよ。
ちなみに、肺の自動起動はどうなってるかと言うと。。。母体の中に居る時は新生児の肺は 肺水に満たされていて機能していない。必要な酸素はへその緒を通じて流れてくる血液から 得ているとか。産道を通って出てくると、肺が圧迫されて肺水が吐き出される。これを トリガーにして、産声と言う肺活動を開始するとな。肺が一時的にぺしゃんこになる訳 だけど、潰れた肺がペタンとくっつかないように、すぐに膨らむように、肺水には界面活性剤 相当の成分が含まれているらしい。何と手回しの良い事。こういう話を聞くと、神の意思を 感じぜずにはいられないな。
それに比べたら、生まれたeclが親と通信出来るようになるなんて、小さい事だろうけど、 どうやってるの? 何か見落としが有るのだろうな。
案として、起動時に引数で渡す、環境変数で渡す、特定なパイプを開いておく、eclがemacsの 起動してる事を自分で察知する、ぐらいかなあ。
親は子供の番号を知ってるけど、子供は親の番号を直接は知らない、まてよ、getppidなんてのが 有ったな。調べてみたけどgetppidなんて使われていなかった。
後はシグナルで通知かなあ。もう少し考えてみよう。
eclでサーバー構築
slimeの中のファイルをぼーっと眺めていたら、start-swank.lisp なんて興味を引くやつに気付いた。 早速開いて点検してみると、CL側でサーバーを立てる為の起動スクリプトである事が判明。 サーバーと言っても、slime語を喋るサーバーですけど。
slimeとかswankとか勝手に出てきてるんで、ちょっと整理しとく。
emacsとCLのやり取りが必要。CLは共通Lispって事だけど、やはり微妙に個性がある。 そこで、emacsと各種CL間のやり取りをするプロトコルを有志が定めた。このプロトコル がslime。各種CL側がサーバを建ててemacsからのslime語を待ちうけ、それに応答する。 各種CL側で動くサーバーやslime語の解釈は、swank-xxってので行う。xxの部分は、CLに 共通な部分と、個別CL用と分かれていて、詰め合わせセットで提供されてる。
sakae@deb:~/.emacs.d/slime$ ecl -load start-swank.lisp ;;; Loading "/home/sakae/.emacs.d/slime/start-swank.lisp" ;;; Loading "/home/sakae/.emacs.d/slime/swank-loader.lisp" ;;; Loading #P"/usr/local/lib/ecl-13.5.1/cmp.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-backend.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-source-path-parser.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-source-file-cache.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-ecl.fas" ;;; Loading #P"/usr/local/lib/ecl-13.5.1/sockets.fas" ;;; Loading #P"/usr/local/lib/ecl-13.5.1/profile.fas" ;;; Loading #P"/usr/local/lib/ecl-13.5.1/serve-event.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-gray.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-match.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank-rpc.fas" ;;; Loading "/home/sakae/.slime/fasl/2013-06-26/ecl-13.5.1-linux-pentium3/swank.fas" ;;; Warning: These Swank interfaces are unimplemented: (ACTIVATE-STEPPING ADD-FD-HANDLER ADD-SIGIO-HANDLER BACKGROUND-SAVE-IMAGE DUP EXEC-IMAGE FRAME-CALL LIST-CALLEES LIST-CALLERS MACROEXPAND-ALL MAKE-FD-STREAM REMOVE-FD-HANDLERS REMOVE-SIGIO-HANDLERS RESTART-FRAME RETURN-FROM-FRAME SAVE-IMAGE SLDB-BREAK-AT-START SLDB-BREAK-ON-RETURN SLDB-STEP-INTO SLDB-STEP-NEXT SLDB-STEP-OUT TOGGLE-TRACE) ;; Swank started at port: 4005.
何やら、見慣れたファイルをローディングしてるなあ。最後に、port 4005で待ってるからね って言ってきた。これが、80番とか443だったら、一般受けするんだろうけど。。。
別端末からemacsを起動して、M-x slime-connect して、localhostの4005番に接続したら、 見慣れた、やつが
ECL Port: 4005 Pid: 2401 ------------------------------------------------------------------------ ; SLIME 2013-06-26 CL-USER>
TCPを使って、emacsとeclが結ばれましたねぇ。なお、件のファイルには、
;;; For additional swank-side configurations see ;;; 6.2 section of the Slime user manual.
なんて、親切にポインターが紹介されてましたよ。これを読むと、通信の秘密が解けるのだるか? 騙されたと思って読んでみれ。刑事物語風に言うと、靴をすり減らして、地取りをせいって 事なんですなあ。そう言えば、昔有った、3億円強奪事件を執念で追ってた刑事が居たなあ。 本を探して、また読んでみるかな。
気になったんで、slime.elを眺めてみたんだ。
;;; ;;; 0. Emacs recompiles/reloads slime.elc if it exists and is stale. ;;; 1. Emacs starts an inferior Lisp process. ;;; 2. Emacs tells Lisp (via stdio) to load and start Swank. ;;; 3. Lisp recompiles the Swank if needed. ;;; 4. Lisp starts the Swank server and writes its TCP port to a temp file. ;;; 5. Emacs reads the temp file to get the port and then connects. ;;; 6. Emacs prints a message of warm encouragement for the hacking ahead. ;;; ;;; Between steps 2-5 Emacs polls for the creation of the temp file so ;;; that it can make the connection. This polling may continue for a ;;; fair while if Swank needs recompilation.
なんてこったい、灯台本暗しだな。親から子へ標準道路を経由して、サーバーの起動を 促しているんか。そして、サーバー起動後も秘密の通路は確保しとくとな。これって、 隠れた親子のキズナでしょうか。麗しや。
ああ、それにしてもslime.elの行数が長すぎるぞ、9500行近くあるぞ。まあ、このファイルは emacs側の画面制御やslime語の送受信と解釈まで、一括して行うブラウザーだから 大きくなるのも当然か。
でも、今回の要所は上記の部分だな。後はオンデマンドで大丈夫。最後に、実験。
sakae@deb:~/.emacs.d/slime$ echo ':ld start-swank.lisp' | ecl : ;; Swank started at port: 4005.
こういう事が出来るのね。知らんかったぞ。これを見て、遠い昔にWebサーバーでcgiを やったのを思い出したぞ。cgiもプロトコルだったな。Webサーバーとcgi側は、標準入出力を 介して繋がってたな。
ManKai Common Lisp (MKCL)
eclからフォークしたと言う ManKai Common Lisp (MKCL) なんてのをLisp netで見つけた。これって、CMU CLから分家したsbclみたいなものだな。 果たして、主流になるか、生暖かく見守りたいと思います。
所で、上記は正式に、ManKaiって書いてるけど、これって、満開から取ったんだろうか。 どうも外人は、漢字に憧れるようで、よく努力とかなんて漢字を刺青に彫っている人が居るな。
おいらのお勧めは闘魂Lispとか絆Lispだったりするけど、どうでしゃろ? あちらの方。 そう言えば、キズナなんて名前のお馬さんが居ますなあ。安田記念では果たして勝つでしょうか。
早速、ウブでやってみると
;;; Compiling /usr/share/common-lisp/source/cl-asdf/build/asdf.lisp.Error during command line arguments processing: Error: in file /usr/share/common-lisp/source/cl-asdf/build/asdf.lisp, end position 208893, and form: (WITH-UPGRADABILITY NIL (MAP NIL 'REGISTER-IMAGE-RESTORE-HOOK ...)) raw-command-line-arguments not implemented yet. : You are recommended to compile again.. make[1]: *** [trivial-features.fasb] Error 1 make[1]: Leaving directory `/home/sakae/mkcl-1.1.8/src' make: *** [all] Error 2
あえなく撃沈。作者の方は、12.04 LTSでやってるって事なんで、cl-asdf(rubyで言ったら、gem みたいなもの、ああ、そこまでデフォになってないかasdfは)は、古めなんでしょうかね。
しょうがないので、fedoraでやったら動いた。
[sakae@fedora ~]$ mkcl This is ManKai Common Lisp 1.1.8 Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya Copyright (C) 1993 Giuseppe Attardi Copyright (C) 2000 Juan J. Garcia-Ripoll Copyright (C) 2010-2014 Jean-Claude Beaudoin ManKai Common Lisp (MKCL) is free software, and you are welcome to redistribute and/or modify it under the terms of the GNU LGPL. See file 'Copyright' in the source code for details. Type :h for Help. Top level in: #<thread "Initial" active (1003) 0xb7754940 08dd4800>. >
やれやれ。
ConEmu
パソコンを起動してる間ほとんどの時間をvboxかVMwareの上で過ごしている。だって、Win上 では開発環境が貧弱過ぎるから。その際たるものがコンソール。やる気零のM$に従うのは 勘弁って訳。
でも、最近はWindows標準のコマンドプロンプトウィンドウをタブ化できる「ConEmu」 があるみたい。これで少しはWin上に止まれるかなあ。おいらは根っからのCUI人ですから。