maximaとか(7)

朝、車の窓に水滴が付くような季節になったのう。

柳田國男風に言うと、ハレの日 がやってきた。今日はむらの神社のお祭りの日。

いつもは誰もいない境内だけど、この日は朝の上野駅ホームも真っ青になるぐらいの混みよう。 境内には屋台が出て、がきちょが眼をらんらんと輝かしているし、灯篭を持ったおばちゃん連中が 隊列を組んでいる。村中を練り歩くんだろうか?

みこしを担いだ青年団だか消防団だかが、境内に入ってきたよ。てんやわんやの大騒ぎ。おはやし が聞こえてきて、舞台では獅子舞が踊り狂ってる。混沌のエリアですよ。

ふと、あたりの立ち木に眼をやると、そこにはぼんぼりが沢山飾ってあった。それぞれのぼんぼりには 墨痕鮮やかに、ざれ句が書かれていた。きっと、公民館の書道部と俳句部会の合作なんだろうな。

めったに謝らなぬ アメリカとうちの女房
糠床を箸でかきます 俺っちの嫁っ子
カーナビで交番探して道を聞き
貰うならお金よね あげるなら気持ち

Lispの掲示板から

ABCL Dev ? Building SBCL with ABCL
@2011-08-25 15:43
In revisiting our compiler for various improvements, it is helpful to have
challenging compilations to perform so that we have some confidence we 
don't break things along the way. One of the more complicated tasks 
we've found is using ABCL as a build host to compile SBCL which has 
seemingly has lots of twisty little macros, all different. A while ago, 
maybe perhaps a year ago, we broke this behavior, closing off this avenue of testing.

But due to recent work, as of ABCL trunk r13538 we've restored this capability, 
once again making ABCL capable of bootstrapping an SBCL build. This may prove 
handy for individuals who wish to port SBCL to new platforms where there is 
a JVM available.

When we mentioned this on #lisp, we were asked how long it takes ABCL to build 
SBCL vs. SBCL building itself.

ABCL building SBCL
//build started:  Thu Aug 25 15:12:30 CEST 2011
//build finished: Thu Aug 25 16:49:30 CEST 2011
real	96m59.819s
user	37m35.702s
sys	32m44.641s

SBCL building SBCL
//build started:  Thu Aug 25 16:51:34 CEST 2011
//build finished: Thu Aug 25 17:07:47 CEST 2011
real	16m12.855s
user	4m40.804s
sys	3m28.145s

So, ABCL is roughly a factor of six slower building SBCL than SBCL itself.

Javaが動けば、この技法で、何処でも sbcl って事でいいのかな? 嗚呼、そんな訳は無いよな。 runtimeを作るのにCのコンパイラーが必要。

しつこく ldb

前からやってる、ldbでセグフォになる件。これほどの地雷が放置されてるとは考え難いよな。 よって、例に示されてた方式でやってみる。

例では、制御不能に陥ったsbclを止めて、解剖するって事を想定してるんだな。まずはsbclを起動 しといて、別端末から、止まれ指令を発してみる。

[sakae@cdr ~]$ ps awx | grep sbcl
 7655   2  I+     0:00.02 sbcl --noinform
[sakae@cdr ~]$ kill -6 7655
[sakae@cdr ~]$ sbcl --noinform
* fatal error encountered in SBCL pid 7655:
SIGABRT received.


Welcome to LDB, a low-level debugger for the Lisp runtime environment.
ldb> ba
Backtrace:
   0: Foreign function ldb_monitor, fp = 0x286ff4e8, ra = 0x8055d27
   1: Foreign function lose, fp = 0x286ff518, ra = 0x8053985
   2: Foreign function sigabrt_handler, fp = 0x286ff528, ra = 0x8053bd2
   3: Foreign function unblock_signals_in_context_and_maybe_warn, fp = 0x286ff548, ra = 0x8055216
   4: Foreign fp = 0x286ff8e0, ra = 0xbfbfffb4
   5: SB-IMPL::SUB-SUB-SERVE-EVENT
   6: SB-IMPL::SUB-SERVE-EVENT
   7: (SB-C::HAIRY-ARG-PROCESSOR SB-SYS::WAIT-UNTIL-FD-USABLE)
   8: SB-IMPL::REFILL-INPUT-BUFFER
   9: SB-IMPL::INPUT-CHAR/UTF-8
  10: (SB-C::VARARGS-ENTRY (COMMON-LISP::LAMBDA (COMMON-LISP::&REST COMMON-LISP::REST)))
  11: (SB-C::&MORE-PROCESSOR (COMMON-LISP::LAMBDA (COMMON-LISP::&REST COMMON-LISP::REST)))
  12: (SB-C::HAIRY-ARG-PROCESSOR COMMON-LISP::READ-CHAR)
  13: (SB-C::HAIRY-ARG-PROCESSOR COMMON-LISP::READ-CHAR)
  14: SB-IMPL::%READ-PRESERVING-WHITESPACE
  15: SB-IMPL::%READ-PRESERVING-WHITESPACE
  16: (SB-C::HAIRY-ARG-PROCESSOR COMMON-LISP::READ)
  17: SB-IMPL::REPL-READ-FORM-FUN
  18: SB-IMPL::REPL-FUN
  19: (COMMON-LISP::LAMBDA ())
  20: SB-IMPL::%WITH-REBOUND-IO-SYNTAX
  21: SB-IMPL::TOPLEVEL-REPL
  22: SB-IMPL::TOPLEVEL-INIT
  23: (COMMON-LISP::LABELS SB-IMPL::RESTART-LISP)
ldb> regs
CSP     =       0x00000000   CFP        =       0x00000000
ALLOC   =       0x59982000
ldb> exit
Argh! lossage_handler() returned, total confusion..

ちゃんと動いた。って事は、おいらが遭遇したのは、lisp機械が準備中の状態で、万全な体勢に なってないんだな(何せ、本体のロード前ですから)。 それでもセグフォは拙いでっせと強弁も出来ようが、極東の アホが過剰品質求めてるって言われそうだな。

そんな事より、ABRTボタンでLisp機械が落とせる仕掛けってなかなかいいね。昔、MACに debuggerSWを取り付けて、無闇にホワイトスクリーンの画面を出して遊んだ事を思い出しちゃったよ。

Windowsでもsbcl

前に、sbclソースを取りに行った時、Windows用バイナリーが公開さてたので取ってきておいたんだ。 すっかり忘れておったわい。そんな訳なんで、遅まきながらWindows7にも入れてあげた。 コンソール上で動く事を確認した後slimeから使おうとすると、動かないんだ。何で?

そもそもslimeの仕組みも知らんしなあ。何処から手を付けたらいいものやら? で、 こちらあたりを見ると、lispとネットワーク 経由で通信してる事が分かった。Windowsの火壁が邪魔してるのかも? でも、ローカルホストって 事だと、そんな事も無いか! そもそも、cclでちゃんと動いているし。そうなるとslimeのcvs版 が怪しいか? FreeBSDで実績があるやつを持ってきてもダメ。

諦めて、Windows専用のsbclサイトへ 行ったら、スナップショットが置いて有ったんで、試してみた。動いた。こんな事もあるのね。

で、unixみたいに、killコマンドが有るかと思って探してみたら、taskkillってのが有ったけど、 このコマンドではシグナルを送れないのね。そもそも、Windowsにはシグナルって概念無いの だろうか? 不幸なOSだ事 > Windows

とか言ってたら、

Shiro(2011/06/10 17:51:41 PDT): Gauche/Winはmingw版ですよね? 無視というか、
そもそもWindowsには「シグナル」という概念が無くて、 Cの標準規格をサポートするために
signal()関数はあるんですが、公式にはSIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERMしか
サポートされていません。「CTRL+Cシグナル」というものは無いんです。

との、解説を発見。自分でボタンをこしらえるといいのかな?

inspect

やっとWindowsでもsbcl出来るようになって、気をよくした。いつでも手軽にsbcl。そうなると sbclでいろいろ探検したくなる。もう、ローレベルな所へは下りて行きませんけど。

そんなんで、面白そうなLisp手続きを見てたら、検査コマンドが見つかった。

C-c I すると、何を調べるなんて聞いてくる。そんじゃ、consでも調べてみてって事で、'cons って 入力すると、画面が割れて

#<SYMBOL {22363867}>
--------------------
Its name is: "CONS"
It is unbound.
It is a function: #<FUNCTION CONS> [unbind]
Function documentation:
  Return a list with SE1 as the CAR and SE2 as the CDR.
It is external to the package: COMMON-LISP [unintern]
Property list: NIL
It names the class CONS [remove]

こんな風にレポートしてきた。勿論、slimeの力を借りなくても

CL-USER> (inspect 'cons)

The object is a SYMBOL.
0. Name: "CONS"
1. Package: #<PACKAGE "COMMON-LISP">
2. Value: "unbound"
3. Function: #<FUNCTION CONS>
4. Plist: NIL
> ?

help for INSPECT:
  Q, E        -  Quit the inspector.
  <integer>   -  Inspect the numbered slot.
  R           -  Redisplay current inspected object.
  U           -  Move upward/backward to previous inspected object.
  ?, H, Help  -  Show this help.
  <other>     -  Evaluate the input as an expression.
Within the inspector, the special variable SB-EXT:*INSPECTED* is bound
to the current inspected object, so that it can be referred to in
evaluated expressions.
> q

; No value

左側の数字がメニュー番号になっているので、数字を指定して深い所まで、検査出来るよ。

apropos

maximaには便利な ?? ってのが有ったな。共通リスプにもきっとあるに違いないと 思って探してみたら、やっぱり有ったよ。gaucheにも有るしね。

CL-USER> (apropos 'macro)
*MACROEXPAND-HOOK* (bound)
COMPILER-MACRO
COMPILER-MACRO-FUNCTION (fbound)
DEFINE-COMPILER-MACRO (fbound)
DEFINE-MODIFY-MACRO (fbound)
DEFINE-SYMBOL-MACRO (fbound)
DEFMACRO (fbound)
  :
SWANK-BACKEND::MACRO-NAME
SWANK-BACKEND:MACROEXPAND-ALL (fbound)
SWANK-BACKEND:WHO-MACROEXPANDS (fbound)
; No value

いろいろ有りすぎて困っちゃうよ!

room

CL-USER> (room)
Dynamic space usage is:   36,748,048 bytes.
Read-only space usage is:      2,752 bytes.
Static space usage is:         1,712 bytes.
Control stack usage is:        3,288 bytes.
Binding stack usage is:          600 bytes.
Garbage collection is currently enabled.

Breakdown for dynamic space:
  10,341,952 bytes for    13,787 code objects.
   6,021,280 bytes for   752,660 cons objects.
   4,609,464 bytes for   106,678 instance objects.
   4,572,416 bytes for    16,098 simple-character-string objects.
   4,547,736 bytes for    71,153 simple-vector objects.
   7,099,760 bytes for   284,199 other objects.
  37,192,608 bytes for 1,244,575 dynamic objects (space total.)

step

面白いのの続き第4段。

(declaim (optimize (debug 3) (safety 3)
                   (speed 0) (space 0) (compilation-speed 0)))

(defun fun (n)
	   (if (zerop n)
	       1
	       (* n (fun (1- n)))))

(step (fun 3))
; Evaluating call:
;   (FUN 3)
; With arguments:
;   3

1] s
; Evaluating call:
;   (- N 1)
; With unknown arguments

0] s
; Evaluating call:
;   (FUN (1- N))
; With arguments:
;   2
  :
0] s
; (FUN (1- N)) => 2
; Evaluating call:
;   (* N (FUN (1- N)))
; With unknown arguments

0] s
; (FUN 3) => 6

6

昔、DrSchemeにこんな動作をするstepperってのが付いてて、よく遊んだなあ。共通Lispでは こんなの当たり前だったのね。

この機能、Windows版ではスレッドの関係からか、エラーに落ちてしまい動かなかったよ。残念!

cltl2

上の面白機能、cltl2を見てて見つけたんだけど、ここらでemacsからも引けるようにして おくかな。

まずはドキュメント と、elispを取ってきて、配置する。 続いて、.emacsに設定を追加する。

;; cltl2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(load-file "~/.emacs.d/cltl2.el")
(require 'cltl2)
(setq cltl2-root-url (concat "file://" (expand-file-name "~/.emacs.d/cltl/")))
(global-set-key "\C-cH" 'cltl2-lookup)

これでOK。思いつく関数名を入れれば、表示してくれるよ。さっと、しおりを開くように。。

しおりと言えば、emacs単独でもBookmark機能があるな。C-c r m で、しおりを挟み、C-c r l で、 しおりを参照して飛んでく。これだけだけど、結構便利。

describe

余りsbcl寄りの事ばかり書いているとあれなんで、少しはmaximaしてみる。で、install手順を 見てると、maxima-dumpなんてのを走らせている。これはmaxima用のcoreを作ってるんだな。 どんなコードになってるか調べてみよう。

(defun maxima-dump ()
  #+clisp (ext:saveinitmem "binary-clisp/maxima.mem" :init-function (function cl-user::run))
  #+sbcl (sb-ext:save-lisp-and-die "binary-sbcl/maxima.core" :toplevel #'cl-user::run)
  #+gcl (si:save-system "binary-gcl/maxima")
  #+cmu (extensions:save-lisp "binary-cmucl/maxima.core" :init-function 'cl-user::run)
  #+scl (extensions:save-lisp "binary-scl/maxima.core" :init-function 'cl-user::run)
  #+allegro (excl:dumplisp :name "binary-acl/maxima.dxl")
  #+lispworks (hcl:save-image "binary-lispworks/maxima" :restart-function 'cl-user::run)
  #+ccl (ccl:save-application "binary-openmcl/maxima" :toplevel-function 'cl-user::run))

シャープ・プラスは、リーダーマクロ。C言語の #if 相当だ。共通リスプと言っても、ここまで 来ると、みんな勝手な関数名にしてるのね。さて、sbcl用のやつの解説は何処に? info sbcl すれば、まあ出てくるんだけど、slime上からも引けるようになっている。

CL-USER> (describe 'save-lisp-and-die)
SB-EXT:SAVE-LISP-AND-DIE
  [symbol]

SAVE-LISP-AND-DIE names a compiled function:
  Lambda-list: (CORE-FILE-NAME &KEY (TOPLEVEL #'TOPLEVEL-INIT)
                (EXECUTABLE NIL) (SAVE-RUNTIME-OPTIONS NIL) (PURIFY T)
                (ROOT-STRUCTURES NIL) (ENVIRONMENT-NAME auxiliary)
                (COMPRESSION NIL))
  Derived type: (FUNCTION
                 (T &KEY (:TOPLEVEL T) (:EXECUTABLE T)
                  (:SAVE-RUNTIME-OPTIONS T) (:PURIFY T)
                  (:ROOT-STRUCTURES T) (:ENVIRONMENT-NAME T)
                  (:COMPRESSION T))
                 NIL)
  Documentation:
    Save a "core image", i.e. enough information to restart a Lisp
    process later in the same state, in the file of the specified name.
    Only global state is preserved: the stack is unwound in the process.
    
    The following &KEY arguments are defined:
    
      :TOPLEVEL
         The function to run when the created core file is resumed. The
         default function handles command line toplevel option processing
         and runs the top level read-eval-print loop. This function returning
         is equivalent to (SB-EXT:QUIT :UNIX-STATUS 0) being called.
    
      :EXECUTABLE
         If true, arrange to combine the SBCL runtime and the core image
         to create a standalone executable.  If false (the default), the
         core image will not be executable on its own. Executable images
         always behave as if they were passed the --noinform runtime option.
                :
  Source file: SYS:SRC;CODE;SAVE.LISP
; No value

これ、なかなか面白い機能を内蔵してるなあ。ついでにソースも見とくか。

(defun save-lisp-and-die (core-file-name &key
                                         (toplevel #'toplevel-init)
                                         (executable nil)
                                         (save-runtime-options nil)
                                         (purify t)
                                         (root-structures ())
                                         (environment-name "auxiliary")
                                         (compression nil))
  #!+sb-doc
  "Save a \"core image\", i.e. enough information to restart a Lisp
process later in the same state, in the file of the specified name.
Only global state is preserved: the stack is unwound in the process.
  :

どうやら、この関数の中で、save-core ってのが本体っぽいな。 runtimeの下には、saveってのがあって(C言語で書かれた)これが最終的に呼び出さ れると思うんだけど、まだ確証は無い。切りが無いので、また次回にでも。

段々とmaximaから遠ざかって行くなあ。それでいいんか? >俺

大丈夫! maximaの事が一行でも書かれていれば、『maximaとか』のタイトルで 無問題。

おまけで、Osaka fonts

CQ誌の付録(一歩先のハムログ活用 -- Turbo HAMLOG)を見てたら、大阪フォントを使おうですって。 理由は、0とOが紛らわしいから。本当に紛らわしいわ。1とlとかも。念力で判断してください、 コンテキストで判断して下さいってか。

判断力が衰えた&&眼がしょぼくなった、老人向け雑誌? ならではの企画だなあ。おいらも その企画に乗ってみるよ。資格は十分だから! (そんな事、自慢してどうする)

WindowsでOsakaフォントを使おう!から 頂いてくれば良い。懐かしいねぇ。MACをやってた頃を思い出すよ。丸漢フォントって呼んでたなあ。 当時は日本語を出せるの、これぐらいしかなかったもの。

それにしても、MACのフォントは、モナコとかカイロとかニューヨークとか地名シリーズが幅を 利かせていた。プログラムをやるんで、モナコを使ってたんだっけかか? それともクーリエ だったか、今となっては忘却の彼方。大阪にはちゃんと等幅フォントが入っているんで、AAも 無問題。使ってみよー。後で、アップルから請求が来るなんて事無いだろうな。