"Lisp as an Alternative to Java -- Erann Gatt, Jet Propulsion Laboratory, California Institute of Technology"という文献があります。 日付は1999年11月9日です。Lispプログラムの実行速度はCで注意深く書かれ た最高速のものには劣るけれどもC++と同等もしくはそれ以上、Javaスクリ プトよりも高速で、プログラムごとの性能の変動はC++よりも著しく少かっ たというデータが示されています。Lispプログラムのメモリ消費量はJavaと 同程度でしたが、実験結果がプログラマの熟練度に依存しておらず、プログ ラムの開発期間がC/C++やJava に比べて著しく短かったことも同時に報告さ れています。マシン語にコンパイルしたLispプログラムが使用されましたの で実行速度については割り引いて考えなければいけませんが、それ以外の特 徴はLispインタープリタにも当てはまると思われます。
Lispに愛着を持つ人々にとってこのような結果は当然で、Lispが優れたプロ グラミング言語であることは確信となっていますが、ならばLispがなぜ普及 しないのかが謎です。この謎を解き明かすのには時間がかかりそうですし、 あるい不可能かも知れません。Shiro Kawaiさんの Practical Schemeのように、実践して示すのが最善と思われます。
Schemeは、プログラミングに必要充分な機能を備えたLisp方言の中 でもっともコンパクトに設計された言語です。Schemeの仕様書は索 引を含めてa4版で50ページです。SchemeがLispであるためでもあり ますが、これほど小さな仕様で定義されたプログラミング言語は類を見ませ ん。Schemeに比べると他の言語は、円を手に入れようとして多角形 の辺の数を限りなく増やそうとしているように見えます。
Schemeの仕様が極めて明解ですので、Schemeプログラムはプ ログラミングを始めた初期の段階から、簡潔で正しく、美しいものになるこ とが保証されています。
Schemeは、「プログラミング言語は機能の上に機能を積み重ねるの ではなく、機能の追加を必要と思わせるような弱点と制限を取り除いて設計 すべきである」として、Lispの機構と構文を使用して作成されました。言語 仕様は、「実用的で効率のよいプログラミング言語を作成するためには、式 を組み立てる方法に制約がなければ極めて少数の式構成規則で足りる」と考 え抜いて設計されています(Revised5 Report on the Algorithmic Language Scheme--r5rs--Introduction)。
規則が正しければ、その規則にしたがうプログラムは正しいものになります。 必要充分な規則の数が少ければ、規則の適用範囲は広いものになります。プ ログラミング言語の規則はプログラムを表現する方法を規定するものですか ら、これはScheme の表現力が多様になることを意味します。しかも Schemeの規則に則る以上、Schemeにしたがって表現された多 様なプログラム1つ1つは、正しい明瞭なものにしかなり得ないことになりま す。
Schemeがはじめて文献に現れたのは、1975年に遡ります。Guy Lewis Steele Jr. と Gerald Jay Sussmanによって発明されました。Guy Lewis Steele Jr. は、「Common Lisp Reference Manual(First edition-1984, Second edition-1989)--Digital Press」の著者でもあり、Common Lispはあ る程度Schemeの影響も受けているとその序文の中で書いています。
Schemeの仕様は、Common Lispの研究成果を取り入れるなどの数度の 改訂を経て、「Revised4 Report on the Algorithmic Language Scheme--r4rs-1991」でほぼ固まりました。現在のScheme処理系のほ とんどは、すくなくともr4rsに準拠しています。
Schemeの最新の仕様は、「 Revised5 Report on the Algorithmic Language Scheme--r5rs-1998」で定められています。r5rsはr4rsの上位セットで す。
r5rsの拙訳を プ ログラミング言語Schemeに置いていただいています。Schemeは上に書いたような特徴からまず教育用の言語として普及 しましたが、それに止まるものではありません。このページでは、 Schemeの実用面をわたしの手が届く範囲で充実させていくつもり です。
拙訳はわたし自身がScheme を使う必要に迫られたときに、Schemeに関す る日本語の文献を見つけることができないままに、もともとはわたし自身 のために訳出したものでした。書いたプログラムがわたしが理解したr5rs の通りに動作することから、拙訳に大きな誤りはなかろうと考えて公表し たものです。今読み返すと不備な点がたくさんありますが、1度公表して しまったので、翻訳をやり直す気になかなかなれません。便覧として使っ ていただければ幸いです。
その後r4rsとr5rsには他にも多くの日本語訳があることがわかりました。原 典はわたしにはかなりわかりにくいものでしたが、いろいろな翻訳を原典 とつき合わせることで、r5rsの理解も進むと思います。
わたしが使用しているOSは、これも使用頻度順に、FreeBSD 7.0-CURRENT、 FreeBSD 6.2-STABLE、Debian Linux sarge (kernel 2.6.10)、Windows 2000(Cygwin、 MinGW)です。ユーザの数から見ると、 これは逆順になるようです。
それぞれにどのようにインストールしたかを次の表にまとめてみました。
わたしがインストールできたScheme処理系
OS SCM Gauche stklos STk guile FreeBSD* 7.0-CURRENT**/6.1-STABLE*** rpmまたはgmake && ./build ./configure && make ./configure && gmake ./configure && make ports collection Debian Linux Unstable****/Sarge***** rpmまたはmake ./configure && make ./configure && make ./configure && make apt-get install Windows 2000****** make ./configure && make or binary / / /
x ...インストールできませんでした。
/ ...インストールしていません。* FreeBSDでコンパイルする場合の注意 これまでのシステムCコンパイラーには過渡的な問題がありました。 portsのように"eval.c"を書き換えて変数にvolatile修飾子をつけてコンパイルするか(volatile struct {SCM arg_1;} t;)、buildスクリプトに引数を渡してコン パイルして、動作するSCMを作成していました。
7.0-CURRENTのシステムコンパイラがversion 4.2.1になってからは上記の書き換えは不要になったようです。
** 7.0-CURRENT% uname -a
FreeBSD hiro 7.0-CURRENT FreeBSD 7.0-CURRENT #0: Sat Aug 18 15:40:31 JST 2007 daip@hiro:/usr/obj/usr/src/sys/DAIKERNEL i386
% cc -v
Using built-in specs.
Target: i386-undermydesk-freebsd
Thread model: posix
gcc version 4.2.1 20070719 [FreeBSD]
*** 6.2-STABLE% uname -a
FreeBSD hiro 6.2-STABLE FreeBSD 6.2-STABLE #0: Sat Aug 11 03:03:31 JST 2007 daip@hiro:/usr/obj/usr/src/sys/DAIKERNEL amd64
% cc -v
Using built-in specs.
Configured with: FreeBSD/amd64 system compiler
Thread model: posix
gcc version 3.4.6 [FreeBSD] 20060305
**** Debian Linux Sarge% uname -a
Linux colinux 2.6.10-co-0.6.2 #5 Sat Feb 5 10:19:16 IST 2005 i686 GNU/Linux
% gcc -v
Reading specs from /usr/lib/gcc/i486-linux/3.4.4/specs Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --disable-werror i486-linux
Thread model: posix
gcc version 3.4.4 20050314 (prerelease) (Debian 3.4.3-13)
***** Windwos 2000にはcygwin環境もしくはMinGW環境を使用してイン ストールできます。
cygwin環境はhttp://sources.redhat.com/cygwin から入手できます。
MinGW環境はhttp://www.mingw.org/ から入手できます。
- 浮動小数点数の精度について。x86系cpuとgccを組み合わせたとき のgccのあやしい振舞いについて、 川合さんが詳しく考察しています。
浮動小数点数の処理については、入出力の精度に不満を残す 処理系が多いようです。例:
Shiro Kawaiさんから、"Printing Floating-Point Numbers Quickly and Accurately", Robert G. Burger and R. Kent Dybvig, Proceedings of the SIGPLAN '96 Conference on Programming Language Design and Implementation. という論文の存在を教えてい ただきました。この論文では、浮動小数点数の高速で正確な出力を 実装するアルゴリズムが述べられており、Chez Schemeを使用してア ルゴリズムの正当性が確認されています。R. Kent Dybvig氏がChez Schemeの開発に主として携わっていることから、Chez Schemeにはこ のアルゴリズムが実装されているようです。(/ 1448997445238699 (expt 10 15)) ≒ 1.448997445238699と(* 6525704354437806 (expt 2 -52))。
ただしここに紹介する処理系はformatのような拡張出力モジュールを 備えているか、あるいはSLIBのprintfが使えますので、出力精度を気 にする必要はないと思います。
SCM
SCMはAubrey Jafferさんが主として保守しているScheme処理系で、r5rsに 忠実に準拠しています。現在のバージョンは「5e3(2006-10-22)」です。 http://swissnet.ai.mit.edu/~jaffer/SCM.html からソースとrpmパッケージを入手できます。
インストールについてわたしが気がついた点を、SCMにつ いてで報告します。
SCMは、Scheme以外のライブラリにまったく依存しない、 自己完結性の高いScheme処理系です。SCMが依存する唯一 の外部ライブラリはSLIBで、これはSchemeで書かれていま すから、SCMが動作しさえすれば利用できます。
したがってSCMを使うためには、SLIBをイン ストールする必要があります。SLIBはr5rs Schemeで書か れたライブラリです。弱いといわれるSchemeの入出力を Scheme自身で拡張するパッケージからフル機能のリレーショナル データベースまで、豊富なパッケージが集められています。Scheme Requests for Implementation (SRFI - サーフィー)のサポートも始まっています。 Xlibの利用も実用レベルに達したようで、一端をhttp://swissnet.ai.mit.edu/~jaffer/Solid/#Example に見ることができます。
SLIBのもう1つの目的は、Scheme処理系ごとの細部の仕様 の違いを吸収して、すべてのScheme処理系が同じように動作する 共通の環境を用意することです。そのためにSLIBには、処理系ご との初期化ファイルの雛型が用意されています。SCMの初期化ファ イルはScmInit.scmですが、SCMの場合はSLIBを使うための 特別な初期化は不要です。
Gauche
GaucheはShiro Kawaiさんが開発中のScheme処理系で、 SLIBもサポートされています。最新バージョンはhttp://www.shiro.dreamhost.com/scheme/gauche/ からダウンロードできます。shiroさんが一応の完成形の目処としている リリース1.0へ向けて、頻繁に更新されています。この原稿を書いている時点でのGaucheはリリース0.8.11です。 r5rs仕様のすべてと、Scheme Requests for Implementation (SRFI - サーフィー)のかなりの部分, POSIXとUNIX のシステムインタフェース、rfc仕様が実装されており、cgi の作成にも便利です。プログラム作成の現場でSchemeを使う苦労 を熟知し、プログラムを作る側から最も使いやすいプログラミング言語を 求めるshiroさんの作品にふさわしく随所に新しい工夫が盛り込まれ、 Scheme と直交する形でオブジェクトシステムが実装されています。
Scheme処理系としてのGaucheは次のような特徴を備えて います。
- 日本語を含めた多バイト文字を取り扱うことを前提として処理系が開 発されている。
- 起動が速い。
Schemeはスクリプト言語として使用することも多いと思いま す。わたしの場合に限りますが、起動に時間がかかる処理系はそれだけ で気が重くなってしまいます。
- 処理が速い。
Schemeインタープリタとしての処理速度で、以前の Scheme処理系の弱点を踏まえた上で、速度を高めるための工 夫がGaucheには随所に盛り込まれています。わたしが使って いるScheme処理系の中でもGaucheはすでに最高速の部 類に属しており、プログラムのデバッグと最適化がこれからも進むこ とを考えると、さらに快適な使い勝手が期待されます。 Gaucheでは、Schemeコードは中間コードにコンパイル された上で仮想Schemeマシンで実行されます。
処理系の速度にはいろいろな要素が絡んできますので一概にはいえないのですが、例えばSCMに付属のpi.scmという、πの値を求めるプログラムがあります。これは pi = 2 + 1/3 * (2 + 2/5 * (2 + 3/7 * (2 + ... (2 + k/(2k+1) * (2 + ... ))...))) というspigotアルゴリズムを利用してπを求める方法で、最後の項は (2 + k/(2k+1) * (4)) で近似できます(ただし求める精度をnとしてk = n * log2(10))。したがって(pi n d)の実行時間はn/dの自乗に比例し、処理系のアルゴリズムの性能比較に利用できるというプログラムです。これを実行すると、最近のGaucheはSCMやstklosに比べても高速で、わたしが使っている処理系の中では最高速です。例えばSCMの場合、メモリ内に大量のモジュールを読み込んだときには動作速度が低下してきます。これはSCMのgarbage collection (gc)が走査する空間が大きくなっていくためと考えられます。Gaucheが採用したBoehm GCにはこの傾向はなく、大規模プログラムの場合にもGaucheは高速性を維持しているといえると思います。
- 静的スコープを持ったモジュールシステムが採用されている。
標準のSchemeでも変数の数が不足することはまず考えられ ませんが、Gaucheではさらに、静的スコープを持つモジュー ルを使ったプログラム開発が可能になっています。モジュール内部で 使用される名前のスコープがモジュールに静的ですので、ライブラリ の数が増えても名前の衝突によるシャドウイングを心配せずに済みま す。SLIB(特にリレーショナルデータベースパッケージ)の中で、名前 をパッケージの中に閉じ込めておくために払われた細心の工夫を思う と、ずいぶんと負担が軽くなります。
プログラミング言語にSchemeを選択することの意味はいま のところ、20ミリ秒で実行されるプログラムを数日かけてコンパイラ 言語で開発するよりは、1時間でプログラムを書いて、結果が出るま で1秒待つ方を好むということになると思います。Gaucheは加 えて高速でもあり、快適な開発環境が得られます。快適さはプログラ ミングを楽しくします。
shiroさんが主宰する Gaucheメーリングリスト@SourceForgeでは、いろいろな国の ユーザが集まってGauche拡張パッケージやバグ修正など、活発な 議論が行なわれており、その成果がWiLiKi で公開されています。Gaucheが各国でユーザを獲得し、主宰者ば かりでなくユーザもバグフィックスに参加し、Gaucheを拡張し、 それによってGaucheがさらに洗練されてまたユーザを獲得すると いう好循環が始まっているようです。
STklos
STklosはErick GallesioさんがSTkの後継として開発中 のScheme処理系で、この原稿を書いている時点でのバージョンは 「0.70」です。最新のバージョンはSTklos Home Pageからダウ ンロードできます。
STkではおまけのように扱われていたオブジェクト志向レイヤ をシステムの中核に据えたということで、この名前が付けられたようです。libgmpを使うと数値計算がかなり速くなります。SLIBもサポー トされていますが、scmのInit$(VERSION).scmに合わせてSTklos.initを書 き換える必要があります。
STk
STkはErick GallesioさんによるScheme処理系で、http://kaolin.unice.fr/STk から入手できます。最後のバージョンは「4.0.1」です。
STk はr4rsに準拠しながら、Schemeに独自の拡張を行なっ ています。
STklosはSTkのオブジェクト志向レイヤで、CLOS(Common Lisp Object System)に似たメタクラス、多重継承、ジェネリック関数、マルチメソッ ドが実装されています。
STk 4.0.1ではSTklosのクラス階層の1つとしてTkウィジェットが実装され ており、Schemeを使用してTkツールキット8.0.3を操作することが できます。
STkの初期化ファイルは.stkrcです。slibディレクトリに入っている STk.initをこの名前でホームディレクトリにコピーすれば、(require 'packagname)でSTkからSLIBライブラリを使 えるようになります。
- Shiro Kawai さんのPractical Schemeでは、日常的に役にたつさまざまな Schemeライブラリと、Schemeのみならずプログラミング 一般の理解を深めるドキュメントが公開されています。Scheme をメジャーに押し上げる強力なサイトになることを願っています。
- 新山さんが、STkのTk部分を日本語化するパッチを公開して いらっしゃいます。わたしもパッチをあてて、.stkrcを次のようにして、 使わせていただいています。
;;; (implementation-vicinity) should be defined to be the pathname of ;;; the directory where any auxillary files to your Scheme ;;; implementation reside. (define (implementation-vicinity) (if (equal? (scheme-implementation-version) "4.0.1jp") "/usr/local/lib/stk/4.0.1jp/" "/usr/local/lib/stk/4.0.1/"))
guile
guileは、Tcl/Tkのデファクトスタンダード化を嫌ったFSF(Free Software Foundation)が、GNUプロジェクトの標準スクリプト言語として 開発した処理系です。GNOMEがインストールされている環境であれば、 guileもインストールされているはずです。guileは ftp://ftp.gnu.org/pub/gnu/guile/から入手できます。
Scheme処理系としてのGuileはほぼr4rs準拠です。環境変 数GUILE_LOAD_PATHにslibディレクトリが存在するパス(/usr/local/lib) を指定するか、guile変数%load-pathにこのパスを追加して(set! %load-path (append (list "/usr/local/lib") %load-path)))、とすれば、requireでSLIBパッケージを利用できるようになります。(use-modules (ice-9 slib))guileとSchemeとのもっとも大きな違いは、guile では識別子とシンボルで大文字と小文字が区別される点です。これは大文 字と小文字を区別する他の言語とのインタフェースをとりやすくするため と考えられます。変数や定数に一貫した名前を使っていれば、 Schemeプログラムはguileでも動作します。
guileではTk、gimp、gtkなどのGUIをモジュール として取り込んで利用したり、逆に異なるアプリケーションから guileオブジェクトを利用することが容易になっています。
ただし以上はGaucheでも採用され ました。同じことをしたときのGaucheの快適さと比較した結果、 わたし自身がguileを使う機会は減ってきています。
guileのベースになったのはAubrey Jafferさんの SCM(version 4e1)ですが、SCMとはだいぶ違ったものになっ ています。
Schemeの拡張と見るか肥大化と見るかによって、guileの 評価は変わるでしょう。guile自体はいずれの評価とも関わりなく、 活動と拡大を活発に続けています。
SCMを使うためには、Schemeで書かれたライブラリ SLIBをあらかじめインストールして、SCMから呼び出せるようにして おく必要があります。SLIB
SLIBはhttp://swissnet.ai.mit.edu/~jaffer/SLIB.html から入手できます。現在のバージョンは「3a4(2006-10-12)」です。Aubrey Jafferさんが保 守しています。SCMとSLIBは密接に結び付いていますので、 奇妙な動作を避けるためにも、両方を同時に更新しておいた方がいいと思い ます。slib3a4.zipを入手したら、コンパイルするscmのソースを置くディレクトリ と同じディレクトリ、例えばscmを$HOME/scmに展開するとすれば、$HOMEに 展開します。
SLIBライブラリは、指定したディレクトリの下の、slibディレクト リに展開されます。scmは実行ファイルが配置されたディレクトリを基準に してslibディレクトリを検索しますから、環境変数'SCHEME_LIBRARY_PATH' を指定する必要は現在では特にないようです。ただしSCHEME_LIBRARY_PATH が設定されていれば、そのディレクトリからライブラリが検索されます。% unzip slib3a4 -d $HOMESCMのインストール
- 入手したscm5e3.zipを適当なディレクトリ、例えば$HOMEに展開します。 SCMは、指定したディレクトリの下のscm ディレクトリに展開されます。
unzip scm5e3 -d $HOME- SCMのコンパイルにとりかかる前に、次を修正しておいた方がいいかもし れません。
bignumデータ形式の使用
SCMのbignumデータ形式を有効に使うためには、scmfig.hで定義され ているNUMDIGS_MAXを20000桁程度にし ておいた方がいいと思います。自前のMakefileでコンパイルする場合 は、コンパイラに-DNUMDIGS_MUX=20000を渡してもいいです。
- SCMセッションのプロンプトに表示する文字列もこのファイルで変更 できます。
% diff -C3 scmfig.h.orig scmfig.h *** scmfig.h.orig Tue Jun 28 07:43:45 2005 --- scmfig.h Tue Jun 28 07:43:55 2005 *************** *** 392,398 **** # ifdef SICP # define PROMPT "==> " # else ! # define PROMPT "> " # endif #endif --- 392,398 ---- # ifdef SICP # define PROMPT "==> " # else ! # define PROMPT "scm5e2> " # endif #endif *************** *** 437,443 **** # define BIGLO(x) ((x) & (BIGRAD-1)) /* NUMDIGS_MAX is the maximum number of digits for BIGNUMS */ # ifndef NUMDIGS_MAX ! # define NUMDIGS_MAX 1000 # endif #endif --- 437,443 ---- # define BIGLO(x) ((x) & (BIGRAD-1)) /* NUMDIGS_MAX is the maximum number of digits for BIGNUMS */ # ifndef NUMDIGS_MAX ! # define NUMDIGS_MAX 20000 # endif #endif
- scm5e2からBツリーの一種wb、ディスクベース連想配列を使用したデー タベースライブラリも標準的にコンパイルできるようになりましたので、 http://swissnet.ai.mit.edu/~jaffer/WB からそのソースコード(wb1c3.zip)も入手しておくと便利です。 入手したらそれも同じディレクトリに展開します。
unzip wb1c3 -d $HOME- scmlitを作成します。
make scmlit (FreeBSDではgmake scmlit -- GNU makeを使用)- scmlitは、Schemeで書かれたスクリプトファイルbuildを実 行するために作成します。
scmlitはbuildスクリプトを実行するために必要な最小限のモジュー ルだけで構成されていますので、どのOSでもコンパイルできる可能性 が高くなっています。scmlitが作成できれば、Linuxの場合はmake allでコンパイルできま す。ただしデフォルトでは、r5rsマクロを組み込んだ実行イメージを ダンプしたSCMが作成されます。Linuxでイメージダンプファイルを使 いたくない場合とFreeBSDでは、Makefileとbuildスクリプトを使って 実行ファイルを作成できます。
buildの引数には、-p freebsdのような短形式と、 --platform=freebsdのような長形式がありますが、ここでは短形式だ けを紹介します。詳しくはscmディレクトリに展開されるinfoファイ ルから、scm -- Installing SCM -- Building SCM -- Build Options を参照して下さい。
- -h バッチスクリプトの形式
バッチスクリプトの形式には、unix、dos、vms、amigados、system のいずれかを指定できます。
-h systemを指定すると、実際にコンパイルが行なわれます。それ 以外の指定では、それぞれのOSに応じたバッチスクリプトが、標準 出力に出力されます。SCMは実際にはbuildを実行する環境からバッ チスクリプトの形式を判断しますので、systemを指定するのでなけ れば-hオプションは不要です。
- -p プラットフォーム
プラットフォームには、buildデータベースが持っているプラット フォーム名を指定します。ここで使用するのは、freebsd、linux、 os/2-emx、unix(cygwin)、gnu-win32(MinGW)のいずれかです。
これによりbuildデータベースから、プラットフォーム固有のコンパイ ルオプションとリンクオプションが選択されます。
- -t 作成するオブジェクトの種類(type)。
デフォルトでは実行形式ファイルが作成されます。
- exe
実行形式プログラム。- lib
ライブラリモジュール。- dlls
すべてのダイナミックリンクリンクライブラリオブジェクトファイル。- dll
特定のダイナミックリンクライブラリオブジェクトファイル。- -F 機能名 ...
-Fオプションの機能名には、次の表に示す機能名を空白で区切って 指定します。表中*(アスタリスク)で印をつけた機能は上記コンパ イル環境でわたしがコンパイルできなかったものです。機能名に対 応する機能の詳細についてはscm.infoとソースファイルを参照して 下さい。
コンパイル可能なSCMの機能(d = ダイナミックリンクライブ ラリ、o = できた、 * = できなかった、 / = テストしていない) 機能名 機能の概要 動的ロード可 FreeBSD Debian Linux cygwin MinGW arrays 多次元配列 o o o o array-for-each arrayのマッピング o o o o bignums 多倍長整数 o o o o cautious 手続きに渡される引数のチェック o o o o compiled-closure C関数の組み込み o o o o curses cursesライブラリの組み込み d o o o / debug デバグ用エラーチェック o o o o dump 実行イメージダンプ * o * * dynamic-linking dlライブラリの使用 o o * * edit-line ラインエディタ d o o o / engineering-notation エンジニアリング表記の使用 o o o o generalized-c-arguments 可変引数C関数の使用 d o o o o i/o-extensions ANSI CファイルI/O d o o o o inexact 浮動小数点数の組み込み o o o o macro r5rsマクロのサポート o o o o posix posix関数(pipe,fork,uname etc.) d o o o / unix posix以外のunix関数(symlink,nice,mknod etc.) d o o * / record レコードデータ型 d o o o o regex 正規表現 d o o * / rev2-procedures r2rs手続き d o o / / sicp (eq? () #f)==>#t, etc / / / / socket BSDソケット d o o o * tick-interrupts ticks, ticks-interrupt, alarm etc. o o o o wb wb、ディスクベースBツリー連想配列プリミティブ d o o o o
- dynamic-linkingはlibdlを使用します。libdlは、Linuxでは 独立したライブラリファイルですが、FreeBSDではlibcに入って います。- i/o-extensionsはスタティックに組み込むことも、dlとして ロードすることもできます。別のライブラリがこれの使用を前提 にしている場合があるので、読み込まれていないと(load "ライ ブラリ")が失敗することがあります。(require '機能)を使用すれ ば、必要に応じてioext.soが先にダイナミックロードされます。- edit-lineは、外部ライブラリlibreadlineを使用します。ター ミナルモードでインタラクティブにSCMを使いたいとき に便利です。libreadlineの日本語対応が不適切だったりして ラインエディタを使いたくない場合は、edit-lineを使わなけ ればいいです。emacsやxemacsのサブプロセスとして SCMを呼び出したときはedit-lineは使用されず、emacs の編集機能でインタラクティブに操作することができます。スクリプトとして使用するときは実行ファイルは小さいほど読み込みが 速く行なわれるので、ダイナミックリンクライブラリの受け口を取り付 けた最小のscmを作っておいて、必要に応じてライブラリを動的にロー ドする方が小回りが効いて便利です。
buildを-Fなしで実行した場合は、デフォルトでarrays、bignums、inexactだけを指定したscmが作成されます。この指定によって汎用的で最小のScheme処理系が作成されます が、拡張機能を動的にロードできないので不便を感ずることがあります。buildの実行例1 ./build -h system -p freebsd
次は1にダイナミックリンクライブラリの受け口を取り付けたscmを 作成する場合です。-Fを指定したときには指定した機能だけが組み込まれ るようになるので、必要な機能をすべて明示的に指定する必要がありま す。
scm5e1以来Makefileを使ったスクリプトbuildへの引数の受渡しが少 し細かくなって、コンパイルが楽になっています。buildの実行例2 ./build -h system -p freebsd -F arrays bignums inexact dynamic-linking
Makefile経由でのbuildへの引数の渡し方。
Makefileの中では変数、SCMLIT(実行ファイルscmlitの呼び出し)、 SCMEXE(実行ファイルscmの呼び出し)、BUILD(スクリプトbuildの呼び 出し)が定義されています。それぞれ新しい定義をMakefileに渡して コンパイラ、リンカを呼び出せば、より細かい制御ができます。
Linux固有のコンパイラオプションを使用してコンパイル をより細かく制御して実行イメージをダンプした実行ファイルを作 成する場合(FreeBSDでの実行イメージダンプをわたしははまだでき ていません)。
r5rsマクロ展開の実行イメージまでを含んだ実行ファイルscmが出 力されます。この実行ファイルはダンプ時に展開されていたscmセッ ションのイメージですので、イメージに含まれるライブラリを新た に読み込む必要はありませんが、ディスク上のファイルは1M近い巨 大なものになります。make dscm5 BUILD="./build -h system -p linux"dynamic-wind、values、syntax-rulesに必要な変数とコー ドはコンパイルするけれども、実行イメージダンプを行なわない場 合。
make scm5 BUILD="./build -h system -p linux"同じ実行ファイルをFreeBSDで生成する場合。
6.2-STABLEの標準のCコンパイラには最適化の 程度を上げるとある種の変数が消失して、存在しない変数を参照す るエラーがまだ発生します。変数にvolatile修飾子を指定して最適 化プロセスから除外するか、変数の型を変更することで回避できま す。gcc 4.2.1では解消されていますが、次のようにすればこのバグを回避できます。以前からscmを使っていてその環境設定ファイルScmInit.scmがホー ムディレクトリに存在すると、まだ実行環境が確定していないscm を実行したときにエラーが発生する場合がありますので、scmlitに もscmにもScmInit.scmを読み込ませないようにしています。gmake scm5 BUILD="./build -DGCC_SPARC_BUG --linker-options=-DGCC_SPARC_BUG -hsystem -pfreebsd" SCMLIT="./scmlit -no-init-file" SCMEXE="./scm -no-init-file"Windows 2000
Cygwin環境とMinGW環境ではダイナミックロードの仕組みがわかりませんので、Makefileのscm5.opt:以降にコンパイル可能モジュール名を追加して、モジュールをスタティックリンクして使用しています。make scm5 BUILD="./build -hsystem -punix"(cygwin) make scm5 BUILD="./build -hsystem -pgnu-win32"(MinGW)いずれの場合にもMakefileによってr4rstest.scm、syntest1.scm(r5rsマ クロの動作の確認)、syntest2.scm(キーワードの再定義の確認)がロード され、実行されます。Linuxでは浮動小数点数の丸め誤差によるエラーが 表示されますが、コンパイルが正常に終了してプログラムコードが正しく 実行されていることがわかります。
- ダイナミックリンクライブラリを作成します。
% make mydlls BUILD="./build -h system -p linux" (Debian Linux) % gmake mydlls BUILD="./build -h system -p freebsd" (FreeBSD)- wbライブラリを作成します。
% cd $HOME/scm % ln -s $HOME/scm/scm.h $HOME/scm/scmfig.h $HOME/scm/scmflags.h ../wb % make db.so BUILD="./build -h system -p linux" (Debian Linux) % gmake db.so BUILD="./build -h system -p freebsd" (FreeBSD)- インストール
インストールはMakefileの中で指定されているprefixディレクトリに行な われ、SCMが使用するライブラリのカタログファイル(implcatと slibcat)もそこに書き込まれますので、ディレクトリに対する書き込み権 限が必要です。スーパーユーザでインストールを実行するか、でなけれ ばご自分が権限を持つディレクトリをprefixに指定しておきます。
% cd $HOME/scm % make install prefix=$HOME/ (最後にフォワードスラッシュが必要です) % cd ../slib % make install prefix=$HOME/ (slibライブラリパッケージをインストールします)実行ファイルが、Makefileの中で指定されているprefixディレクトリの下 のbinディレクトリに、Init$(VERSION).scmその他の初期化ファイルが $(prefix)/lib/scmディレクトリに、slibライブラリパッケージが $(prefix)/lib/slibにインストールされます。ダイナミックロードライブ ラリ(*.so)を作成していれば、それもlib/scmディレクトリにインストー ルされます。
カタログファイルを更新するために(require 'new-catalog)を発行します。
Schemeの世界を楽しんで下さい。scm -no-init-file -e'(require (quote new-catalog))'