factor(2)
ニュートン誌のバックナンバーを見てたら、巨木の記事が出てた。それによると日本では、 地上高1.3mの所で幹回りが3mを超える樹が巨木と定義されてるようだ。
そんな樹なら近くの神社にいっぱいあるぞ。神社のスペック表によると、本社の社は京都に あって、そこからの出張所らしい。もう、この地に来てから1000年以上は経っているらしい。 そんな神社だからこそ、りっぱな樹があるのだろう。樹の種類はけやきだそうだ。
まいにち、境内を通っているのに、いままで知らなかったよ。C.W.ニコルさんの、『マザーツリー 母なる樹の物語』 だったかに倣って、樹の息を聞いてみよう。散歩の間の一休みに丁度良さそう。野鳥さんも 一杯来てさえずっているし、耳の保養にも良い所だから。
所で、幹回り3mってどれぐらい。直径1mぐらいだな。大人2人が手をつないでみて、つなげる ぐらいか。身体尺ですな。歩数も巻尺の変わりをするな。昔、伊能さんは、全国を歩いて 回って地図を作ったらしいけど、歩数が正確だからこそ出来た偉業らしい。
外国の王様はそういう事が出来ない為、指の長さをインチという単位で残したらしい。 フィートもヤードも身体尺。そんじゃ、もう一つの単位系、重さはどうだ。後世まで 重さを残すなら、王様の金玉を乾かしたものがいいな。ダイヤモンドの重さを測る単位は 豆の重さだったそうだから、金の重さを測るには金玉が最適。3金玉って、時価価値で 幾らぐらいになるんでしょうね?
金に縁のない人は、そんな事考えるな。時間の無駄だ。時は金也!
factorでApp製作
前回factorの資料をちらちら見てたら、factor語で書かれたソースを元にアプリが 製作出来るよって書いてあった。
factorは、factorって言うアプリとそれが参照するイメージ(Diskみたいにイメージしてね)が セットで動いている。そのイメージがまた大きいんだな。今、FreeBSDに入れてるのを確認 したら、63Mも有った。
これにfactor上のアプリ(テトリスとか)をsaveして、相手に配るってなると、例のiOSの アプリみたいになっちゃって、はなはだ具合が悪い。そこで、factorチームの人は、必要な ものだけを入れたイメージとそれを動かすVMを一まとまりにする事を考えた。 これなら何処でも動かせるって訳だな。
Windows7にもfactorを入れておいたので、Winの方でやってみる。
IN: scratchpad USE: ui.tools.deploy IN: scratchpad "tetris" deploy-tool IN: scratchpad Command: deploy Loading resource:extra/tetris/tetris.factor : Clearing megamorphic caches Saving final image
これで、単独で動くtetris.exeが出来上がった。容量は1.8Mだったよ。
FreeBSDの方だと
( scratchpad ) USE: tools.deploy ( scratchpad ) "tetris" deploy { "Tetris/tetris" "-i=/home/sakae/factor/temp/staging.math-threads-compiler-ui.image" "-resource-path=/home/sakae/factor/" "-run=tools.deploy.shaker" "-vocab-manifest-out=/home/sakae/factor/temp/vocab-manifest-tetris" "-deploy-vocab=tetris" "-deploy-config=/home/sakae/factor/temp/deploy-config-tetris" "-output-image=Tetris/tetris.image" "-pic=0" } Loading resource:basis/tools/deploy/shaker/shaker.factor : Saving final image Binary deployed to /home/sakae/factor/Tetris.
FreeBSDのfactorは時代が古いせいか、ファイルが2つに分かれていた。容量的にはWinとさほど 変わらず。
[sakae@pcbsd ~/factor]$ ls -l factor Tetris/* -rwxr-xr-x 1 sakae sakae 400362 Jul 12 10:40 Tetris/tetris -rw-r--r-- 1 sakae sakae 1225776 Jul 12 10:41 Tetris/tetris.image -rwxr-xr-x 1 sakae sakae 400362 Jul 3 09:38 factor
これを見ると、deploy用にダイエットしたイメージを作っているのね。そして、factor本体と イメージを一つにするって進化があるのね。 Debian版では進化が有って、実行ファイルが一つだけになってた。
scaffold
かの有名なレールには、scaffold なんてのが付いていたように思う。Rails4になっても 健在なのかしらん? あちら方面にはすっかりご無沙汰だからなあ。
factorに付属してるemacsモジュールは、fuelって言うんだけど、こやつにも足場が付属 してる。ボキャブラリィーって言うモジュールって言うかアプリを開発する為の道具セットだ。 どんなのがあるかと言うと
fuel-scaffold-authors fuel-scaffold-help fuel-scaffold-platforms fuel-scaffold-summary fuel-scaffold-tags fuel-scaffold-tests fuel-scaffold-vocab
コードを書いたりヘルプを書いたりテストを書いたりが簡単に出来るようになってる。上で 見たdeployは、まあ稀な事だから出来ないけど。
新しいボキャブラリィーを作る時は、fuel-scaffold-vocabする。どんな名前にするかって 聞いてくるんで適当に名前を付ける。ああ、末代までこの名前が付いて回るんで、愛情 溢れる名前を付けてあげよう。
次は Vocab root: resource: って聞いてくるんで、workって応答。これで、work-dirの 中に、指定した名前のdirが作られて、その中に指定した名前.factorってファイルが出来る。 続けて、幾つが質問されるけど、付属ファイルの事だから後で指定してもいいし、雛形だけを 先に作っておいても良い。
今回は、factで行ってみる。
! Copyright (C) 2013 Your name. ! See http://factorcode.org/license.txt for BSD license. USING: ; IN: fact : fact ( n -- n! ) dup 0 = [ 1 ] [ dup 1 - fact * ] if ;
これで、C-c C-l して、コンパイルすると、文句を言われた。
Restarts: :1 Use the kernel vocabulary :2 Defer word in current vocabulary :3 Load /home/sakae/factor/work/fact/fact.factor again ----------- Press g go to file, 1-3 invoke restarts, q bury buffer
kernelをインクルードせいとな。インクルードのfactor方言はUSING なので、そこに 追加してく。
Note: Already using ``kernel'' vocabulary Loading /home/sakae/factor/work/fact/fact.factor /home/sakae/factor/work/fact/fact.factor 9: [ dup 1 - fact * ] ^ No word named “-” found in current vocabulary search path Error: condition Restarts: :1 Use the math vocabulary :2 Defer word in current vocabulary :3 Load /home/sakae/factor/work/fact/fact.factor again
今度は、引き算が無いとぬかす。math をUSING しろとな。嗚呼、マシンに使われてるな。 mathを追加したら、コンパイルが通ったので、いよいよ使うぞ。
IN: scratchpad USE: fact :errors - show 1 compiler errors IN: scratchpad :errors ==== /home/sakae/factor/work/fact/fact.factor /home/sakae/factor/work/fact/fact.factor: 6 Asset: fact The input quotations to “if” don't match their expected effects Input Expected Got [ 1 ] ( ..a -- ..b ) ( x -- x x ) [ dup 1 - fact * ] ( ..a -- ..b ) ( x -- x ) :errors - show 1 compiler errors
今度は論理エラーですかい。6行目。期待値と実値を見比べると、あらら、スタックが 成長してるってさ。dropしとけばいいんだな。
IN: scratchpad 5 fact --- Data stack: 120
やっと動いたよ。そんじゃ、順序が逆になるけどテストコードを書いてみる。
! Copyright (C) 2013 Your name. ! See http://factorcode.org/license.txt for BSD license. USING: tools.test fact ; IN: fact.tests [ 24 ] [ 4 fact ] unit-test [ 20 ] [ 5 fact ] unit-test
間違ったテストコードです。実行してみると、
IN: scratchpad "fact" test Loading resource:work/fact/fact-tests.factor Unit Test: { [ 24 ] [ 4 fact ] } Unit Test: { [ 20 ] [ 5 fact ] } --> test failed! :test-failures - show 1 unit test failures --- Data stack: 120 IN: scratchpad :test-failures ==== resource:work/fact/fact-tests.factor resource:work/fact/fact-tests.factor: 8 Unit Test: { [ 20 ] [ 5 fact ] } === Expected: 20 === Got: 120 [Traceback]
なる程、エラーの時はこんな風になるんだ。そんじゃ、引数を与えないで実行したらどうなる?
IN: scratchpad fact Data stack underflow Type :help for debugging help. IN: scratchpad :help datastack-underflow. ( obj -- ) Vocabulary debugger Error description Thrown by the Factor VM if an attempt is made to pop elements from an empty data stack. Notes You can use the stack effect tool to statically check stack effects of quotations. See Stack effect checking. Definition IN: debugger : datastack-underflow. ( obj -- ) "Data" stack-underflow. ; Debugger commands: :s - data stack at error time :r - retain stack at error time :c - call stack at error time :edit - jump to source location (parse errors only) :get ( var -- value ) accesses variables at time of the error :vars - list all variables at error time
ふむ、:helpで、debuggerが起動してきた。データスタック、予備のスタック、コールスタック っていう構成で動いているのね。面白そうなんで、コールスタックを覗いてみる。
IN: scratchpad :c (U) Quotation: [ c-to-factor -> ] Word: c-to-factor (U) Quotation: [ [ catchstack* push ] dip call -> catchstack* pop* ] (O) Word: command-line-startup (O) Word: listener (O) Word: (listener) (U) Quotation: [ [ ~quotation~ dip swap ~quotation~ dip ] dip swap [ call datastack ] dip -> swap [ set-datastack ] dip ] (U) Quotation: [ call -> datastack ] (O) Word: fact (U) Quotation: [ signal-handler -> ] Word: signal-handler (U) Quotation: [ OBJ-CURRENT-THREAD special-object error-thread set-global current-continuation -> error-continuation set-global [ original-error set-global ] [ rethrow ] bi ]
今の所、意味不! ソース嫁なんですかね。ちょっと調べてみる。ハンドブックに 困った時は、 helpかseeって書いてあったから。
IN: scratchpad \ :c help :c ( -- ) Factor documentation > Factor handbook > The language > Exception handling > The debugger Prev: :r ( -- ) Next: :get ( variable -- value ) Vocabulary debugger Word description Prints the call stack at the time of the most recent error. Used for interactive debugging. Definition USING: accessors continuations namespaces prettyprint ; IN: debugger : :c ( -- ) error-continuation get call>> callstack. ;
IN: scratchpad \ :c see USING: accessors continuations namespaces prettyprint ; IN: debugger : :c ( -- ) error-continuation get call>> callstack. ;
ふむ、helpの方が親切だな。こうして定義までもさっと見られるって、ほらsmalltalkっぽく ないかい。
データと言うか引数がスタックを渡り歩いてくる、それをforth用語で言う所のword、一般 用語で言うと関数で加工してくって見方をすれば、おいらにはパイプでいろいろ処理 してくように思えるぞ。
後、上のfactでもそうなんだけど、変数ってものがさっぱり顔を出さない。と言う事は 変数名についてあれこれ悩む必要無し。(悩み無用の・・・ なんてCMも有ったな)この辺はハスケラーさん達が有り難がる、 ポイントフリースタイルが、自然に実現されてるぞ。華麗もとえカリー化なんて機能も 備わっているしね。至れり尽くせりですよ。
そうそう、ワード名(関数名)を英字で始めなきゃいかんと言う変な制限も無いし、 記号文字を適当にワード名に混ぜ込んでもOK。こういう所は、Schemeチックだなあ。
App製作
折角factなんてのを書いたんで、強制的にAppにしてみる。Appに出来る条件としてMAINが 必要との事なんで、
USING: kernel math ; IN: fact : fact ( n -- n! ) dup 0 = [ drop 1 ] [ dup 1 - fact * ] if ; MAIN: fact
と書いて、それを deployしてみた。
sakae@debian7:~/factor/fact$ ls -lh fact -rwxr-xr-x 1 sakae sakae 1.2M Jul 12 16:42 fact sakae@debian7:~/factor/fact$ ldd fact | wc -l 62
色々リンクしてますなあ。記念にobjdump -d したやつ
08080ef0 <start_standalone_factor>: 8080ef0: 55 push %ebp 8080ef1: 57 push %edi 8080ef2: 56 push %esi 8080ef3: 53 push %ebx 8080ef4: 83 ec 6c sub $0x6c,%esp 8080ef7: e8 e4 b0 fd ff call 805bfe0 <pthread_self@plt> 8080efc: 8b bc 24 80 00 00 00 mov 0x80(%esp),%edi 8080f03: c7 04 24 9c 02 00 00 movl $0x29c,(%esp) 8080f0a: 8b ac 24 84 00 00 00 mov 0x84(%esp),%ebp 8080f11: 89 c3 mov %eax,%ebx 8080f13: e8 68 ab fd ff call 805ba80 <_Znwj@plt> 8080f18: 89 5c 24 04 mov %ebx,0x4(%esp) 8080f1c: 89 04 24 mov %eax,(%esp) 8080f1f: 89 c6 mov %eax,%esi 8080f21: e8 2a 19 02 00 call 80a2850 <_ZN6factor9factor_vmC1Em> 8080f26: 89 34 24 mov %esi,(%esp) 8080f29: e8 32 db fd ff call 805ea60 <_ZN6factor23register_vm_ :
実際に走らせてみると、、、
sakae@debian7:~/factor/fact$ ./fact The die word was called by the library. Unless you called it yourself, you have triggered a bug in Factor. Please report. Starting low level debugger... Basic commands: q ^D -- quit Factor c -- continue executing Factor - NOT SAFE t -- throw exception in Factor - NOT SAFE .s .r .c -- print data, retain, call stacks help -- full help, including advanced commands
factorのBUGを踏んだか心配してくれてるよ。今回は確信犯ですから、何も言うまい。
less.el
emacs 24を使ってて、ふと less-minor-mode が無い事に気付いた。何か設定でも 必要なの? それとも他のモードに吸収されちゃの? 調べてみたけど分からんので elファイルが無いかと探ってみたよ。
そしたら、less.elなんて名前の ずばりのやつが出てきた。
易しくコードが書いてあって、勉強になるなあ。