"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は上に書いたような特徴からまず教育用の言語として普及 しましたが、それに止まるものではありません。このページもShiro Kawaiさん にならって、Schemeの実用面を充実させていくつもりです。
拙訳はわたし自身がScheme を使う必要に迫られたときに、Schemeに関す る日本語の文献を見つけることができないままに、もともとはわたし自身 のために訳出したものでした。書いたプログラムがわたしが理解したr5rs の通りに動作することから、拙訳に大きな誤りはなかろうと考えて公表し たものです。今読み返すと不備な点がたくさんありますが、1度公表して しまったので、翻訳をやり直す気になかなかなれません。便覧として使っ ていただければ幸いです。
その後r4rsとr5rsには他にも日本語訳があることがわかり、最近になって 村上雅章さんの 新しい翻訳も出ました。原典はわたしにはかなりわかりにくいものでした が、いろいろな翻訳を原典とつき合わせることで、r5rsの理解も進むと思 います。
わたしが使用しているOSは、これも使用頻度順に、FreeBSD 4.4-RELEASE、
Debian Linux Potato (kernel 2.2r1)、OS/2 Warp V4.0、Windows 2000、
Windows 98です。ユーザの数から見ると、これは丁度逆順になるようです。
UNIX/Linuxは融通性に富んでいて使いやすいものですが、設定が簡単でない
のであまり普及していません。
それぞれにどのようにインストールしたかを次の表にまとめてみました。
わたし がインストールできたScheme処理系 OS SCM Gauche STk guile mit-scheme FreeBSD 4.4 make configure && make configure && make configure && make binary Debian Linux 2.2 make / configure && make configure && make binary OS/2 Warp V4.0 make / * * binary Windows 2000 make / * * / Windows 98 make / * * /
* ...インストールできませんでした。
/ ...インストールしていません。- Windwos 2000とWindows 98にはcygwin環境を使用してイン ストールしました。
cygwin環境はhttp://sources.redhat.com/cygwin から入手できます。- OS/2では、emx環境でインストールしました。gccの他にgnu make とbashが必要です。
emx環境はhttp://hobbes.nmsu.eduから入 手できます。- Windows(MS-DOS)用のSCMについては、Jafferさんのサイト から、バイナリも入手できます。ただしバイナリを実行するためには、 次に述べるSLIBライブラリの他に、ソースコードとともに配布されてい る*.scmファイルが、(implementation-vicinity)になければなりません。- 浮動小数点数について、Linuxでは発生しませんが、FreeBSD上の SCMで後に述べるr4rstest.scmを通すためには、仮数部のデフォルト の精度を拡張精度にする必要があります(SCM on FreeBSD)。
浮動小数点数の処理については、入出力の精度に不満を残す 処理系が多いようです(例:(/ 1448997445238699 (expt 10 15) ≒ 1.448997445238699と(* 6525704354437806 (expt 2 - 52)))。 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にはこ のアルゴリズムが実装されているようです。
SCM
SCMはAubrey Jafferさんが主として作成したScheme処理系で、最新のバー ジョンは「5d4」です。http://swissnet.ai.mit.edu/~jaffer/SCM.html から入手できます。
SCMはr5rs に 準拠しており、わたしが使っているScheme処理系の中でもっとも 高速です。
インストールについて私が気がついた点を、SCMについて で報告します。
SCMを使うためには、SLIBをインストールす る必要があります。SLIBはr5rs Schemeで書かれたライブ ラリです。弱いといわれるSchemeの入出力をScheme自身で 拡張するパッケージからフル機能のリレーショナルデータベースまで、豊 富なパッケージが集められています。
SLIBのもう1つの目的は、Scheme処理系ごとの細部の仕様 の違いを吸収して、すべてのScheme処理系が同じように動作する 共通の環境を用意することです。そのためにSLIBには、処理系ご との初期化ファイルの雛型が用意されています。SCMの初期化ファ イルはScmInit.scmですが、SCMの場合はSLIBを使うための 特別な初期化は不要です。
Gauche
GaucheはShiro Kawaiさんが開発中のScheme処理系です。最 新バージョンはhttp://www.shiro.dreamhost.com/scheme/gauche/ からダウンロードできます。Kawaiさんが一応の完成形の目処としているリ リース1.0へ向けて、頻繁に更新されています。リリース0.6ではマルチスレッ ドが,0.7ではGTkインタフェースが実装される予定になっています。この原稿を書いている時点でのGaucheはリリース0.4.11で、 r5rs仕様のすべてと、Scheme Requests for Implementation (SRFI - サーフィー)のかなりの部分, POSIXとUNIXのシステムインタフェースが実装されており、Scheme処 理系としてGaucheは実用レベルに達していると思われます。プログ ラム作成の現場でSchemeを使う苦労を熟知し、プログラムを作る側 から最も使いやすいプログラミング言語を求めるKawaiさんの作品にふさわ しく随所に新しい工夫が盛り込まれ、Schemeと直交する形でオブジェ クトシステムが実装されています。
Scheme処理系としてのGaucheは次のような特徴を備えて います。
- 日本語を含めた多バイト文字を取り扱うことを前提として処理系が開 発されている。
guileにもこの試みがありましたが、guileでは放棄 されました。うろ覚えですが、guileではScheme以外の システムの文字列処理との整合性がとりにくかったようです。
- 起動が速い。
Schemeはスクリプト言語として使用することも多いと思いま す。わたしの場合に限りますが、起動に時間がかかる処理系はそれだけ で気が重くなってしまいます。
- 処理が速い。
Schemeインタープリタとしての処理速度です。コンパイラ言 語と同じスピードをインタープリタに求めるひとはいないでしょうが、 それでも処理は速いに越したことはありません。Gaucheでは、 Schemeコードは中間コードにコンパイルされた上で仮想 Schemeマシンで実行されます。デバッグやマルチスレッド化に もこのメリットが出てくるものと理解しています。
プログラミング言語にSchemeを選択することの意味はいまの ところ、20ミリ秒で実行されるプログラムを数日かけてコンパイラ言語 で開発するよりは、1時間でプログラムを書いて、結果が出るまで1秒待 つ方を好むということになると思います。インタープリタとしての Gaucheはこの期待をふくらませてくれます。
Gaucheについては別項目を立てて使い方などを追いかけたいと思っ ています。
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/から入手できます。
guileの最新のバージョンは「1.4」です。マニュアルよりもguile 本体(core)と周辺プログラムの開発が先行していて、使い方にはよくわか らない部分もありますが、Scheme処理系としてはほぼ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オブジェクトを利用することが容易になっています。
guileのベースになったのはAubrey Jafferさんの SCM(version 4e1)ですが、SCMとはだいぶ違ったものになっ ています。SCMの軽快さはguileでは当初から失われていました。
Schemeの拡張と見るか肥大化と見るかによって、guileの 評価は変わるでしょう。guile自体はいずれの評価とも関わりなく、 活動と拡大を活発に続けています。mit-scheme
mit-schemeは、別の処理系で書いたSchemeプログラムの動 作を確認するために使っています。mit-schemeの初期化ファイルは scheme.initです。
SCMを使うためには、Schemeで書かれたライブラリ SLIBをあらかじめインストールして、SCMから呼び出せるようにして おく必要があります。SLIB
SLIBはhttp://swissnet.ai.mit.edu/~jaffer/SLIB.html から入手できます。最新のバージョンは「2d2」です。Aubrey Jafferさんが保 守しています。slib2d2.zipを入手したら適当なディレクトリ、例えば'/usr/local/lib' に 展開します。
SLIBライブラリは、指定したディレクトリの下の、slibディレクト リに展開されます。このディレクトリを、セッションの環境設定ファイルで 環境変数'SCHEME_LIBRARY_PATH'に指定しておきます。あとでライブラリファ イル名を環境変数に連結する必要がありますので、最後にフォワードスラッ シュ(OS/2とWindowsでは円記号)が必要です。% unzip slib2d2 -d /usr/local/lib
- UNIX/Linux
- ログインシェルがcsh、tcshの場合、環境設定ファイルは.login か. cshrc、あるいは.tcshrcです。
setenv SCHEME_LIBRARY_PATH /usr/local/lib/slib/- ログインシェルがsh、bashの場合、環境設定ファイルは.profile か. bashrcです。xdmからログインする場合は、例えば.xsessionに書いて おきます。
SCHEME_LIRBRARY_PATH="/usr/local/lib/slib/" export SCEHEME_LIBRARY_PATH- OS/2では、環境設定はconfig.sysで行ないます。ドライブ名には、パ スが存在するドライブを指定して下さい。
set SCHEME_LIBRARY_PATH=e:/usr/local/lib/slib/- Windows98では、環境設定はautoexec.batで行ないます。ドライブ 名 には、パスが存在するドライブを指定して下さい。
set SCHEME_LIBRARY_PATH=e:/usr/local/lib/slib/SCMのインストール
- 入手したscm5d4.zipを適当なディレクトリ、例えば/homeに展開します。 SCMは、指定したディレクトリの下のscm ディレクトリに展開されます。
unzip scm5d4 -d /home- SCMのコンパイルにとりかかる前に、次の点に注意する必要があるかもし れません。
bignumデータ形式の使用
SCMのbignumデータ形式を有効に使うためには、scmfig.hで定義され ているNUMDIGS_MAXを20000桁程度にし ておいた方がいいと思います。
FreeBSDでコ ンパイルする場合の注意
FreeBSDではdouble(flonum)の仮数部のデフォルトの長さが53ビッ ト(IEEE 754)に設定されています。flonum を64ビットに設定 するためにはコンパイル単位に' floatingpoint.h'を#includeし、 main関数の開始時に引数FP_PEを渡して、fpsetprec()を呼び出す必要 があります(FreeBSD Q and A)。これにより、Intel CPUのレジスタが64ビット浮動小 数点演算用にリセットされます。ただし以後はdoubleの内部演算がす べて64ビットで行なわれるようになりますので、桁溢れ、あるいは拡 張精度をdoubleに丸めた結果の誤差が発生する可能性が高くなります。
ご自分の責任でscmmain.cへのパッチ を当てるか、scmmain.cを編集して下さい。わたしの環境ではこれま で特に重大な問題は発生していません。SCMの開発バージョン にはすでにパッチがあてられています。次のリリースからはパッチを あてる必要はなくなります。
FP_PEは'ieeefp.h'で宣言されており、floatingpoint.hをincludeす ると取り込まれます。... /* * FP precision modes */ typedef enum { FP_PS=0, /* 24 bit (single-precision) */ FP_PRS, /* reserved */ FP_PD, /* 53 bit (double-precision) */ FP_PE /* 64 bit (extended-precision) */ } fp_prec_t; ...- scmlitを作成します。
make scmlit- scmlitは、Schemeで書かれたスクリプトファイルbuildを実 行するために作成します。
scmlitはbuildスクリプトを実行するために必要な最小限のモジュー ルだけで構成されていますので、どのOSでもコンパイルできる可能性 が高くなっています。- OS/2-emxでコンパイルする場合、オリジナルのfindexec.cでは必要 なインクルードファイルが取り込まれませんので、パッチを当てるなり書き変えるなり して下さい。これはフル仕様のSCMをコンパイルする場合にも必要で す。- 引数を渡して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用)のいずれかです。
これによりbuildデータベースから、プラットフォーム固有のコンパイ ルオプションとリンクオプションが選択されます。
- -F 機能名 ...
-Fオプションの機能名には、次の表に示す機能名を空白で区切って 指定します。表中*(アスタリスク)で印をつけた機能は上記コンパ イル環境でわたしがコンパイルできなかったものです。機能名に対 応する機能の詳細についてはscm.infoとソースファイルを参照して 下さい。
コンパイル可能なSCMの機能(o = できた, * = できなかった, / = テストしていない) 機能名 機能の概要 FreeBSD Debian Linux OS/2- emx cygwin 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ライブラリの組み込み o o o o debug デバグ用エラーチェック / / / / dump 実行イメージダンプ * * * * dynamic-linking dldライブラリの使用 * * * * read-line ラインエディタ o o / / engineering-notation エンジニアリング表記の使用 o o o o generalized-c-arguments 可変引数C関数の使用 o o o o i/o-extensions ANSI CファイルI/O o o o * inexact 浮動小数点数の組み込み o o o o macro r5rsマクロのサポート o o o o posix posix関数(pipe,fork,uname etc.) o o * o unix posix以外のunix関数(symlink,nice,mknod etc.) o o * * record レコードデータ型 o o o o regex 正規表現 o o * * rev2-procedures r2rs手続き o o / / sicp (eq? () #f)==>#t, etc o o / / socket BSDソケット o o * / tick-interrupts ticks, ticks-interrupt, alarm etc. o o o o
この指定によりコンパイルとリンクが行なわれて、実行ファイルscmが作 成されるはずですが、組み込むモジュールによってはbuildデータベース が対応していないために、コンパイルかリンクで失敗する場合がありま す。buildの実行例1(FreeBSD) ./build -h system -p freebsd -F arrays array-for-each bignums \ cautious compiled-closure generalized-c-arguments i/o-extensions \ inexact macro record
その場合は直接コンパイルとリンクを行なわずに一旦実行スクリプトを 作成し、そのスクリプトファイルを編集して実行してみて下さい。次の ようにします。次のようなスクリプトファイルが作成されます。buildの実行例2(FreeBSD) ./build -p freebsd -F arrays array-for-each bignums \ cautious compiled-closure curses generalized-c-arguments \ i/o-extensions inexact macro posix unix record \ regex socket tick-interrupts > makescm chmod +x ./makescm./makescmを実行すると、ファイルscmflags.hにマクロ定義が書き込ま れ、実行ファイルscmが作成されます。今の段階では次のメッセージが 表示されます。#!/bin/sh # unix script created by SLIB/batch # ================ Write file with C defines rm -f scmflags.h echo '#define IMPLINIT "Init5d4.scm"'>>scmflags.h echo '#define INITS init_ramap();init_gsubr();init_ioext();init_posix();init_record();init_rgx();init_sc2();init_socket();init_unix();'>>scmflags.h echo '#define ARRAYS'>>scmflags.h echo '#define BIGNUMS'>>scmflags.h echo '#define CAUTIOUS'>>scmflags.h echo '#define FLOATS'>>scmflags.h echo '#define MACRO'>>scmflags.h echo '#define CCLO'>>scmflags.h echo '#define TICKS'>>scmflags.h # ================ Compile C source files cc -O -c rope.c unif.c subr.c sys.c eval.c scl.c repl.c time.c script.c findexec.c scmmain.c scm.c continue.c unix.c socket.c sc2.c rgx.c record.c posix.c ioext.c gsubr.c ramap.c # ================ Link C object files mv -f scm scm~ cc -o scm -lc -lgnuregex -lm ramap.o gsubr.o ioext.o posix.o record.o rgx.o sc2.o socket.o unix.o continue.o scm.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o unif.o rope.otmpnamに関するwarning以外は無視して構いません。tmpnamに関する warningは、このコンパイル方法ではtmpnam関数がリンクされていない ことを示しています。libcにはtmpnamが含まれているので理由がわか らないのですが、リンカに渡すオプション-lcを削除するとtmpnam が使 えるようになります。sys.c: In function `prinport': sys.c:311: warning: passing arg 1 of `lputs' makes pointer from integer without a cast posix.c: In function `l_ttyname': posix.c:322: warning: assignment makes pointer from integer without a cast sys.o: In function `ltmpnam': sys.o(.text+0x40c): warning: tmpnam() possibly used unsafely; consider using mkstemp() /usr/libexec/elf/ld: sys.o: warning: unresolvable relocation against symbol `tmpnam' from .text section
FreeBSDのCコンパイラはgcc(4.2-RELEASEでは2.95.2)ですが、FreeBSDの CライブラリはGNUのものとは別物とのことです。
FreeBSDではtmpfileとtmpnamについて、mkstemp()の使用を強く推奨し ていますので(tmpfile (3))、標準Cライブラリを指定したときにtmpnam をリンクしないようなメカニズムがどこかにあるのかもしれません。ご 存知の方がいたら、教えていただければありがたいです。ともかく上のスクリプトファイルを次のように編集して実行すれば、フ ル仕様のSCMが作成されます。例では最適化オプションを最大のO3にし て、SCMセッションに表示するプロンプトも指定しています。
次はDebian Linuxの場合です。#!/bin/sh # unix script created by SLIB/batch # ================ Write file with C defines rm -f scmflags.h echo '#define IMPLINIT "Init5d4.scm"'>>scmflags.h echo '#define INITS init_ramap();init_gsubr();init_ioext();init_posix();init_record();init_rgx();init_sc2();init_socket();init_unix();'>>scmflags.h echo '#define ARRAYS'>>scmflags.h echo '#define BIGNUMS'>>scmflags.h echo '#define CAUTIOUS'>>scmflags.h echo '#define FLOATS'>>scmflags.h echo '#define MACRO'>>scmflags.h echo '#define CCLO'>>scmflags.h echo '#define TICKS'>>scmflags.h echo '#define PROMPT "SCM> "'>>scmflags.h # ================ Compile C source files cc -O3 -c rope.c unif.c subr.c sys.c eval.c scl.c repl.c time.c script.c findexec.c scmmain.c scm.c continue.c unix.c socket.c sc2.c rgx.c record.c posix.c ioext.c gsubr.c ramap.c # ================ Link C object files mv -f scm scm~ cc -o scm -lgnuregex -lm ramap.o gsubr.o ioext.o posix.o record.o rgx.o sc2.o socket.o unix.o continue.o scm.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o unif.o rope.o次のようなスクリプトファイルが作成されます。buildの実行例3(linux) ./build -p linux -F arrays array-for-each bignums \ cautious compiled-closure curses generalized-c-arguments \ i/o-extensions inexact macro posix unix record \ regex socket tick-interrupts > makescmこのスクリプトに実行ビットを立てて実行すると、Debian Linuxには libregexが存在しないのでリンクに失敗します。Debian Linuxをインス トールするために消してしまったのですが、Laser5 Linux 6.0 (Japanese Redhat Linux 6.0) kernel 2.2.5をインストールしていたと きにもlibregexはありませんでした。Linuxでは正規表現ライブラリは 標準ライブラリになっているようです。リンクオプションから-lregex を削除すればリンクもエラーなしで終了し、rgx.cモジュールは正しく 動作します。#!/bin/sh # unix script created by SLIB/batch # ================ Write file with C defines rm -f scmflags.h echo '#define IMPLINIT "Init5d4.scm"'>>scmflags.h echo '#define INITS init_ramap();init_gsubr();init_ioext();init_posix();init_record();init_rgx();init_sc2();init_socket();init_unix();'>>scmflags.h echo '#define ARRAYS'>>scmflags.h echo '#define BIGNUMS'>>scmflags.h echo '#define CAUTIOUS'>>scmflags.h echo '#define FLOATS'>>scmflags.h echo '#define MACRO'>>scmflags.h echo '#define CCLO'>>scmflags.h echo '#define TICKS'>>scmflags.h # ================ Compile C source files gcc -O2 -c rope.c unif.c subr.c sys.c eval.c scl.c repl.c time.c script.c findexec.c scmmain.c scm.c continue.c unix.c socket.c sc2.c rgx.c record.c posix.c ioext.c gsubr.c ramap.c # ================ Link C object files gcc -rdynamic -o scm -lc -lregex -lm ramap.o gsubr.o ioext.o posix.o record.o rgx.o sc2.o socket.o unix.o continue.o scm.o scmmain.o findexec.o script.o time.o repl.o scl.o eval.o sys.o subr.o unif.o rope.o
os/2では、makefileを作成してコンパイル しました。buildの実行例4(cygwin) ./build -p unix -F arrays array-for-each bignums \ cautious compiled-closure curses generalized-c-arguments \ inexact macro posix unix record tick-interrupts > makescm chmod +x makescm ; ./makescm無論どのOSでも、Makefileを作成してコンパイルすることもできます。 わたし自身は、version 4e3以来のMakefileを次のように書き変えたも のを使うこともあります。
Makefileはscmとlibscm.aの作成に使用し、Makefileでコンパイルする ときは空のscmflags.hを作成しています(rm scmflags.h ; touch scmflags.h)。
- r4rstest.scmを 実行して、作成したSCMの動作を確認します。
./scm r4rstest SECTION(2 1) SECTION(3 4) #<;primitive-procedure boolean?>; ... Passed all tests To fully test continuations, Scheme 4, and DELAY/FORCE do: (test-cont) (test-sc4) (test-delay) SCM> (test-cont) (test-sc4) (test-delay) ... Passed all tests ... (exit)わたしの環境(Pentium Pro 200 MHz, 128 MB memory)のFreeBSD、Debian Linux、Windows98--cygwinではすべてのテストに合格しましたが、環境に よっては次のように表示される場合もあり得ます。... errors were: (SECTION (got expected (call))) ((6 5 6) (#f #t (mult-float-print-test #f))) ((6 5 6) (#f #t (mult-float-print-test #f))) ((6 5 6) (#f #t (mult-float-print-test #f))) ((6 5 6) (#f #t (mult-float-print-test #f))) ((6 5 6) (#f #t (mult-float-print-test #f))) ...最初の数字のリストはr4rsのセクション番号(上の例では§6.5.6 Numerical input and output--r5rsでは§6.2.6)で、組み込み手続き string->numberとnumber->stringの仕様に対応します。エラーは浮動小数 点数の入出力の精度によるもので、Schemeの本質的な動作には関係 しませんので、通常のプログラミングで問題になることはないと思います。