Gauche リファレンスマニュアル

version 0.6.5

Shiro Kawai (shiro@acm.org)


1. はじめに

本書はGauche Scheme systemに関する、プログラマーのためのガイドと リファレンスです。なるべくGaucheの実装を正確に記述することを 目的として、時には背景となる設計上の選択も含めて説明しています。

したがって、既にSchemeを知っていてGaucheの全機能を活用して プログラムを書きたいという読者を対象にしています。 Schemeに触れるのが初めての読者は、何らかのチュートリアルを併用すると 良いでしょう。私もいずれチュートリアルめいたものを書くつもりです。

このマニュアルでは、GaucheのScheme言語としての面のみを扱います。 GaucheはC言語から呼べる汎用リスト処理ライブラリとしての側面も持っていますが、 それは別ドキュメントで解説する予定です。Gaucheを組み込み言語として使いたい、 もしくはGaucheをC言語で拡張したいという読者はそのドキュメントが必要となります。

Scheme言語としての側面に関しては、なるべくこのマニュアル一冊でリファレンスとしての 用が足りるように記述しました。標準に定められている関数でも、こちらのマニュアルだけで 使うのに必要な事項を知ることができます。但し、このマニュアルは標準文書の替わりには なりません。記述を短くするために理論的な背景などは省略してあります。 オリジナルのドキュメントへのポインタを参考文献の項に上げておきましたので、 必要に応じて参照して下さい。

もしあなたがこのマニュアルをオフラインで読んでいるなら、 時々下記のURLをチェックしてみて下さい。更新があるかもしれません。

http://www.shiro.dreamhost.com/scheme/gauche/.

1.1 Gaucheの概要

GaucheはScheme言語に基づくスクリプトインタプリタです。 Scheme言語の標準である、"Revised^5 Report on the Algorithmic Language Scheme" (@xref{r5rs,[R5RS],R5RS})に準拠しています。また、SRFI (http://srfi.schemers.org) に規定されている数多くのライブラリを サポートしています。

Gaucheは、プログラマやシステム管理者がこなす日常の雑事を 効率よくSchemeで書けるようにすることを目的として設計されています。

世の中には多くのSchemeの実装がありますが、 それぞれの実装には長所と短所があります。 Gaucheが長所とするべく重点を置いているのは次のようなポイントです。

立ち上りが速いこと
Gaucheが想定している用途のひとつは、プロダクション環境でちょろっと 10行スクリプトをでっちあげて、それが非常に頻繁に呼ばれるようなケースです。 CGIスクリプトなどもそうです。 Gaucheでは、言語のコアとスクリプトとして良く使いそうな機能に絞って 実行ファイルにコンパイルインし、使う分野が特定される機能は必要に応じて 読み込むようにしています。
マルチバイト文字列
文字列が1バイトキャラクタのみを扱っていれば良かった時代は過ぎ去りました。 現代のプログラミングシステムは、様々なエンコーディングによるマルチバイト文字/文字列を 自然に扱える必要があります。 Gaucheは内部的に文字列を全て、コンパイル時に選択したエンコーディングの マルチバイト文字列として扱います。後から付け足したライブラリレベルでの マルチバイト文字列のサポートよりも、一貫性がありロバストな文字列操作が可能になっています。 詳しくはsection 2.2 マルチバイト文字列を参照してください。
モジュラー開発
Gaucheは名前空間を分離する単純なモジュールシステムを備えており、 名前の衝突を心配せずに複数の開発者が並行して作業をすることができます。
統合されたオブジェクトシステム
CLOSライクなメタオブジェクトプロトコルを備えた強力なオブジェクトシステム が組み込んであります。STklosやGuileのオブジェクトシステムとかなり互換性があります。
システムインタフェース
Schemeは計算機の詳細の多くを抽象化しますが、プログラムを書いていると、 それらの高レベル層をバイパスして地下室に降りて作業しなければならないような時が あります。GaucheはPOSIX.1システムコールのほとんどを組み込みでサポートします。 また、ネットワーキングモジュールなど他のシステム関連モジュールは通常、 高レベルの抽象的なインタフェースと低レベルのシステムコールに近いインタフェースを 両方提供します。
強化された入出力
本物のアプリケーションはI/O無しでは成り立ちません。 SchemeはI/Oをポートとして簡潔に抽象化していますが、 標準のSchemeには最低限の操作しか定義されていません。 Gaucheはポートオブジェクトを入出力のための統合された抽象化オブジェクトと考え、 それを通して下位のI/Oシステム層にアクセスするユーティリティ関数を提供しています。 section 6.18 入出力を参照して下さい。

一方、Gaucheは所詮インタプリタですから、高速に大量の計算をこなしたり 巨大なデータセットを扱ったりするのは苦手です。

但し、そのような場合でも、Gaucheを各コンポーネントをつなぐ「糊」言語として 使うことは可能です。例えば性能の要求の厳しい部分はネイティブコードにコンパイルする言語で 書いておき、セットアップにGaucheを使うといった方法があります。

1.2 表記について

このマニュアルでは、各項目は次のようなフォーマットで表記されています。

カテゴリ: foo arg1 arg2
[spec] fooの説明

カテゴリ は項目fooの種別を示します。 次のようなカテゴリがあります。
Function Scheme手続き
Special Form 特殊形式 (R5RSでは「構文」)
Macro マクロ
Module モジュール
Class クラス
Generic Function ジェネリックファンクション
Method メソッド
Reader Syntax リーダによって解釈される構文要素

手続き、特殊形式、マクロに関しては、エントリの後に引数の仕様が示されます。 引数リストの中には次のような表記が現れることがあります。

arg ...
ゼロ個以上の可変個の引数。
&optional x y z
&optional (x x-default) (y y-default) z
省略可能な引数の表記。この例では3つまでの省略可能な引数が取られることを示します。 2番目の形式では省略された場合の既定値も示しています。 この表記はCommonLispのスタイルにならっていますが、Gauche自身がラムダリストに &optionalのような表記を受け付けるわけではないことに注意してください。 マニュアルの表記を簡潔にするためにこのような表現を用いているだけです。
&keyword x y z
&keyword (x x-default) (y y-default) z
キーワード引数の表記。この例ではxyzの3つのキーワード引数を 取ることが示されます。2番目の形式では省略された場合の既定値も示されます。 この表記はCommonLispのスタイルにならっていますが、Gauche自身がラムダリストに &optionalのような表記を受け付けるわけではないことに注意してください。 マニュアルの表記を簡潔にするためにこのような表現を用いているだけです。
&rest args
残りの引数全てがリストになってargsに束縛されることを示します。 この表記はCommonLispのスタイルにならっていますが、Gauche自身がラムダリストに &optionalのような表記を受け付けるわけではないことに注意してください。 マニュアルの表記を簡潔にするためにこのような表現を用いているだけです。

説明が項目の行に続きます。もし項目が特定の標準に準拠している場合は、 もととなった標準が次のような形式で示されます。

[R5RS]
[R5RS+]
この項目はR5RSに定義されるように動作します。"[R5RS+]"とマークされている場合は R5RSの仕様に上位互換な形で追加の機能が実装されていることを示します。
[SRFI-n]
[SRFI-n+]
この項目はSRFI-nに定義されるように動作します。"[SRFI-n+]"とマークされている場合は SRFI-nの仕様に上位互換な形で追加の機能が実装されていることを示します。
[POSIX]
この項目はPOSIXのAPIを反映していることを示します。

2. 主要な概念

本章では、Gauche動作の背景となるいくつかの概念を説明します。 Gaucheの動作を正確に理解する助けになると思います。

2.1 標準への準拠

Gaucheは、以下に挙げる点を除き、オプショナルな構文や手続きも含め "Revised^5 Report of Algorithmic Language Scheme" に準拠しています。

Gaucheはまた、以下のSRFIをサポートしています。

SRFI-0, Feature-based conditional expansion construct.
オートロードされるマクロとしてサポートされます。section 10.1 srfi-0 - Feature conditional参照。
SRFI-1, List library.
モジュールsrfi-1でサポートされます。section 10.2 srfi-1 - List library参照。 SRFI-1の手続きのうちいくつかは組み込みになっています。
SRFI-2, AND-LET*: an AND with local bindings, a guarded LET* special form.
モジュールsrfi-2でサポートされます。section 10.3 srfi-2 - And-let*参照。
SRFI-4, Homogeneous numeric vector datatypes.
モジュールgauche.uvectorが、 srfi-4の手続きのスーパーセットを提供します。 同モジュールにはSRFI-4の手続きに加え、 算術演算やジェネリックなインタフェースが定義されています。section 9.24 gauche.uvector - ユニフォームベクタ参照。
SRFI-6, Basic String Ports.
SRFI-6の手続きは組み込みになっています。section 6.18.4 文字列ポート参照。
SRFI-8, receive: Binding to multiple values.
構文receiveは組み込みになっています。section 4.6 変数束縛参照。
SRFI-9, Defining record types.
モジュールsrfi-9でサポートされます。section 10.5 srfi-9 - Record types参照。
SRFI-10, Sharp-comma external form.
組み込みです。section 6.18.6.2 読み込み時コンストラクタ参照。
SRFI-11, Syntax for receiving multiple values.
モジュールsrfi-11でサポートされます。section 10.6 srfi-11 - Let-values参照。
SRFI-13, String library
モジュールsrfi-13でサポートされます。section 10.7 srfi-13 - String library参照。 (SRFI-13の手続きのいくつかは組み込みになっています)。
SRFI-14, Character-set library
文字集合と基本的なSRFI-14手続きは組み込みになっています。 section 6.9 文字集合参照。SRFI-14の完全なサポートはモジュールsrfi-14 で提供されています。section 10.8 srfi-14 - Character-set library参照。
SRFI-17, Generalized set!
組み込みです。section 4.4 代入参照。
SRFI-18, Multithreading support
いくつかのSRFI-18の機能は組み込みであり、、残りのAPIは gauche.threadsモジュールで提供されます。section 9.22 gauche.threads - スレッド参照。
SRFI-19, Time Data Types and Procedures.
時間のデータ型はGauche組み込みです(section 6.21.8.2 SRFI time参照)。 SRFI-19の完全なサポートはモジュールsrfi-19で提供されています。 section 10.9 srfi-19 - 時間のデータ型と手続き参照。
SRFI-22, Running Scheme scripts on Unix
サポートされています。section 3.4 Schemeスクリプトを書く参照。
SRFI-23, Error reporting mechanism.
組み込みです。section 6.16.1 エラーの通知参照。
SRFI-25, Multi-dimensional array primitives.
モジュールgauche.arrayが、SRFI-25のスーパーセットと なっています。section 9.1 gauche.array - 配列参照。
SRFI-26, Notation for specializing parameters without currying.
オートロードされるマクロとして定義されています。section 4.3 手続きを作る参照。
SRFI-27, Sources of Random Bits.
モジュールsrfi-27でサポートされます。section 10.10 srfi-27 - ランダムビットのソース参照。
SRFI-28, Basic format strings.
Gauche組み込みのformatがSRFI-28のもののスーパーセットに なっています。section 6.18.7 出力参照。
SRFI-30, Nested multi-line comments.
ネイティブのリーダでサポートされています。section 4.1 字句構造参照。

2.2 マルチバイト文字列

伝統的に、文字列は単なるバイトの配列として長く扱われてきました。 一文字が複数バイトを占めるようになっても、 文字列は単純な文字の配列であると考えられがちです。 しかしGaucheにおいては、そうではありません。

Gaucheは内部的にマルチバイト文字列をサポートします。 すなわち、文字列中の文字が占めるバイト数は一定していません。 Schemeの文字列プリミティブのセマンティクスは保たれているので、 詳細を気にしないでもプログラムは書けますが、 下にあげるいくつかの点を知っておいたほうが良いでしょう。

文字列オブジェクトは型タグと文字列本体へのポインタを保持しています。 文字列本体は「copy-on-write」方式で管理されます。すなわち、substring や正規表現を使って部分文字列を切り出したり、あるいは単に文字列をコピーした場合、 文字列オブジェクトそのものは別につくられますが、文字列本体は共有されます。 文字列が破壊的に変更される場合にのみ、文字列本体がコピーされます。

したがって、make-stringである大きさの文字列をあらかじめアロケート しておき、string-set!で順に埋めて行くようなアルゴリズムは Gaucheでは非常に効率が悪くなります。そのようなアルゴリズムは使わない方が良いでしょう。 (そのようなアルゴリズムはマルチバイト文字列とも相性が良くありません)。 文字列を順に埋めて行く場合はstring portsを使うのが 効率の良い方法です (section 6.18.4 文字列ポート参照)。

string-scan (section 6.10.7 文字列を扱うその他の手続き参照) や正規表現 (section 6.11 正規表現参照) など文字列を検索するプリミティブは、 インデックスを介さずに一致した文字列を直接返すことができます。

Gaucheのコンパイル時に、文字の内部エンコーディングを選択することができます。 実行時に手続きgauche-character-encodingによってどの内部エンコーディング でコンパイルされたかを知ることが出来ます。 今のところ、以下のエンコーディングがサポートされています。

euc-jp
ASCII、JIS X 0201カナ、JIS X 0212及びJIS X 0213:2000文字集合のEUC-JP エンコーディング
sjis
JIS X 0201カナ及びJIS X 0213:2000文字集合のShift-JISエンコーディング。 ソースコードの互換性のため、文字コード0から0x7fの範囲はJIS X 0201 roman ではなくASCIIにマップされます。
utf-8
UnicodeのUTF-8エンコーディング。
none
8ビット固定長の文字エンコーディング。文字コード0から0x7fの範囲はASCIIと みなします。Unicodeとの変換の際にはISO8859-1エンコーディングを仮定します。

他の文字エンコーディングからの変換は特別なポートを使って行われます。 section 9.2 gauche.charconv - 文字コード変換 を参照して下さい。

Gaucheは、Schemeプログラムはその内部エンコーディングと同じエンコーディングで 書かれているものとして読み込みます。

2.3 大文字小文字の区別

Lisp系の言語は歴史的にシンボルの大文字小文字を区別していませんでした。 Schemeもその流れを汲んでおり、R5RSでもシンボルは読み込まれる時に大文字小文字の 区別をしないと定義されています。(但し、R5RSの範囲内でも内部的なシンボル名は 大文字小文字の区別がなされます。ここで問題としているのは読み込み時の動作です)。

しかし現在では、プログラミングが一つの言語で完結することは滅多にありません。 他の言語とインタフェースを取る場合、Scheme側でも大文字小文字を区別するように しておいた方が便利です。

そこでGaucheでは、シンボルの読み込みと書き出しに2つのモードを用意しました。 デフォルトのモードでは、Gaucheのリーダとライタはシンボルの大文字小文字を区別します。 このふるまいは厳密にはR5RSに準拠しません。

; In case-sensitive mode (default)
(eq? 'a 'A) => #f  ; #t in R5RS
(symbol->string 'ABC) => "ABC"
(symbol->string 'abc) => "abc"
(display (string->symbol "ABC")) => writes ABC
(display (string->symbol "abc")) => writes abc

goshインタプリタの起動時に-fcase-foldコマンドライン引数を 与えると、Gaucheは大文字小文字を区別しないモードで動作します (section 3.1 Gaucheを起動する参照)。 このモードでは、リーダはシンボルの読み込みの際に大文字を小文字に変換します。 大文字を含んでいるシンボルに関しては、`|' 文字でエスケープされて書き出されます (section 6.5 シンボル参照)。

; In case-insensitive mode (with -fcase-fold option)
(eq? 'a 'A) => #t
(symbol->string 'ABC) => "abc"
(symbol->string 'abc) => "abc"
(display (string->symbol "ABC")) => writes |ABC|
(display (string->symbol "abc")) => writes abc

今のところ、インタプリタの中から両方のモードを切り替えることはできません。 将来のバージョンではその方法が提供されるでしょう。

2.4 統合されたオブジェクトシステム

GaucheはCLOSに類似した、STklosスタイルのオブジェクトシステムを持っています。 あなたが何らかのオブジェクト指向(OO)言語を使ったことがあれば、 基本的な使い方は簡単にわかるでしょう。

;; x, y座標を持つpointクラスを定義
(define-class point ()
  ((x :init-value 0)
   (y :init-value 0))
  )

(define-method move ((p point) dx dy)
  (inc! (slot-ref p 'x) dx)
  (inc! (slot-ref p 'y) dy))

(define-method write-object ((p point) port)
  (format port "[point ~a ~a]"
          (slot-ref p 'x)
          (slot-ref p 'y)))

しかし、主流のオブジェクト指向言語に慣れてはいるがCLOSスタイルのオブジェクトシステムに 慣れていないプログラマは、Gaucheのオブジェクトシステムの詳細を見てゆくと 奇妙に感じることがあるのではないかと思います。 ここではGaucheのオブジェクトシステムの代表的な性質を簡単に述べておきます。 詳しくはsection 7. オブジェクトシステムの章を参照して下さい。

全てはオブジェクトである (それが気になる人には)
このような主張は他のOO言語でも見たことがあるでしょう。 Gaucheもその例にもれず、実行時にクラスを得たりメソッドを呼び出したりといった 操作が任意のオブジェクトに対して出来るという意味で、全てはオブジェクトです。 また組込みクラスを含めたどんなクラスに対しても新しいメソッドを定義することができます。 しかし、CLOS系のパラダイムでは、全てがオブジェクトかどうかという議論はあまり 問題ではありません。というのは次のような性質があるからです。
メソッドは全ての引数によってディスパッチされる
C++、Objective C、Python、RubyなどのOO言語では、メソッドは特定のクラスに 所属しています。Gaucheではメソッドはクラスに従属しません。 例えば、数値だけを要素に持つベクタークラス<num-vector>と 行列クラス<num-matrix>を定義したとします。 プログラマは、以下のようなあらゆる場合についてメソッドproductを 別々に定義することができます。
  (product <num-vector> <num-matrix>)
  (product <num-matrix> <num-vector>)
  (product <num-vector> <num-vector>)
  (product <num-matrix> <num-matrix>)
  (product <number>     <num-vector>)
  (product <number>     <num-matrix>)
  (product <number>     <number>)
これらの各メソッドは、<num-vector>クラスや<num-matrix> クラスに所属するわけではありません。 メソッドがクラスに所有されているわけではないので、既に存在するクラスに対していつでも 独自のメソッドを定義することができます(但し、いくつかの組込みクラスの既定のメソッドには 変更できないものがあります)。上の例で既にこれは示されています。プログラマは メソッドproductを組込みクラス<number>に対して定義することが できます。これが、全てはオブジェクトであるかどうかはCLOSスタイルのオブジェクトシステム では問題にならないと言った理由です。
クラスはインスタンスでもある
デフォルトでは、クラスは<class>というクラスのインスタンスであり、 ジェネリック関数は<generic>というクラスのインスタンスです。 しかし、<class>を継承したクラスを定義することにより、 オブジェクトの初期化がどのように行われるかとか、スロットがどのように アクセスされるかといった動作をカスタマイズすることができます。 また、<generic>を継承したクラスを定義することにより、 適用可能なメソッドがどのように選択されて、どのような順序で適用されるか といったことがカスタマイズ可能です。このメカニズムはメタオブジェクトプロトコル と呼ばれています。メタオブジェクトプロトコルは、言語をその言語そのもので拡張する方法と 言えるでしょう。 例として、ディストリビューションに含まれるlib/gauche/singleton.scmlib/gauche/validator等があります。lib/gauche/object.scmを 読めば、クラス自身がGaucheでどのように定義されているかがわかります。 メタオブジェクトプロトコルの更に詳しいことについては、 @xref{mop,[MOP],MOP}が参考になります。
クラスは名前空間を作らない
メインストリームのOO言語ではクラスが名前空間を作ることがよくあります。 CLOSスタイルのオブジェクトシステムはそうではありません。 Gaucheでは、名前空間はオブジェクトシステムとは直交する、 モジュールシステムによって管理されます。

2.5 モジュールシステム

Gaucheは大きなソフトウェアをモジュール化して開発するための、 単純なモジュールシステムを備えています。

高レベルのインタフェースを使うのはユーザにとっては非常に簡単です。 モジュールfooが提供する機能を使いたければ、 プログラム中で(use foo)と表記するだけです。 このフォームはマクロで、コンパイル時に解釈されます。 通常は、fooの機能を実装したファイルをロードし、 その外部APIを呼び出したモジュール中にインポートします。

useメカニズムは、名前空間の分離とファイルローディングという 二つの独立な低レベルのメカニズムの上に実装されています。 これらの低レベルメカニズムはそれぞれ別々に使うこともできます。

useメカニズムは非遷移的です。すなわち、 モジュールBがモジュールAを'use'し、さらにモジュールCがモジュールBを 'use'している場合、モジュールCからはモジュールA内の束縛は見えません。 BとAはis-a関係ではないためです。 例えばモジュールAが低レベルの操作を実装し、 モジュールBがその上に高レベルの抽象的なインタフェースを実装しているとしましょう。 モジュールCがモジュールBを'use'しているということは、 CはBの提供する抽象レイヤに興味があるということです。 もしCがさらに低レベルの層にもアクセスしたいならば、CはAを明示的に'use'しなければ なりません。

しかし、別の形の関係が必要な場合もあります。例えば既存のモジュールAに ちょっと新しいインタフェースを付け加えたモジュールBをAの拡張として 提供したいという場合です。この時、BとAはis-a関係であり、Bを'use' しているモジュールからA内の束縛も見えるのが自然です。 Gaucheでは、これをモジュールの継承と呼び、 extendフォームにより実現しています。

以下のセクションでモジュールの機能について詳しく説明しています。

2.6 コンパイル

Gaucheは、Schemeフォームをひとつづつ読み込んでは評価するという意味では インタプリタです。しかし内部では、Gaucheはひとつひとつのフォームを中間形式に コンパイルして仮想マシンで実行しています。

組み込みの構文とマクロはコンパイル時に認識されて展開されます。 よく使われる組み込み関数は、コンパイル時にグローバルな束縛が置き換わっていない場合に、 インライン展開されます。

プログラマは通常、コンパイラの動作を気にする必要はほとんどありませんが、 いくつかの点に注意する必要があります。

loadは実行時に評価される
loadはGaucheでは一般の関数なので、実行時に評価されます。 ロードされるファイル中でマクロを定義している場合、そのマクロは そのloadの呼び出しを含むトップレベルフォームが評価された後で 有効になります。例えば、foo.scmがマクロfooを定義しているとして、 次のような用法を考えてみてください。
;; in ``foo.scm''
(define-syntax foo
  (syntax-rules () (_ arg) (quote arg)))

;; in your program
(begin (load "foo") (foo (1 2 3)))
  => error, bad procedure: `1'

(load "foo")
(foo (1 2 3)) => '(1 2 3)
beginloadfooの呼び出しを囲んだ場合、 コンパイラはまずbegin全体をコンパイルします。その時点でマクロ fooは定義されていませんから、これは評価時にエラーになります。 一方、後者ではloadが評価されてからfooがコンパイルされるので、 問題は起きません。 このような混乱を避けるために、別のプログラムファイルを読み込む必要がある時は requireuseを使うことを勧めます。これらは構文であり、 コンパイラに認識されます。
require はコンパイル時に評価される
上記の裏返しですが、requireuseはコンパイル時に 解釈されます。したがって、ifなどの条件文のボディにこれらのフォームを 置いておいても、指定されたファイルは条件にかかわらず読み込まれてしまいます。 どうしてももし条件によって読み込むかどうかを変えたい場合は、loadを使うか、 条件判断自体をマクロで行うようにしてください。

3. Gaucheでのプログラミング

3.1 Gaucheを起動する

Gaucheは独立したSchemeインタプリタとしても、組み込みのSchemeライブラリとしても 使うことができます。Gaucheのディストリビューションには、goshという インタプリタが附属しています。

Program: gosh [options] [scheme-file arg ...]
Gaucheのインタプリタです。 scheme-fileが与えられなければ、 goshはインタラクティブに動作します。すなわち、標準入力からScheme式を読み込み、 それを評価して結果をプリントするという動作を、EOFを読むか明示的に終了させられるまで 続けます。

もしscheme-fileが与えられておらず、しかし入力が端末でない場合、 goshはread-eval-printループに入りますが、入力待ちの際にプロンプトを 表示しません。これはScheme式をパイプでgoshに処理させる場合に便利です。 -bまたは-iオプションでこの動作を強制的にonまたはoffできます。

scheme-fileが与えられた場合、goshはそれをSchemeプログラムとして ロードし、終了します。この動作に関してはsection 3.4 Schemeスクリプトを書くを参照して 下さい。

以下のコマンドラインオプションがgoshに認識されます。 `-' で始まらない最初のコマンドライン引数がスクリプトファイルと認識されます。 スクリプトファイル名が `-' で始まっている可能性がある場合は、ダミーオプション `--' をスクリプトファイル名の前に置いて下さい。

Command Option: -I path
pathをロードパスのリストの最初に加えます。このオプションは複数指定できます。

Command Option: -A path
pathをロードパスのリストの末尾に加えます。このオプションは複数指定できます。

Command Option: -q
goshが起動時にシステムの初期化ファイルを読まないようにします。

Command Option: -V
goshのバージョンを表示して終了します。

Command Option: -u module
起動後、インタラクティブなread-eval-printループに入る前、もしくはscheme-file をロードする前にmoduleを"use"します。つまりそのモジュールがロードされ インポートされます。(useの詳細についてはsection 4.11.2 モジュールの定義と選択を参照して下さい)。 このオプションは複数回指定できます。

Command Option: -l file
起動後、インタラクティブなread-eval-printループに入る前、もしくはscheme-file をロードする前にfileをロードします(ロードの詳細についてはsection 6.19.1 Schemeファイルのロード を参照して下さい)。このオプションは複数回指定できます。

Command Option: -e scheme-expression
起動後、インタラクティブなread-eval-printループに入る前、もしくはscheme-file をロードする前にscheme-expressionを評価します。評価は interaction-environment中で行われます(section 6.17 Eval and repl参照)。 このオプションは複数回指定できます。

Command Option: -E scheme-expression
オプション-eとほぼ同じですが、scheme-expressionは それが括弧で囲まれているかのように読まれます。 このオプションは複数回指定できます。例:
% gosh -umath.const -E"print (sin (* pi/180 15))" -Eexit
0.25881904510252074

Command Option: -b
バッチ。入力が端末であっても、read-eval-printループがプロンプトを出さないようにします。

Command Option: -i
インタラクティブ。入力が端末で無くても、read-eval-printループが プロンプトを出すようにします。

Command Option: -f compiler-option
このオプションはコンパイラの動作に影響を与えます、今のところ、次のオプションのみが compiler-optionとして有効です。
no-inline
Schemeの基本関数のインライン展開を行いません。
no-source-info
デバッグのためのソースファイル情報を保持しません。メモリの使用量は小さくなります。
load-verbose
ファイルがロードされる時にそれを報告します。
case-fold
R5RSに示される通り、シンボルの大文字小文字を区別しません。 (デフォルトではこれらは区別されます)。 section 2.3 大文字小文字の区別 を参照して下さい。

Command Option: --
このオプションに出会うと、goshはオプションの解析を止めて、その次の引数を 無条件にscheme-fileであると見倣します。scheme-fileがマイナス記号で 始まっている場合に必要です。

オプション-I, -A, -l, -u, -e 及び -E は、それらがコマンドライン引数として 出現した順に処理されます。例えば、-Iにより追加されるロードパスは それ以降の-lや-uオプションに影響を与えますが、それ以前のものには影響を 与えません。

3.2 インタラクティブな開発

スクリプトファイルが与えられなかった場合、 goshはインタラクティブなread-eval-printループに入ります。

インタプリタを終了するには、EOF文字(Unix端末では通常Control-D)をタイプするか、 (exit)を評価します。

goshをEmacs内部で走らせることをお勧めします。 EmacsはSchemeサブプロセスを操作するための豊富な機能を持っています。 次の行を`.emacs'に加えておくと、M-x run-scheme で Emacsのバッファ内でgoshが走ります。

(setq scheme-program-name "gosh")

対話環境でマルチバイト文字を使う場合は、端末の文字エンコーディングをgoshの 内部エンコーディングと合わせるようにして下さい。

今のところ、goshは行編集やコマンドヒストリなどの便利な機能を 備えていません。将来はこのへんも充実してゆくでしょう。

インタラクティブセッションで便利な手続きがsection 9.6 gauche.interactive - インタラクティブセッションで定義されています。

3.3 デバッグ

Gaucheにはまだデバッグをサポートする機能があまり実装されていません。 デバッギングのインタフェースに関して良いアイディアがあればお寄せください。

今のところ、作者は必要な時は古典的な「プリントスタブ」方式を使っています。 そのためのリーダーマクロ #?=expr が定義されています。 これは (debug-print expr) のように読まれ、 マクロ debug-printexprを評価してその値を返しますが、 評価前と評価後にメッセージを出力します。

gosh> #?=(+ 2 3)
#?="(stdin)":1:(+ 2 3)
#?-    5
5
gosh> #?=(begin (print "foo") (values 'a 'b 'c))
#?="(stdin)":2:(begin (print "foo") (values 'a 'b 'c))
foo
#?-    a
#?+    b
#?+    c
a
b
c
gosh> (define (fact n)
        (if (zero? n)
            1
            (* n #?=(fact (- n 1)))))
fact
gosh> (fact 5)
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?="(stdin)":6:(fact (- n 1))
#?-    1
#?-    1
#?-    2
#?-    6
#?-    24
120

また、木村栄伸さんがGauche用のtrace/untraceマクロを書いてくれました: http://homepage.mac.com/skimu/ggc/.

3.4 Schemeスクリプトを書く

goshのコマンドラインにSchemeプログラムのファイル名が渡された場合、 goshはそれ以降のコマンドライン引数のリストをグローバル変数*argv*に束縛し、 Schemeプログラムをロードします。もしscheme-fileの最初の行が"#!"で始まって いたら、その行は無視されます。これにより、Unix系のシステムで実行可能なSchemeスクリプト を書くことが出来ます。

典型的なGaucheスクリプトの最初の行は次のようなものです。

#!/usr/local/bin/gosh
  または,
#!/usr/bin/env gosh
  または,
#!/bin/sh
:; exec gosh -- $0 "$@"

後の2つは「シェルトランポリン」テクニックを用いて、goshがPATHにあるディレクトリの どこかにあれば起動できるようにしています。3番目の方法は、 goshにいくつかコマンドラインオプションを渡したい時に便利です。

ファイルが正常にロードされたら、goshは userモジュールに `main' という手続きが定義されているかどうか調べ、 定義されていればそれを呼びます。mainには、スクリプトへの引数のリストが 唯一の引数として渡されます。リストの最初の要素はスクリプトファイル名です。

mainが整数の値を返したら、goshはその値を終了ステータスとして終了します。 mainが整数以外の値を返した場合はgoshは終了ステータス70 (EX_SOFTWARE)で終了します。このふるまいはSRFI-22と互換です。

(注:このインタフェースはGauche release 0.5から非互換な形で 変更されました。section 3.4.1 リリース0.5以前とのスクリプトの互換性を参照して下さい。)

mainが定義されていなければgoshはロード後にそのままステータス0で 終了します。

シェルスクリプトやPerlスクリプトと同じように、スクリプトのボディに直接 実行される式を書くこともできますが、なるべく `main' を使った方法を 使うことをお薦めします。そうすると、スクリプトをインタプリタにインタラクティブに ロードしてデバッグすることもできます。

Variable: *argv*
Schemeスクリプト以降のコマンドライン引数のリストは、スクリプトのロードの前に この変数に束縛されます。goshがインタラクティブモードで起動された場合は この変数は()となります。

この変数はSTkと互換性がありますが、他のScheme実装は違った方法を使ってコマンドライン 引数を得ます。ポータブルなスクリプトを書くには、main手続きを使う方法を お薦めします。

Variable: *program-name*
この変数はスクリプトファイル名に束縛されます。インタラクティブモードでは この変数はgosh自身の名前を持っています。

この変数はSTkと互換性がありますが、他の実装は違った方法を使います。

いくつか簡単な例を示します。最初の例はUnixのcat(1)コマンドを模するものです。 エラー処理やコマンドラインオプションの処理は行っていません。

#!/usr/bin/env gosh

(define (main args)   ;entry point
  (if (null? (cdr args))
      (copy-port (current-input-port) (current-output-port))
      (for-each (lambda (file)
                  (call-with-input-file file
                    (lambda (in)
                      (copy-port in (current-output-port)))))
                (cdr args)))
  0)

次のスクリプトは簡単なgrepコマンドです。

#!/usr/bin/env gosh

(define (usage)
  (format (current-error-port)
          "Usage: ~a regexp file ...\n" *program-name*)
  (exit 2))

(define (grep rx port)
  (with-input-from-port port
    (lambda ()
      (port-for-each
       (lambda (line)
         (when (rxmatch rx line)
           (format #t "~a:~a: ~a\n"
                   (port-name port)
                   (- (port-current-line port) 1)
                   line)))
       read-line))))

(define (main args)
  (if (null? (cdr args))
      (usage)
      (let ((rx (string->regexp (cadr args))))
        (if (null? (cddr args))
            (grep rx (current-input-port))
            (for-each (lambda (f)
                        (call-with-input-file f
                          (lambda (p) (grep rx p))))
                      (cddr args)))))
  0)

コマンドライン引数を処理するモジュールがあります。 section 9.13 gauche.parseopt - コマンドライン引数の解析を参照してください。

3.4.1 リリース0.5以前とのスクリプトの互換性

SRFI-22に準拠するために、Gaucheはリリース0.5.1からmainの呼ばれ方を 変更しました。残念ながら、この変更によりそれ以前のGaucheのために書かれたスクリプトは 動作しなくなります。 標準(srfi)との非互換性を後々まで引きずるよりは、まだ開発の早い段階の今の時点で 変更をしておいたほうが良いと判断しました。

非互換な変更は以下の2点です。

3.5 Gaucheのモジュールを書く

Gaucheのライブラリはモジュール毎に整理されています。Gaucheはどんな形式でも、 有効なScheme式が書かれてさえいればロードすることができますが、 Gaucheのライブラリは一定の形式を保って書かれています。 Gauche用にまとまったSchemeコードを書いたら、それをモジュール形式にしておくと 再利用がしやすくなるでしょう。

通常ひとつのファイルで ひとつのモジュールを定義しますが、モジュールを複数のファイルに分けることもできます。 まずひとつのファイルでモジュールを定義する方法を説明します。 Gaucheのライブラリで使われているテンプレートは次のような形式です。

;; モジュールのインタフェースの定義
(define-module foo
  (use xxx)
  (use yyy)
  (export foo1 foo2 foo3)
  )
;; モジュール本体
(select-module foo)

... module body ...

;; `require' に対応するprovide
(provide "foo")

このファイルは"foo.scm"という名で、*load-path*にあるディレクトリの いずれかに置かれなければなりません。

まず、define-moduleフォームがモジュールfooを作成します。 define-moduleフォーム内で、このモジュールが依存している他のモジュール を `use' マクロを使ってロードし、このモジュールがエクスポートするシンボルを `export' 構文を使って指定します。(これらの構文の詳細はsection 4.11.2 モジュールの定義と選択を 参照して下さい)。

これらのuseフォームやexportフォームは必ずしもdefine-module フォームの先頭に置く必要はありませんが、このようにファイルの最初の方に固めておくことで、 fooが依存しているモジュール群やfooが提供するシンボル等が 一覧しやすくなります。

次の、`select-module' フォームにより、それ以降のScheme式が モジュールfooの中で評価されます。モジュールの内容を全てdefine-moduleの中に 書いてしまうことも出来ますが、最後の括弧を閉じ忘れやすいことや、エディタのインデントが 狂うことなどから、あまりお薦めしません。

select-moduleフォームの後には、モジュールの内容であるScheme式を自由に書けます。 それらはモジュールfooの中で評価されます。モジュール内で定義するトップレベルの 束縛のうち、明示的に`export'で指定されたシンボルのみが、このモジュールをインポートする他の モジュールから見えます。

最後のprovideは一種の定型句です。`use'がrequire-provideメカニズムを 利用しているために必要です。

これで、他のプログラムは `(use foo)' とするだけでこのモジュールの機能が 利用可能になります。もしモジュールをサイト全体で利用できるようにしたければ、gosh内で

(gauche-site-library-directory)

を評価して得られるディレクトリにfoo.scmを置いて下さい。

モジュールの名前空間のトップに新たなモジュールを追加するのに気が引ける場合は、 モジュールを階層的に構成することもできます。Gaucheのモジュールの多くは既に階層的に 構成されています。具体的なモジュール例はsection 8. ライブラリモジュール - 概要を参照して下さい。 例えば、text.trモジュールは "text/tr.scm" ファイルに 実装されています。パス名の区切り文字`/'がモジュール名ではピリオドになることに 注意して下さい。

4. 基本的な構文

4.1 字句構造

GaucheはR5RS Schemeのパーザをいくつかの点で拡張しています。

ネスト可能なブロックコメント (SRFI-30)
'#|' と '|#' で囲まれたテキストはコメントになります。 ネスト可能です。
数値リテラル
不正確な実数の整数部または小数部のいずれかが0の場合、それを省略することが できます。例:30., .25, -.4。 不正確な桁を '#' で表現する構文はサポートされていません。
シンボル名
シンボル名はデフォルトで大文字小文字を区別します (section 2.3 大文字小文字の区別参照)。 数字や'+', '-' で始まるシンボル名も、 トークンが有効な数値リテラルを構成しない限り許されます。 また、他の変な文字も '|' でシンボルを囲むことによってシンボル名に含めることが できます (例:'|this is a symbol|')。 section 6.5 シンボルも参照して下さい。
文字コードによる文字リテラル
文字リテラルを文字コードにより表記することができます。 Gauche内部コードを使う #\xNN と、 Unicodeを使う #\uNNという表記があります。 section 6.8 文字を参照して下さい。
拡張された#構文
'#' で始まる特殊構文がたくさん定義されています。 下の表を参照して下さい。

The table below lists sharp-syntaxes.

  • #! [SRFI-22] Specifies interpreter at the beginning of file. Scheme loader ignores the line.
  • #", ##, #$, #%, #&, #' Unused.
  • #( [R5RS] Introduces a vector.
  • #) Unused.
  • #* If followed by a double quote, denotes an incomplete string. See section 6.10 文字列.
  • #+ Unused.
  • #, [SRFI-10] Introduces reader constructor syntax.
  • #-, #. Unused.
  • #/ Introduces a literal regular expression. See section 6.11 正規表現.
  • #0 ... #9 Reserved for shared structure reference.
  • #:, #; Unused
  • #< Introduces an unreadable object.
  • #=, #> Unused.
  • #? Introduces debug macros. See section 3.3 デバッグ.
  • #@ Unused.
  • #a Unused.
  • #b [R5RS] Binary number prefix.
  • #c Unused.
  • #d [R5RS] Decimal number prefix.
  • #e [R5RS] Exact number prefix.
  • #f [R5RS] Boolean false, or introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - ユニフォームベクタ.
  • #g, #h Unused.
  • #i [R5RS] Inxact number prefix.
  • #j, #k, #l, #m, #n Unused.
  • #o [R5RS] Octal number prefix.
  • #p, #q, #r Unused.
  • #s [SRFI-4] introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - ユニフォームベクタ.
  • #t [R5RS] Boolean true.
  • #u [SRFI-4] introducing SRFI-4 uniform vector. See section 9.24 gauche.uvector - ユニフォームベクタ.
  • #v, #w Unused.
  • #x [R5RS] Hexadecimal number prefix.
  • #y, #z Unused.
  • #[ Introduces a literal character set. See section 6.9 文字集合.
  • #\ [R5RS] Introduces a literal character. See section 6.8 文字.
  • #], #^, #_ Unused.
  • #` Introduces an interpolated string. See section 6.10.4 文字列の補間.
  • #{ Unused.
  • #| [SRFI-30] Introduces a block comment. Comment ends by matching '|#'.
  • #}, #~ Unused.

    4.2 リテラル

    Special Form: quote datum
    [R5RS] datumそれ自身を返します。
    (quote x) => x
    (quote (1 2 3)) => (1 2 3)
    

    Reader Syntax: 'datum
    [R5RS] (quote datum)の略記です。
    'x => x
    '(1 2 3) => (1 2 3)
    

    注: R5RSは、リテラル式の値を変更するのはエラーであるとしています。 しかしGaucheはペアとベクタについてはそれが定数であるかどうかをチェックしておらず、 set-car!vector-set!等の破壊的手続きによってそれらの値を 変更できてしまいます。そうした場合の動作は不定です。 文字列に関しては定数かどうかのチェックを行っており、定数文字列を変更しようとすると エラーが報告されます。

    4.3 手続きを作る

    Special Form: lambda formals body ...
    [R5RS] この式は評価されると手続きを生成します。この式が評価された時点の環境が手続き中に保持されます。 手続きが呼ばれると、記憶された環境に引数の束縛を追加した環境中でbody が順に評価され、 最後の式の値が返されます。

    Formals は以下のいずれかの形でなければなりません。

    • (variable ...) : 手続きは決まった数の引数を取ります。 実引数がそれぞれ対応するvariableに束縛されます。
    • variable : 手続きは不定個の引数を取ります。 実引数は新しいリストに集められて、そのリストがvaribleに束縛されます。
    • (variable_0 ... variable_N-1. variable_N) : 手続きは少なくともN個の引数を取ります。N個までの実引数は対応するvariable に束縛されます。N個を越えた実引数は新しいリストに集められて variable_Nに束縛されます。
    (lambda (a b) (+ a b))
      => 二つの引数を加算する手続き
    
    ((lambda (a b) (+ a b)) 1 2)
      => 3
    

    注: いくつかのSchemeの実装ではformalsの構文を拡張して、 CommonLispのように省略可能引数やキーワード引数などの表記を可能にしているものが あります。Gaucheには今のところそのような拡張はありません。

    Macro: cut expr-or-slot expr-or-slot2 ...
    Macro: cute expr-or-slot expr-or-slot2 ...
    [SRFI-26] 手続きを簡潔に書ける便利なマクロです。 いわゆる部分適用を実現するために使えます。

    expr-or-slotは式またはシンボル<>でなければなりません。 最後のexpr-or-slotはシンボル<...>であっても構いません。 cutは、そのフォーム中にある<>と同じ数の引数を取る lambdaフォームに展開されます。そのフォームのボディには次の式が置かれます。

      (expr-or-slot expr-or-slot2 ...)
    

    但し、各<>は対応する仮引数に置き換えられます。 もしシンボル<...>が与えられていた場合、展開されたlambdaフォームは 可変長引数を取る手続きとなり、作成される手続きに与えられたすべての引数が expr-or-slotを呼び出すのに使われます(下の4番目の例を参照のこと)。

    (cut cons (+ a 1) <>)  == (lambda (x2) (cons (+ a 1) x2))
    (cut list 1 <> 3 <> 5) == (lambda (x2 x4) (list 1 x2 3 x4 5))
    (cut list)             == (lambda () (list))
    (cut list 1 <> 3 <...>)
       == (lambda (x2 . xs) (apply list 1 x2 3 xs))
    (cut <> a b)           == (lambda (f) (f a b))
    
    ;; Usage
    (map (cut * 2 <>) '(1 2 3 4))
    (for-each (cut write <> port) exprs)
    

    cutecutとほぼ同じですが、expr-or-slotに与えられた フォームが手続きを作る前に評価される点が異なります。

    (cute cons (+ a 1) <>)
       == (let ((xa (+ a 1))) (lambda (x2 (cons xa x2))))
    

    Gaucheはまた、部分適用を行うpa$という組み込み手続きを持っています (See section 6.15.1.2 コンビネータ参照)。

    4.4 代入

    Special Form: set! symbol expression
    Special Form: set! (proc arg ...) expression
    [R5RS][SRFI-17] まずexpressionが評価されます。最初の形式では、symbolへの束縛が expressionの結果を指すように変更されます。 もしsymbolがローカルに束縛されていない場合は、グローバルな変数symbolが 存在していなければなりません。そうでなければエラーが報告されます。

    2番目の形式はSRFI-17に定義されている「一般化されたset!」です。 これは構文的な装飾であり、実際は以下のように解釈されます。

    ((setter proc) arg ... expression)
    

    CommonLispのsetfとは、setter手続きに渡される引数の順序が異なることに注意して下さい。

    例:

    (define x 3)
    (set! x (list 1 2))  => undefined
    x                    => (1 2)
    
    (set! (car x) 5)     => undefined
    x                    => (5 2)
    

    Macro: set!-values (var ...) expr
    複数の変数を同時に更新します。Exprは与えられた変数と同じ 数だけの値を生成しなけばなりません。各値が対応するvarに セットされます。
    (define a 0)
    (define b 1)
    (set!-values (a b) (values 3 4)) => undefined
    a => 3
    b => 4
    (set!-values (a b) (values b a)) => undefined
    a => 4
    b => 3
    

    Function: setter proc
    [SRFI-17] 手続きprocのsetter手続きを返します。もしprocがsetter手続きを持たなければ、 エラーが返されます。

    ある関数fのsetter手続きgとは、もし(g a b ... v)のように 呼ばれた場合、次の(f a b ...)vを返すようになる手続きのことです。

    ある手続きにsetter手続きを関連付けるには、setter自身のsetter手続きを使うことが できます。

    (set! (setter f) g)
    

    特定の手続きにsetter手続きを「ロック」することができます。システム既定のsetter手続き、 例えばcarに対するset-car!等はロックされていて、上記のような方法で 変更することは出来ません。ユーザ定義手続きにsetter手続きをロックするには下記の getter-with-setterを使います。

    Function: getter-with-setter get set
    [SRFI-17] 2つの手続き、getsetを取り、新しい手続きを返します。 新しい手続きはgetと同じ動作をし、そのsetter手続きはsetにロックされて います。

    この手続きは、SRFI-17によれば、setter手続きのインライン展開を可能にするための ものですが、Gaucheではまだそのような最適化は実装されていません。

    Gaucheでは、一般化されたset!と同じセマンティクスを持ついくつかのマクロが定義 されています。これらはset!を使った形に展開されます。

    Macro: push! place item
    itemplaceの値をコンスし、その結果を再びplaceにセットします。 placeset!と同様に、 変数か(proc arg ...)という形式でなければなりません。このマクロの戻り値は 未定義です。
    (define x (list 2))
    (push! x 3) => undefined
    x => (3 2)
    
    (push! (cdr x) 4) => undefined
    x => (3 4 2)
    

    placeがリストの場合、だいたいこんなふうに展開されます。

    (push! (foo x y) item)
     ==
     (let ((tfoo foo)
           (tx x)
           (ty y))
       ((setter tfoo) tx ty (cons item (tfoo tx ty))))
    

    註:Common Lispのpushマクロは引数を逆の順番で取ります。 push!は他の副作用を持つ形式との互換性を考えてこの順番としました。 Perlのpush関数はpush!マクロと同じ引数順ですが、 itemはシーケンスの末尾に追加されます (Perlのunshiftの方が push!の動作に近いです)。 Perlのpushオペレータの動作が必要ならQueueが使えます (section 11.22 util.queue - キュー参照)。

    Macro: pop! place
    placeの値を取り出し、そのcdrplaceにセットします。 元の値のcarを返します。
    (define x (list 1 2 3))
    (pop! x) => 1
    x => (2 3)
    
    (define x (vector (list 1 2 3)))
    x => #((1 2 3))
    (pop! (vector-ref x 0)) => 1
    x => #((2 3))
    

    註:この動作はCommon Lispのpopと同じです。 Perlのpopはシーケンスの末尾から値を取ります。 Perlならshiftpop!の動作に近いです。

    Macro: inc! place &optional delta
    Macro: dec! place &optional delta
    placeの値を評価します。それは数値にならなければなりません。 その値にdeltaが加算(inc!)もしくは減算(dec!)され、 結果がplaceに格納されます。deltaの既定値は1です。

    Common Lispのincfdecfに当たります。

    Macro: update! place proc
    push!等のマクロの一般化された形式です。 procは一つの引数を取り、一つの値を返す手続きでなければなりません。 placeの値がprocに渡され、procの結果がplaceに格納されます。
    (define a (cons 2 3))
    (update! (car a) (lambda (v) (* v 3))) => undefined
    a => (6 . 3)
    
    (update! (cdr a) (cut - <> 3))
    a => (6 . 0)
    

    4.5 条件式

    Special Form: if test consequent alternative
    Special Form: if test consequent
    [R5RS] まずtestを評価し、それが真の値を返したらconsequentを評価します。 そうでなければalternativeを評価します。もしalternativeが与えられて いなければ未定義の値を返します。
    (if (number? 3) 'yes 'no) => yes
    (if (number? #f) 'yes 'no) => no
    
    (let ((x '(1 . 2)))
      (if (pair? x)
          (values (car x) (cdr x))
          (values #f #f)))
      => 1 and 2
    

    Special Form: cond clause1 clause2 ...
    [R5RS] 各clause節は次のいずれかの形式でなければなりません。
    (test expr ...)
    (test => expr)
    (else expr expr2 ...)
    

    最後の形式は最後の節のみに許されます。

    最初の節から順にtestが評価され、それが真の値を返すまで次の節のtestが 評価されます。testが真の値を返したら、それが最初の形式であれば その節のexprが順に評価され、最後の評価値が戻り値となります。 それが2番目の形式であれば、exprがまず評価されます。 exprは引数をひとつ取る手続きを返さねばなりません。 続いて、testの結果がその手続きに渡され、その手続きの戻り値がcond形式の 評価値となります。 もし全てのテストが偽の値を返し、最後の節が3番目の形式(else節)でなければ、未定義の値が返されます。

    最後の節がelse節で、他の全てのテストが失敗した場合、else節のexpr が順に評価され、その最後の値がcond形式の値となります。

    (cond ((> 3 2) 'greater)
          ((< 3 2) 'less)) => greater
    (cond ((> 3 3) 'greater)
          ((< 3 3) 'less)
          (else 'equal)) => equal
    (cond ((assv 'b '((a 1) (b 2))) => cadr)
          (else #f)) => 2
    

    Special Form: case key clause1 clause2 ...
    [R5RS] keyは任意の式です。clauseは以下の形式でなければなりません。
    ((datum ...) expr expr2 ...)
    

    ここで、各datumはSchemeオブジェクトの外部表現であり、全てのdatumは 異なっていなければなりません。最後のclauseには次の形式を持つelse節が許されます。

    (else expr expr2 ...)
    

    まずkeyが評価され、その結果がそれぞれのdatumと比較されます。 keyの値とeqv?(section 6.1 等価参照)を使って一致するdatum が見つかれば、対応するexprが順に評価され、その最後の値がcaseの 値となります。もし一致するdatumが見つからない場合、else節が与えられていれば そのexprが順に評価され、最後の値が返されます。else節がなければcase節 の値は未定義です。

    (case (* 2 3)
      ((2 3 5 7) 'prime)
      ((1 4 6 8 9) 'composite)) => composite
    (case (car '(c d))
      ((a) 'a)
      ((b) 'b)) => undefined
    (case (car '(c d))
      ((a e i o u) 'vowel)
      ((w y) 'semivowel)
      (else 'consonant)) => consonant
    

    Special Form: and test ...
    [R5RS] test式が順に評価されます。最初に偽の値を返したところで評価が止まり、 偽の値が返されます。残りの式は評価されません。 もし全ての式が真の値を返した場合は、最後の式の値が返されます。 式が与えれない場合は#tが返されます。
    (and (= 2 2) (> 2 1)) => #t
    (and (= 2 2) (< 2 1)) => #f
    (and 1 2 'c '(f g))   => (f g)
    (and)                 => #t
    

    Special Form: or test ...
    [R5RS] test式が順に評価されます。最初に真の値を返したところで評価が止まり、 その値が返されます。残りの式は評価されません。 もし全ての式が偽の値を返した場合は、偽の値が返されます。 式が与えれない場合は#fが返されます。
    (or (= 2 2) (> 2 1)) => #t
    (or (= 2 2) (< 2 1)) => #t
    (or #f #f #f)        => #f
    (or (memq 'b '(a b c)) 
        (/ 3 0)) => (b c)
    

    Special Form: when test body ...
    Special Form: unless test body ...
    まずtestが評価されます。それが真の値(unlessの場合は偽の値)を返した場合、 引続きbodyが順に評価され、最後のbodyの評価値が返されます。 そうでなければ、未定義の値が返されます。

    4.6 変数束縛

    Special Form: let ((var expr) ...) body ...
    Special Form: let* ((var expr) ...) body ...
    Special Form: letrec ((var expr) ...) body ...
    [R5RS] 各変数varexprの値に束縛されているローカルな環境を作成し、 その中でbody ...を評価します。varはシンボルでなければ ならず、重複があってはなりません。body ...の最後の式の値が このフォームの値となります。

    これらの3つのフォームの違いは、exprが評価される時点のスコープにあります。 letexprletフォームに入る前の環境において評価します。 let*exprを順に、それ以前のvarが束縛された環境において評価して ゆきます。letrecは全てのvarが仮想的に不定の値に束縛された環境において 各exprを評価します。letrecは相互再帰的なローカル関数を定義する場合に 必要です。

    (define x 'top-x)
    
    (let  ((x 3) (y x)) (cons x y)) => (3 . top-x)
    (let* ((x 3) (y x)) (cons x y)) => (3 . 3)
    
    (let ((cons (lambda (a b) (+ a b)))
          (list (lambda (a b) (cons a (cons b 0)))))
      (list 1 2))  => (1 2 . 0)
    
    (letrec ((cons (lambda (a b) (+ a b)))
             (list (lambda (a b) (cons a (cons b 0)))))
      (list 1 2))  => 3
    

    Macro: let1 var expr body ...
    変数が一つしか無い場合の便利なマクロです。次のように展開されます。
    (let ((var expr)) body ...)
    

    Special Form: receive formals expression body ...
    [SRFI-8] この構文により、多値を受け取ることができます。 formalsはシンボルのリストです。不完全なリストであっても構いません。 expressionが評価され、返された値がlambda形式の引数の束縛と 同じようにしてformals内の変数と束縛され、その環境下でbody ...が 評価されます。
    (define (divrem n m)
      (values (quotient n m) (remainder n m)))
    
    (receive (q r) (divrem 13 4) (list q r))
      => (3 1)
    
    (receive all (divrem 13 4) all)
      => (3 1)
    
    (receive (q . rest) (divrem 13 4) (list q rest)
      => (3 (1))
    

    なお、section 6.15.4 多値call-with-valuesreceiveと等価な手続き的インタフェースです。 多値を複数のトップレベル変数に束縛するには、define-values (section 4.10 定義参照) が使えます。 また、SRFI-11 (section 10.6 srfi-11 - Let-values) のlet-valueslet*-valuesletのような形式で多値を扱うことができます。

    4.7 順次実行

    Special Form: begin form ...
    [R5RS] formを順に評価し、最後の値を返します。

    Beginletのような「ブロック」を作成するわけではありません。 すなわち、一般的にはform ...の先頭に「内部のdefine (internal define)」を 置くことはできません。意味的には、beginはまるでform ...が beginを囲むコンテクスト中に展開されているかのように振舞います。 例えば、トップレベルに次のような式があった場合、それは2つのトップレベルのdefineと 同等です。

    (begin (define x 1) (define y 2))
    

    よりトリッキーな例:

    (let ()
      (begin 
        (define x 2)
        (begin
          (define y 3)
        ))
      (+ x y))
    
      ==
    
    (let ()
      (define x 2)
      (define y 3)
      (+ x y))
    

    Macro: begin0 exp0 exp1 ...
    exp0, exp1, ... を評価し、exp0の結果を返します。 この名前はMzSchemeから取られました。これはCommonLispで prog1と呼ばれているものです。

    beginと違って、これは「ブロック」を構成します。 begin1フォームは次のように展開されるからです。

    (receive tmp exp0
      exp1 ...
      (apply values tmp))
    

    4.8 繰り返し

    Special Form: do ((variable init [step]) ...) (test expr ...) body ...
    [R5RS]

    Special Form: let name bindings body ...
    [R5RS]

    Macro: dotimes (variable limit [result]) body ...
    Macro: dolist (variable lexpr [result]) body ...
    Common Lispからの輸入です。それぞれ以下のように展開されます。
    (dotimes (variable limit result) body ...)
    ==>
    (do ((tlimit limit)
         (variable 0 (+ variable 1)))
        ((>= variable tlimit) result)
      body ...)
    
    (dolist (variable lexpr result) body ...)
    ==>
    (begin
      (for-each (lambda (variable) body ...) lexpr)
      (let ((variable '())) result))
    

    4.9 準クオート(Quasiquote)

    Special Form: quasiquote template
    [R5RS]

    4.10 定義

    Special Form: define variable expression
    Special Form: define (variable . formals) body ...
    [R5RS] この形式はトップレベル (ローカルな束縛が無い状態) とローカルスコープがある状態とで 別の意味を持ちます。

    トップレベルでは、この形式は変数variableに対するグローバルな束縛を定義します。 最初の形式では、expressionが評価され、その結果が変数variableの値となります。

    (define x (+ 1 2))
    x => 3
    (define y (lambda (a) (* a 2)))
    (y 8) => 16
    

    2番目の形式は手続きを定義するための構文的な修飾で、以下の形式と同じです。

    (define (name . args) body ...)
      == (define name (lambda args body ...))
    

    このフォームがローカルスコープの中に現われた場合、ローカル変数の束縛となります。

    beginは新しいスコープを作らないことに注意してください(section 4.7 順次実行参照)。 beginの中に現われるdefineは、あたかもbeginとそれを囲む 括弧な無いかのように振舞います。すなわち、以下の2つの形式は等価です。

    (let ((x 0))
      (begin
        (define (foo y) (+ x y)))
      (foo 3))
     ==
    (let ((x 0))
      (define (foo y) (+ x y))
      (foo 3))
    

    Macro: define-values (var ...) expr
    まずexprが評価されます。それは与えられたvarと同数の値を 返さなければなりません。続いて各値がvarに順に束縛されます。 section 10.6 srfi-11 - Let-valuesも参照してください。
    (define-values (lo hi) (min&max 3 -1 15 2))
    
    lo => -1
    hi => 15
    

    Special Form: define-constant variable expression
    Special Form: define-constant (variable . formals) body ...
    defineと同じように動作しますが、 コンパイラはvariableの値が今後変更されないものとして 最適化されたコードを生成します。

    variableの値をset!で変更しようとするとエラーとなります。 variableを再定義することは許されますが、警告が表示されます。

    Special Form: define-in-module module variable expression
    Special Form: define-in-module module (variable . formals) body ...
    この形式はvariableのグローバルな束縛をmodule中に作成します。 moduleはモジュール名を表すシンボルか、モジュールオブジェクトで なければなりません。moduleがシンボルの場合、その名前を持つ モジュールが既に存在している必要があります。

    expressionは現在のモジュール中で評価されます。

    2番目の形式は次の形式の構文的修飾です。

    (define-in-module module variable (lambda formals body ...))
    

    4.11 モジュール

    この章では、GaucheのモジュールのセマンティクスとAPIを述べます。 Gaucheで使われているモジュールの書法についてはsection 3.5 Gaucheのモジュールを書くも 併せて参照して下さい。

    4.11.1 モジュールのセマンティクス

    モジュールは、シンボルを束縛へとマップするオブジェクトで、 グローバル変数の解決に影響を与えます。

    CommonLispのパッケージは名前からシンボルへのマッピングを行いますが、 Gaucheでは同じ名前を持つシンボルは常にeq?です。しかし、 Gaucheのシンボルは「値」のスロットを持っていません。 モジュールによってシンボルに対応する束縛が見付けられ、値はそこに 格納されています。 モジュールが違えば同じシンボルは別々の束縛へとマップされ、違う値を 返します。

    ;; 二つのモジュールAとBを作成し、グローバル変数'x'をその中で定義
    (define-module A (define x 3))
    (define-module B (define x 4))
    
    ;;  #<symbol 'x'> ---[module A]--> #<binding that has 3>
    (with-module A x) => 3
    
    ;;  #<symbol 'x'> ---[module B]--> #<binding that has 4>
    (with-module B x) => 4
    

    モジュールは、自身が持つ一部または全ての束縛を他のモジュールからも 使えるようにexportすることができます。モジュールが他の モジュールをimportすると、それらのモジュールでexportされている 束縛が元もモジュールから見えるようになります。 モジュールはいくつでも他のモジュールをimportすることができます。

    (define-module A
      (export pi)
      (define pi 3.1416))
    
    (define-module B
      (export e)
      (define e 2.71828))
    
    (define-module C
      (import A B))
    
    (select-module C)
    (* pi e) => 8.539748448
    

    また、モジュールは継承することもできます。 既存のモジュールを継承したモジュールに新しい束縛を足してexportすることにより、 既存のモジュールを拡張することができます。新しいモジュールの内部からは、 継承元のモジュールの束縛が(exportされていないものも含め)全て見えます。 (新しく作られるモジュールはデフォルトでgaucheモジュールを継承しています。 新しいモジュールからgaucheの組込み手続き等が使えるのはそのためです)。 外からは、新しいモジュールには元のモジュールの全てのexportされた束縛と 新たに追加されexportされた束縛が見えます。

    ;; Module A defines and exports deg->rad.
    ;; A binding of pi is not exported.
    (define-module A
      (export deg->rad)
      (define pi 3.1416)   ;; not exported
      (define (deg->rad deg) (* deg (/ pi 180))))
    
    ;; Module Aprime defines and exports rad->deg.
    ;; The binding of pi is visible from inside Aprime.
    (define-module Aprime
      (extend A)
      (export rad->deg)
      (define (rad->deg rad) (* rad (/ 180 pi))))
    
    ;; Module C imports Aprime.
    (define-module C
      (import Aprime)
      ;; Here, both deg->rad and rad->deg are visible,
      ;; but pi is not visible.
      )
    

    コンパイル中のどの時点でも、「カレントモジュール」が一意に決定され、 グローバル変数の束縛はそのカレントモジュールを起点に探されます。 その変数の束縛が見付かれば、変数参照の式はその束縛へアクセスするコードとして コンパイルされます。もしコンパイラが束縛を見付けられなかった場合、 変数参照の式はカレントモジュールでマークされ、束縛の解決はランタイムへと 先送りされます。すなわち、ランタイムにその変数が使われる時点で 再びマークされていたモジュールから束縛の探索が行われます (ランタイムでのカレントモジュールからでは無いことに注意)。 束縛が見付かれば、束縛へアクセスするコードがコンパイルされたコード列に 挿入されます。見付からなければ'undefined variable'エラーが報告されます。

    グローバル変数に対して適切な束縛がひとたび発見されれば、 その束縛へのアクセスはコンパイルされたコードに埋め込まれ、 その変数の束縛の探索は二度と行われません。

    definedefine-syntax等の定義を行う特殊形式は カレントモジュールに束縛を挿入します。これは、importしたり継承したりしている モジュールの同名の束縛をシャドウします。

    グローバル変数の束縛の解決は次の手順で行われます。 まずカレントモジュールが探されます。次に、importしているモジュールが importの順番に並べられ、それぞれについてそのモジュールおよびそのモジュールの先祖 (継承されているモジュール)が順に探されます。 importは遷移的ではありません;importされたモジュールがimportしているモジュール… というふうに再帰的に辿ることはしません。 最後に、カレントモジュールの先祖が順に探されます。

    4.11.2 モジュールの定義と選択

    Special Form: define-module name body ...
    nameはシンボルでなければなりません。 名前nameを持つモジュールが存在しなければまず作成します。 それから、body ... をモジュールname中で評価します。

    Special Form: select-module name
    名前nameを持つモジュールをカレントモジュールとします。 その名前を持つモジュールが無ければエラーとなります。

    select-moduleがSchemeファイルの中で用いられた場合、 その効果はそのファイルの終了までに限られます。select-moduleを中で呼んでいる ファイルをloadやrequireしても、呼んだ側のカレントモジュールは影響を受けません。

    Special Form: with-module name body ...
    名前nameを持つモジュールをカレントモジュールとした状態でbody ... を順に評価し、最後の結果を返します。該当するモジュールが存在しなければエラーとなります。

    Special Form: current-module
    コンパイル時点でのカレントモジュールに評価されます。 これは手続きではなく特殊形式です。 Gaucheではモジュールはコンパイル時に静的に決定されます。
    (define-module foo
      (export get-current-module)
      (define (get-current-module) (module-name (current-module))))
    
    (define-module bar
      (import foo)
      (get-current-module)) => foo ; not bar
    

    4.11.3 モジュールの使用

    Special Form: export symbol ...
    カレントモジュールの中で、シンボルsymbolに対応する束縛をexportします。 exportされた束縛は、カレントモジュールをimportしたモジュール中で見えるようになります。

    Special Form: export-all
    カレントモジュール中の全ての束縛をexportします。

    Special Form: import module-name ...
    名前module-nameを持つモジュールがexportしている束縛を カレントモジュール中で使えるようにします。該当するモジュールが既に定義されて いなければなりません。

    モジュールのimportは遷移的でないことに注意してください。 module-nameで指定されるモジュール内でimportしているモジュールは、 カレントモジュールにはimportされません。 これはモジュールのモジュラリティを保つために必要です; 例えば、ライブラリモジュールは内部で使用するためにいくつも他のモジュールを importするかもしれませんが、それがそのライブラリモジュールを使用するモジュールの 名前空間に影響することはないわけです。

    Macro: use name
    モジュールのインポートとオンデマンドのファイルのロードを合わせて行う、 便利なマクロです。基本的に、(use foo) は以下のふたつのフォームと 等価です。
    (require "foo")
    (import foo)
    

    すなわち、まず名前"foo"を持つライブラリファイルが(まだロードされて いなければ)ロードされ、その中で定義されているモジュールfooをカレントモジュールに インポートします。

    ファイルのロードとモジュールとは直交する概念ですが、 現実にはモジュール毎にファイルを分割するのが便利です。 必ずしもそうする必要は無く、requireimport を別々に 使っても構いません。が、Gaucheに附属してくるライブラリはすべて、 use マクロで使えるように書かれています。

    もしモジュールが一つのファイルに収めるには大きすぎる場合、一つのメインファイルと いくつかのサブファイルに分けることも出来ます。メインファイルの中でモジュールを 定義し、サブファイルをまとめてロードするか、オートロードを設定します。

    もしnameがピリオド`.'を含んでいる場合、requireするファイル名 ではそれが`/'に置換されます。例えば(use foo.bar.baz)

    (require "foo/bar/baz")
    (import foo.bar.baz)
    

    となります。これはあまりScheme風ではありませんが、便利ではあります。 (別の設計方針として、Gaucheでは採用していませんが、 例えばGuileで用いられているような、シンボルのリストを 階層的なモジュールに使用することも考えられます。)

    4.11.4 モジュールの継承

    export-importメカニズムは、次のような場合をうまく処理できません。

    このような場合にモジュールの継承が使えます。

    Macro: extend module-name ...
    カレントモジュールが、module-name ...に挙げられたモジュールを 継承するようにします。それまでの継承の情報は捨てられ、module-name ... から計算される継承情報が有効になります。

    新たに作られるモジュールはデフォルトでgaucheモジュールを継承しています。 例えばそのモジュールに(extend scheme)というフォームを入れた場合、 その時点でそのモジュールはschemeモジュール(R5RSで定義された束縛 のみを含む)を直接継承するようになります。したがって、そのフォームの後で 'import' やその他gauche特有の束縛はそのモジュール内では 使えなくなります。

    module-nameに挙げられたモジュールがまだ存在しなかった場合、 extenduseと同じメカニズムを使ってファイルをロードすることを 試みます。

    モジュールは複数のモジュールを継承することができます。 丁度、クラスが複数のクラスを継承できるのと同じようにです。 多重継承の場合、次のようにしてモジュール間の優先順位が決められます。

    各モジュールはmodule precedence listというモジュールのリストを 持っています。そこにリストされた順に束縛が探されます。 モジュールが複数のモジュールを多重継承した場合、継承される各モジュールの module precedence listを、次に挙げる制約を満たすようにマージ したものが新たなmodule precedence listとなります: (1) あるmodule precedence listでモジュールAがモジュールBより前に現れていたら、 結果のmodule precedence listでもAはBより前に現れる: (2) モジュールAがモジュールBよりextendフォームで前に現れていたら、 結果のmodule precedence listでもAはBより前に現れる。 この条件を満たすようなmodule precedence listが構成できない場合はエラーとなります。

    例えばあなたがライブラリを3つのモジュール、 mylib.basemylib.utilmylib.systemに分けて 書いたとしましょう。次のように書けば、これらのモジュールを 一つのmylibモジュールに見せることができます。

    (define-module mylib
      (extend mylib.system mylib.util mylib.base))
    

    このライブラリモジュールのユーザは (use mylib) とするだけで 全てのサブモジュールのexportされた束縛を利用することができるようになります。

    4.11.5 モジュールイントロスペクション

    Builtin Class: <module>
    モジュールクラスです。

    Function: module? obj
    objがモジュールなら真の値を返します。

    Function: find-module name
    名前がシンボルnameであるようなモジュールを返します。 その名前をもつモジュールが存在しなければ、#fを返します。

    Function: all-modules
    現在存在する全てのモジュールのリストを返します。

    Function: module-name module
    Function: module-imports module
    Function: module-exports module
    Function: module-table module
    モジュールオブジェクトのアクセスメソッドです。 moduleの名前(シンボル)、moduleがインポートしているモジュールのリスト、 エクスポートしているシンボルのリスト、そして シンボルから束縛へのマップを行うハッシュテーブルを返します。

    もしmoduleが全てのシンボルをエクスポートしている場合は、module-exports#tを返します。

    モジュールオブジェクト以外が渡された場合はエラーになります。

    Function: module-parents module
    Function: module-precedence-list module
    モジュールの継承に関する情報を返します。 module-parentsmoduleが直接継承しているモジュールのリストを 返します。module-precedence-listmoduleのmodule precedence list (section 4.11.4 モジュールの継承参照) を返します。

    4.11.6 組み込みモジュール

    Gauche起動時にいくつかのモジュールがあらかじめ定義されています。

    Builtin Module: null
    このモジュールはR5RSで述べられている"null environment"に相当します。 R5RSの構文要素への束縛だけを含んだモジュールです。 (但し現在の実装では一つだけ例外があります:Gaucheが内部処理に必要とするために、 構文with-moduleがこのモジュールに含まれています。 将来これは除かれます。)

    Builtin Module: scheme
    このモジュールはnullモジュール内の束縛全てに加えて、 R5RSで定義されている全ての手続きの束縛を含みます。

    Builtin Module: gauche
    このモジュールはschemeモジュール内の全ての束縛に加え、 Gaucheの組込み手続きや構文が含まれています。

    Builtin Module: user
    このモジュールはユーザコードがコンパイルされる既定のモジュールです。 gaucheモジュール内の全ての束縛がインポートされています。

    5. マクロ

    Gaucheでは、R5RSに定義される「健全な(hygienic)」マクロと 伝統的なマクロの両方が使えます。

    Lisp系言語のマクロは、他の言語に見られるマクロ(例えばCプリプロセッサマクロ)とは 大きく異なります。Lispのマクロは元の言語の構文を拡張する手段なのです。 例えば、Gaucheの構文を若干変えることで他のScheme実装用に書かれたSchemeプログラムを 走らせたり、あるいは自分の問題解決に適した「ミニ言語」をデザインすることさえできます。

    5.1 健全なマクロ

    R5RSの健全なマクロは特別なパターン言語に基づいていて、 また「変数捕捉」が起こらないことが保証されています。 「変数捕捉」とは、マクロが新しい変数束縛を導入した時に、その束縛が マクロに渡されたフォーム中の変数名と衝突して、その変数名の本来の束縛を隠して しまうことを言います。

    Special Form: define-syntax name transformer-spec
    [R5RS]

    Special Form: let-syntax ((name transformer-spec) ...) body
    Special Form: letrec-syntax ((name transformer-spec) ...) body
    [R5RS]

    Special Form: syntax-rules literals clause1 clause2 ...
    [R5RS]

    5.2 伝統的なマクロ

    Special Form: define-macro name procedure
    Special Form: define-macro (name formals) body ...
    Defines name to be a global macro whose transformer is procedure. The second form is a shorthand notation of the following form:
    (define-macro name (lambda formals body ...))
    

    When a form (name arg ...) is seen by the compiler, it calls procedure with arg .... When procedure returns, the compiler inserts the returned form in place of the original form, and compile it again.

    5.3 マクロの展開

    Function: macroexpand form
    Function: macroexpand-1 form
    If form is a list and its first element is a variable globally bound to a macro, macroexpand-1 invokes its macro transformer and returns the expanded form. Otherwise, returns form as is.

    macroexpand repeats macroexpand-1 until the form can't be expanded.

    These procedures can be used to expand globally defined macros.

    Special Form: %macroexpand form
    Special Form: %macroexpand-1 form

    5.4 マクロユーティリティ

    Macro: syntax-error msg arg ...
    Macro: syntax-errorf fmt arg ...
    Signal an error. They are same as error and errorf (See section 6.16.1 エラーの通知), except that the error is signalled at macro-expansion time (i.e. compile time) rather than run time.

    They are useful to tell the user the wrong usage of macro in the comprehensive way, instead of the cryptic error from the macro expander. Because of the purpose, arg ... are first passed to unwrap-syntax described below, to strip off the internal syntactic binding informations.

    (define-syntax my-macro
      (syntax-rules ()
        ((_ a b)   (foo2 a b))
        ((_ a b c) (foo3 a b c))
        ((_ . ?)
         (syntax-error "malformed my-macro" (my-macro . ?)))))
    
    (my-macro 1 2 3 4)
      => error: "malformed my-macro: (mymacro 1 2 3 4)"
    

    Function: unwrap-syntax form
    Removes internal syntactic information from form. In order to implement a hygienic macro, macro expander replaces symbols in the macro form for identifiers, which captures the syntactic environment where they are defined. Although it is necessary information for the compiler, it is rather confusing for users if it appears in the messages. This function replaces occurrences of identifiers in form to the original symbols.

    6. 組み込みライブラリ

    6.1 等価

    Schemeには等価性を判定する汎用的な述語が3つあります。 また、これらの他に、いくつかの型はその型同士で使える比較手続きを持っています。

    Function: eq? obj1 obj2
    [R5RS] 最も高速で、細かい区別ができる述語です。 obj1obj2がアロケートされる同じ型のオブジェクトで、 かつ両者がメモリ上の全く同じ場所を占めるオブジェクトを指している場合に #tを返します。また、obj1obj2がともに #f, #tあるいは()である場合も#tを返します。 ポインタ比較と考えても良いでしょう。 obj1obj2がともに文字、あるいは数値であった場合の振るまいは Schemeの標準では定められていません。
    (eq? #t #t)               => #t
    (eq? #t #f)               => #f
    (eq? 'a 'a)               => #t
    (eq? 'a 'b)               => #f
    (eq? (list 'a) (list 'a)) => #f
    (let ((x (list 'a)))
      (eq? x x))              => #t
    

    Function: eqv? obj1 obj2
    [R5RS] obj1obj2がともに正確な数値、もしくはともに不正確な数値である場合、 (= obj1 obj2)が真であれば#tが、偽であれば#fが 返されます。 obj1obj2がともに文字である場合、 (char=? obj1 obj2)が真であれば#tが、偽であれば#fが 返されます。 それ以外の場合は、Gaucheではeqv?eq?と同じです。
    (eqv? #\a #\a)             => #t
    (eqv? #\a #\b)             => #f
    (eqv? 1.0 1.0)             => #t
    (eqv? 1 1)                 => #t
    (eqv? 1 1.0)               => #f
    (eqv? (list 'a) (list 'a)) => #f
    (let ((x (list 'a)))
      (eqv? x x))              => #t
    

    Function: equal? obj1 obj2
    [R5RS+] obj1obj2がリストやベクタなどの複合型である場合、 equal?は再帰的に対応する要素同士をequal?で比較してゆきます。 そうでなければ、equal?eqv?と同じようにふるまいます。

    もしobj1obj2が論理値、数値、文字、ペア、文字列、 ベクタのいずれでもなく、かつ両者のクラスが等しい場合、equal?は ジェネリックファンクションobject-equal?を呼びます。 object-equal?にメソッドを定義することにより、 ユーザ定義のデータ型に対するequal?の振るまいを拡張することができます。

    (equal? (list 1 2) (list 1 2)) => #t
    (equal? "abc" "abc")           => #t
    (equal? 100 100)               => #t
    (equal? 100 100.0)             => #f
    

    Generic Function: object-equal? obj1 obj2
    equal?が未知のオブジェクトに対して呼ばれた場合、 このジェネリックファンクションが呼ばれます。自分で定義したクラスに対して このメソッドを定義することにより、equal?で等価判定が行えるように なります。メソッドは、obj1obj2が等価ならば#tを、 そうでなければ#fを返さねばなりません。 オブジェクトの各要素に対して再帰的に等価判定を行いたい場合は、 object-equal?を直接呼ぶのではなく、equal?を各要素に対して 呼ぶようにして下さい。
    (define-class <foo> ()
      ((x :init-keyword :x)
       (y :init-keyword :y)))
    
    (define-method object-equal? ((a <foo>) (b <foo>))
      (and (equal? (slot-ref a 'x) (slot-ref b 'x))
           (equal? (slot-ref a 'y) (slot-ref b 'y))))
    
    (equal? (make <foo> :x 1 :y (list 'a 'b))
            (make <foo> :x 1 :y (list 'a 'b)))
      => #t
    
    (equal? (make <foo> :x 1 :y (make <foo> :x 3 :y 4))
            (make <foo> :x 1 :y (make <foo> :x 3 :y 4)))
      => #t
    

    しばしば、ふたつの複合型オブジェクトに関して、両者がトポロジー的に等しいこと、 すなわち一方が共有する部分構造を持っている場合にもう一方も同じように部分構造を 共有しているかどうかを調べたいことがあります。equal?はその目的には 使えません。モジュールutil.isomorphの提供するisomorphic?が その目的に使えます。(section 11.21 util.isomorph - 同型判定参照)。

    6.2 数値

    Gaucheは次のタイプの数値をサポートしています。

    多倍長の正確な整数
    メモリの許す限りの精度が扱えます。
    浮動少数点の不正確な実数
    実装に使われるC言語のdouble型で表現されます。通常IEEE 64bit浮動少数点数です。
    浮動少数点の不正確な複素数
    実部と虚部はそれぞれ浮動少数点の不正確な実数で表現されます。

    6.2.1 数値クラス

    Builtin Class: <number>
    Builtin Class: <complex>
    Builtin Class: <real>
    Builtin Class: <integer>
    数値オブジェクトのクラス階層を構成します。<complex><number>を継承し、<real><complex>を継承し、 <integer><real>を継承します。

    これらのクラスはR5RSで定義されている数値の階層とは必ずしも対応しません。 特に、<integer>クラスのインスタンスはR5RSでいうexact integerのみになります。

    (integer? 1)        => #t
    (is-a? 1 <integer>) => #t
    (is-a? 1 <real>)    => #t
    
    (integer? 1.0)        => #t
    (is-a? 1.0 <integer>) => #f
    (is-a? 1.0 <real>)    => #t
    
    (class-of (expt 2 100)) => #<class <integer>>
    (class-of (sqrt -3)) => #<class <complex>>
    

    6.2.2 数値に関する述語

    Function: number? obj
    Function: complex? obj
    Function: real? obj
    Function: rational? obj
    Function: integer? obj
    [R5RS] objがそれぞれ数、複素数、実数、有理数、整数ならば#tを返します。 Gaucheでは、数の集合は複素数の集合と同一であり、有理数の集合は整数の集合と同一です。
    (complex? 3+4i)   => #t
    (complex? 3)      => #t
    (real? 3)         => #t
    (real? -2.5+0.0i) => #t
    (real? #e1e10)    => #t
    (integer? 3+0i)   => #t
    (integer? 3.0)    => #t
    

    Function: exact? obj
    Function: inexact? obj
    [R5RS] objがそれぞれ正確な数、不正確な数ならば#tを返します。
    (exact? 1)       => #t
    (exact? 1.0)     => #f
    (inexact? 1)     => #f
    (inexact? 1.0)   => #t
    
    (exact? (modulo 5 3)) => #t
    (inexact? (modulo 5 3.0)) => #f
    

    Function: zero? z
    [R5RS] 数値zがゼロに等しければ#tを返します。
    (zero? 1)        => #f
    (zero? 0)        => #t
    (zero? 0.0)      => #t
    (zero? 0.0+0.0i) => #t
    

    Function: positive? x
    Function: negative? x
    [R5RS] 実数xがそれぞれ正または負なら#tを返します。 非実数を渡すとエラーになります。

    Function: odd? n
    Function: even? n
    [R5RS] 整数nがそれぞれ奇数または偶数なら#tを返します。 非整数を渡すとエラーになります。
    (odd? 3)     => #t
    (even? 3)    => #f
    (odd? 3.0)   => #t
    

    Function: fixnum? n
    Function: bignum? n
    nが正確な整数で、かつ内部的にそれぞれfixnumもしくはbignum で表現されているときに#tを返します。 通常のSchemeプログラムは整数の内部表現を気にする必要はありません。 これらの手続きは、ある種の最適化を行う低レベル手続きのために用意されています。

    6.2.3 数値の比較

    Function: = z1 z2 z3 ...
    [R5RS] 与えられた全ての数値zが等しければ#tを返します。
    (= 2 2)          => #t
    (= 2 3)          => #f
    (= 2 2.0)        => #t
    (= 2 2.0 2.0+0i) => #t
    

    Function: < x1 x2 x3 ...
    Function: <= x1 x2 x3 ...
    Function: > x1 x2 x3 ...
    Function: >= x1 x2 x3 ...
    [R5RS] 与えられた全ての実数xがそれぞれ単調増加、単調非減少、単調減少、単調非増加している 場合に#tを返します。

    Function: max x1 x2 ...
    Function: min x1 x2 ...
    [R5RS] 与えられた実数のうち、それぞれ最大と最小のものを返します。

    Function: min&max x1 x2 ...
    与えられた実数から、最大値と最小値の二つの値を返します。

    6.2.4 数値の演算

    Function: + z ...
    Function: * z ...
    [R5RS] 与えられた数の和と積をそれぞれ返します。引数が与えられない場合、 (+) は 0、 (*) は 1 となります。

    Function: - z1 z2 ...
    Function: / z1 z2 ...
    [R5RS] 一つだけ数値が与えられた場合、それぞれnegationと逆数を返します。

    2つ以上の数値が与えられた場合、それぞれ次の結果を返します。

    z1 - z2 - z3 ...
    z1 / z2 / z3 ...
    
    (- 3)       => -3
    (- -3.0)    => 3.0
    (- 5+2i)    => -5.0-2.0i
    (/ 3)       => 0.333333333333333
    (/ 5+2i)    => 0.172413793103448-0.0689655172413793i
    
    (- 5 2 1)     => 2
    (- 5 2.0 1)   => 2.0
    (- 5+3i -i)   => 5.0+2.0i
    (/ 6+2i 2)    => 3.0+1.0i
    

    Function: abs z
    [R5RS+] 実数のzに対しては、その絶対値を返します。 複素数のzに対しては、そのmagnitudeを返します。 複素数を扱うのはGaucheの拡張です。
    (abs -1)   => 1
    (abs -1.0) => 1.0
    (abs 1+i)  => 1.4142135623731
    

    Function: quotient n1 n2
    Function: remainder n1 n2
    Function: modulo n1 n2
    [R5RS] 整数n1を整数n2で割った商(quotient)および余り(remainder, modulo) を返します。 n1n2の両方が正確な数値の時のみ、戻り値は正確な数値になります。

    remaindermodulo はどちらかの引数が負の時に異なる値を返します。 Remainder R と商 Q とは次の関係があります。

      n1 = Q * n2 + R
    

    ここで商について abs(Q) = floor(abs(n1)/abs(n2)) ですから、Rの符号は常にn1と同じになります。

    一方、moduloはn2が正の時はn1の符号に関わらず期待したように動作します (例: (modulo -1 n2) == n2 - 1)。 n2が負の場合は次の式によって正の場合にマップできます。

      modulo(n1, n2) = -modulo(-n1, -n2)
    

    したがって、moduloの結果の符号は常にn2の符号と同じになります。

    (remainder 10 3)    => 1
    (modulo 10 3)       => 1
    
    (remainder -10 3)   => -1
    (modulo -10 3)      => 2
    
    (remainder 10 -3)   => 1
    (modulo 10 -3)      => -2
    
    (remainder -10 -3)  => -1
    (modulo -10 -3)     => -1
    

    Function: quotient&remainder n1 n2
    整数n1を整数n2で割った商(quotient)および余り(remainder) を同時に計算し、2つの値として返します。

    Function: gcd n ...
    Function: lcm n ...
    [R5RS] 与えられた整数の、最大公約数と最小公倍数をそれぞれ返します。

    Function: numerator q
    Function: denominator q
    [R5RS] 有理数qの分子と分母をそれぞれ返します。Gaucheでは今のところ有理数を完全には サポートしていないため、これらの手続きは実際には整数にしか使えません。すなわち、 整数qに対してnumeratorは常にqを返し、denominator は常に1を返します。

    Function: floor x
    Function: ceiling x
    Function: truncate x
    Function: round x
    [R5RS] 引数xは実数でなければなりません。floorceilingはそれぞれ xを越えない最大の整数と、xを下回らない最小の整数を返します。 truncatexの小数部をゼロの方向に向かって切捨てた整数を返します。 roundxに最も近い(四捨五入した)整数を返します。xの 小数部が0.5ぴったりだった場合はroundは最も近い偶数を返します。

    Function: clamp x &optional min max
     min if x < min
     x   if min <= x <= max
     max if max < x
    

    を返します。もしminまたはmaxが省略されるか#fが与えられたら、 それぞれ -∞ もしくは +∞ と解釈されます。 与えられた全ての数値が正確な整数の場合に限り正確な整数を返します。

    (clamp 3.1 0.0 1.0) => 1.0
    (clamp 0.5 0.0 1.0) => 0.5
    (clamp -0.3 0.0 1.0) => 0.0
    (clamp -5 0)        => 0
    (clamp 3724 #f 256) => 256
    

    Function: exp z
    Function: log z
    Function: sin z
    Function: cos z
    Function: tan z
    Function: asin z
    Function: acos z
    Function: atan z
    [R5RS] 超越関数です。複素数も扱えます。

    Function: atan x y
    [R5RS] 実数xyに対してatan(y/x)を返します。

    Function: sinh z
    Function: cosh z
    Function: tanh z
    Function: asinh z
    Function: acosh z
    Function: atanh z
    双曲線関数です。複素数も扱えます。

    Function: sqrt z
    [R5RS] 複素数zの平方根のひとつを返します。枝刈りの定義はCommon Lispと同じです。 実数に対しては正の平方根を返します。

    Function: expt z1 z2
    [R5RS] 複素数z1, z2に対して、 z1^z2 (z1z2乗)を返します。

    6.2.5 数値の変換

    Function: make-rectangular x1 x2
    Function: make-polar x1 x2
    [R5RS] 二つの実数x1x2から複素数を作ります。 make-rectangularx1 + ix2 を返します。 make-polarx1e^(ix2) を返します。

    Function: real-part z
    Function: imag-part z
    Function: magnitude z
    Function: angle z
    [R5RS] 複素数zを取り、実数を返します。 real-partimag-partzの実数部と虚数部をそれぞれ返し、 magnitudeanglezの絶対値と偏角をそれぞれ返します。

    Function: decode-float x
    与えられた浮動小数点数(不正確な実数)xに対して、 3つの正確な整数からなるベクタ #(m, e, sign) を返します。ここで、
      x = (* sign m (expt 2.0 e))
      sign は 1, 0 または -1.
    

    です。このAPIはChezSchemeから取られました。

    (decode-float 3.1415926)
     => #(7074237631354954 -51 1)
    (* 7074237631354954 (expt 2.0 -51))
     => 3.1415926
    

    Function: fmod x y
    Function: modf x
    Function: frexp x
    Function: ldexp x n
    [POSIX] これらの手続きは、浮動少数点数を分解したり合成するのに使えます。 fmodは実数xを実数yで割った余りを返します。すなわち、 x/yを0に近いほうの整数に丸めた値をnとするとき、 x-n*yを返します。 modfxの少数部と整数部を返します。 frexpは実数xを、仮数部と指数部に分解して返します。すなわち、 x = fraction * 2^exponent かつ 0 <= fraction <= 0.5 であるところのfractionexponentを返します。 ldexpfrexpの逆関数で、x * 2^n を返します。
    (fmod 32.1 10.0)  => 2.1
    (fmod 1.5 1.4)    => 0.1
    (modf 12.5)       => 0.5 and 12.0
    (frexp 3.14)      => 0.785 and 2
    (ldexp 0.785 2)   => 3.14
    

    Function: exact->inexact z
    Function: inexact->exact z
    [R5RS] 正確な数を不正確な数に変換、またその逆を行う手続きです。

    Gaucheは一般的な有理数をサポートしないため、inexact->exactの結果は 常に整数となります。整数でない数を渡した場合は小数点以下が丸められます。但しこれは 実装依存の振舞いなので、ポータブルなプログラムで不正確な実数を正確な整数に丸めたい 時にはinexact->exactの前に明示的にroundを使うべきでしょう。

    不正確な数をexact->inexactに渡したり、または正確な数を inexact->exactに渡した場合、Gaucheでは今のところエラーにならず 引数がそのまま返されます。これも実装依存の振舞いなのでなるべく避けるようにして下さい。

    Function: number->string z &optional radix use-upper?
    Function: string->number string &optional radix
    [R5RS+] これらの手続きは数値とそれをradix進数で表現する文字列とを変換します。 radixは2から36の間でなければなりません。省略された場合は10進数とみなされます。

    number->stringは数値zを取り文字列を返します。 zが正確な整数以外の場合、radixは10でなければなりません。 10より大きいradixに関しては、小文字のアルファベットが桁として使われます。 但し、省略可能な引数use-upper?に真の値が与えられた場合は大文字のアルファベットが 使われます。use-upper?引数はGaucheの拡張です。

    string->numberは文字列stringを取り数値を返します。 不正確な数値は10進数表記しか認識されません。与えられた文字列が数値を構成しない 場合は#fが返されます。

    Generic Function: x->number obj
    Generic Function: x->integer obj
    数値への強制型変換手続きです。 objをそれぞれ数値もしくは正確な整数と解釈して返します。 数値と文字列に対してのメソッドは定義されています (文字列はstring->numberを使って変換されます。 数値として解釈できない文字列に関しては0が返されます)。 その他のobjについては単に0が返されます。 x->integerは、objが数値として表現できるけれど正確な整数では ない場合、roundinexact->exactによって正確な整数に変換します。

    他のクラスはこのメソッドを定義することにより、独自の変換関数を提供することができます。

    6.2.6 ビット演算

    これらの手続きは整数を半無限のビットベクタとして扱います。 正の整数の場合、数値の左側に無限に0が続いていると見倣されます。 負の整数の場合、数値は2の補数で表現され、左側に無限に1が続いていると見倣されます。

    APIはSLIBの"logical"モジュールに合わせてあります。

    Function: ash n count
    整数nを左に整数countビットだけシフトします。 countが負であれば、-countだけnを右にシフトします。
    ; Note: 6  == [...00110], and
    ;       -6 == [...11010]
    (ash 6 2)   => 24  ;[...0011000]
    (ash 6 -2)  => 1   ;[...0000001]
    (ash -6 2)  => -24 ;[...1101000]
    (ash -6 -2) => -2  ;[...1111110]
    

    Function: logand n1 n2 ...
    Function: logior n1 n2 ...
    Function: logxor n1 n2 ...
    2つ以上の整数n1, n2 ...の、それぞれ論理和、論理積、 排他的論理積を返します。

    Function: lognot n
    整数nのビット否定を返します。

    Function: logtest n1 n2 ...
    == (not (zero? (logand n1 n2 ...)))

    Function: logbit? index n
    整数nindex目のビットが1ならば#tを、0ならば#fを 返します。

    Function: bit-field n start end
    整数nstart+1ビット目からendビット目(両端含む)までを 取り出した数値を返します。start < end でなければなりません。

    Function: copy-bit index n bit
    bitが真の値なら、整数nindexビット目をセットした数値を 返します。 bitが偽の値なら、整数nindexビット目をリセットした数値を 返します。

    Function: copy-bit-field n start end from

    Function: logcount n

    Function: integer-length n

    6.3 論理値

    Builtin Class: <boolean>
    論理値のクラスです。#t#fのみがこのクラスのインスタンスです。

    Function: not obj
    [R5RS] obj#fの時のみ#tを返し、それ以外の場合は#fを 返します。

    Function: boolean? obj
    [R5RS] objが論理値である場合に#tを返します。

    6.4 ペアとリスト

    6.4.1 pairクラスとnullクラス

    Builtin Class: <list>
    リストを表す抽象クラスで、クラス<null>とクラス<pair>の親クラスです。 クラス<sequence>を継承します。

    循環リストやドットリストも<list>クラスのインスタンスですが、 list?は偽の値を返すことに注意して下さい。

    (use srfi-1)
    (list? (circular-list 1 2)) => #f
    (is-a? (circular-list 1 2) <list>) => #t
    

    Builtin Class: <null>
    空リストのクラスです。()がこのクラスの唯一のインスタンスです。

    Builtin Class: <pair>
    ペアのクラスです。

    6.4.2 リストに関する述語

    Function: pair? obj
    [R5RS] objがペアなら#tを、そうでなければ#fを返します。

    Function: null? obj
    [R5RS] objが空リストなら#tを、そうでなければ#fを返します。

    Function: list? obj
    [R5RS] objが正しいリストなら#tを、そうでなければ#fを返します。 この手続きはobjがドットリストや循環リストなら#fを返します。

    SRFI-1(section 10.2.2 リストに関する述語)には更に、 proper-list?circular-list?dotted-list? といった手続きが定義されています。

    6.4.3 リストの作成

    Function: cons obj1 obj2
    [R5RS] obj1obj2のペアを作成します。
    (cons 'a 'b) => (a . b)
    

    Function: acons obj1 obj2 obj3
    (cons (cons obj1 obj2) obj3) を返します。 連想リストの先頭に新しいエントリを加えるのに便利です。
    (acons 'a 'b '((c . d))) => ((a . b) (c . d))
    

    Function: make-list len &optional fill
    [SRFI-1] 長さlenの正規のリストを返します。引数fillが与えられていれば、各要素は fillになります。そうでなければ各要素の値は不定です。
    (make-list 5 #t) => (#t #t #t #t #t)
    

    Function: list obj ...
    [R5RS] 要素がobj ...であるリストを作成します。
    (list 1 2 3) => (1 2 3)
    (list) => ()
    

    Function: list* obj1 obj2 ...
    listとほぼ同じですが、最後の引数が作成されるリストの最後のペアのcdrになります。 SRFI-1ではこの手続きがcons*という名で定義されています。
    (list* 1 2 3) => (1 2 . 3)
    (list* 1) => 1
    

    Function: list-copy list
    [SRFI-1] listの浅いコピーを行います。 listが循環リストの場合、この手続きは停止しません。

    6.4.4 リストへのアクセスと変更

    Function: car pair
    Function: cdr pair
    [R5RS] それぞれpairのcarとcdrを返します。

    Function: set-car! pair obj
    Function: set-cdr! pair obj
    [R5RS] pairのcarもしくはcdrをobjで置き換えます。

    注: (setter car) == set-car! であり、 (setter cdr) == set-cdr! です。

    Function: caar pair
    Function: cadr pair
    ...
    Function: cdddar pair
    Function: cddddr pair
    [R5RS] caar == (car (car x)), cadr == (car (cdr x)), 等々。

    対応するsetterも定義されています。

    (let ((x (list 1 2 3 4 5)))
      (set! (caddr x) -1)
      x)
      => (1 2 -1 4 5)
    

    Function: length list
    [R5RS] 正規のリストlistの長さを返します。 listがドットリストならばエラーが起きます。 listが循環リストの場合、この関数は無限ループします。

    循環リストも取り扱う場合は、SRFI-1のlength+を使って下さい (section 10.2.4 List miscellaneous routines参照)。

    Function: list-tail list k
    [R5RS] listk番目のcdrを返します。listは 正規のリストでもドットリストでも循環リストでも構いません。

    Function: list-ref list k &optional fallback
    [R5RS+] listk番目の要素を返します。listは 正規のリストでもドットリストでも循環リストでも構いません。

    もしkがリストの長さを超えていたり、負数であった場合は通常はエラーが起こります。 しかし、オプショナルな引数fallbackが与えられていた場合は、エラーは起きず fallbackが返されます。これはGaucheの拡張です。

    Function: last-pair list
    [SRFI-1] listの最後のペアを返します。listは 正規のリストかドットリストです。

    6.4.5 他のリスト手続き

    Function: append list ...
    [R5RS] 渡されたリストの要素を繋げたリストを返します。最後の引数の部分以外は新しいセルがアロケート されて使われます。最後の引数は正規のリストである必要がありません。その場合、結果は正規でない リストとなります。

    Function: append! list ...
    [SRFI-1] 渡されたリストの要素を繋げたリストを返します。最後の引数以外のリストのセルは、結果を 作成するために再利用されるかもしれません。 最後の引数は正規のリストである必要はありません。

    Function: reverse list
    [R5RS] listの各要素を逆順に持つリストを新しく作成して返します。

    Function: reverse! list
    [SRFI-1] listの各要素を逆順に持つリストを返します。結果を作成するために、 listのセルは再利用されるかもしれません。

    Function: memq obj list
    Function: memv obj list
    Function: member obj list
    [R5RS] listからobjを探します。もしlistn番目の要素が objと同一ならば、(list-tail list n)を返します。 memqは同一性の判定にeq?を、memveqv?を、 memberequal?を使います。 objlist中に見つからなければ#fが返されます。

    SRFI-1 (section 10.2 srfi-1 - List library) を使うと、memberは オプショナルな同一性判定手続きを取るように拡張されます。

    (memq 'a '(a b c))          => (a b c)
    (memq 'b '(a b c))          =>  (b c)
    (memq 'a '(b c d))          => #f
    (memq (list 'a) '(b (a) c)) => #f
    (memv 101 '(100 101 102))   => (101 102)
    

    Function: assq obj list
    Function: assv obj list
    Function: assoc obj list
    [R5RS] listの各要素はペアでなければなりません。 これらの手続きは、listの要素であるペアのうち、そのcarが objと一致するペアを左から探して行きます。もし見付かればそのペアが、 見付からなければ#fが返されます。 assqは比較関数にeq?を、assveqv?を、 assocequal?をそれぞれ用います。

    SRFI-1 (section 10.2 srfi-1 - List library) を使うと、assocは オプショナルな同一性判定手続きを取るように拡張されます。

    6.5 シンボル

    Builtin Class: <symbol>
    シンボルを表すクラスです。

    Gaucheでは、全てのシンボルはintern、すなわち内部のテーブルに登録されています。 そのため、同じ外部表記を持つシンボルは常にeq?です。

    Reader Syntax: |name|
    R5RSのシンボルの定義では許されていない文字を使った妙な名前のシンボルを表記するのに 使う構文です。インタプリタが大文字小文字を区別しないモードで走っている場合は、 大文字を含むシンボルを表記するときにも使えます (section 2.3 大文字小文字の区別参照)。

    この表記はCommonLispから取られました。いくつかのSchemeでも同様の表記を採用しています。

    Function: symbol? obj
    [R5RS] objがシンボルなら#tを返します。
    (symbol? 'abc)     => #t
    (symbol? 0)        => #f
    (symbol? 'i)       => #t
    (symbol? '-i)      => #f
    (symbol? '|-i|)    => #t
    

    Function: symbol->string symbol
    [R5RS] symbolの名前を文字列で返します。返される文字列は変更不可です。
    (symbol->string 'foo) => foo
    

    Function: string->symbol string
    [R5RS] 文字列stringを名前に持つシンボルを返します。
    (string->symbol "a") => a
    (string->symbol "A") => A
    (string->symbol "weird symbol name" => |weird symbol name|
    

    Function: gensym &optional prefix

    6.6 キーワード

    Builtin Class: <keyword>
    A keyword is a sort of a special symbol that is automatically quoted. It is extensively used in pass-by-name arguments (keyword arguments), and keyword-value list Unlike CommonLisp, keywords and symbols are distinct types.

    See also let-keywords* macro (section 6.15.1.3 省略可能引数のパージング) for keyword argument processing.

    Reader syntax: :name
    Read to a keyword whose name is name. (Note that the preceding ':' is not a part of the keyword's name.)

    Function: keyword? obj
    Returns #t iff obj is a keyword.

    Function: make-keyword name
    Returns a keyword whose name is name.

    Function: keyword->string keyword
    Returns the name of the keyword keyword.

    Function: get-keyword key list &optional fallback
    A useful procedure to extract a value from key-value list. A key-value list list must contains even number of elements; the first, third, fifth ... elements are regarded as keys, and the second, fourth, sixth ... elements are the values of the preceding keys.

    This procedure looks for key from the keys, and if it finds one, it returns the corresponding value. If there are more than one matching keys, the leftmost one is taken. If there is no matching key, it returns fallback if provided, or signals an error otherwise.

    It is an error if list is not a proper, even-number element list.

    Actually, `keywords' in the keyword-value list and the key argument need not be a keyword--it can be any Scheme object. Key comparison is done by eq?.

    This procedure is taken from STk.

    Macro: get-keyword* key list &optional fallback
    Like get-keyword, but fallback is evaluated only if list does not have key.

    6.7 Identifier

    Builtin Class: <identifier>

    Function: identifier? obj

    Function: identifier->symbol identiifer

    6.8 文字

    Builtin Class: <char>

    Reader Syntax: #\charname
    [R5RS] リテラルの文字オブジェクトを表現します。

    リーダーは#\に出会うと、まず次の文字を読み込みます。それが文字 ()[]{}" \|;# のいずれかならば、その文字自身となります。 そうでなければ、単語を構成しない文字に出会うまで文字が続けて読み込まれます。 もし一文字しか読まれなければ、その文字自身となります。そうでなければ その単語が文字の名前として解釈されます。 それが有効な文字の名前でなければエラーとなります。

    以下の文字の名前が認識されます。これらの文字の名前は大文字小文字を区別しません。

    space
    スペース (ASCII #x20)
    newline, nl, lf
    改行文字 (ASCII #x0a)
    return, cr
    復帰文字 (ASCII #x0d)
    tab, ht
    水平タブ (ASCII #x09)
    page
    フォームフィード、改ページ (ASCII #x0c)
    escape, esc
    エスケープ (ASCII #x1b)
    delete, del
    デリート (ASCII #x7f)
    null
    NUL文字 (ASCII #x00)
    xN
    N が16進表記の整数であるとき、内部エンコーディングが整数N であるような文字。この表記はASCII文字の範囲の外では、内部エンコーディングが異なる 処理系間で互換性が無いことに注意して下さい。
    uN
    Nが4桁または8桁の16進数整数であるとき、UCSコードNであるような文字。 Gaucheの内部エンコーディングがUTF-8以外でコンパイルされている場合には、 リーダーはgauche.charconvモジュールを使ってUnicodeを内部エンコーディングへと 変換します。Unicodeの該当する文字が内部エンコーディングで定義されていない場合、 代替文字に置換されるか、エラーとなります。
    #\newline => #\newline ; 改行文字
    #\x0a     => #\newline ; 改行文字
    #\x41     => #\A       ; ASCII文字 'A'
    #\u0041   => #\A       ; ASCII文字 'A', UCSコード
    #\u3042   => #\あ      ; 平仮名「あ」, UCSコード
    #\u0002a6b2 => ; JISX0213 2-94-86 UCS4コード
    

    プログラムテキストがGaucheの内部エンコーディングと同じエンコーディングで 書かれていれば、マルチバイト文字を直接表記することもできます。

    #\あ => ; 文字「あ」
    

    Function: char? obj
    [R5RS] objが文字なら#tを、そうでなければ#fを返します。

    Function: char=? char1 char2
    Function: char<? char1 char2
    Function: char<=? char1 char2
    Function: char>? char1 char2
    Function: char>=? char1 char2
    [R5RS] 文字を比較します。比較は内部の文字エンコーディングで行われます。

    Function: char-ci=? char1 char2
    Function: char-ci<? char1 char2
    Function: char-ci<=? char1 char2
    Function: char-ci>? char1 char2
    Function: char-ci>=? char1 char2
    [R5RS] 文字を、大文字小文字を区別せずに比較します。 現在のバージョンではASCII文字の範囲外における大文字小文字の扱いが きちんと定義されていないことに注意して下さい。

    Function: char-alphabetic? char
    Function: char-numeric? char
    Function: char-whitespace? char
    Function: char-upper-case? char
    Function: char-lower-case? char
    [R5RS] 文字charがそれぞれ英字([A-Za-z])、数字([0-9])、 空白文字、大文字および小文字の時に真の値を返します。 今のところ、これらの手続きはASCII文字のみで動作します。 それ以外の文字に対しては#fが返されます。

    Function: char->integer char
    Function: integer->char n
    [R5RS] char->integerは文字charの内部エンコーディングに対応する 整数値を返します。integer->charは数値nと内部エンコーディングが 同じ文字を返します。有効な文字charに対して以下の式は常に真となります。
    (eq? char (integer->char (char->integer char)))
    

    対応する内部エンコーディングを持つ文字が無い数値をinteger->charに渡した 場合の結果は不定です。

    Function: char->ucs char
    Function: ucs->char n
    それぞれ、文字charをUCSコードポイントを表す整数へ変換し、 またUCSコードポイントを表す整数nを文字へと変換する手続きです。

    Gaucheの内部文字エンコーディングがUTF-8でコンパイルされている場合は、 これらの手続きはそれぞれchar->integerおよびinteger->char と等価です。

    Gaucheの内部文字エンコーディングがUTF-8でない場合、 これらの手続きはgauche.charconvモジュールを使って 内部文字コードとUCSとの変換を行います (section 9.2 gauche.charconv - 文字コード変換参照)。 charが対応するUCSコードを持っていない場合、char->ucs#fを 返します。UCSコードnに対応する文字が内部エンコーディングで定義されていない 場合、変換ルーチンが代替文字を提供していればそれを、そうでなければ#f が返されます。

    Function: char-upcase char
    Function: char-downcase char
    [R5RS] charの大文字と小文字をそれぞれ返します。charに大文字小文字の区別が 無ければcharがそのまま返されます。

    現在のバージョンではASCII文字の範囲外における大文字小文字の扱いが きちんと定義されていないことに注意して下さい。

    Function: digit->integer char &optional (radix 10)
    文字charradix進数の数字を構成するのに有効な文字であれば、 対応する整数が、そうでなければ#fが返されます。
    (digit->integer #\4) => 4
    (digit->integer #\e 16) => 14
    (digit->integer #\9 8) => #f
    

    Common Lispには同様の手続きがdigit-char-pというやや曖昧な名で定義されています。

    Function: integer->digit integer &optional (radix 10)
    digit->integerの逆です。整数integerradix進数 ひと桁で 表現するのに使われる文字を返します。integerがひと桁で表現できない数値の場合は #fが返されます。
    (integer->digit 13 16) => #\d
    (integer->digit 10) => #f
    

    Common Lispのdigit-charに当たります。

    Function: gauche-character-encoding
    コンパイル時に選択された内部文字エンコーディングを表すシンボルを返します。 返される値は以下のいずれかです。
    euc-jp
    EUC-JP
    utf-8
    UTF-8
    sjis
    Shift JIS
    none
    No multibyte character support (8-bit fixed-length character).

    Function: supported-character-encodings
    Returns a list of string names of character encoding schemes that are supported in the native multibyte encoding scheme.

    6.9 文字集合

    Builtin Class: <char-set>
    文字の集合を取り扱う、文字集合(キャラクタセット)のクラスです。 Gaucheは文字集合オブジェクトのサポートと、 ある文字がその集合に属するかどうかを調べる手続きを言語組み込みで持っています。

    文字集合に関する他の操作、例えば集合演算などは、SRFI-14モジュール (section 10.8 srfi-14 - Character-set library参照) で提供されています。

    Reader Syntax: #[char-set-spec]
    この構文で、リテラル文字集合を記述することができます。 char-set-specには集合に含める文字を列挙します。 次の特殊なシーケンスを含めることができます。
    x-y
    文字xと文字yの間の文字全て。xyも含みます。 xyよりも内部文字コードで比較して小さくなければなりません。
    ^
    カレットがchar-set-specの最初に来た場合、以降に示される文字集合の 補集合がこの文字集合となります。
    \xNN
    内部文字コードNN(16進数表記)の文字。
    \uNNNN
    UnicodeのUCS-2でNNNN(16進数表記4桁)の文字。
    \UNNNNNNNN
    UnicodeのUCS-4でNNNNNNNN(16進数表記8桁)の文字。
    \s
    空白文字。
    \S
    空白でない文字。(\sの補集合)
    \d
    10進数の数字
    \D
    \dの補集合
    \w
    アルファベットと数字
    \W
    \wの補集合
    \\
    バックスラッシュ文字
    \-
    マイナス文字
    \^
    カレット文字
    [:alnum:] ...
    POSIX流文字集合表記。以下の文字集合名が認識されます: alnum, alpha, blank, cntrl, digit, graph, lower, print, punct, space, upper, xdigit
    #[aeiou]     ; 母音文字'a', 'e', 'i', 'o', 'u'の集合
    #[a-zA-Z]    ; アルファベット
    #[[:alpha:]] ; アルファベット (POSIX表記)
    #[\x0d\x0a]  ; 改行とリターン
    #[\\\-]      ; バックスラッシュとマイナス文字
    #[]          ; 空の文字集合
    #[ぁ-ん]     ; 平仮名の集合
    

    Function: char-set? obj
    [SRFI-14] objが文字集合であれば真の値を返します。

    Function: char-set-contains? char-set char
    [SRFI-14] 文字集合char-setが文字charを含んでいれば真の値を返します。
    (char-set-contains? #[a-z] #\y) => #t
    (char-set-contains? #[a-z] #\3) => #f
    
    (char-set-contains? #[^ABC] #\A) => #f
    (char-set-contains? #[^ABC] #\D) => #t
    
    (char-set-contains? #[あ-お] #\う) => #t
    (char-set-contains? #[あ-お] #\ぷ) => #f
    

    Function: char-set char ...
    [SRFI-14] 文字char ... からなる文字集合を作成して返します。
    (char-set #\a #\b #\c)   => #[a-c]
    (char-set #\あ #\い #\う) => #[あいう]
    

    Function: char-set-copy char-set
    [SRFI-14] char-setのコピーを作って返します。

    6.10 文字列

    Builtin Class: <string>
    文字列のクラスです。Gaucheでは、文字列は文字のシーケンスともバイトのシーケンスとも みなすことができます。

    R5RSに定義されている文字列操作は非常に限られています。 Gaucheでは追加の組込み手続きのほか、 SRFI-13に定義されている豊富な文字列ライブラリを備えています。 SRFI-13についてはsection 10.7 srfi-13 - String libraryを参照してください。

    6.10.1 文字列の表記

    Reader syntax: "..."
    [R5RS+] リテラル文字列です。ダブルクオートの中では、 以下のエスケープシーケンスが認識されます。
    \"
    [R5RS] ダブルクオート文字
    \\
    [R5RS] バックスラッシュ文字
    \n
    改行文字 (ASCII 0x0a)
    \r
    復帰文字 (ASCII 0x0d)
    \f
    フォームフィード (ASCII 0x0c)
    \t
    タブ文字 (ASCII 0x09)
    \0
    NUL文字 (ASCII 0x00)
    \xNN
    2桁の16進数NNで指定されるバイト。 このバイトは内部エンコーディングによって解釈されます。
    \uNNNN
    4桁の16進数NNNNによって示されるUCS2コードを持つ文字。
    \UNNNNNNNN
    8桁の16進数NNNNNNNNによって示されるUCS4コードを持つ文字。

    GaucheがUTF-8以外の内部エンコーディングでコンパイルされていた場合、 リーダーはgauche.charconvモジュールを使って エスケープシーケンス\uNNNN\UNNNNNNNNの解釈を行います。

    Reader syntax: #*"..."
    不完全な文字列のリテラル表記です。完全な文字列と同様のエスケープシーケンスが 使えます。

    註:以前は、不完全な文字列のリテラル表記には#"..."という構文が使われていました。 Gauche 0.6.3から構文は#*"..."に変更されました。 以前の構文もしばらくは認識されますが、いずれサポートされなくなります。 その後、文字列の補間機能が#"..."構文を使うようになります。

    '#*' という構文はCommon Lispでビットベクタの表記に使われています。 不完全な文字列は実際はバイトベクタであることから、類似点を認めてこの構文を 採用しました。(もし将来必要になってビットベクタが実装されたとしても、 この構文と共存できます)。

    6.10.2 文字列に関する述語

    Function: string? obj
    [R5RS] objが文字列なら#tを、そうでなければ#fを返します。

    Function: string-immutable? obj
    objが変更不可な文字列なら#tを、そうでなければ#fを返します。

    Function: string-incomplete? obj
    Returns #t if obj is an incomplete string, #f otherwise

    6.10.3 文字列の作成

    Function: make-string k &optional char
    [R5RS] 長さkの文字列を作成して返します。 charが与えられればそれで内容を満たします。charが与えられなければ 空白文字で満たされます。常に完全な文字列が返されます。
    (make-string 5 #\x) => "xxxxx"
    (make-string 5 #\ふ) => "ふふふふふ"
    

    make-stringで必要な長さの文字列をアロケートして、string-set! で順番に埋めて行くアルゴリズムは、Gaucheでは極めて非効率であることに 注意してください。そのようなアルゴリズムは、文字列の内部表現とアロケーションメカニズムに 関して不必要な仮定を置いており、Gaucheはその仮定とは合致しません。 文字列の順次作成に適しているのは文字列ポートです (section 6.18.4 文字列ポート参照)。それが使えない場合、 文字のリストを作成し、list->stringで変換する方がまだmake-stringstring-set!を使うより良いでしょう。

    Function: string char ...
    [R5RS] 文字char ... から構成された文字列を返します。

    Generic Function: x->string obj
    文字列への強制型変換手続きです。 objの文字列表現を返します。 デフォルトのメソッドでは、文字列はそのまま返され、数値はnumber->stringで、 シンボルはsymbol->stringで変換され、その他のオブジェクトはdisplay表現 が使われます。

    他のクラスはこのメソッドを定義することにより、独自の変換関数を提供することができます。

    6.10.4 文字列の補間

    「文字列の補間(string interpolation)」という用語は、 PerlやPythonなど様々なスクリプト言語で、文字列リテラル内に式を埋め込んでおき 実行時に式を評価した値をそのリテラル内に埋め込む機能を指します。

    Schemeはそのような機能を定義していませんが、Gaucheではリーダーマクロを使って 文字列の補間を実装しました。

    Reader syntax: #`string-literal
    文字列に評価されます。string-literal内に、,expr というシーケンス(ここでexprは有効なScheme式の外部表現)が 現われたら、exprが評価されてその結果がもとの位置に埋め込まれます。 結果の文字列化にはx->stringが使われます(section 6.10.3 文字列の作成参照)。

    コンマと続く式とは、空白文字等を入れずに隣接していなければなりません。 そうでない場合は置換されません。

    二つの連続するコンマは一つのリテラルのコンマ文字に置き換えられます。 これによって、コンマと非空白文字の連続をstring-literalに入れることができます。

    それ以外のstring-literal内の文字シーケンスはそのままコピーされます。

    Exprに単独の変数を使う場合で、それに続く文字列と変数名を区切りたい 場合は、`|'文字を使ったシンボルエスケープ構文が使えます。下の例の最後の 2つを見て下さい。

    #`"This is Gauche, version ,(gauche-version)."
     => "This is Gauche, version 0.6.5."
    
    #`"Date: ,(sys-strftime \"%Y/%m/%d\" (sys-localtime (sys-time)))"
     => "Date: 2002/02/18"
    
    (let ((a "AAA")
          (b "BBB"))
     #`"xxx ,a ,b zzz")
     => "xxx AAA BBB zzz"
    
    #`"123,,456,,789"
     => "123,456,789"
    
    (let ((n 5)) #`"R,|n|RS")
     => "R5RS"
    
    (let ((x "bar")) #`"foo,|x|.")
     => "foobar"
    

    実は、リーダーはこの構文をマクロ呼び出しへと変換し、それが最終的には string-appendへの呼び出しへと変換されます。

    #`"This is Gauche, version ,(gauche-version)."
     ==
    (string-append "This is Gauche, version "
                   (x->string (gauche-version))
                   ".")
    

    この構文を採用した理由: 他のスクリプト言語では、`$expr' や '#{...}' が良く使われています。 準クオート (section 4.9 準クオート(Quasiquote)参照) との類似性からこの構文を採用しました。 変数名の区切りを明確にするのに`|'を使う必要があるのは少々奇妙ですが、 慣れたSchemeプログラマならコンマ構文を読むのは他の言語から借りた構文よりも 楽だと思います。

    Schemeは他のスクリプト言語より一般的により多くの文字を変数名に使うことが出来ることに注意して下さい。 結果として、変数の値を文字列に挿入する際、ほとんどの場合において変数名を`|'で区切る 必要があるでしょう。例えば、Perlでは "$year/$month/$day $hour:$minutes:$seconds" と書けたものが、Gaucheでは #`",|year|/,|month|/,day ,|hour|:,|minutes|:,seconds" と書かねばなりません。 混乱を避けるためには、この構文内では常に直接の変数参照は`|'で区切るようにしておくのが良いかもしれません。

    6.10.5 文字列のアクセスと変更

    Function: string-length string
    [R5RS] 文字列stringの長さ(文字数)を返します。 stringは不完全な文字列であっても構いません。

    Function: string-size string
    文字列stringの大きさを返します。文字列の大きさは、 stringが占めるメモリ上のバイト数で、これは文字列の内部エンコーディングに 依存します。同じ文字列であっても内部エンコーディングが違えば違う大きさになる場合も あります。

    不完全な文字列では、文字列の長さと大きさは常に一致します。

    Function: string-ref cstring k &optional fallback
    [R5RS+] 完全な文字列cstringk番目の文字を返します。 不完全な文字列を渡すのはエラーです。

    kが負数であったりcstringの長さと同じかそれ以上であった場合には エラーが報告されます。但し、引数fallbackが与えられている場合にはエラーを 報告せずfallbackが返されます。これはGaucheの拡張です。

    Function: string-byte-ref string k
    Returns k-th byte of a (possibly incomplete) string string. Returned value is an integer in the range between 0 and 255. k must be greater than or equal to zero, and less than (string-size string).

    Function: string-set! string k char
    [R5RS] Substitute string's k-th character by char. k must be greater than or equal to zero, and less than (string-length string). Return value is undefined.

    If string is an incomplete string, integer value of the lower 8 bits of char is used to set string's k-th byte.

    See the notes in make-string about performance consideration.

    Function: string-byte-set! string k byte
    Substitute string's k-th byte by integer byte. byte must be in the range between 0 to 255, inclusive. k must be greater than or equal to zero, and less than (string-size string). If string is a complete string, it is turned to incomplete string by this operation. Return value is undefined.

    6.10.6 文字列の比較

    Function: string=? string1 string2
    Function: string-ci=? string1 string2
    [R5RS]

    Function: string<? string1 string2
    Function: string<=? string1 string2
    Function: string>? string1 string2
    Function: string>=? string1 string2
    Function: string-ci<? string1 string2
    Function: string-ci<=? string1 string2
    Function: string-ci>? string1 string2
    Function: string-ci>=? string1 string2
    [R5RS]

    6.10.7 文字列を扱うその他の手続き

    Function: substring string start end
    [R5RS]

    Function: string-append string ...
    [R5RS]

    Function: string->list string &optional start end
    Function: list->string list
    [R5RS+][SRFI-13]

    Function: string-copy string &optional start end
    [R5RS+][SRFI-13]

    Function: string-fill! string char &optional start end
    [R5RS+][SRFI-13] Fills string by char. Optional start and end limits the effective area.
    (string-fill! "orange" #\X)
      => "XXXXXX"
    (string-fill! "orange" #\X 2 4)
      => "orXXge"
    

    Function: string-join strs &optional delim grammer
    [SRFI-13] Concatenate strings in the list strs, with a string delim as `glue'.

    The argument grammer may be one of the following symbol to specify how the strings are concatenated.

    infix
    Use delim between each string. This mode is default. Note that this mode introduce ambiguity when strs is an empty string or a list with a null string.
    (string-join '("apple" "mango" "banana") ", ") 
      => "apple, mango, banana"
    (string-join '() ":")
      => ""
    (string-join '("") ":")
      => ""
    
    strict-infix
    Works like infix, but empty list is not allowed to strs, thus avoiding ambiguity.
    prefix
    Use delim before each string.
    (string-join '("usr" "local" "bin") "/" 'prefix)
      => "/usr/local/bin"
    (string-join '() "/" 'prefix)
      => ""
    (string-join '("") "/" 'prefix)
      => "/"
    
    suffix
    Use delim after each string.
    (string-join '("a" "b" "c") "&" 'suffix)
      => "a&b&c&"
    (string-join '() "&" 'suffix)
      => ""
    (string-join '("") "&" 'suffix)
      => "&"
    

    Function: string-scan string item &optional return
    Scan item (either a string or a character) in string. The return argument specifies what value should be returned when item is found in string. It must be one of the following symbols.
    index
    Returns the index in string if item is found, or #f. This is the default behavior.
    (string-scan "abracadabra" "ada") => 5
    (string-scan "abracadabra" #\c) => 4
    (string-scan "abracadabra" "aba") => #f
    
    before
    Returns a substring of string before item, or #f if item is not found.
    (string-scan "abracadabra" "ada" 'before) => "abrac"
    (string-scan "abracadabra" #\c 'before) => "abra"
    
    after
    Returns a substring of string after item, or #f if item is not found.
    (string-scan "abracadabra" "ada" 'after) => "bra"
    (string-scan "abracadabra" #\c 'after) => "adabra"
    
    before*
    Returns a substring of string before item, and the substring after it. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'before*)
      => "abrac" and "adabra"
    (string-scan "abracadabra" #\c 'before*)
      => "abra" and "cadabra"
    
    after*
    Returns a substring of string up to the end of item, and the rest. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'after*)
      => "abracada" and "bra"
    (string-scan "abracadabra" #\c 'after*)
      => "abrac" and "adabra"
    
    both
    Returns a substring of string before item and after item. If item is not found, returns (values #f #f).
    (string-scan "abracadabra" "ada" 'both)
      => "abrac" and "bra"
    (string-scan "abracadabra" #\c 'both)
      => "abra" and "adabra"
    

    Function: string-split s char

    6.10.8 文字列ポインタ

    Builtin Class: <string-pointer>
    String pointer is an object to access string efficiently in sequential order (either forward or backward).

    Higher level string iterators and accessors are constructed on top of this primitive. See section 10.7 srfi-13 - String library, for details. It is highly recommended to use SRFI-13 functions instead of these string pointer objects, for portability.

    Function: make-string-pointer str &optional (index 0)
    Creates a string pointer that points to the index-th character of string str.

    Function: string-pointer-copy sp
    Copies a string pointer. The resulting string pointer shares the same string as sp, but has distinct pointer.

    Function: string-pointer? obj
    Returns #t iff obj is a string pointer.

    Function: string-pointer-next! sp
    Function: string-pointer-prev! sp

    Function: string-pointer-set! sp index

    Function: string-pointer-substring sp &keyword (after #f)

    Function: string-pointer-index sp
    Function: string-pointer-byte-index sp

    6.10.9 Incomplete strings

    Function: string-complete->incomplete str

    Function: string-incomplete->complete str

    6.11 正規表現

    Builtin Class: <regexp>
    正規表現オブジェクトのクラスです。string->regexpを使って実行時に 作成できます。また、Gaucheはリテラルの正規表現を表す構文を持っており、 ロード時に作成することもできます。

    Gaucheの正規表現エンジンはマルチバイト文字列に対応しています。

    Builtin Class: <regmatch>
    正規表現マッチオブジェクトのクラスです。正規表現エンジンrxmatchは、 一致した場合にこのオブジェクトを返します。部分一致の情報を含めた 全てのマッチに関する情報がこのオブジェクトに含まれています。

    一致した部分文字列やそのインデックスのリストではなく マッチオブジェクトを返すことの利点は効率です。 regmatchオブジェクトはマッチの内部状態を保持しており、 要求された時にはじめて該当する部分文字列やインデックスを計算します。 これは特にマルチバイト文字列に有効です。マルチバイト文字列 へのインデックスアクセスは遅いからです。

    Reader Syntax: #/regexp-spec/
    Reader Syntax: #/regexp-spec/i
    リテラルの正規表現オブジェクトを表記します。読まれた際に<regexp>の インスタンスとなります。

    末尾に文字iが与えられた場合は、マッチ時に大文字小文字を区別しない 正規表現オブジェクトとなります。(現在のバージョンでは、大文字小文字の 同一視はASCII文字のみに対して行われます。それ以外の文字は通常の方法でマッチします)。

    string->regexpに対してこの構文を使う利点は、 正規表現のコンパイルが一度しか行われない点です。この構文は、 内部ループの中でも、正規表現のコンパイルのオーバヘッドを気にせずに 使うことができます。動的に正規表現を作成したい場合のみstring->regexpを 使って下さい。

    認識される構文はPOSIX拡張正規表現のサブセットに、Perlの拡張の一部を 採り入れたものです。具体的には以下の構文がサポートされます。

    • *+?による繰り返しの指定。
    • ()によるグルーピング。括弧の前にバックスラッシュは不要です。
    • |による選択。
    • []による文字クラス。文字集合リテラル (section 6.9 文字集合参照) で認識される 表記が全て有効です。
    • 文字列の先頭^、および末尾$へのマッチ。
    • いくつかの特定の文字クラスの略記。 数字\d、数字の補集合\D、アルファベットと数字\w、 その補集合\W、空白文字\s、その補集合\Sが使えます。 これらは通常のコンテクストでも、文字クラス[]の中でも使えます。

    以下の機能はサポートされていません。

    • [=e=][.ll.]のような、コレーティングエレメント。
    • 単語の先頭/終了へのマッチ。
    • {m,n}のような、回数を指定した繰り返し。
    • 部分一致へのバックリファレンス。

    これらのサポートされていない機能のうち、最初の3つはいずれサポートする予定です。 但し、バックリファレンスに関してはおそらくサポートしないでしょう。 バックリファレンスを使わなければならないということは、 その対象は正規文法では表現できないということです。 それならばより複雑なクラスの文法を扱うのに適したツールを使うべきであって、 無理矢理正規表現を使おうとするのは良くありません。

    Function: string->regexp string &keyword case-fold
    文字列stringを正規表現とみなして、<regexp>のインスタンスを 作成して返します。

    キーワード引数case-foldに真の値が与えられた場合、作成される正規表現は 大文字小文字を区別しないものとなります。 (大文字小文字を区別しない正規表現に関しては上の説明を参照して下さい)。

    Function: regexp? obj
    objが正規表現オブジェクトなら真の値を返します。

    Function: regexp->string regexp
    正規表現regexpを記述する元になった文字列を返します。 返される文字列は変更不可な文字列です。

    Function: rxmatch regexp string
    正規表現オブジェクトregexpに一致するものを文字列stringから 探します。一致が見付かった場合は<regmatch>オブジェクトを返し、 見付からなかった場合は#fを返します。

    他のScheme処理系ではこれは matchregexp-searchstring-matchなど 様々な名で呼ばれています。

    Generic application: regexp string
    正規表現オブジェクトは直接文字列に対して適用することもできます。 これは(rxmatch regexp string)と同じ動作をしますが、 表記が短くて済みます。この機能はsection 6.15.2 適用可能なオブジェクト で述べているメカニズムを 使って実装されています。

    Function: rxmatch-start match &optional (i 0)
    Function: rxmatch-end match &optional (i 0)
    Function: rxmatch-substring match &optional (i 0)
    rxmatchが返すマッチオブジェクトmatchから情報を取り出します。 iが省略されるか0の場合、これらの手続きはそれぞれ一致した 文字列の開始インデックス、終了インデックス、および一致した部分文字列を 返します。iに正の整数が与えられた場合は、i番目のサブマッチ に関する情報を返します。iにそれ以外の値を与えるのはエラーです。

    簡便のために、match#fを渡すことも許されています。 その場合、これらの手続きは#fを返します。

    これらの手続きはScshでmatch:startmatch:endmatch:substringと呼ばれているものと等価です。

    Function: rxmatch-after match &optional (i 0)
    Function: rxmatch-before match &optional (i 0)
    マッチオブジェクトmatchの前および後の文字列を返します。 正の整数がiに与えられた場合はi番目のサブマッチの前および後の 文字列を返します。
    (define match (rxmatch #/(\d+)\.(\d+)/ "pi=3.14..."))
    
    (rxmatch-after match) => "..."
    (rxmatch-after match 1) => ".14..."
    
    (rxmatch-before match) => "pi="
    (rxmatch-before match 2) => "pi=3."
    

    Generic application: regmatch &optional index
    Generic application: regmatch 'before &optional index
    Generic application: regmatch 'after &optional index
    マッチオブジェクトは直接整数のインデックスもしくはシンボルbeforeまたは afterに対して適用することができます。 それぞれ(rxmatch-substring regmatch index)(rxmatch-before regmatch)、および (rxmatch-after regmatch)と同じ動作をしますが、 表記が短くて済みます。 この機能はsection 6.15.2 適用可能なオブジェクト で述べているメカニズムを使って実装されています。
    (define match (#/(\d+)\.(\d+)/ "pi=3.14..."))
    
    (match)           => "3.14"
    (match 1)         => "3"
    (match 2)         => "14"
    
    (match 'after)    => "..."
    (match 'after 1)  => ".14..."
    
    (match 'before)   => "pi="
    (match 'before 2) => "pi=3."
    

    また、section 9.15 gauche.regexp - 正規表現ユーティリティには、正規表現検索に便利な マクロや手続きが定義されています。参照して下さい。

    6.12 ベクター

    Builtin Class: <vector>
    ベクタはSchemeオブジェクトの単純な一次元配列です。 インデックスを用いて定数時間でその要素にアクセスできます。 一度作成されたベクタはその大きさを変えることはできません。

    <vector>クラスはまた<sequence>クラスを継承し、 mapfoldなど様々な総称関数を使うことができます。 section 9.3 gauche.collection - コレクションフレームワーク と section 9.18 gauche.sequence - シーケンスフレームワーク を参照して下さい。

    数値しか要素に持たないベクタを使う場合、SRFI-4の 単一型ベクタも使えるかもしれません (section 10.4 srfi-4 - 単一型のベクタ参照)。

    Function: vector? obj
    [R5RS] objがベクタなら#tを、そうでなければ#fを返します。

    Function: make-vector k &optional fill
    [R5RS] 長さkのベクタを作成して返します。 省略可能な引数fillが与えられていれば、ベクタの各要素はその値で 初期化されます。そうでなければベクタの各要素の値は不定です。

    Function: vector obj ...
    [R5RS] 要素がobj ...であるようなベクタを作成して返します。

    Function: vector-length vector
    [R5RS] ベクタvectorの長さを返します。

    gauche.collectionモジュールをロードしていれば、 メソッドsize-ofも同じ目的で使えます。

    Function: vector-ref vector k &optional fallback
    [R5RS+] ベクタvectork番目の要素を返します。

    vector-refkが負の値であったりベクタの長さより 大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback が与えられている場合はその値が返されます。これはGaucheの拡張です。

    gauche.sequenceモジュールをロードしていれば、 メソッドrefも同じ目的で使えます。

    Function: vector-set! vector k obj
    [R5RS] ベクタvectork番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。

    gauche.sequenceモジュールをロードしていれば、 メソッドrefのsetterメソッドも使えます。

    Function: vector->list vector &optional start end
    Function: list->vector list
    [R5RS+] ベクタをリストに変換したり、その逆を行う手続きです。

    vector->listに省略可能な引数startendを与えることにより、 値を取り出す範囲を制限することができます。

    (vector->list '#(1 2 3 4 5))     => (1 2 3 4 5)
    (list->vector '(1 2 3 4 5))      => #(1 2 3 4 5)
    (vector->list '#(1 2 3 4 5) 2 4) => (3 4)
    

    gauche.collectionモジュールをロードしていれば、 (coerce-to <list> vector)(coerce-to <vector> list) も同じ目的で使えます。

    Function: vector-fill! vector fill &optional start end
    [R5RS+] ベクタvectorの全ての要素をfillに変更します。

    省略可能な引数startendが与えられた場合、 start番目の要素からend-1番目の要素までのみに fillを格納します。startendの既定値は それぞれ0とvectorの大きさです。 start, end引数はGaucheの拡張です。

    Function: vector-copy vector &optional start end
    ベクタvectorをコピーします。引数startendを与えることで コピーされる範囲を制限することができます。
    (vector-copy '#(1 2 3 4 5))     => #(1 2 3 4 5)
    (vector-copy '#(1 2 3 4 5) 2 4) => #(3 4)
    

    6.13 ハッシュテーブル

    Builtin Class: <hash-table>
    ハッシュテーブルのクラスです。

    Function: make-hash-table &optional type
    ハッシュテーブルを作成します。シンボルtypeはテーブルのタイプを指定します。 現在、以下のようなタイプがサポートされています。
    eq?
    キーの比較にeq?を使います。
    eqv?
    キーの比較にeqv?を使います。
    equal?
    キーの比較にequal?を使います。
    string=?
    キーの比較にstring=?を使います。キーは文字列でなければなりません。

    typeが省略された場合はeq?とみなされます。

    Function: hash-table? obj
    objがハッシュテーブルであれば#tを返します。

    Function: hash-table-get hash key &optional default
    キーkeyをハッシュテーブルhashから探します。見つかればキーに対応する 値を返します。キーが見つからなかった場合、defaultが与えられていればそれを 返し、そうでなければエラーを報告します。

    Function: hash-table-put! hash key value
    キーkeyと対応する値valueをハッシュテーブルhashに挿入します。

    Function: hash-table-exists? hash key
    ハッシュテーブルhashにキーkeyを持つエントリがあれば#tを返します。

    Function: hash-table-delete! hash key
    ハッシュテーブルhashからキーkeyを持つエントリを削除します。 keyを持つエントリが実際に存在して削除された場合は#tを、 エントリが存在しなかった場合は#fを返します。 この手続きはSTkでhash-table-remove!と呼ばれているものです (STkのは戻り値が定義されていませんが)。GaucheではSRFI-1, SRFI-13やその他の ライブラリとの一貫性のために `delete' を採用しました。

    Function: hash-table-push! hash key value
    ハッシュテーブルhash中の、キーkeyに対応する値にvalueをコンスし、 それをkeyに対する新たな値とします。もしkeyに対応する値がまだ無ければ、 新たなエントリが作成され、(list value)がその値となります。

    この手続きは次のコードと同じ動作をしますが、キーの探索が一度しか行われないためより高速です。

    (hash-table-put! hash key
        (cons value (hash-table-get hash key '())))
    

    Function: hash-table-pop! hash key &optional default
    ハッシュテーブルhash中のキーkeyに対応する値が存在し、かつペアで あった場合に、そのエントリーを元の値のcdrで置き換え、元の値のcarを返します。 keyに対応する値が存在しないかペアではなかった場合、テーブルは変更されず、 defaultが与えられていればそれが返され、与えられていなければエラーが報告されます。

    値が置き換えれる場合でもキーの探索は一度しか行われないため効率が良いです。

    Function: hash-table-for-each hash proc
    Function: hash-table-map hash proc
    ハッシュテーブルhash内の全てのエントリについて、各エントリのキーと値を 2つの引数として手続きprocを呼びます。

    Function: hash-table-keys hash
    Function: hash-table-values hash
    それぞれ、ハッシュテーブルhash内の全てのキーまたは値をリストにして返します。

    6.14 Weak pointer

    Weak pointerとは、それが参照しているオブジェクトがガベージコレクトされることを 許すようなポインタです。 Gaucheはweak vectorオブジェクトによってweak pointerの機能を提供します。 Weak vectorは通常のベクタに似ていますが、要素のオブジェクトがweak vector以外から 参照されていない場合、オブジェクトはガベージコレクトされ、weak vectorの該当するエントリは #fで置き換えられます。

    gosh> (define v (make-weak-vector 1))
    v
    gosh> (weak-vector-ref v 0)
    #f
    gosh> (weak-vector-set! v 0 (cons 1 1))
    #<undef>
    gosh> (weak-vector-ref v 0)
    (1 . 1)
    gosh> (gc)
    #<undef>
    gosh> (gc)
    #<undef>
    gosh> (weak-vector-ref v 0)
    #f
    

    Builtin Class: <weak-vector>
    Weak vectorのクラスです。<sequence><collection>を継承しているので、 gauche.collection (section 9.3 gauche.collection - コレクションフレームワーク参照) と gauche.sequence (section 9.18 gauche.sequence - シーケンスフレームワーク参照) も使えます。
    (coerce-to <weak-vector> '(1 2 3 4))
      => a weak vector with four elements
    

    Function: make-weak-vector size
    大きさsizeのweak vectorを作成して返します。

    Function: weak-vector-length wvec
    Weak vector wvecの大きさを返します。

    Function: weak-vector-ref wvec k &optioal fallback
    Weak vector wveck番目の要素を返します。

    weak-vector-refkが負の値であったりベクタの長さより 大きかったりした場合はエラーを通知します。但し、省略可能な引数fallback が与えられている場合はその値が返されます。

    gauche.sequenceモジュールをロードしていれば、 メソッドrefも同じ目的で使えます。

    Function: weak-vector-set! wvec k obj
    Weak vector wveck番目の要素をobjに変更します。 kが負数であったりベクタの長さより大きい場合はエラーとなります。

    6.15 制御

    6.15.1 手続き

    Builtin Class: <procedure>

    Function: procedure? obj
    [R5RS] objが手続きなら#tを、そうでなければ#fを返します。

    Function: apply proc arg1 ... args
    [R5RS] (arg1 ... . args)を引数として手続きprocを呼びます。 最後の引数argsは正規のリストでなければなりません。 procが返す 値をそのまま返します。
    (apply list 'a 'b '(c d e)) => (a b c d e)
    
    (apply + 1 2 '(3 4 5))      => 15
    

    6.15.1.1 マッピング

    Function: map proc list1 list2 ...
    [R5RS+] 与えられたリストの各要素に対してprocを適用し、その結果をリストにして 返します。R5RSではprocの適用順序が定められていませんが、Gaucheでは 常にprocはリスト内の順番で呼ばれます。 複数のリストが与えられた場合、最も短いリストが終了した時点でprocの適用を 打ち切ります。
    (map car '((a b) (c d) (e f))) => (a c e)
    
    (map cons '(a b c) '(d e f))
      => ((a . d) (b . e) (c . f))
    

    gauche.collectionモジュール(section 9.3 gauche.collection - コレクションフレームワーク参照) を使うと、mapがリスト以外のコレクション型に対しても動作するようになります。

    Function: for-each proc list1 list2 ...
    [R5RS] 手続きprocをリストの各エレメントに対して順に適用します。 procの結果は捨てられます。for-eachの戻り値は定義されていません。 複数のリストが与えられた場合、一番短いリストが終了した時点でfor-eachは終了します。

    gauche.collectionモジュール(section 9.3 gauche.collection - コレクションフレームワーク参照) を使うと、for-eachがリスト以外のコレクション型に対しても動作するようになります。

    6.15.1.2 コンビネータ

    Gaucheには、combinatory programmingに使えるいくつかの基本手続きがあります。

    Function: pa$ proc arg ...
    部分適用。手続きを返します。その手続きが引数m ...を伴って 呼ばれた場合、それは(proc arg ... m ...)と等価になります。
    (define add3 (pa$ + 3))
    (add3 4) => 7
    
    (map (pa$ * 2) '(1 2 3)) => (2 4 6)
    

    SRFI-26で定義されているマクロcutcuteも似たような抽象化の 方法を提供しますが、pa$より多少柔軟性が高く、その分やや冗長です。 section 4.3 手続きを作るを参照して下さい。

    Function: apply$ proc
    Function: map$ proc
    Function: for-each$ proc
    apply, mapfor-eachの部分適用版です。
    (define map2* (map$ (pa$ * 2)))
    (map2* '(1 2 3)) => (2 4 6)
    

    他にもfold$filter$member$等 いくつかの部分適用版の手続きが定義されています。 section 10.2 srfi-1 - List libraryを参照してください。

    Function: compose f g h ...
    2つ以上の手続きを結合します。引数は全て手続きでなければなりません。 2つの引数が渡された時、(compose f g)は次の式と等価です。
    (lambda args (call-with-values (lambda () (apply g args)) f))
    

    いくつか例を示します。

    (define not-zero? (compose not zero?))
    (not-zero? 3) => #t
    (not-zero? 0) => #f
    
    (define dot-product (compose (apply$ +) (map$ *)))
    (dot-product '(1 2 3) '(4 5 6)) => 32
    

    Function: any-pred pred ...
    Returns a procedure which applies given argument(s) to each predicate pred. If any pred returns a non-#f value, the value is returned. If all the preds return #f, #f is returned.
    (define string-or-symbol? (any-pred string? symbol?))
    (string-or-symbol? "abc") => #t
    (string-or-symbol? 'abc)  => #t
    (string-or-symbol? 3)     => #f
    
    (define <> (any-pred < >))
    (<> 3 4) => #t
    (<> 3 3) => #f
    
    ((any-pred (cut memq <> '(a b c))
               (cut memq <> '(1 2 3)))
     'b)  => '(b c)
    

    Function: every-pred pred ...
    Returns a procedure which applies given argument(s) to each predicate pred. If every pred returns a non-#f value, the value returned by the last pred is returned. If any pred returns #f, every-pred returns #f without calling further preds.
    ((every-pred odd? positive?) 3)  => #t
    ((every-pred odd? positive?) 4)  => #f
    ((every-pred odd? positive?) -3) => #f
    
    (define safe-length (every-pred list? length))
    (safe-length '(a b c))  => 3
    (safe-length "aaa")     => #f
    

    6.15.1.3 省略可能引数のパージング

    To have optional arguments or keyword arguments in Scheme, you have to take variable arguments as a list and decompose them by yourself. The following macros help it.

    Macro: let-optionals* restargs (var-spec ...) body ...
    Macro: let-optionals* restargs (var-spec ... . restvar) body ...
    Given a list of values restargs, binds variables accodring to var-spec, then evaluates body.

    Var-spec can be either a symbol, or a list of two elements and its car is a symbol. The symbol is the bound variable name. The values in restargs are bound to the symbol in order. If there are not as many values in restargs as var-spec, the rest of symbols are bound to the default values, determined as follows: If var-spec is just a symbol, the default value is undefined. If var-spec is a list, the default value is the result of evaluation of the second element of the list. In the latter case the second element is only evaluated when there are not enough arguments. The binding proceeds in the order of var-spec, so the second element may refer to the bindings of previous var-spec.

    In the second form, restvar must be a symbol and bound to the list of values whatever left from restargs after binding to var-spec.

    It is not an error if restarg has more values than var-specs. The extra values are simply ignored in the first form.

    (define (proc x . args)
      (let-optionals* args ((a 'a)
                            (b 'b)
                            (c 'c))
        (list x a b c)))
    
    (proc 0)         => (0 a b c)
    (proc 0 1)       => (0 1 b c)
    (proc 0 1 2)     => (0 1 2 c)
    (proc 0 1 2 3)   => (0 1 2 3)
    
    (define (proc2 . args)
      (let-optionals* args ((a 'a) . b)
        (list a b)))
    
    (proc2)          => (a ())
    (proc2 0)        => (0 ())
    (proc2 0 1)      => (0 (1))
    (proc2 0 1 2)    => (0 (1 2))
    
    (define (proc3 . args)
      (let-optionals* args ((a 0)
                            (b (+ a 1))
                            (c (+ b 1)))
        (list a b c)))
    
    (proc3)          => (0 1 2)
    (proc3 8)        => (8 9 10)
    (proc3 8 2)      => (8 2 3)
    (proc3 8 2 -1)   => (8 2 -1)
    

    Macro: get-optional restargs default
    This is a short version of let-optionals* where you have only one optional argument. Given the optional argument list restargs, this macro returns the value of optional argument if one is given, or the result of default otherwise. Default is not evaluated unless restargs is an empty list.
    (define (proc x . maybe-opt)
      (let ((option (get-optional maybe-opt #f)))
        (list x option)))
    
    (proc 0)         => (0 #f)
    (proc 0 1)       => (0 1)
    

    Macro: let-keywords* restarg (var-spec ...) body ...
    This macro is for keyword arguments. Var-spec can be one of the following forms:
    (symbol expr)
    If the restrag contains keyword which has the same name as symbol, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.
    (symbol keyword expr)
    If the restrag contains keyword keyword, binds symbol to the corresponding value. If such a keyword doesn't appear in restarg, binds symbol to the result of expr.

    The default value expr is only evaluated when the keyword is not given to the restarg. The binding is done in the order of var-spec, so the expr can refer to the variables bound by preceding var-spec.

    If a keyword that doesn't listed in var-spec appears in restarg, it is simply ignored.

    (define (proc x . options)
      (let-keywords* options ((a 'a)
                              (b :beta 'b)
                              (c 'c))
        (list x a b c)))
    
    (proc 0)         => (0 a b c)
    (proc 0 :a 1)    => (0 1 b c)
    (proc 0 :beta 1) => (0 a 1 c)
    (proc 0 :beta 1 :c 3) => (0 a 1 3)
    

    6.15.1.4 手続きのアリティ

    Interface to query procedure's arity. The API is taken from MzScheme (PLT Scheme).

    Function: arity proc
    Given procedure proc, returns an integer, an arity-at-least object, or a list of integer(s) and arity-at-least objects.

    An integer result indicates proc takes exactly that number of arguments. An arity-at-least indicats proc takes at least (arity-at-least-value arity-at-least) arguments. The list indicates there are multiple procedures with different arities.

    Since one can add methods to an existing procedure or generic function at any moment in Gauche, the value returned by arity only indicates the current state of the procedure. It will change if new method is added to the procedure/generic-function.

    (arity cons) => 2
    (arity list) => #<arity-at-least 0>
    (arity make) => (#<arity-at-least 1>)
    

    Function: arity-at-least? obj
    Returns true if obj is an arity-at-least object.

    Function: arity-at-least-value arity-at-least
    Returns the number of required arguments the arity-at-least object indicates.

    Function: procedure-arity-includes? proc k
    If a procedure proc can take k arguments, returns #t. Otherwise returns #f.

    6.15.2 適用可能なオブジェクト

    Gaucheでは、特別な組み込みの機構によって任意のオブジェクトを 「適用可能」にすることができます。

    Generic Function: object-apply object arg ...
    手続きでもジェネリックファンクションでもないオブジェクトが何らかの引数に 適用されたとき、そのオブジェクトと引数がジェネリックファンクションobject-apply に渡されます。

    この機能は、具体的な例を挙げた方が説明し易いでしょう。

    例えば、次のような式を評価しようとしたとします。

    ("abcde" 2)
    

    オペレータは文字列に評価されますから、手続きでもジェネリックファンクションでも ありません。そこで、Gaucheはこの式を、あたかも次のような式が与えられた かのように解釈します。

    (object-apply "abcde" 2)
    

    デフォルトでは、<string><integer>を引数とする object-applyのメソッドは定義されていないので、 この式はエラーになります。しかし、次のようなメソッドを定義すると:

    (define-method object-apply ((s <string>) (i <integer>))
      (string-ref s i))
    

    最初の式はまるで文字列が整数に適用されたかのように動作します。

    ("abcde" 2) => #\c
    

    このメカニズムは手続きが許されるほとんどの箇所で使うことができます。

    (apply "abcde" '(1))   => (#\b)
    (map "abcde" '(3 2 1)) => (#\d #\c #\b)
    

    Gauche組み込みオブジェクトのうち、<regexp>オブジェクトと <regmatch>オブジェクトに対してはobject-applyメソッドが定義されて います。section 6.11 正規表現を参照して下さい。

    Generic Function: (setter object-apply) object arg ... value
    適用可能オブジェクトを適用するフォームがset!フォームの第一ポジションに 現れた場合、そのフォームは下に示すように展開され、このメソッドが呼ばれます。
    (set! (object arg ...) value)
     => ((setter object-apply) object arg ... value)
    

    6.15.3 継続

    Function: call-with-current-continuation proc
    Function: call/cc proc
    [R5RS] 現在の継続を手続き (継続手続き) にパッケージ化して、それを引数として procを呼び出します。procが戻ったら、その返り値がcall/ccの 値となります。作成された継続手続きがどこかで0個または複数個の引数を伴って呼ばれたら、 あたかもcall/ccから戻ったかのように実行が継続されます。その場合、 call/ccは、継続手続きに与えられた引数を複数の値として返します。

    ファーストクラスの継続はSchemeの最も特徴的な機能のひとつですが、それを 十分に説明するにはこの本の余白は狭すぎます。適切なドキュメントを参照してください。

    Gaucheはわずかの例外を除いて、完全な継続をサポートしています。つまり継続は通常 無制限のエクステントを持ちます。しかし、継続がCコードからの「コールバック」 ---SchemeがCで書かれたコードを呼び出し、それが再びSchemeコードを呼び出した場合--- で作られたら、その継続のエクステントはコールバックが呼び出したCコードに戻るまでと なります。エクステントの切れた継続を呼ぼうとするとGaucheはエラーを報告します。 これは根本的な制限であり、おそらく解決されないでしょう。

    なお、コールバックコードから有効な継続を呼ぶことは常に可能です。また、 高階関数を使うmapfor-eachapplyといった手続きは Cからのコールバックを使っておらず、この制限の影響を受けません。

    おそらく、そのようなコールバック内で無制限のエクステントを持つ継続を作る必要というのは あまり無いでしょう。Gauche組み込みの機能では、以下のようなコードがCからのコールバックで 呼び出されます。さらに、外部のCライブラリを使った場合、例えばGUIツールキットからの コールバックなどはこの制限を受けるでしょう。

    • writedisplayformatから呼び出される write-objectメソッド (section 6.18.7 出力参照)。
    • sortから呼び出される比較クロージャ (section 6.20 比較とソート参照)。
    • バッファードポートから呼び出されるfillerとflusher手続き。 (section 6.18.5 手続き的ポート参照)。
    (define *oob-cont* #f)
    
    (call/cc (lambda (valid-cont)
               (sort '(1 2 3 4 5 6)
                     (lambda (a b)
                       (call/cc (lambda (oob-cont)
                                  (set! *oob-cont* oob-cont)))
                       (valid-cont 'ok)))))
     => ok  ;callback can call a continuation
    
    (*oob-cont* 'not-ok)
     => ;error -- *oob-cont* is out of its extent.
    

    Function: dynamic-wind before thunk after
    [R5RS] beforethunkおよびafter は引数を取らない手続きです。 dynamic-windはまずbeforeを呼び出し、続いてthunkを呼び出し、 続いてafterを呼び出します。そしてthunkが返した値を返します。

    もしdynamic-windのダイナミックスコープの外で捕捉された継続が thunkの中で呼ばれることにより制御がthunkから飛び出した場合、 (thunkの中でエラーが起こった場合などが考えられます)、 afterが呼ばれます。

    もし、thunkの中で捕捉された継続がdynamic-windのダイナミックスコープの 外で呼ばれることにより制御がthunkの中へ飛び込んだ場合、 beforeが呼ばれます。

    (letrec ((paths '())
             (c #f)
             (add (lambda (s) (push! paths s))))
      (dynamic-wind
       (lambda () (add 'connect))
       (lambda ()
         (add (call/cc (lambda (c0) (set! c c0) 'talk1))))
       (lambda () (add 'disconnect)))
      (if (< (length paths) 4)
          (c 'talk2)
          (reverse paths)))
     => (connect talk1 disconnect connect talk2 disconnect)
    

    6.15.4 多値

    Function: values obj ...
    [R5RS] obj ... を多値として返します。 呼び出し側は、組み込み構文の receive (section 4.6 変数束縛参照)か、 下に説明するR5RSの手続きcall-with-valuesを使って多値を受け取ることが できます。 section 10.6 srfi-11 - Let-valuesも参照してください。
    (values 1 2) => 1 and 2
    

    Function: call-with-values producer consumer
    [R5RS] 手続きproducerを引数無しで呼びます。そして、それが返した値 を引数としてconsumerを呼びます。consumerが返す値を 返します。
    (call-with-values (lambda () (values 1 2)) cons)
      => (1 . 2)
    

    6.15.5 遅延評価

    Special Form: delay expression
    [R5RS]

    Function: force promise
    [R5RS]

    6.16 例外

    In Gauche, error singnaling mechanism is implemented in multiple layers. The lower layer provides very simple mechanism with which the user can implement various semantics. The higher layer provides a way to handle common patterns like error handling in a simple way.

    6.16.1 エラーの通知

    Function: error string arg ...
    [SRFI-23] Signals an error. Internally the action is realized by those two steps.
    1. An error exception is created, with the message prefixed by string and followed by args.
    2. The error exception is thrown, which may be handled by the current active error handler, if any.

    If no error handler is active, the default error handler is used, which prints the error message to the current error port and some debug information. Then, if Gauche is running interactively, the control moves to the toplevel; if Gauche is running as a script, it exits with the exit status EX_SOFTWARE (70).

    Function: errorf fmt-string arg ...
    Similar to an error, but the error message is formatted by format, i.e. it is equivalent to:
    (define (errorf fmt . args)
      (error (apply format #f fmt args)))
    

    6.16.2 エラーの処理

    Function: with-error-handler handler thunk
    Makes handler the active error handler and executes thunk. If thunk returns normally, the result(s) will be returned. If an error is signalled during execution of thunk, handler is called with one argument, an exception object representing the error, with the continuation of with-error-handler. That is, with-error-handler returns whatever value(s) handler returns.

    If handler signals an error, it will be handled by the handler installed when with-error-handler called.

    The dynamic environment where handler is executed is the same as the error occurs. If dynamic-wind is used in thunk, its after method is called after handler has returned, and before with-error-handler returns.

    The behavior of with-error-handler can be described in the form of Scheme code shown below, using the low-level mechanism (See section 6.16.4 Low-level exception mechanism). Note that the actual function is built in VM, using lighter mechanisms (similar to "one-shot continuation", @xref{onecont, [1CC], 1CC}).

    ;; conceptual implementation of with-error-handler
    (define (with-error-handler handler thunk)
      (call/cc
        (lambda (cont)
          (let* ((prev-handler (current-exception-handler))
            (with-exception-handler
              (lambda (exn)
                (if (error? exn)
                    (with-exception-handler
                      (lambda (err) (prev-handler err))
                      (lambda () (call-with-values (handler exn) cont)))
                    (prev-handler exn)))
              thunk))))))
    

    6.16.3 例外オブジェクト

    Class: <exception>
    Represents An exception. The complete exception class hierarchy is under construction. Right now, only the following information is available.

    Instance Variable: <exception> message
    For an error exception, this is the error message.

    6.16.4 Low-level exception mechanism

    This layer provides SRFI-18 compatible simple exception mechanism. You can override the behavior of higher-level constructs such as with-error-handler by using with-exception-handler.

    Note that it is a double-edged sword. You'll get a freedom to construct your own exception handling semantics, but the Gauche system won't save if something goes wrong. Use these primitives when you want to customize the system's higher-level semantics or you are porting from other SRFI-18 code.

    Function: current-exception-handler
    [SRFI-18] Returns the current exception handler.

    Function: raise exception
    [SRFI-18] Invokes the current exception handler with one argument, exception. exception can be any Scheme object; it doesn't need to be an instance of <exception> class. Combined with with-exception-handler you can give your own semantics to the exception. raise returns whatever the handler returns.

    Function: with-exception-handler handler thunk
    [SRFI-18] A procedure handler must take one argument. This procedure sets handler to the current exception handler and calls thunk.

    Generally, if you want to handle non-continuable exception such as errors using this low-level mechanism, you have to transfer the control from the handler explicitly (See the explanation of with-error-handler above). raise detects if the handler returns on the non-continuable exceptions and reports an error using the default error handler mechanism, but it is just a safety net.

    Note also that handler is called in the same dynamic environment of raise. So if you raise an exception inside handler, it is captured by handler again. It is the programmer's responsibility to propagate the exception handling to the "outer" exception handlers.

    The behavior of those procedures can be explained in the following conceptual Scheme code.

    ;; Conceptual implementation of low-level exception mechanism.
    ;; Suppose %xh is a list of exception handlers
    
    (define (current-exception-handler) (car %xh))
    
    (define (raise exn)
      (receive r ((car %xh) exn)
        (when (uncontinuable-exception? exn)
          (set! %xh (cdr %xh))
          (raise (make-error "returned from uncontinuable exception")))
        (apply values r)))
    
    (define (with-exception-handler handler thunk)
      (let ((prev %xh))
        (dynamic-wind
          (lambda () (set! %xh (cons handler)))
          thunk
          (lambda () (set! %xh prev)))))
    

    6.17 Eval and repl

    Function: eval expr env
    [R5RS] Evaluate expr. env must be a value returned by the following procedures below. Right now it is just a <module> object, but it is possible that the Gauche adopts a first-class environment object in future.

    Function: null-environment version
    Function: scheme-report-environment version
    Function: interaction-environment
    [R5RS] Returns an environment specifier which can be used as the second argument of eval. Right now an environment specifier is just a module. (null-environment 5) returns a null module, which contains just the syntactic bindings specified in R5RS, (scheme-report-environment 5) returns a scheme module, which contains syntactic and procedure bindings in R5RS, and (interaction-environment) returns a user module that contains all the Gauche built-ins plus whatever the user defined. It is possible that the Gauche adopts a first-class environment object in future, so do not rely on the fact that the environment specifier is just a module.

    An error is signaled if a value other than 5 is passed as version argument.

    There's one difference from R5RS in null-environment and scheme-report-environment; they contain with-module special form. It is necessary to define R5RS procedure using Gauche built-ins for now. It'll be removed as soon as I find a better way.

    Function: read-eval-print-loop &optional reader evaluator printer prompter
    This exports Gosh's default read-eval-print loop to applications. Each argument can be #f, which indicates it to use Gauche's default procedure(s), or a procedure that satisfies the following conditions.
    reader
    A procedure that takes no arguments. It is supposed to read an expression and returns it.
    evaluator
    A procedure that takes two arguments, an expression and an environment specifier. It is supposed to evaluate the expression and returns zero or more value(s).
    printer
    A procedure that takes zero or more arguments. It is supposed to print out these values. The result of this procedure is discarded.
    prompter
    A procedure that takes no arguments. It is supposed to print out the prompt. The result of this procedure is discarded.

    Given those procedures, read-eval-print-loop runs as follows:

    1. Prints the prompt by calling prompter.
    2. Reads an expression by calling reader. If it returns EOF, exits the loop and returns from read-eval-print-loop.
    3. Evaluates an expression by calling evaluator
    4. Prints the result by calling printer, then repeats from 1.

    When an error is signaled from one of those procedures, it is captured and reported by the default escape handler, then the loop restarts from 1.

    It is OK to capture a continuation within those procedures and re-invoke them afterwards.

    6.18 入出力

    6.18.1 ポート

    Builtin Class: <port>
    Portは、Schemeにおいて抽象化された入出力のインタフェースを提供します。 Gaucheはportにいくつかの拡張を行い、いろいろなアプリケーションに対応できるようにしました。

    標準のSchemeでは、portはキャラクタを一文字づつ読み込む(一文字先読み可)、 もしくは書き出すだけのもので、他の入出力ルーチンはその上に構築されています。

    Gaucheではさらに次のような操作がportに対して可能になっています。

    バイトI/O
    キャラクタ毎でなく、バイト毎のI/Oが可能です(Gaucheではマルチバイト文字を 扱うので、この2つが異なることに注意して下さい)。大抵のポートでは キャラクタI/OとバイトI/Oを混ぜて使うことができます。
    ブロックI/O
    ポートから指定した数のバイト列を読んだり、ポートへ書いたりできます。 ポートがブロックI/Oを行うデバイスに接続されている場合、ある程度大きなブロック毎に 読み書きすると効率の良いデータ転送ができます。
    変換
    ポートはまた、データストリームを変換するのにも使えます。例えばgauche.charconv モジュールでは、文字コード間の変換を行うポートを提供しています (詳しくはsection 9.2 gauche.charconv - 文字コード変換を参照)。 プロシージャルなポートを定義することにより、様々な機能を実装できます。

    6.18.2 ポート共通の操作

    Function: port? obj
    Function: input-port? obj
    Function: output-port? obj
    [R5RS] obj がそれぞれポート、入力ポート、出力ポートなら真を返します。 port?はR5RSの"Standard Procedures"の項には 載っていませんが、"Disjointness of Types"の項に挙げられています。

    Function: port-closed? port
    objがポートであり、既に閉じられていた場合に真を返します。 一度閉じたポートは再び開くことはできません。

    Function: current-input-port
    Function: current-output-port
    [R5RS] 現在の入力ポートと出力ポートをそれぞれ返します。

    Function: current-error-port
    現在のエラーポートを返します。

    Function: standard-input-port
    Function: standard-output-port
    Function: standard-error-port
    プログラム開始時点の入力、出力、エラーポートをそれぞれ返します。

    Function: with-input-from-port port thunk
    Function: with-output-to-port port thunk
    Function: with-error-to-port port thunk
    それぞれ入力、出力、エラーポートはportにセットした状態でthunkを呼び出します。

    Function: close-input-port port
    Function: close-output-port port
    [R5RS] それぞれ、入力ポートと出力ポートを閉じます。

    Function: port-type port
    portのタイプを、シンボルfilestringprocの いずれかで返します。

    Function: port-name port
    portの名前を返します。ポートがファイルに関連付けられている場合は、ポートの名前は ファイル名です。そうでない場合、ポートを説明する文字列が返されます。

    Function: port-buffering port
    Function: (setter port-buffering) port buffering-mode
    ファイルポート((port-type port)fileを返すもの) に対して、そのバッファリングモードを読みだし、もしくは変更します。 入力ポートではバッファリングモードは :full:modest:noneのいずれかです。 出力ポートでは :full:line:noneのいずれかです。 バッファリングモードの詳細な説明は、section 6.18.3 ファイルポート を参照してください。

    port-bufferingがファイルポート以外のポートに対して呼ばれた場合は #fを返します。port-bufferingのsetterが ファイルポート以外のポートに対して呼ばれた場合はエラーとなります。

    Function: port-current-line port
    portの現在の行番号を返します。行番号は、ファイルに関連付けられたポートで かつシーケンシャルなキャラクタI/Oを行っている場合のみ有効です。それ以外の場合は -1を返します。

    Function: port-file-number port
    portがファイルに関連付けられている場合、そのファイルディスクリプタ番号を 返します。それ以外の場合は#fを返します。

    Function: copy-port src dst &keyword (unit 0)
    srcからEOFまでデータを読みだし、dstへ書き出します。

    キーワード引数unitは0以上の整数か、シンボルbyteもしくはchar でなければなりません。これはデータをコピーする単位を指定します。 整数ならば、その大きさ(0の場合はシステム規定の大きさ)のバッファが確保され、 ブロックI/Oを使って転送が行われます。通常のファイルをコピーする場合などはこれが 速いでしょう。もしunitがシンボルbyteであれば、バイト毎 に読みだし/書き込みが行われます。unitがシンボルcharであれば、 キャラクタ毎に読みだし/書き込みが行われます。

    6.18.3 ファイルポート

    Function: open-input-file filename &keyword if-does-not-exist buffering element-type
    Function: open-output-file filename &keyword if-does-not-exist if-exists buffering element-type
    [R5RS+] ファイルfilenameを入力または出力用にオープンし、 入力ポートまたは出力ポートを作成して返します。

    キーワード引数により、例外的な場合の動作を細かく指定できます。

    :if-exists
    このキーワード引数はopen-output-fileのみに指定でき、 filenameが既に存在した場合の動作を指定します。次の値のいずれかを与えることができます。
    :supersede
    既存のファイルが長さ0に縮められます。これが既定の動作です。
    :append
    既存のファイルにこれから書き出す内容が追加されます。
    :error
    エラーが報告されます。
    #f
    何もせず、#fを返します。
    :if-does-not-exist
    このキーワード引数はfilenameが存在しない場合の動作を指定します。
    :error
    エラーを報告します。これがopen-input-fileの既定の動作です。
    :create
    ファイルが作成されます。これがopen-output-fileの既定の動作です。 ファイルの存在のチェックと作成はアトミックに行われます。 このオプションに加え、if-existsオプションに:error#fを 指定することで、排他的にファイルを作成することができます。 open-input-fileに対してはこの値を指定することはできません。
    #f
    何もせず、#fを返します。
    :buffering
    この引数はバッファリングモードを指定します。以下の値が設定できます。 ポートのバッファリングモードは手続きport-buffering (section 6.18.2 ポート共通の操作参照)によって 読みだし/変更可能です。
    :full
    出来る限りデータをバッファリングします。これがデフォルトのモードです。
    :none
    バッファリングを行いません。出力ポートにデータが書き出されるか、 入力ポートからデータが読み込まれる度に、下位にあるシステムコールが呼ばれます。 プロセスの標準エラーポートはこのモードでオープンされています。
    :line
    このモードは出力ポートにのみ有効です。書き出されたデータはバッファに 貯められますが、改行文字が書かれたらフラッシュされます。 このモードは対話的な出力ポートなどに便利です。 プロセスの標準出力ポートはこのモードでオープンされています。 (これは、Cのstdioライブラリの「ラインバッファリング」とちょっと違うことに 注意してください。stdioでは同じファイルディスクリプタから入力が行われる時も バッファはフラッシュされますが、Gaucheではそうはなりません)。
    :modest
    このモードは入力ポートにのみ有効です。ほとんど:fullバッファリングモードと 同じですが、read-blockはポートに要求されたデータより少ないデータしか 無かった場合、要求された量がたまるまで待つのではなく、今あるデータだけを 返します。このモードはポートがパイプやネットワークに接続されている場合に 便利です。
    :element-type
    この引数はファイルのタイプを指定します。
    :character
    ファイルはキャラクタモード(テキストモード)でオープンされます。
    :binary
    ファイルはバイナリモードでオープンされます。
    現在のバージョンでは、この引数は無視され、全てのファイルはバイナリモードで オープンされます。いずれにせよUnixプラットフォームでは違いはありません。

    if-existsif-does-not-existフラグの組合せにより、 色々な動作を実現できます。

    (open-output-file "foo" :if-exists :error)
     => ;"foo"を排他的にオープンするかエラーを報告する
    
    (open-output-file "foo" :if-exists #f)
     => ;"foo"を排他的にオープンするか#fを返す
    
    (open-output-file "foo" :if-exists :append
                            :if-does-not-exist :error)
     => ;"foo"が既に存在する場合に限り、それを追加モードでオープン
    

    ファイルをオープンせずにその存在をチェックするには、 sys-accessfile-exists?を使って下さい (section 6.21.3.4 ファイルの状態参照)。

    註:gauche.charconvモジュールはこれらの手続きを、 encodingキーワード引数を取るように拡張して、 異なる文字エンコーディングでのファイルの読み書きを可能にします。 section 9.2 gauche.charconv - 文字コード変換参照。

    移植性に関する註:Schemeシステムによっては、filenameのところに シェルコマンドを指定して、サブプロセスの標準入出力と通信できるようにするものが あります。他のスクリプティング言語(例:Perl)にも同様の機能があります。 Gaucheでは、open-input-fileopen-output-fileは あくまでファイル (OSがファイルとして扱うもの) のみに対して使えます。 サブプロセスと通信するためには、「プロセスポート」という機能が提供されています。 section 9.14.2 Process portsを参照して下さい。

    Function: call-with-input-file string proc &keyword if-exists buffering element-type
    Function: call-with-output-file string proc &keyword if-does-not-exist if-exists buffering element-type
    [R5RS] stringで示されるファイルを入力または出力用にオープンし、 作成されたポートを引数として手続きprocを呼び出します。 procが正常終了するか、proc内で捕捉されないエラーが起きた場合に ファイルはクローズされます。

    キーワード引数はif-existsbuffering, element-typeif-does-not-existopen-input-file及びopen-output-fileのものと同じ意味を持ちます。 if-existsif-does-not-exist#fを指定した場合、 ファイルがオープンされなかった場合はprocにポートではなく#fが渡される ことに注意して下さい。

    procが返す値を返します。

    Function: with-input-from-file string thunk &keyword if-exists buffering element-type
    Function: with-output-to-file string thunk &keyword if-does-not-exist if-exists buffering element-type
    [R5RS] stringで示されるファイルを入力または出力用にオープンし、オープンされた ポートを現在の入力または出力ポートに設定して、thunkを呼び出します。 thunkが戻るか、thunk内で捕捉されないエラーが生じた際にファイルは閉じられます。

    キーワード引数は open-input-file及びopen-output-fileのものと同じ意味を持ちます。 但しif-existsif-does-not-exist#fを指定することは 出来ません。ファイルがオープンできなかった場合は常にエラーとなります。

    thunkが返す値を返します。

    ポートを閉じるセマンティクスについて: R5RSはcall-with-input-file等の説明において、次のように述べています。 「procが戻って来なかった場合、今後ポートが読み書きに一切使われないことが 証明できない限りは、ポートは自動的には閉じられない」。

    Gaucheの実装は若干この条件には反しています。捕捉されないエラーがprocから 発せられたというだけでは、そのポートが今後一切使われないかどうかはわかりません。 しかし実際には、そのようなエラーが発せられた後でポートに対して意味のある操作をするのは 非現実的です。ポートがどのような状態にあるかわからないわけですから。 現実的なプログラムでは、ポートに対して意味のある操作をしつづけたいのなら、 procの中で明示的にエラーをハンドルすべきでしょう。

    call-with-input-fileの外で捕捉された継続をproc内で呼んだ場合には ポートは閉じられないことに注意して下さい。後でprocへと制御が戻ってくるかも しれないからです (コルーチン等)。また、 低レベルの例外メカニズム(section 6.16.4 Low-level exception mechanism 参照)を利用した場合、エラー時にポートを閉じるのはプログラマの責任になります。

    Function: open-input-fd-port fd &keyword buffering name owner?
    Function: open-output-fd-port fd &keyword buffering name owner?
    与えられたファイルディスクリプタにアクセスする入力または出力ポートを 作成して返します。bufferingopen-input-file の項で 説明されたポートのバッファリングモードを指定します。デフォルトは:fullです。 nameport-nameによって返されるポートの名前を指定します。 owner? は、このポートを閉じた時にfdもクローズすべきかどうかを 指定するブーリアン値です。

    6.18.4 文字列ポート

    文字列ポートは、メモリ上のデータと関連付けられたポートです。

    Function: open-input-string string
    [SRFI-6] stringを内容とする入力文字列ポートを作って返します。 文字列に逐次的にアクセスする場合、インデックスをインクリメントしながら string-refを呼び出すより効率の良い方法です。
    (define p (open-input-string "文字 列"))
    (read p) => 文字
    (read-char p) => #\space
    (read-char p) => #\列
    (read-char p) => #<eof>
    (read-char p) => #<eof>
    

    Function: open-output-string
    [SRFI-6] 出力文字列ポートを作成して返します。このポートに書き出された文字列は 内部のバッファにたくわえられ、get-output-string で取り出すことが できます。 これは、順番に文字列を構成する方法として、あらかじめ文字列をアロケートして string-set!で埋めて行くよりもずっと効率の良い方法です。

    Function: get-output-string port
    [SRFI-6] 出力文字列ポートportを取り、それまでそのポートに蓄積された 文字列を返します。バイトデータがそのポートに書き出されていた場合、 この手続きはまず内部バッファをスキャンし、結果が完全な文字列で表現できるかどうかを 調べます。もし表現できなければ、不完全な文字列が返されます。

    Function: call-with-input-string string proc
    Function: call-with-output-string proc
    Function: with-input-from-string string thunk
    Function: with-output-to-string thunk
    これらのユーティリティ関数は次に定義されるような動作をします。 インタフェースはファイルポートを扱う類似の関数と揃えてあります。
    (define (call-with-output-string proc)
      (let ((out (open-output-string)))
        (proc out)
        (get-output-string out)))
    
    (define (call-with-input-string str proc)
      (let ((in (open-input-string str)))
        (proc in)))
    
    (define (with-output-to-string thunk)
      (let ((out (open-output-string)))
        (with-output-to-port out thunk)
        (get-output-string out)))
    
    (define (with-input-from-string str thunk)
      (with-input-from-port (open-input-string str) thunk))
    

    Function: call-with-string-io str proc
    Function: with-string-io str thunk
    (define (call-with-string-io str proc)
      (let ((out (open-output-string))
            (in  (open-input-string str)))
        (proc in out)
        (get-output-string out)))
    
    (define (with-string-io str thunk)
      (with-output-to-string
        (lambda ()
          (with-input-from-string str
            thunk))))
    

    Function: write-to-string obj &optional writer
    Function: read-from-string string &optional start end
    文字列ポートを使う定型句をユーティリティ関数にしました。
    (write-to-string obj writer)
      ==
      (with-output-to-string (lambda () (writer obj)))
    
    (read-from-string string)
      ==
      (with-input-from-string string read)
    

    writerの既定値はwriteです。start, endは 省略されればそれぞれ0と文字列の長さになります。

    移植性への註:Common Lispに同名の関数があります。必須引数の動作は同じですが、 省略可能な引数は異なります。 STkにはread-from-stringがありますが、省略可能な引数は取りません。

    6.18.5 手続き的ポート

    The underlying mechanism of procedural ports is very flexible, but I don't have Scheme interface yet, except the following ones:

    Function: open-input-buffered-port filler buffer-size
    Function: open-output-buffered-port flusher buffer-size
    These procedures are deprecated and will be replaced by more general procedural APIs.

    These are the Scheme interface to the "buffered port".

    open-input-buffered-port creates and returns an input port, with associated buffer of size buffer-size. The data is read from the buffer. When the port is read and the buffer is empty, a procedure filler is called with one argument, the size of required data. filler must return a string (either complete or incomplete) of the specified size. It is permitted for filler to return a string shorter than the size, if not enough data is available. The behavior is undefined if filler returns larger string than specified. Note that the size of string matters, not the length of string. If filler finds that it reached EOF of its data source, it can return EOF. Retuning zero size string has the same effect as EOF. Initially, the buffer is empty, so filler is always called at the first attempt of reading from the port.

    open-output-buffered-port creates and returns an output port, with associated buffer of size buffer-size. The data output to the port is accumulated in the buffer. When the buffer gets full, or flush is called on the port, a procedure flusher is called with an incomplete string to be flushed. flusher must return a number of bytes flushed, which must be the same as the size of the passed string. The string may shorter than buffer-size. When the port is closed, flusher is called with any data remaining in the buffer, then it is called again with #f to indicate the port is closed.

    6.18.6 入力

    入力に関する手続きで、省略可能な引数iportは入力ポートでなければなりません。 省略された場合が現在の入力ポートが使われます。

    6.18.6.1 データの読み込み

    Function: read &optional iport
    [R5RS]

    Function: read-char &optional iport
    [R5RS]

    Function: peek-char &optional iport
    [R5RS]

    Function: read-byte &optional iport
    入力ポートiportから1バイト読み込み、0から255までの整数値として返します。 iportが既にEOFに達していた場合はeofオブジェクトを返します。

    Function: read-line &optional iport
    入力ポートから、行末もしくはEOFまで読み込んで文字列として返します。 よく使われる行末 (LF only, CRLF, and CR only) を認識します。 戻り値にはこれらの行末文字は含まれません。 iportが既にEOFに達していた場合はeofオブジェクトを返します。

    Function: read-block nbytes &optional iport
    nbytesバイトのデータをiportから読み込み、 不完全な文字列として返します。iportに十分なデータが無い場合、 返される文字列はnbytesより短いかもしれません。 iportが既にEOFに達していた場合はEOFオブジェクトが返されます。

    iportがファイルポートだった場合、read-blockは ポートのバッファリングモードによってふるまいが異なります (バッファリングモードの詳細についてはsection 6.18.3 ファイルポートを参照して下さい)。

    • バッファリングモードが:fullの場合、read-blockは EOFを読まない限り、nbytesのデータが読まれるまで待ちます。
    • バッファリングモードが:modest:noneである場合、 read-blockはEOFが読まれなくても、すぐに読めるデータがnbytesよりも 少ない場合はそのデータだけを返します。

    read-blockは呼ばれるたびに新たな文字列をアロケートします。 アロケーションを避け、あらかじめ用意された固定長のバッファにデータを読み込みたい 場合は、gauche.uvectorモジュールのread-block! を使って下さい (section 9.24.4 ユニフォームベクタのブロック入出力参照)。 Read-block!はuniform vectorをバッファとして用います。

    データブロックをポートに書き出すには、データが文字列で表現されている 場合は単純にdisplayが使えます。データがuniform vectorで表現されている 場合はgauche.uvectorモジュールのwrite-blockが 使えます (section 9.24.4 ユニフォームベクタのブロック入出力参照)。

    Function: eof-object? obj
    [R5RS] objがEOFオブジェクトなら#tを返します。

    Function: char-ready? port
    [R5RS] portから文字が読み出せる状態ならば#tを返します。

    今のところ、この手続きはportから少なくとも1バイト読み出せる状態なら#t を返します。そのバイトがマルチバイト文字を構成する場合、char-ready?を返した ポートから文字全てを読み込もうとすると、ブロックする可能性があります。 (通常の使用状況ではそのようなことは起きないでしょうが、理論的には起こり得ます。 慎重を期したい場合はread-blockでバイトシーケンスとして読み込んだ後、 入力文字列ポート等を使って文字毎に読むようにして下さい。)

    6.18.6.2 読み込み時コンストラクタ

    Read-time constructor, defined in SRFI-10, provides an easy way to create an external representation of user-defined structures.

    Reader Syntax: #,(tag arg ...)
    [SRFI-10]

    Function: define-read-ctor tag procedure
    [SRFI-10]

    6.18.6.3 入力ユーティリティ手続き

    Function: port->string port
    Function: port->list reader port
    Function: port->string-list port
    Function: port->sexp-list port
    便利な入力手続きです。APIはScshとSTkから取りました。

    port->stringportをEOFまで読み込み、 読んだものを文字列として返します。

    port->listは手続きreaderportに繰り返し適用し、 結果をリストに蓄積します。readerがEOFを返したら 蓄積されたリストを返します。

    (port->string-list port) == (port->list read-line port) であり、 (port->sexp-list port) == (port->list read port) です。

    Function: port-fold fn knil reader
    Function: port-fold-right fn knil reader
    Function: port-for-each fn reader
    Function: port-map fn reader
    readerによって読まれる入力に対する便利な繰り返し手続きです。 基本的に、readerが引数無しでEOFを返すまで繰り返し呼ばれ、 それが返した値に対してfnが呼ばれます。 readerはいずれEOFを返す手続きなら、入力ポートと関係している必要はありません。

    readerが要素 {X0, X1, ..., Xn} を返したとすると、 port-fold は次の値を返します。

    (fn Xn (fn Xn-1 ... (fn X0 knil)))
    

    一方、port-fold-rightは次の値を返します。

    (fn X0 (fn X1 ... (fn Xn knil)))
    

    すなわち、(port-fold cons '() read)は全ての入力の逆リストを 返し、(port-fold-right cons '() read)(port->list read port)と同じものを返します。

    port-for-eachport-mapfnを読まれた要素に 次々と適用します。前者はfnの結果を捨てますが、後者はfnの 結果をリストにして返します。

    6.18.7 出力

    以下の手続きで、省略可能な引数portは出力ポートでなければなりません。 省略された場合が現在の出力ポートが使われます。

    Function: write obj &optional port
    [R5RS]

    Function: display obj &optional port
    [R5RS]

    Function: print expr ...
    expr ... をdisplayを使って現在の出力ポートに表示し、 最後に改行を書き出します。

    Method: write-object (obj <object>) port
    You can customize how the object is printed out by this method.

    Function: newline &optional port
    [R5RS] portに改行文字を書き出します。

    Function: flush &optional port
    Function: flush-all-ports
    それぞれ、port、および全てのポートにバッファされているデータを 全て書き出します。

    手続き"flush"はScheme実装によって様々な名前で呼ばれています: force-output (Scsh, SCM)、 flush-output (Gambit)、flush-output-port (Bigloo) 等。 flushの名前はSTkとSTklosから取りました。

    Function: write-char char &optional port
    [R5RS] 文字charをポートに出力します。

    Function: write-byte byte &optional port
    出力ポートに1バイトのデータbyteを書き出します。 byteは0から255の間の正確な整数でなければなりません。

    Function: write* obj &optional port

    Function: format port string arg ...
    Function: format string arg ...
    [SRFI-28+] string の指示に従い、arg ...をフォーマットします。 この手続きはCommonLispのformatのサブセットに、Gauche独自の拡張を 加えたものです。また、これはSRFI-28 "Basic format strings" のスーパーセットに なっています (@xref{srfi-28,[SRFI-28],SRFI-28})。

    portは出力先を指定します。それが出力ポートであれば、フォーマットされた 結果はそのポートに書き出されます。port#tであれば、結果は 現在の出力ポートに書き出されます。port#fであれば、結果は 文字列としてformatから返されます。 portは省略することもできます。その場合は、port#f を指定したのと同じ動作をします(SRFI-28のformat)。

    stringはフォーマット指示子を含んだ文字列です。 フォーマット指示子はチルダ`~'から始まり、特定の文字で終了する文字の並びで、 それぞれのフォーマット指示子が対応するargを取りフォーマットします。 string内のフォーマット指示子以外の文字列はそのまま出力されます。

    (format #f "the answer is ~s" 42)
      => "the answer is 42"
    

    フォーマット指示子は一つ以上のコンマで区切られたパラメータを取ることもできます。 パラメータは整数か文字です。文字の場合、クオート文字に続けてその文字を置きます。 パラメータが省略された場合は既定値が使われます。パラメータの意味はフォーマット指示子毎に 異なります。

    さらに、フォーマット指示子は2種類のフラグ、`@' と `:' を 取ることができます。これらの組合せでフォーマットの動作が変わります。フラグは (もしあれば)パラメータの後、指示子の文字の直前に置かれなければなりません。

    パラメータの位置に文字 `v' か `V' を置くこともできます。 その場合、パラメータの値が引数リストから取られます。対応する引数は整数か 文字、または#fでなければなりません。#fの場合はそのパラメータが 省略されたのと同じになります。

    いくつかの例です。

    ~10,2s
    パラメータ10と2を伴う、フォーマット指示子~s
    ~12,,,'*A
    第1パラメータに数値12、第4パラメータに文字`*'を取るフォーマット指示子~a。 第2と第3のパラメータは省略されています。
    ~10@d
    フォーマット指示子~d。パラメータ10と`@'フラグがついています。
    ~v,vx
    フォーマット指示子~x。第1パラメータと第2パラメータは引数リストから取られます。

    以下にサポートされているフォーマット指示子を示します。フォーマット指示子の文字自体は 大文字であっても小文字であっても構いません。特に断りのない限り両者は同じ動作をします。

    ~mincol,colinc,minpad,padchar,maxcolA
    ASCII出力。対応する引数がdisplayを使ってフォーマットされます。 整数がmincolに与えられた場合、それは出力される最小の文字数を指定します。 引数のフォーマット結果がmincolより短ければ、空白が右に追加されます(つまり、 左詰めになります)。 colincminpad、そしてpadcharは更に細かいパディング方法を 指定します。padcharに文字が与えられた場合、それが空白文字の代わりにパディング文字と して使われます。minpadに0以上の整数が与えられた場合、少なくともその数だけの パディング文字が追加されます。colincが指定された場合、 追加されるパディング文字の数がcolincの倍数に調整されます。 アトマーク `@' フラグが与えられた場合、結果は右詰めになります。 maxcolパラメータは与えられていれば書かれる文字数の上限を指定します。 フォーマット後の文字列の長さがmaxcolを超えた場合、maxcol文字だけが 書かれます。コロン `:' フラグが同時に与えられていれば、 maxcol - 4 文字が書かれた後、文字列" ..."が書かれます。
    (format #f "|~a|" "oops")
      => "|oops|"
    (format #f "|~10a|" "oops")
      => "|oops      |"
    (format #f "|~10@a|" "oops")
      => "|      oops|"
    (format #f "|~10,,,'*@a|" "oops")
      => "|******oops|"
    (format #f "|~10,,,'☆a|" "oops")
      => "|oops☆☆☆☆☆☆|"
    
    (format #f "|~,,,,10a|" '(abc def ghi jkl)
      => "|(abc def gh|" 
    (format #f "|~,,,,10:a|" '(abc def ghi jkl)
      => "|(abc de ...|" 
    
    ~mincol,colinc,minpad,padchar,maxcolS
    S式出力。対応する引数がwriteを使ってフォーマットされます。 パラメータの意味は~A指示子と同じです。
    (format #f "|~s|" "oops")
      => "|\"oops\"|"
    (format #f "|~10s|" "oops")
      => "|\"oops\"    |"
    (format #f "|~10@s|" "oops")
      => "|    \"oops\"|"
    (format #f "|~10,,,'*@s|" "oops")
      => "|****\"oops\"|"
    (format #f "|~10,,,'★s|" "oops")
      => "|\"oops\"★★★★|"
    
    ~mincol,padchar,commachar,intervalD
    10進出力。対応する引数が10進数表記でフォーマットされます。もし引数が数値でなければ、 全てのパラメータは(`v'パラメータの処理後に)無視され、 引数は~Aでフォーマットされます。 もしmincolに整数が与えられたら、それが最小の文字数を指定します。 結果の文字数がそれより少なければ、文字padcharが左に追加されます(右詰めになります)。 padcharが省略された場合は空白文字が使われます。
    (format #f "|~d|" 12345)
      => "|12345|"
    (format #f "|~10d|" 12345)
      => "|     12345|"
    (format #f "|~10,'0d|" 12345)
      => "|0000012345|"
    
    アトマーク `@' フラグが与えられた場合、正の引数に対して `+' が 先頭につけられます。 コロンフラグ `:' が与えられた場合、結果の文字はinterval文字毎に まとめられ、間に文字commacharが挿入されます。デフォルトでは3文字毎にコンマが 挿入されます。
    (format #f "|~:d|" 12345)
      => "|12,345|"
    (format #f "|~,,'_,4:d|" -12345678)
      => "|-1234_5678|"
    
    ~mincol,padchar,commachar,intervalB
    2進出力。対応する引数が2進数の整数としてフォーマットされます。 パラメータの意味は~Dと同じです。
    ~mincol,padchar,commachar,intervalO
    8進出力。対応する引数が8進数の整数としてフォーマットされます。 パラメータの意味は~Dと同じです。
    ~mincol,padchar,commachar,intervalX
    ~mincol,padchar,commachar,intervalx
    16進出力。対応する引数が16進数の整数としてフォーマットされます。 フォーマット指示文字に `X' が与えられた場合は `ABCDEF' が桁文字として 使われ、 `x' が与えられた場合は `abcdef' が桁文字として使われます。 パラメータの意味は~Dと同じです。
    (format #f "~8,'0x" 259847592)
      => "0f7cf5a8"
    (format #f "~8,'0X" 259847592)
      => "0F7CF5A8"
    
    ~count*
    引数のカウンタをcountだけ後方にずらします。つまり、count個の引数が 無視されることになります。countのデフォルト値は1です。 コロンフラグが与えられた場合は引数カウンタを前方に動かします。 例えば~:*は次のディレクティブが直前に使った引数を再び使うようにします。 アトマークフラグが与えられた場合は、countが引数の絶対位置を示します。 0が最初の引数です。

    6.19 プログラムのロード

    6.19.1 Schemeファイルのロード

    Function: load file &keyword paths (error-if-not-found #t)
    [R5RS+] fileをロードします。すなわち、fileに書かれたScheme式を順次読み込んで 評価します。fileの拡張子 (".scm") は省略できます。

    fileが "/", "./" または "../" で始まっていない場合は、 システムファイルサーチパス (変数*load-path* に格納されています) の中から該当ファイルが探されます。あるいは、キーワード引数pathsにディレクトリ名の リストを渡すことによりサーチパスを指定することもできます。

    ロードに成功した場合は#tが返されます。 指定ファイルがみつからない場合はエラーとなりますが、もしキーワード引数 error-if-not-found#fが与えられていれば単にloadから #fが返されます。

    カレントモジュールは保存されます。つまり、file中でselect-moduleによって カレントモジュールを変更しても、loadが終わったらloadを読んだ時点の モジュールに戻ります。

    ライブラリファイルをロードする場合は、`use' (section 4.11.2 モジュールの定義と選択参照) を 使うか、下に説明する`require' を使う方が良いでしょう。 loadrequireの違いについてはsection 2.6 コンパイルを参照してください。

    Variable: *load-path*
    loadrequireがファイルを探すディレクトリのリストを保持しています。

    もしサーチパスにディレクトリを追加したい場合は、この変数を直接変更せずに、下に説明する add-load-pathを用いて下さい。

    Special Form: add-load-path path &optional (afterp #f)
    パスpathをライブラリロードパスのリストに加えます。 afterpに真の値が与えられていればpathは既存のリストの末尾に 追加されます。そうでなければpathは既存のリストの先頭に追加されます。

    ロードパスを変更したい場合、*load-path*を直接替えずにこのフォームを 使って下さい。このフォームはコンパイル時に解釈されるのに対し、*load-path*を 書き換えるコードは実行時に解釈されます。"use" や "require" は コンパイル時のロードパスを使うので、*load-path*への変更は反映されないかもしれません。

    更に、add-load-pathpathの下にアーキテクチャ依存のディレクトリが ないかどうかを探し、あればそれを内部の共有ライブラリサーチパスに追加します。 例えばあなたが自分のSchemeモジュールを/home/yours/libに入れていて、 それが共有ライブラリを必要としていたとします。手続きgauche-architecture (section 6.21.2 環境の問い合わせ参照)が返す値をARCHとして、 共有ライブラリを/home/yours/lib/ARCH/に置いておくと、 共有ライブラリはそこからロードされます。この方法を取ると、複数のプラットフォーム用に 別々にコンパイルされた共有ライブラリを管理することができます。

    Function: load-from-port port
    入力ポートportから、EOFを読むまで繰り返しScheme式を読み込み評価します。

    Function: current-load-port
    Function: current-load-history
    Function: current-load-next
    これらの手続きによって、現在のロードのコンテクストを知ることができます。 ロードされているファイルの中でこれらの手続きを呼ぶと、次のような値が返されます。
    current-load-port
    現在のファイルがロードされている入力ポート。
    current-load-history
    入力ポートと行番号のペアのリストで、ロードのネスティングを示したもの。 例えばあなたが`foo.scm'をロードし、そのファイルの7行目で `bar.scm'がロードされ、そのファイルの18行目で`baz.scm'が ロードされたとします。current-load-history`baz.scm'中で 呼ぶと、それは次のような値を返します。
    ((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))
    
    current-load-next
    現在のファイルがロードされた時点での、ファイルサーチパスの残りを返します。 例えば *load-path*("." "../lib" "/home/gauche/lib" "/share/gauche/lib")で、 あなたが`foo.scm'をロードしたところ、それが`../lib/'中に見つかったと しましょう。このとき、`foo.scm'中でcurrent-load-nextを呼べば
    ("/home/gauche/lib" "/share/gauche/lib")
    
    が返されます。

    loadされていない状態で呼ばれた時は、これらの手続きはそれぞれ#f()()を返します。

    6.19.2 ダイナミックライブラリのロード

    Function: dynamic-load file &keyword init-function export-symbols
    ダイナミックローダブルライブラリ(共有ライブラリ)fileをロードしてリンクします。 fileにはサフィックス(".so" 等) を含めないで下さい。システムによって サフィックスは異なるため、dynamic-loadがそれを追加します。

    キーワード引数init-functionは共有ライブラリ中の初期化関数の名前を 指定します。デフォルトでは、サフィックスを除くファイル名が "foo" の場合、 初期化関数名は "Scm_Init_foo" となります。

    キーワード引数export-symbolsは、ロードされるライブラリ中の外部シンボルを プロセスのシンボルテーブルに追加すべきかどうかを指定します。(註:ここでの「シンボル」 とはCの関数名や変数名のことで、Schemeのシンボルのことではありません)。 デフォルトでは共有ライブラリの外部シンボルはプロセスのシンボルテーブルに追加されず、 それぞれの共有ライブラリは他の共有ライブラリのシンボルを見ることができません。 export-symbolsに真の値を渡すと、フラグRTLD_GLOBALdlopen()に渡されて、その共有ライブラリ中のシンボルがこれからロードされる 共有ライブラリからも見えるようになります。

    通常、共有ライブラリはSchemeモジュール中でロードされるので、モジュールユーザが 直接この手続きを呼ぶ必要はほとんどないでしょう。

    一度ロードされた共有ライブラリをアンロードすることはできません。

    6.19.3 requireとprovide

    Special Form: require feature
    featureがまだロードされていなければロードします。featureは文字列で なければなりません。それがそのまま(サフィックスを除く)ファイル名としてロードパスから 探されます。requireの解釈はコンパイル時に行われます。 ロードされたファイルはその中でfeatureをprovideしなければなりません。 そうでないと警告が出されます。

    SLIBモジュールをロードすると、requireが拡張されます。詳しくはsection 11.15 slib - SLIB interfaceを 参照して下さい。

    Function: provide feature
    featureをシステムのprovideされたフィーチャーリストに加えます。 以降、featurerequireされてもファイルはふたたびロードされません。 通常この手続きは、requireされるファイルの末尾で呼ばれます。ファイルの末尾で呼ぶのが良いのは、 もしファイルのロード中にエラーが発生した場合、そのエラーを修正した上でふたたびrequire でロードできるからです。

    Function: provided? feature
    featureが既にprovideされていれば#tを返します。

    6.19.4 Autoload

    Macro: autoload file/module item ...
    item ... がオートロードされるように設定します。すなわち、 次にitemが参照された時、それが実際に評価される前にfile/moduleがロード されるようにします。これによって、必要とされる時までfile/moduleのロードを遅らせる ことができます。

    引数file/moduleには、文字列かシンボルを指定できます。文字列の場合は そのファイルがロードされます。シンボルの場合、その名のモジュールが(useと 同じルールで)ロードされ、itemfile/moduleから オートロードを呼び出したモジュールへとインポートされます。 (モジュールのuseの詳細についてはsection 4.11.2 モジュールの定義と選択を参照して下さい)。

    itemは変数名(シンボル)か、(:macro symbol)というフォーム でなければなりません。変数名の場合は、その変数が評価されようとした時に 指定のファイル/モジュールがロードされます。後者のフォームの場合は、 (symbol arg ...) というフォームがコンパイルされようとした 時に指定のファイル/モジュールがロードされます。後者はマクロのオートロードになります。

    symbolfile/moduleの中で定義されなければなりません。 そうでなければロード時にエラーが報告されます。

    手続きのオートロードの例を示します。

    (autoload "foo" foo0 foo1)
    (autoload "bar" bar0 bar1)
    
    (define (foobar x)
      (if (list? x)
          (map bar0 x)
          (foo0)))
    
    (foobar '(1 2)) ; この時点で "bar" がロードされる
    
    (foobar #f)     ; この時点で "foo" がロードされる
    

    マクロのオートロードを設定した場合、指定のファイルまたはモジュールは、 そのマクロを使っているフォームが実行されるされないにかかわらず、 コンパイラがそのフォームを見た時点でロードされることに注意してください。

    6.20 比較とソート

    Function: compare obj1 obj2

    Generic Function: object-compare obj1 obj2

    Function: sort list &optional cmfpn
    Function: sort! list &optional cmfpn
    Sorts elements in list in ascending order and returns the sorted list. sort! destructively reuses the cons cells of the original list. The sorting order is specified by cmpfn, which is a procedure takes two elements of list, and returns #t if the first argument strictly precedes the second.
    (sort '(("Chopin" "Frederic") 
            ("Liszt" "Franz")
            ("Alkan" "Charles-Valentin"))
          (lambda (x y) (string<? (car x) (car y))))
      => (("Alkan" "Charles-Valentin")
                 ("Chopin" "Frederic")
                 ("Liszt" "Franz"))
    

    Some builtin objects have natural comparison order, and it is used if cmpfn is omitted.

    6.21 システムインタフェース

    GaucheはPOSIX.1の多くの関数と、さまざまなUnixで共通して使われているシステム関数へのインタフェースを 組込み手続きとして提供しています。

    多くのScheme実装はいろいろな形で何らかのシステムインタフェースを提供 しています。名前だけが違うもの(例:delete-fileremove-fileunlink) もあれば、新しいSchemeオブジェクトを導入して 抽象化を行っているものもあります。Gaucheでは、既存のAPIのどれかを そのまま真似るのではなく、2つのレイヤを提供することにしました。 この章で述べられる低レベルレイヤは、OSのインタフェースに似せたものを実装します。 その上に、既存のシステムと互換性のある高レベルのインタフェースが実装されます。

    sys-nameという名前を持つ手続きは、多くの場合、 システムコールnameに対応しています。 可能な限り、インタフェースが似るようにしました。

    Cによるシステムプログラミングに慣れている方は、 section B. CとSchemeの関数の対応も参考にして下さい。 Cの標準ライブラリとGaucheの手続きとの対応が示してあります。

    6.21.1 プログラムの終了

    Function: exit &optional (code 0)
    [POSIX] 現在のプロセスを終了し、codeを終了コードにします。 codeはゼロもしくは正の正確な整数でなければなりません。 この手続きはまずアクティブなダイナミックハンドラのafter手続きを全て呼び出し (See section 6.15.3 継続)、続いてオープンされている出力ポートのバッファを フラッシュし、最後にexit(2)を呼び出します。

    Function: sys-exit &optional (code 0)
    [POSIX] 現在のプロセスを終了し、codeを終了コードにします。 codeはゼロもしくは正の正確な整数でなければなりません。 この手続きは_exit(2)を直接コールします。 クリーンアップは一切行われません。 フラッシュされてないファイルバッファの内容は捨てられます。

    Function: sys-abort
    [POSIX] POSIXのabort()を呼びます。通常、現在のプロセスは終了され、コアダンプされます。 クリーンアップは一切行われません。

    6.21.2 環境の問い合わせ

    Function: sys-getenv name
    [POSIX] 環境変数nameの値を文字列で返します。もしnameが定義されていなければ、 #fが返ります。

    Function: sys-putenv name value
    プロセスの環境変数nameに値valueをセットします。システムが putenv()をサポートしていない場合はエラーが通知されます。

    Function: gauche-version
    Function: gauche-architecture
    Function: gauche-library-directory
    Function: gauche-architecture-directory
    Function: gauche-site-library-directory
    Function: gauche-site-architecture-directory
    これらの手続きはGaucheインタプリタの情報を文字列で返します。

    6.21.3 ファイルシステム

    ファイルシステムに関するシステムコール群です。 ここで述べる手続きの上に、より高レベルなAPIがモジュールfile.utilとして 実装されています。section 11.6 file.util - ファイルシステムユーティリティを参照して下さい。

    6.21.3.1 ディレクトリ

    高レベルAPIに関してはsection 11.6.1 ディレクトリユーティリティも参照して下さい。

    Function: sys-readdir path
    pathは存在するディレクトリを示すパス名でなければなりません。 この手続きはディレクトリの全エントリを文字列のリストとして返します。 リストはソートされません。pathが存在しなかったり、ディレクトリでなかった場合は エラーとなります。

    Function: sys-glob pattern
    glob(3)関数へのインタフェースです。patternはsh(1)で使われるパターンです: `?'は任意の一文字にマッチし、`*'は0以上の任意の文字にマッチし、 `[abc]'は文字`a', `b', `c' のいずれにも マッチします。マッチするパス名が無ければ空のリストが返されます。

    glob()をサポートしていないシステムでは、エラーが通知されます。

    註:glob()の実装にセキュリティ上の問題のあるシステムがあることが知られています。 Gaucheではいずれ、自前のglob()実装を持つ予定です。

    パスがディレクトリかどうかチェックする方法は、section 6.21.3.4 ファイルの状態を参照してください。

    6.21.3.2 ディレクトリ操作

    Function: sys-remove filenmae
    [POSIX] filenameがファイルであればそれを消去します。 システムによってはfilenameが空のディレクトリであっても動作しますが、 移植性を気にする場合はその動作に依存しない方が良いでしょう。

    Function: sys-rename old new
    [POSIX] ファイルoldnewにリネームします。新しい名前は 古い名前と異なるディレクトリにあってもかまいませんが、両者は同じデバイス上に なければなりません。

    Function: sys-tmpnam
    [POSIX] ユニークなファイル名を作成して返します。この関数はPOSIXに含まれていますが、 セキュリティ上の問題が指摘されており、使わない方が良いとされています。 可能なら下にあげるsys-mkstempを使って下さい。

    Function: sys-mkstemp template
    ユニークな名前を持つファイルを作成してオープンし、オープンされたポートとファイル名の 二つの値を返します。ファイルは排他的に作成されるため、レースコンディションは起こりません。 tmpnameはファイル名のプレフィックスに使われます。Unixのmkstempと違って、 パディングキャラクタをつける必要はありません。ファイルは書き込み用としてオープンされ、 パーミッションは600にセットされます。

    Function: sys-link existing new
    [POSIX] 既存のファイルexistingに対し、newという名のハードリンクを作成します。

    Function: sys-unlink pathname
    [POSIX] pathnameで示されるファイルを消去します。 pathnameはディレクトリであってはなりません。 もし消去に成功したら#tが、pathnameが存在しなければ#fが返されます。 他の場合はエラーが通知されます。

    Function: sys-symlink existing new
    existingを指すnewという名のシンボリックを作成します。 シンボリックリンクをサポートしないシステムでは、この手続きは定義されません。

    Function: sys-readlink path
    pathで示されるファイルがシンボリックリンクならば、それが指すパスを返します。 もしpathが存在しなかったり、シンボリックリンクでなければ、エラーが通知されます。 シンボリックリンクをサポートしないシステムでは、この手続きは定義されません。

    Function: sys-mkdir pathname mode
    [POSIX] ディレクトリpathnameをモードmodeで作成します。 pathnameの親ディレクトリは存在して、プロセスが書き込めるようになっていなければ なりません。中間のディレクトリも一度に作成するには、 file.utilmake-directory*が使えます (section 11.6.1 ディレクトリユーティリティ)。

    Function: sys-rmdir pathname
    [POSIX] ディレクトリpathnameを消去します。ディレクトリは空でなければなりません。 ディレクトリの内容も一緒に消去するには、file.utilremove-directory* が使えます(section 11.6.1 ディレクトリユーティリティ)。

    Function: sys-umask mode
    [POSIX] umaskをmodeにセットします。変更される前のumaskを返します。 umaskについてはman umaskを参照してください。

    6.21.3.3 パス名

    高レベルのAPIに関してはsection 11.6.2 パスネームユーティリティも参照して下さい。

    Function: sys-normalize-pathname pathname &keyword absolute expand canonicalize
    与えられたキーワード引数によってpathnameを以下のように変換します。 キーワード引数は同時に複数指定できます。
    absolute
    このキーワード引数に真の値が与えられて、pathnameが絶対パスでない場合、 pathnameの前にプロセスのワーキングディレクトリを足して絶対パスにします。
    expand
    このキーワード引数に真の値が与えられて、pathnameが`~' で始まっていた 場合、以下のように展開されます。
    • pathnameが"~"のみであるか、または"~/"で始まっている 場合、文字"~"が現在のプロセスのユーザのホームディレクトリに置き換えられます。
    • 上記以外の場合、`~'以降、`/'かpathnameの終端までの文字列 がユーザ名とみなされ、そのユーザのホームディレクトリに置換されます。もし該当するユーザが いなければエラーとなります。
    canonicalize
    パス名から "." や ".." を除き、単純化します。 この操作は実際のファイルシステムを参照せずに行われます。元のパス名がディレクトリへの シンボリックリンクを含んでいた場合、単純化されたパス名は正しくないかもしれません。

    Function: sys-basename pathname
    Function: sys-dirname pathname
    sys-basenameは与えられたパスのベース名、すなわち最後のコンポーネントを返します。 sys-dirnameは与えられたパスのディレクトリ名、すなわち最後のコンポーネント以外の コンポーネントを返します。pathnameの末尾が`/'である場合、その文字は 無視されます。
    (sys-basename "foo/bar/bar.z") => "bar.z"
    (sys-basename "coo.scm") => "coo.scm"
    (sys-basename "x/y/") => "y"
    (sys-dirname "foo/bar/bar.z") => "foo/bar"
    (sys-dirname "coo.scm") => "."
    (sys-dirname "x/y/") => "x"
    

    この手続きはpathnameが存在するかどうかはチェックしません。

    特殊なケース:

    (sys-basename "") => ""
    (sys-dirname "") => "."
    
    (sys-basename "/") => ""
    (sys-dirname "/") => "/"
    

    註:このふるまいはPerlのbasenameおよびdirnameと同様です。 システムによっては、コマンドのbasename"/"に対して"/"を、 "."に対して"."を返すものがあります。

    6.21.3.4 ファイルの状態

    高レベルのAPIに関してはsection 11.6.3 ファイル属性ユーティリティも参照して下さい。

    Function: file-exists? path
    Function: file-is-regular? path
    Function: file-is-directory? path
    それぞれ、pathが存在するか、存在してそれがレギュラーファイルであるか、 存在してそれがディレクトリであれば#tを返します。

    これらの手続きは便利であり、STkとの互換性もあるので定義されていますが、 実体は下に説明されている低レベル手続きの上に作成されています。

    Builtin Class: <sys-stat>
    ファイルシステム内のエントリの属性を表す、struct statのラッパー オブジェクトです。以下に示す読みだし専用のスロットを持ちます。

    Instance Variable: <sys-stat> type
    ファイルのタイプを示すシンボルです。
  • regular a regular file
  • directory a directory
  • character a character device
  • block a block device
  • fifo a fifo
  • symlink a symbolic link
  • socket a socket 以上のどれにも当てはまらない場合は#fが返されます。 注:いくつかのオペレーティングシステムではsocketファイルタイプを fifoと区別せず、どちらに対してもfifoを返します。 ポータブルなプログラムを書くときは注意して下さい。
  • Instance Variable: <sys-stat> perm
    パーミッションビットマスク。"mode"スロットの下位9ビットと同じですが、 便利なので独立したスロットとして提供されます。
    Instance Variable: <sys-stat> mode
    Instance Variable: <sys-stat> ino
    Instance Variable: <sys-stat> dev
    Instance Variable: <sys-stat> rdev
    Instance Variable: <sys-stat> nlink
    Instance Variable: <sys-stat> uid
    Instance Variable: <sys-stat> gid
    Instance Variable: <sys-stat> size
    struct statの該当するフィールドの値。正確な整数です。
    Instance Variable: <sys-stat> atime
    Instance Variable: <sys-stat> mtime
    Instance Variable: <sys-stat> ctime
    struct statの該当するフィールドの値を、Unix Epochからの秒数で。
    Function: sys-stat path
    Function: sys-fstat port-or-fd
    [POSIX] 与えられたパス名path、またはポートかファイルディスクリプタ port-or-fdで示されるファイルの情報を<sys-stat>オブジェクトで 返します。 sys-statは、pathがシンボリックリンクであった場合は リンクの指す先のファイルに関する情報を返します。 sys-fstatは、port-or-fdがファイルに関係ないポートであった 場合は#fを返します。
    Function: sys-lstat path
    sys-statと同じですが、pathがシンボリックリンクであった 場合はリンクそのものの情報を返します。
    gosh> (describe (sys-stat "gauche.h"))
    #<<sys-stat> 0x815af70> is an instance of class <sys-stat>
    slots:
      type      : regular
      perm      : 420
      mode      : 33188
      ino       : 845140
      dev       : 774
      rdev      : 0
      nlink     : 1
      uid       : 400
      gid       : 100
      size      : 79549
      atime     : 1020155914
      mtime     : 1020152005
      ctime     : 1020152005
    
    Function: sys-stat->mode stat
    Function: sys-stat->ino stat
    Function: sys-stat->dev stat
    Function: sys-stat->rdev stat
    Function: sys-stat->nlink stat
    Function: sys-stat->size stat
    Function: sys-stat->uid stat
    Function: sys-stat->gid stat
    Function: sys-stat->atime stat
    Function: sys-stat->mtime stat
    Function: sys-stat->ctime stat
    Function: sys-stat->file-type stat
    Deprecated. <sys-stat>オブジェクトの情報にアクセスするにはslot-refを 使って下さい。
    Function: sys-access pathname amode
    [POSIX] access(2)へのインタフェースです。pathnameへのアクセスが modeに示されるモードで許可されているかどうかを示す真偽値を返します。 modeは以下に示す定数のコンビネーション(logical or)です。
    R_OK
    pathnameをカレントユーザが読み出し可能かどうか
    W_OK
    pathnameへカレントユーザが書き込み可能かどうか
    X_OK
    pathnameをカレントユーザが実行可能かどうか(pathnameが ディレクトリの場合はサーチ可能かどうか)
    F_OK
    pathnameのパーミッションフラグにかかわらず、pathnameが 存在するかどうか (但しpathnameがあるディレクトリの読みだし許可は必要)。
    Function: sys-chmod path mode
    ファイルpathのパーミッションビットをmodeに変更します。 modeは小さな正の正確な整数で、POSIXスタイルのパーミッションビットマスク でなければなりません。
    Function: sys-chown path owner-id group-id
    ファイルpathのオーナーとグループをowner-idgruop-id で示されるものに変更します。owner-idgruop-idは正確な整数で なければなりません。どちらかに-1が渡された場合は、対応する情報は変更されません。
    Function: sys-utime path &optional atime mtime
    ファイルのアクセスタイムと変更タイムをatimemtimeが示す 値にセットします。atimemtimeが省略された場合は現在の時刻が 使われます。 section 11.6.4 ファイル操作touch-fileも参照して下さい。

    6.21.3.5 他のファイル操作

    Function: sys-chdir dir
    [POSIX] chdir(2)へのインタフェースです。 current-direoctry(section 11.6.1 ディレクトリユーティリティ)も参照して下さい。

    Function: sys-pipe &keyword (buffering :line)
    [POSIX] Creates a pipe, and returns two ports. The first returned port is an input port and the second is an output port. The data put to the output port can be read from the input port.

    Buffering can be :full, :line or :none, and specifies the buffering mode of the ports opened on the pipe. See section 6.18.3 ファイルポート, for details of the buffering mode. The default mode is sufficient for typical cases.

    (receive (in out) (sys-pipe)
      (display "abc\n" out)
      (flush out)
      (read-line in)) => "abc"
    

    Note: the returned value is changed from version 0.3.15, in which sys-pipe returned a list of two ports.

    Function: sys-mkfifo path mode
    [POSIX] creates a fifo (named pipe) with a name path and mode mode. Mode must be a positive exact integer to represent the file mode.

    Function: sys-isatty port-or-fd
    [POSIX] port-or-fd may be a port or an integer file descriptor. Returns #t if the port is connected to the console, #f otherwise.

    Function: sys-ttyname port-or-fd
    [POSIX] port-or-fd may be a port or an integer file descriptor. Returns the name of the terminal connected to the port, or #f if the port is not connected to a terminal.

    6.21.4 Unixのグループとユーザ

    6.21.4.1 Unixのグループ

    Builtin Class: <sys-group>
    Unixのグループの情報です。以下のスロットを持ちます。

    Instance Variable: <sys-group> name
    グループ名。

    Instance Variable: <sys-group> gid
    グループID

    Instance Variable: <sys-group> passwd
    グループパスワード。

    Instance Variable: <sys-group> mem
    このグループに属するユーザ名のリスト。

    Function: sys-getgrgid gid
    Function: sys-getgrnam name
    [POSIX] グループIDgidもしくはグループ名nameで示されるグループの情報を <sys-group>で返します。該当するグループが存在しない場合は #fが返されます。

    Function: sys-gid->group->name gid
    Function: sys-group-name->gid name
    グループIDとグループ名を相互変換する便利な手続きです。

    6.21.4.2 Unixのユーザ

    Builtin Class: <sys-passwd>
    Unixのユーザの情報です。以下のスロットを持ちます。

    Instance Variable: <sys-group> name
    ユーザ名。

    Instance Variable: <sys-group> uid
    ユーザID

    Instance Variable: <sys-group> gid
    ユーザのプライマリグループID。

    Instance Variable: <sys-group> passwd
    ユーザの(暗号化された)パスワード。システムがシャドウパスワードファイルを 使っている場合は、 "x" のような無意味な文字列が入っています。

    Instance Variable: <sys-group> gecos
    Gecosフィールド。

    Instance Variable: <sys-group> dir
    ユーザのホームディレクトリ。

    Instance Variable: <sys-group> shell
    ユーザのログインシェル。

    Instance Variable: <sys-group> class
    ユーザのクラス。(特定のシステムでのみ有効)。

    Function: sys-getpwuid uid
    Function: sys-getpwnam name
    [POSIX] ユーザIDuidもしくはユーザ名nameで示されるユーザの情報を <sys-passwd>で返します。該当するユーザが存在しない場合は #fが返されます。

    Function: sys-uid->user-name uid
    Function: sys-user-name->uid
    ユーザIDとユーザ名を相互変換する便利な手続きです。

    6.21.4.3 パスワードの暗号化

    Function: sys-crypt key salt
    This is the interface to crypt(3). Key and salt must be a string, and an encrypted string is returned. On systems where crypt(3) is not available, call to this function signals an error.

    6.21.5 ロケール

    Function: sys-setlocate category locale
    [POSIX] カテゴリーcategoryのロケールをlocaleにセットします。 categoryは整数でなければなりません;以下の変数がcategoryの ために定義されています。localeはロケールを表す文字列です。 成功した場合は新しいロケール名を、ロケールが変更できなかった場合は#fを 返します。

    Variable: LC_ALL
    Variable: LC_COLLATE
    Variable: LC_CTYPE
    Variable: LC_MONETARY
    Variable: LC_NUMERIC
    Variable: LC_TIME
    sys-setlocalecategoryに渡せる数値を定義しています。

    Function: sys-localeconv
    [POSIX] 現在のロケールで数値をフォーマットする際に必要な様々な情報をassoc listに して返します。

    例を示します。あなたのシステム設定によっては異なる結果になるかもしれません。

    (sys-localeconv)
     =>
       ((decimal_point . ".") (thousands_sep . "")
        (grouping . "") (int_curr_symbol . "")
        (currency_symbol . "") (mon_decimal_point . "")
        (mon_thousands_sep . "") (mon_grouping . "")
        (positive_sign . "") (negative_sign . "")
        (int_frac_digits . 127) (frac_digits . 127)
        (p_cs_precedes . #t) (p_sep_by_space . #t)
        (n_cs_precedes . #t) (n_sep_by_space . #t)
        (p_sign_posn . 127) (n_sign_posn . 127))
    
    (sys-setlocale LC_ALL "fr_FR")
     => "fr_FR"
    
    (sys-localeconv)
     =>
      ((decimal_point . ",") (thousands_sep . "")
       (grouping . "") (int_curr_symbol . "FRF ")
       (currency_symbol . "F") (mon_decimal_point . ",")
       (mon_thousands_sep . " ") (mon_grouping . "\x03\x03")
       (positive_sign . "") (negative_sign . "-")
       (int_frac_digits . 2) (frac_digits . 2)
       (p_cs_precedes . #f) (p_sep_by_space . #t)
       (n_cs_precedes . #f) (n_sep_by_space . #t)
       (p_sign_posn . 1) (n_sign_posn . 1))
    

    6.21.6 シグナル

    Gaucheでは、OSのシグナルを自分自身や他のプロセスに送ったり、 送られたシグナルを処理することができます。

    マルチスレッド環境では、全てのスレッドがシグナルハンドラを共有し、 各スレッドが独自のシグナルマスクを持ちます。 詳しくはsection 6.21.6.5 シグナルとスレッドを参照して下さい。

    6.21.6.1 シグナルとシグナルセット

    シグナルはオペレーティングシステムで定義された小さな整数値で表現されます。 システムのシグナル番号に束縛された変数が定義されています。 システムのシグナル番号はアーキテクチャによって異なるので、 なるべく変数を利用するようにして下さい。

    Variable: SIGABRT
    Variable: SIGALRM
    Variable: SIGCHLD
    Variable: SIGCONT
    Variable: SIGFPE
    Variable: SIGHUP
    Variable: SIGILL
    Variable: SIGINT
    Variable: SIGKILL
    Variable: SIGPIPE
    Variable: SIGQUIT
    Variable: SIGSEGV
    Variable: SIGSTOP
    Variable: SIGTERM
    Variable: SIGTSTP
    Variable: SIGTTIN
    Variable: SIGTTOU
    Variable: SIGUSR1
    Variable: SIGUSR2
    これらの変数はPOSIXで定義された対応するシグナルの番号に束縛されています。

    Variable: SIGTRAP
    Variable: SIGIOT
    Variable: SIGBUS
    Variable: SIGSTKFLT
    Variable: SIGURG
    Variable: SIGXCPU
    Variable: SIGXFSZ
    Variable: SIGVTALRM
    Variable: SIGPROF
    Variable: SIGWINCH
    Variable: SIGPOLL
    Variable: SIGIO
    Variable: SIGPWR
    これらの変数はシステム依存のシグナル番号に束縛されています。 全てのシステムで全てのシグナルがサポートされているわけではありません。

    それぞれのシグナル番号の他に、<sys-sigset>オブジェクトを使って シグナルの集合を扱うことができます。シグナルの集合はシグナルマスクを操作したり、 ひとつのシグナルハンドラを多数のシグナルに同時に設定したりする際に使えます。

    Class: <sys-sigset>
    シグナルの集合を表します。空のシグナルの集合は次の式で作成できます:
    (make <sys-sigset>)
    

    Function: sys-sigset-add! sigset signal ...
    Function: sys-sigset-delete! sigset signal ...
    sigset<sys-sigset>オブジェクトでなければなりません。 これらの手続きはsigsetに指定されたシグナルを追加、 もしくはsigsetから指定されたシグナルを削除します。 変更されたsigsetが返されます。

    Function: sys-sigset-fill! sigset
    Function: sys-sigset-empty! sigset
    システムで定義された全てのシグナルをsigsetにセット、 もしくはsigsetを空にします。

    Function: sys-signal-name signal
    シグナルの名前を返します。

    6.21.6.2 シグナルの送出

    シグナルを送るには、sys-killを使うことができます。 これはシステムのkill(2)のように動作します。

    Function: sys-kill pid sig
    [POSIX] シグナルsigを指定されたプロセス(群)に送ります。 sigは正確な正整数でなければなりません。pidは正確な整数でなければ ならず、次のルールで対象となるプロセスを指定します。
    • pidが正ならば、それがそのまま対象となるプロセスIDです。
    • pidがゼロならば、シグナルは現在のプロセスのプロセスグループ内の全ての プロセスに送られます。
    • pidが-1より小さければ、シグナルはプロセスグループIDが-pidである 全てのプロセスに送られます。

    POSIXのraise()に対応するScheme関数はありませんが、 (sys-kill (sys-getpid) sig) で同じことができます。

    6.21.6.3 シグナルの処理

    Schemeでシグナルを処理する手続きを登録できます。 (マルチスレッド環境では、シグナルハンドラの設定は全てのスレッドで共有されます。 section 6.21.6.5 シグナルとスレッドを参照して下さい)。

    シグナルがSchemeプロセスに送られると、それはVM中のキューに入れられます。 VMは「安全なポイント」に達した時にキューを検査し、シグナルが届いていれば それを順に処理します。 (このメカニズムのため、SIGILLのようなシグナルはSchemeレベルでは 処理できません。そのシグナルをキューに入れた後でプロセスが処理を続行できない からです)。

    goshインタプリタを使っている場合、デフォルトでのシグナルの処理は 次のように設定されています。

    SIGABRT, SIGILL, SIGKILL, SIGCONT, SIGSTOP, SIGSEGV, SIGBUS
    Schemeでは処理できません。goshではこれらのシグナルを受けると システムのデフォルトの動作をします。
    SIGCHLD, SIGTSTP, SIGTTIN, SIGTTOU, SIGWINCH
    goshは初期状態ではこれらのシグナルのハンドラを設定せず、 システムのデフォルトの振るまいに任せます。Schemeプログラムは必要ならば これらのシグナルのハンドラを設定できます。
    SIGHUP, SIGQUIT, SIGTERM
    goshはこれらのシグナルに対して、終了コード0でアプリケーションを 終了するシグナルハンドラをセットします。
    SIGPWR, SIGXCPU, SIGUSR1, SIGUSR2
    Linuxプラットフォームでスレッドを使用している場合は、 これらのシグナルはシステムで使用されるため、Schemeからは使用できません。 他のシステムではこれらのシグナルは下記の「他のシグナル」と同じ動作と なります。
    他のシグナル
    goshはデフォルトのシグナルハンドラを設定します。 デフォルトのシグナルハンドラは "unhandled signal" エラーを通知します。 Schemeプログラムはシグナル毎に独自のハンドラを設定することが可能です。

    goshでなく、他のアプリケーションに埋め込まれたGaucheを使っている場合、 Schemeレベルでのシグナルの使用をアプリケーションが制限している場合があります。

    Schemeからシグナルハンドラを設定するには以下の手続きを使って下さい。

    Function: set-signal-handler! signals handler
    signalsはシグナル番号か<sys-sigset>オブジェクト、 handler#t#f、一つの引数を取る手続きのいずれか でなければなりません。 handlerが手続きの場合、プロセスが指定されたシグナル(のうちのいずれか)を 受けた時に、そのシグナル番号を引数としてhandlerが呼ばれます。 handlerの中でできる操作にはほとんど制限がありません。 handlerからエラーを投げたり、他の場所で補足された継続を呼ぶことも できます。但し、handler内で補足した継続はhandlerから 戻った時点で無効になります。

    handler#tの場合、指定されたシグナルにはオペレーティングシステムの デフォルトの振るまいが設定されます。 handler#fの場合、指定されたシグナルは無視されます。

    マルチスレッドプログラムでは、 シグナルハンドラの設定はスレッド間で共有されることに注意して下さい。 ハンドラはシグナルを受けたスレッドで実行されます。 詳しくはsection 6.21.6.5 シグナルとスレッドを参照して下さい。

    Function: get-signal-handler signum
    シグナルsignumに設定されたハンドラを返します。

    Function: get-signal-handlers
    現在の全てのシグナルハンドラの設定を連想リストにして返します。 返されるリストの各要素のcarには<sys-sigset>オブジェクトが、 cdrにはそれらのシグナルに対応するハンドラ(手続きもしくはブール値)がセットされて います。

    Macro: with-signal-handlers (handler-clause ...) thunk
    thunkの実行中だけシグナルハンドラを一時的に設定する便利なマクロです (このマクロは便利ですが下に述べるような多少危険な性質もあるので、 注意して使って下さい)。

    handler-clauseは以下のいずれかの形式です

    (signals expr ...)
    signalsは、評価された時に単独のシグナル番号、シグナル番号のリスト、 あるいは<sys-sigset>オブジェクトを生成する式でなければなりません。 signalsに含まれるシグナルを受け取った時に、expr ...を 評価するようなハンドラを設定します。
    (signals => proc)
    signalsは上と同じです。signalsに含まれるシグナルに 対して、一つの引数を取る手続きprocをハンドラとして設定します。

    thunkから制御が抜けた時に、with-signal-handlersが呼ばれた時点での シグナルハンドラが再設定されます。

    注意: このフォームで一つ以上のシグナルハンドラを設定する場合、 それらは順にシステムに設定されます。全てのハンドラの設定が終る前に シグナルが届いた場合、シグナルハンドラの設定や再設定が不完全なままになる かもしれません。また、シグナルハンドラはグローバルな設定であり、 「スレッドローカル」なハンドラを設定することはできませんが、 with-signal-handlersの形式はそれを誤解させるかもしれません。

    6.21.6.4 シグナルのマスクと待機

    A Scheme program can set a signal mask, which is a set of signals to be blocked from delivery. If a signal is delivered which is completely blocked in the process, the signal becomes "pending". The pending signal may be delivered once the signal mask is changed not to block the specified signal. (However, it depends on the operating system whether the pending signals are queued or not.)

    In multithread environment, each thread has its own signal mask.

    Function: sys-sigmask how mask
    Modifies the current thread's signal mask, and returns the previous signal mask. Mask should be a <sys-sigset> object. How argument should be one of the following integer constants:
    SIG_SETMASK
    Sets mask as the thread's signal mask.
    SIG_BLOCK
    Adds signals in mask to the thread's signal mask.
    SIG_UNBLOCK
    Removes signals in mask from the thread's signal mask.

    Function: sys-sigsuspend mask
    Atomically sets thread's signal mask to mask and suspends the calling thread. When a signal that is not blocked and has a signal handler installed is delivered, the associated handler is called, then sys-sigsuspend returns.

    6.21.6.5 シグナルとスレッド

    The semantics of signals looks a bit compilated in the multithread environment. Nevertheless, it is pretty comprehensible once you remember a small number of rules. Besides, Gauche sets up the default behavior easy to use, while allowing programmers to do tricky stuff.

    If you don't want to be bothered by the details, just remember one thing, with one sidenote. By default, signals are handled by the primordial (main) thread. However, if the main thread is suspended on mutex or condition variable, the signal may not be handled at all, so be careful.

    Now, if you are curious about the details, here are the rules:

    Now, these rules have several implications.

    If there are more than one thread that don't block a particular signal, you can't know which thread receives the signal. Such a situation is much less useful in Gauche than C programs because of the fact that the signal handling can be delayed indefinitely if the receiver thread is waiting on mutex or condition variable. So, it is recommended to make sure, for each signal, there is only one thread that can receive it.

    In Gauche, all threads created by make-thread (See section 9.22.1 Thread procedures) blocks all the signals by default (except the reserved ones). This lets all the signals to be directed to the primordial (main) thread.

    Another strategy is to create a thread dedicated for handling signals. To do so, you have to block the signals in the primordial thread, then create the signal-handling thread, and within that thread you unblock all the signals. Such a thread can just loop on sys-pause.

    (thread-start!
      (make-thread
        (lambda ()
          (sys-sigmask SIG_SETMASK (make <sys-sigset>)) ;;empty mask
          (let loop () (sys-pause) (loop)))))
    

    Complicated application may want to control per-thread signal handling precisely. You can do so, just make sure that at any moment only the designated thread unblocks the desired signal.

    6.21.7 システムへの問い合わせ

    Function: sys-uname
    [POSIX] Returns a list of five elements, (sysname nodename release version machine).

    Function: sys-gethostname
    Returns the host name. If the system doesn't have gethostname(), the second element of the list returned by sys-uname is used.

    Function: sys-getdomainname
    Returns the domain name. If the system doesn't have getdomainname(), "localdomain" is returned.

    Function: sys-getcwd
    [POSIX] Returns the current working directory by a string. If the current working directory couldn't be obtained from the system, an error is signalled. See also sys-chdir (See section 6.21.3.5 他のファイル操作), current-directory (See section 11.6.1 ディレクトリユーティリティ).

    Function: sys-getgid
    Function: sys-getegid
    [POSIX] Returns integer value of real and effective group id of the current process, respectively.

    Function: sys-setgid gid
    [POSIX] Sets the effective group id of the current process.

    Function: sys-getuid
    Function: sys-geteuid
    [POSIX] Returns integer value of real and effective user id of the current process, respectively.

    Function: sys-setuid uid
    [POSIX] Sets the effective user id of the current process.

    Function: sys-getgroups
    [POSIX] Returns a list of integer ids of supplementary groups.

    Function: sys-getlogin
    [POSIX] Returns a string of the name of the user logged in on the controlling terminal of the current process. If the system can't determine the information, #f is returned.

    Function: sys-getpgrp
    [POSIX] Returns a process group id of the current process.

    Function: sys-getpgid pid
    Returns a process group id of the process specified by pid. If pid is zero, the current process is used.

    Note that getpgid() call is not in POSIX. If the system doesn't have getpgid(), sys-getpgid still works if pid is zero (it just calls sys-getpgrp), but signals an error if pid is not zero.

    Function: sys-setpgid pid pgid
    [POSIX] Sets the process group id of the process pid to pgid. If pid is zero, the process ID of the current process is used. If pgid is zero, the process ID of the process specified by pid is used. (Hence sys-setpgid(0, 0) sets the process group id of the current process to the current process id).

    Function: sys-setsid
    [POSIX] Creates a new session if the calling process is not a process group leader.

    Function: sys-getpid
    Function: sys-getppid
    [POSIX] Returns the current process id and the parent process id, respectively.

    Function: sys-times
    [POSIX]

    Function: sys-ctermid
    [POSIX] Returns the name of the controlling terminal of the process. This may be just a "/dev/tty". See also sys-ttyname.

    6.21.8 時間

    Gaucheでは時間は2種類の表現を持ちます。ひとつはPOSIX APIとコンパチブルな 表現で、もう一つはSRFI-18、SRFI-19、SRFI-21とコンパチブルな表現です。 多くの手続きはどちらの表現も理解しますが、そうでない場合は 適用可能な表現を'POSIX time'または'SRFI time'と表記します。

    POSIX timeは実数で、Unix Epoch(Jan 1, 1970, 0:00:00GMT)からの秒数で 表現されます。POSIXのtime(2)に対応するsys-time手続きは この表現を返します。

    SRFI互換の時間は<time>クラスのインスタンスとして表現され、 秒、およびナノ秒のスロットを持ちます。 また、時間の種別(UTC、TAI、期間、プロセス時間、他)も保持しています。 Current-timeはこの表現を返します。

    6.21.8.1 POSIX time

    Function: sys-time
    [POSIX] Returns the current time in POSIX time (the time since Epoch (00:00:00 UTC, January 1, 1970), measured in seconds). It may be a non-integral number, depending on the architecture.

    Note that POSIX's definition of "seconds since the Epoch" doesn't take leap seconds into acount.

    Function: sys-gettimeofday
    Returns two values. The first value is a number of seconds, and the second value is a fraction in a number of microseconds, since 1970/1/1 0:00:00 UTC. If the system doesn't have gettimeofday call, this function calls time(); in that case, microseconds portion is always zero.

    Builtin Class: <sys-tm>
    Represents struct tm, a calendar date. It has the following slots.
    Instance Variable: <sys-tm> sec
    Seconds. 0-61.
    Instance Variable: <sys-tm> min
    Minutes. 0-59.
    Instance Variable: <sys-tm> hour
    Hours. 0-23.
    Instance Variable: <sys-tm> mday
    Day of the month, counting from 1. 1-31.
    Instance Variable: <sys-tm> mon
    Month, counting from 0. 0-11.
    Instance Variable: <sys-tm> year
    Years since 1900, e.g. 102 for the year 2002.
    Instance Variable: <sys-tm> wday
    Day of the week. Sunday = 0 .. Saturday = 6.
    Instance Variable: <sys-tm> yday
    Day of tye year. January 1 = 0 .. December 31 = 364 or 365.
    Instance Variable: <sys-tm> isdst
    A flag that indicates if the daylight saving time is in effect. Positive if DST is in effect, zero if not, or negative if unknown.

    Function: sys-gmtime time
    Function: sys-localtime time
    [POSIX] Converts time to <sys-tm> object, represented in GMT or local timezone, respectively. Time can be either POSIX-time or SRFI-time.

    Function: sys-ctime time
    [POSIX] Converts time to it string representation, using POSIX ctime(). Time can be either POSIX-time or SRFI-time.

    Function: sys-difftime time1 time0
    [POSIX] Returns the difference of two times in the real number of seconds. Time0 and tiem1 can be either POSIX-time or SRFI-time.

    Function: sys-asctime tm
    [POSIX] Converts <sys-tm> object tm to a string representation.

    Function: sys-strftime format tm
    [POSIX] Converts <sys-tm> object tm to a string representation, according to a format string format.

    Function: sys-mktime tm
    [POSIX] Converts <sys-tm> object tm, expressed as local time, to the POSIX-time (number of seconds since Epoch).

    Function: sys-tm->alist tm
    (Deprecated function)

    6.21.8.2 SRFI time

    Builtin Class: <time>
    The <time> object also represents a point of time.

    Instance Variable: <time> type
    Indicates time type. time-utc is the default, and that represents the number of seconds since Unix Epoch. SRFI-19 (See section 10.9 srfi-19 - 時間のデータ型と手続き) adds more types.
    Instance Variable: <time> second
    Second part of the time.
    Instance Variable: <time> nanosecond
    Nanosecond part of the time.

    Function: current-time
    [SRFI-18][SRFI-21] Returns the <time> object representing the current time in time-utc. See section 10.9 srfi-19 - 時間のデータ型と手続き, for it redefines current-time to allow optional argument to specify time type.

    Function: time? obj
    [SRFI-18][SRFI-19][SRFI-21] Returns #t if obj is a time object.

    Function: time->seconds time
    Function: seconds->time seconds
    [SRFI-18][SRFI-21] Converts between time object and the number of seconds (POSIX-time). Time argument of time->seconds has to be a <time> object.

    6.21.9 Unixのプロセス管理

    6.21.9.1 forkとexec

    Function: sys-system command
    [POSIX] Runs command in a subprocess. command is usually passed to sh, so the shell metacharacters are interpreted.

    This function returns an integer value system() returned. Since POSIX doesn't define what system() returns, you can't interpret the returned value in a portable way.

    Function: sys-fork
    [POSIX] Fork the current process. Returns 0 if you're in the child process, and a child process' pid if you're in the parent process. All the opened file descriptors are shared between the parent and the child. See fork(2) of your system for details.

    If the forked process runs some Scheme code and exits instead of calling sys-exec, the forked process should call sys-exit to terminate itself. Normal exit call tries to flush the file buffers, and on some OS it messes up the parent's file buffers.

    Function: sys-exec command args &optional iomap
    [POSIX+] Execute command with args, a list of arguments. The current process image is replaced by command, so this function never returns.

    All elements of args must be strings. The first element of args is used as argv[0], i.e. the program name.

    The optional iomap argument, when provided, specifies how the open file descriptors are treated. It must be the following format:

    ((to-fd . from-port-or-fd) ...)
    

    To-fd must be an integer, and from-port-or-fd must be an integer file descriptor or a port. Each element of the list makes the file descriptor of from-port-or-fd of the current process be mapped to the file descriptr to-fd in the executed process.

    If iomap is provided, any file descriptors other than specified in the iomap list will be closed before exec(). Otherwise, all file descriptors in the current process remain open.

    (sys-exec "ls" '("ls" "-l")) => ;; ls is executed.
    
    (sys-exec "ls" '("ls" "-l") '((1 . 2) (1 . 1)))
       => ;; ls is executed, with its stderr and stdout are mapped to the
                  current process's stdout.
    

    When it encounters an error, most of the time it raises an error condition. Once the file descriptors are permuted, however, it would be impractical to handle errors in reasonable way (you don't even know stderr is still available!), so Gauche simply exits on the error.

    See also section 9.14 gauche.process - 高レベルプロセスインタフェース, which provides more convenient process handling on top of above primitives.

    6.21.9.2 Wait

    Function: sys-wait
    [POSIX] Calls system's wait(2). The process suspends its execution until one of the child terminates. Returns two exact integer values, the first one is the child's process id, and the second is a status code. The status code can be interpreted by the following functions.

    Function: sys-waitpid pid &keyword nohang untraced
    [POSIX] This is an interface to waitpid(3), an extended version of wait.

    pid is an exact integer specifying which child(ren) it's waiting. If it is a positive integer, it waits fot that specific child. If it is zero, it waits for any member of this process group. If it is -1, it waits for any child process. If it is less than -1, it waits for any child process whose process group id is equal to the absolute value of pid.

    The calling process suspends until one of those child process is terminated, unless true is specified to the keyword argument nohang.

    If true is specified to the keyword argument untraced, the status of stopped child process can be also returned.

    The return values are two exact integers, the first one is the child process id, and the second is a status code. If nohang is true and no child process status is available, the first value is zero.

    Function: sys-wait-exited? status
    Function: sys-wait-exit-status status
    [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-exited? returns #t if the child process is terminated normally. sys-wait-exit-status returns the exit code the child process passed to exit(2), or the return value of main().

    Function: sys-wait-signaled? status
    Function: sys-wait-termsig status
    [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-signaled? returns #t if the child process is termintaed by an uncaught signal. sys-wait-termsig returns the signal number that terminted the child.

    Function: sys-wait-stopped? status
    Function: sys-wait-stopsig status
    [POSIX] The argument is an exit status returned as a second value from sys-waitpid. sys-wait-stopped? returns #t if the child process is stopped. This status can be caught only by sys-waitpid with true untraced argument. sys-wait-stopsig returns the signum number that stopped the child.

    6.21.10 I/Oの多重化

    The interface functions for select(2). The higher level interface is provided on top of these primitives; see section 9.17 gauche.selector - 簡単なディスパッチャ.

    Builtin Class: <sys-fdset>
    Represents fd_set, a set of file descriptors. You can make an empty file descriptor set by make method:
    (make <sys-fdset>)
    

    Function: sys-fdset-ref fdset port-or-fd
    Function: sys-fdset-set! fdset port-or-fd flag
    Gets and sets specific file descritor bit of fdset. port-or-fd may be a port or an integer file descriptor. If port-or-fd is a port that doesn't have associated file descriptor, sys-fdset-ref returns #f, and sys-fdset-set! doesn't modify fdset. flag must be a boolean value.

    You can use generic setter of sys-fdset-ref as this:

    (set! (sys-fdset-ref fdset port-or-fd) flag)
      == (sys-fdset-set! fdset port-or-fd flag)
    

    Function: sys-fdset-max-fd fdset
    Returns the maximum file descriptor number in fdset.

    Function: sys-select readfds writefds exceptfds &optional timeout
    Function: sys-select! readfds writefds exceptfds &optional timeout
    Waits for a set of file descriptors to change status. readfds, writefds, and exceptfds are <fdset> objects to represent a set of file descriptors to watch. File descriptors in readfds are watched to see if characters are ready to be read. File descriptors in writefds are watched if writing to them is ok. File descriptors in exceptfds are watched for exceptions. You can pass #f to one or more of those arguments if you don't care about watching the condition.

    timeout specifies maximum time sys-select waits for the condition change. It can be a real number, for number of microseconds, or a list of two integers, the first is the number of seconds and the second is the number of microseconds. If you pass #f, sys-select waits indefinitely.

    sys-select returns four values. The first value is a number of descriptors it detected status change. It may be zero if timeout expired. The second, third and fourth values are <fdset> object that contains a set of descriptors that changed status for reading, writing, and exception, respectively. If you passed #f to one or more of readfds, writefds and exceptfds, the corresponding return value is #f.

    sys-select! variant works the same as sys-select, except it modifies the passed <fdset> arguments. sys-select creates new <fdset> objects and doesn't modify its arguments.

    6.21.11 その他のシステムコール

    Function: sys-pause
    [POSIX] Suspends the process until it receives a signal whose action is to either execute a signal-catching function or to terminate the process. This function only returns when the signal-catching function returns. The returned value is undefined.

    Note that just calling pause() doesn't suffice the above semantics in Scheme-level. Internally this procedure calls sigsuspend() with the current signal mask.

    Function: sys-alarm seconds
    [POSIX] Arranges a SIGALRM signal to be delivered after seconds. The previous settings of the alarm clock is cancelled. Passing zero to seconds doesn't schedule new alarm. Returns the number of seconds remaining until previously scheduled alarm was due to be delivered (or zero if no alarm is active).

    Function: sys-sleep seconds
    [POSIX] Suspends the process until the specified number of seconds elapses, or the process receives a signal. Returns zero if it sleeps well, or the number of unslept seconds if it is woke up by a signal.

    To be porable across POSIX implementation, keep seconds less than 65536.

    Function: sys-nanosleep nanoseconds
    [POSIX] Suspends the process until the specified number of nanoseconds elapses, or the process receives a signal. The argument nanoseconds can be a <time> object (See section 6.21.8.2 SRFI time), or a real number. Returns #f if nanoseconds elapsed, or a <time> object that indicates the remaining time if sys-nanosleep is interrupted by a signal.
    ;wait for 0.5 sec
    (sys-nanosleep 500000000)
    
    ;wait for 1.3 sec
    (sys-nanosleep (make <time> :second 1 :nanosecond 300000000)
    

    Function: sys-random
    Function: sys-srandom seed
    A pseudo random number generator. sys-random returns a random number between 0 and a positive integer rand_max, inclusive. This is a straightforward interface to random(3). If the underlying system doesn't have random(3), lrand48(3) is used.

    sys-srandom sets the seed of the random number generator. It uses either srandom(3) or srand48(3), depending on the system.

    The intension of these functions are to provide an off-the-stock handy random number generator (RNG) for applications that doens't sensitive to the quality and/or speed of RNG. For serious statistics analysis, use Mersenne Twister RNG in math.mt-random module (See section 11.8 math.mt-random - Mersenne Twister乱数発生器).

    Variable: RAND_MAX
    Bound to a positive integer that sys-random may return.

    7. オブジェクトシステム

    7.1 一般的な問い合わせ

    Function: class-of obj
    Returns a class metaobject of obj.

    Function: is-a? obj class
    Returns true if obj is an instance of class or an instance of descendants of class.

    7.2 クラスの定義

    A class is a first-class object in Gauche and you can create it on the fly at run-time using procedure calls. However, for convenience, a macro is defined to create a class and bind it globally.

    Macro: define-class name supers (slot-spec ...) option ...
    Creates a class object according to the arguments, and globally bind it to a variable name. This macro should be used at toplevel.

    Supers is a list of direct superclasses from which this class inherits. You can use multiple inheritance. See section 7.2.1 多重継承 below, for the rule that determines precedence of inheritance chain.

    Slot-spec is a specification of a "slot", sometimes known as a "field" or an "instance variable" (but you can specify "class variable" in slot-spec as well). The simplest form of slot-spec is just a symbol, which names the slot. Or you can give a list, whose first element is a symbol and whose rest is an interleaved list of keywords and values. The list form not only defines a name of the slot but specifies behavior of the slot. See section 7.2.2 スロットの記述, for details.

    Finally, option ... is an interleaved list of keywords and values, specifies how class object should be created. This macro recognizes one keyword, :metaclass, whose corresponding value is used for metaclass (class that instantiates another class). Other options are passed to the make method to create the class object. See section 7.6.3 クラスのインスタンシエーション, for the usage of metaclass.

    7.2.1 多重継承

    7.2.2 スロットの記述

    7.3 メソッドの定義

    Macro: define-generic name

    Macro: define-method name specs body

    7.4 インスタンスの作成

    Generic Function: make class arg ...

    Method: make (class <class>) arg ...

    Method: make (class <method>) arg ...
    Method: make (class <generic>) arg ...

    Method: initialize (class <class>) initargs

    7.5 インスタンスへのアクセス

    Function: slot-ref obj slot

    Function: slot-set! obj slot

    Function: slot-bound? obj slot

    Function: slot-exists? slot

    Generic Function: slot-unbound

    Method: slot-unbound (class <class>) obj slot

    Generic Function: slot-missing

    Method: slot-missing (class <class>) obj slot &optional value

    Function: class-slot-ref class slot-name
    Function: class-slot-set! class slot-name obj

    7.6 メタオブジェクトプロトコル

    7.6.1 システムメタクラス

    Class: <top>

    Class: <class>

    Class: <generic>

    Class: <method>

    Class: <object>

    7.6.2 クラスのイントロスペクション

    7.6.2.1 クラスメタオブジェクト

    Function: class-name class

    Function: class-precedence-list class

    Function: class-direct-supers class

    Function: class-direct-slots class

    Function: class-slots

    7.6.2.2 スロット定義

    Class: <slot-accessor>

    Function: class-slot-definition class slot-name

    Function: class-slot-accessor class slot-name

    Function: slot-definition-name slot-def
    Function: slot-definition-allocation slot

    Function: slot-definition-getter slot
    Function: slot-defininion-setter slot
    Function: slot-definition-accessor slot

    Function: slot-definition-options slot-def
    Function: slot-definition-option slot-def key &optional default

    7.6.3 クラスのインスタンシエーション

    Method: make (class <class>) &rest initargs

    7.6.4 スロットアクセスのカスタマイズ

    Generic Function: compute-slots

    Generic Function: compute-get-n-set

    Function: slot-ref-using-accessor obj slot-accessor
    Function: slot-set-using-accessor obj slot-accessor value

    7.6.5 メソッドのインスタンシエーション

    Method: make (class <method>) &rest initargs

    7.6.6 メソッド適用のカスタマイズ

    Generic Function: apply-generic gf args

    Generic Function: sort-applicable-methods gf methods args

    Generic Function: method-more-specific? method1 method2 classes

    Generic Function: apply-methods gf methods args

    Generic Function: apply-method gf method build-next args

    8. ライブラリモジュール - 概要

    続くいくつかの章で、Gaucheのディストリビューションに含まれる ライブラリモジュールを解説します。 これらのモジュールを使うにあたっては、特に断りのない限り、 モジュールをロードしてimportすることが必要です (通常はuseマクロが使えます。section 4.11.3 モジュールの使用参照)。

    section 9. ライブラリモジュール - Gauche拡張モジュールでは、 gauche.*モジュールを解説します。 これらのモジュールはGaucheのコアの機能ですが、使用頻度が少ないために モジュールとして分離されたものです。 (一部のモジュールはそれほど重要ではありませんが、 歴史的な理由からこのカテゴリに含まれています)。 このカテゴリに含まれるモジュールには、システムAPI (gauche.fcntlgauche.termios等)、ネットワーキング(gauche.net)、 スレッドAPI (gauche.threads)、 それからGaucheの低レベルのコアAPIの上に実装された高レベルなルーチン (gauche.processgauche.regexp等) があります。

    section 10. ライブラリモジュール - SRFIでは、SRFIの機能を提供するモジュールを 解説します。一部のSRFIはGaucheのコアに組み込まれており、 この章には挙げられていないことに注意して下さい。 サポートされている全てのSRFIのリストはsection 2.1 標準への準拠にあります。

    section 11. ライブラリモジュール - ユーティリティ ではその他のさまざまなユーティリティ 関数を提供するモジュールを解説します。dbmスタイルのデータベース インタフェース、ファイルシステムユーティリティ、ネットワークプロトコルユーティリティ 等があります。

    下の表は、モジュールの名前付けの分類を示します。 外部モジュール、及び将来予定されているモジュールも含みます。

    data.*
    汎用的なデータ構造。(予定)
    dbm.*
    DBMインタフェース
    gauche.*
    Gauche本体の一部として考えられている機能。
    gl.*
    OpenGLバインディングと関連するライブラリ (外部パッケージ)。
    gtk.*
    GTk+バインディングと関連するライブラリ (外部パッケージ)。
    file.*
    ファイルとディレクトリの操作。
    lang.*
    言語に関するライブラリ(人工的なものも自然言語関連も)。(予定)
    math.*
    数学。
    compat.*
    他の実装とのコンパチビリティに関するライブラリ。 (予定)
    rfc.*
    RFCで定義されているデータフォーマットやネットワークプロトコルの実装。
    srfi-*
    SRFIの実装
    text.*
    テキストデータを扱うライブラリ
    util.*
    汎用的なアルゴリズムの実装。
    www.*
    WWWで主として使われるプロトコルやデータフォーマットの実装。

    9. ライブラリモジュール - Gauche拡張モジュール

    9.1 gauche.array - 配列

    Module: gauche.array
    このモジュールは多次元配列のデータタイプとそれに関する操作を提供します。 プリミティブなAPIはSRFI-25で定義されているものに従います。 さらにいくつかの便利な操作も定義されています。 また、SRFI-10を使った配列の外部表現も実装されます。

    N次元の配列の各エレメントはN個の整数のインデックス [ i_0 i_1 ... i_N-1 ]でアクセスされます。 配列は、各次元のインデックスの下限s_kおよび上限e_kを決める shapeを持っています。ここで、s_k <= e_kであり、 k次元目のインデックスi_ks_k <= i_k < e_k を満たすものとします。 (s_k == e_k であるような配列も作れますが、 その配列にはデータをストアすることはできません。 また、0次元の配列は作れます。それは一つだけデータを保持できます)。 Shapeはそれ自体が [ D x 2 ] の配列です。 ここでDはそのshapeが表現する配列の次元数です。

    配列のプリミティブに対しインデックスを渡すにはいくつか方法があります。 各インデックスをばらばらの引数として渡すこともできますし、 ベクタや1次元の配列にパックして渡すこともできます。 後者においてインデックスがパックされたベクタや配列を「インデックスオブジェクト」 と呼ぶことがあります。Gaucheでは、配列の要素に次々とアクセスするような処理では ベクタをインデックスオブジェクトとして使うと若干効率が良いでしょう。

    配列はequal?手続きで比較することが出来ます。 二つの配列のshapeが等しく、また対応する各要素がequal?の意味で 等しい場合に二つの配列はequal?であると見なされます。

    内部的には、配列は1次元のインデックスでアクセスされるバッキングストレージと、 多次元のインデックスをバッキングストレージへのインデックスにマップする手続きとから 構成されています。

    Class: <array>

    Reader syntax: #,(<array> shape obj ...)
    配列をこの形式で書き出されます。shapeは偶数個の整数のリストで、 2n番目の整数がn次元目のインデックスの下限を、2n+1番目の 整数がn次元目のインデックスの上限(+1)を表します。 その後に、配列の要素がrow-majorの順で書き出されます。

    この構文が読み込まれると、もとの配列とequal?である配列が作成されます。

    ; 次のような配列:
    ;   8 3 4
    ;   1 5 9
    ;   6 7 2
    #,(<array> (0 3 0 3) 8 3 4 1 5 9 6 7 2)
    
    ; 4x4の単位行列
    #,(<array> (0 4 0 4) 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1)
    

    Function: array? obj
    [SRFI-25] objが配列であれば#tが、そうでなければ#fが返されます。

    Function: make-array shape &optional init
    [SRFI-25] Shapeがshapeである配列を作成します。 Shapeは [ D x 2 ] の配列で、 0 <= k < D なる各kに対して要素 [ k 0 ] は 要素[ k 1 ]以下でなければなりません。 initが与えられた場合は、配列の各要素がinitで初期化されます。 initが与えられなかった場合の配列の要素の初期値は不定です。
    (make-array (shape 0 2 0 2 0 2) 5)
     => #,(<array> (0 2 0 2 0 2) 5 5 5 5 5 5 5 5)
    

    Function: shape bound ...
    [SRFI-25] 偶数個の正確な整数を引数に取り、配列のshapeとして使える2次元の配列を返します。
    (shape 0 2 1 3 3 5)
     => #,(<array> (0 3 0 2) 0 1 3 2 3 5)
    
    (shape)
     => #,(<array> (0 0 0 2))
    

    Function: array shape init ...
    [SRFI-25] Shapeがshapeであるような配列を作成し、 その要素をinit ...で初期化します。
    (array (shape 0 2 1 3) 'a 'b 'c 'd)
     => #,(<array> (0 2 1 3) a b c d)
    

    Function: array-rank array
    [SRFI-25] 配列arrayの次元数を返します。
    (array-rank (make-array (shape 0 2 0 2 0 2))) => 3
    (array-rank (make-array (shape))) => 0
    

    Function: array-shape array
    配列arrayのshapeを表す配列を返します。

    Function: array-start array dim
    Function: array-end array dim
    Function: array-length array dim
    [SRFI-25+] array-startは配列arraydim番目の次元の インデックスの下限を返します。 array-endは上限+1を、そしてarray-startは両者の差を返します。 array-startarray-endはSRFI-25で定義されています。
    (define a (make-array (shape 1 5 0 2)))
    
    (array-start a 0)  => 1
    (array-end a 0)    => 5
    (array-length a 0) => 4
    (array-start a 1)  => 0
    (array-end a 1)    => 2
    (array-length a 1) => 2
    

    Function: array-size array
    配列arrayの全要素数を返します。
    (array-size (make-array (shape 5 9 1 3))) => 8
    (array-size (make-array (shape))) => 1
    (array-size (make-array (shape 0 0 0 2))) => 0
    

    Function: array-ref array k ...
    Function: array-ref array index
    [SRFI-25] 配列arrayの要素を取り出します。最初の形式では、 要素は整数のインデックスk ...で指定されます。 2番目の形式では、要素はベクタまたは1次元配列のインデックスオブジェクトindex で指定されます。

    Function: array-set! array k ... value
    Function: array-set! array index value
    [SRFI-25] 配列arrayの要素にvalueをセットします。 最初の形式では、 要素は整数のインデックスk ...で指定されます。 2番目の形式では、要素はベクタまたは1次元配列のインデックスオブジェクトindex で指定されます。

    Function: share-array array shape proc
    [SRFI-25] Shapeがshapeであり、与えられた配列arrayとバッキングストレージを 共有する新しい配列を作成して返します。 procは、新しい配列へのインデックスを古い配列へのインデックスへ マップする手続きです。新しい配列の次元数をn、古い配列の次元数をmと した時、procn個の引数を取りm個の値を返す手続きでなければ なりません。さらに、各マッピングはaffineマッピング、すなわち、 出力は入力の線形合成(プラス定数)でなければなりません。 (share-arrayprocがaffineマッピングであるという事実に基づいた 最適化を行います。新しい配列にアクセスする度にprocが呼ばれるというわけでは ありません)。

    Function: array-for-each-index array proc &optional index

    Function: shape-for-each shape proc &optional index

    Function: tabulate-array shape proc &optional index

    Function: array-retabulate! array shape proc &optional index
    Function: array-retabulate! array proc &optional index

    Function: array-map! array shape proc array0 array1 ...
    Function: array-map! array proc array0 array1 ...

    Function: array-map shape proc array0 array1 ...
    Function: array-map proc array0 array1 ...

    Function: array->vector array
    Function: array->list array

    9.2 gauche.charconv - 文字コード変換

    Module: gauche.charconv
    与えられたデータストリームの文字エンコーディングを変換するための手続き群を提供する モジュールです。また、このモジュールはopen-input-filecall-with-output-file等のファイルストリームを作成する手続きを 置き換え、:encoding キーワード引数を認識するようにします。

    リリース0.5.6より、Gaucheは日本語の主要エンコーディング (ISO2022JP, ISO2022JP-3, EUC-JP (EUC-JISX0213), Shift_JIS (Shift_JISX0213), UTF-8 (Unicode 3.2))間の変換を自前で持つようになりました。 上記以外のコードとの変換はiconv(3)を利用します。 サポートされるコーディングシステムに関する詳細は section 9.2.1 サポートされる文字エンコーディングを参照して下さい。

    9.2.1 サポートされる文字エンコーディング

    CESの名前は文字列で指定します。大文字小文字の違いは無視されます。 同じCESにいくつかの別名がついていることがあります。

    特定の変換がシステムでサポートされているかどうかは次の手続きで調べることができます。

    Function: ces-conversion-supported? from-ces to-ces
    符号化方法from-cesからto-cesへの変換がサポートされていれば#tを、 そうでなければ#fを返します。

    日本語の文字セットJIS X 0201及びJIS X 0213のエンコーディング (EUC_JP、Shift JIS、UTF-8及びISO2022-JP) 間の変換に関しては、 Gaucheが内部に変換アルゴリズムを持っています (詳細は下の注記を参照)。 それ以外のCESに関しては、リンクされていればGaucheはiconv(3)を用いて 変換を行います。

    出力CESへマップ不可能な入力文字に出会った場合、Gaucheの変換ルーチンは その文字が入力CESでマルチバイトである場合はgeta mark '〓' (U+3013) に、 入力CESでシングルバイトである場合は '?' に置換します。 iconvによる変換でマップ不可能な文字に出会った場合の処理はiconvの実装に 依存します(例えばglibcではエラーとなります)。

    変換ルーチンが、入力CESとして不正な入力文字列に出会った場合は エラーが報告されます。

    Gaucheの内部変換アルゴリズムの詳細: EUC_JP、Shift JIS、及びISO2022JP間の変換は可能な限り計算で行います。 文字が未定義のコードポイントも計算式に従って変換されます。 Unicode(UTF-8)とEUC_JP間の変換はテーブルルックアップによって行われます。 UnicodeとShift JISまたはISO2022JP間の変換は、入力CESを一度EUC_JPに 変換し、それを出力CESに変換することによって行います。 入力と出力のCESがGaucheの内部アルゴリズムがサポートする範囲で等しかった場合、 Gaucheの変換ルーチンはエンコーディングの正当性はチェックせず、 単に入力を出力にコピーします。

    EUC_JP, EUCJP, EUCJ, EUC_JISX0213
    ASCII, JIS X 0201カナ、JIS X 0212、及びJIS X 0213文字セットをカバーします。 JIS X 0212は、単にJIS X 0213と重ならないコードを使っているためにサポート されていますが、他のCESへの変換は行われないので注意して下さい。 なるべくJIS X 0213の使用をおすすめします。
    SJIFT_JIS, SHIFTJIS, SJIS
    Shift_JISX0213をカバーします。但し、0x5cと0x7eに関しては JIS X 0201 Roman (YEN SIGNとOVERLINE) ではなく ASCII (REVERSE SOLIDUSとTILDE) にマップされます。
    UTF-8, UTF8
    Unicode 3.2です。JIS X 0213中の文字のいくつかはExtension B (U+20000〜) にマップされます。JIS X 0213中の他の文字のいくつかは2つのUnicode文字 (base character + combining character)にマップされます。
    ISO2022JP, CSISO2022JP, ISO2022JP-1, ISO2022JP-2, ISO2022JP-3
    これらのエンコーディングは、CSISO2022JPがISO2022JPのエイリアスであることを除き 異なるエスケープシーケンスを使いますが、Gaucheの中では同じルーチンで処理されます。 これらのエンコーディングのいずれかが入力CESに指定された場合、 Gaucheは全てのバリエーションのエスケープシーケンスを認識します。 但し、ISO2022JP-2に定義された日本語以外の言語のエスケープシーケンスに関しては、 Gaucheはエスケープシーケンスの認識だけを行い、 文字は'?'あるいは'〓' に置換します。 出力に関してはGaucheは出来る限りISO2022JPでエンコードし、 JIS X 0212文字に出会ったらISO2022JP-1のエスケープシーケンスを、 JIS X 0213の第2面の文字に出会ったらISO2022JP-3のエスケープシーケンスを 用います。したがって、文字列がJIS X 0208の範囲だけで構成されていた場合は 出力はISO2022JP互換となります。 厳密には、JIS X 0213では包摂基準の変更により、 「JIS X 0208と同じコードポイントを用いるがJIS X 0208のエスケープシーケンスを 使ってはいけない文字」というのが定義されています。 Gaucheでは互換性のため、これらの文字もJIS X 0208のエスケープシーケンスを 用いてエンコードします (これは、Emacs-Muleにおけるiso2022jp-3-compatible モードと同じ方針です)。

    9.2.2 文字エンコーディングの自動判定

    しばしば、入力のCESが未知であり、可能性のあるいくつかの候補から入力のCESを 推測しなければならない場合があります。推測するアルゴリズムはいくつも考えられるので、 それぞれに名前がついています。今のところ、一つのアルゴリズムしか実装されていません。

    "*JP"
    日本語のテキストのCESを、ISO2022-JP(-1,2,3), EUCJP, SHIFT_JIS または UTF-8の いずれかであるとして推測する。

    このアルゴリズム名は、いくつかの変換関数においてCES名の代わりに使うことができます。

    Function: ces-guess-from-string string scheme
    文字列stringのCESを、CES推測アルゴリズムscheme ("*JP"など) を使って推測し、結果のCES名を返します。もしどのCESにも該当しないデータが 含まれていれば#fが返されます。複数のCESが可能である場合、 ネイティブエンコーディングが含まれていればそれを、 そうでなければ可能なCESからどれかひとつが選んで返されます。

    9.2.3 変換ポート

    Function: open-input-conversion-port source from-code &keyword to-code buffer-size owner?
    文字が符号化方法from-codeで符号化されているデータを読み出せる 入力ポートsourceを取り、符号化方法to-codeで符号化されたデータを 読み出せるポートを作成して返します。

    to-codeが省略された場合はネイティブのCESと見なされます。

    buffer-sizeは変換のための内部バッファのサイズを指定します。 省略時のサイズは1Kバイト程で、通常の使用には問題ないサイズです。

    入力のCESが不明な場合、"*JP"などのCES推測アルゴリズム名をfrom-code として指定することができます。変換ポートは最高でバッファサイズまでのデータを先読みし、 CESを推測しようとします。そのアルゴリズムで推測されるどのCESにも該当しないデータが 検出された場合はエラーが報告されます。もし複数のCESが可能であるようなデータであった 場合は、Gaucheのネイティブエンコーディングが可能なCESに含まれていればそれが選ばれ、 そうでなければいずれかのCESが適当に選ばれます。従って、バッファサイズが小さすぎると 誤った判定をする可能性が高くなります。大抵のテキストドキュメントに対して、 既定のバッファサイズは十分ですが、大きなテキストのほとんどがASCII文字で最後だけ マルチバイト文字が現われるようなテキストでは誤判定の可能性があります。 最悪の場合でも結果を保障するには、テキスト全体が格納できるバッファサイズを指定すると 良いでしょう。

    通常、open-input-conversion-portは変換が全て終了した後でもsource はオープンしたままにします。キーワード引数owner?に真の値を指定すると、 EOFが読まれた後でsourceはクローズされます。

    例を示しましょう。以下のコードは未知のCES(但しEUC-JP, SJIS, ISO2022-JP, UTF8の いずれかであることは分かっている)で書かれたテキストファイル`unknown.txt'を 読みだし、文字エンコーディングをEUC-JPに変換して`eucjp.txt'に書き出します。

    (call-with-output-file "eucjp.txt"
      (lambda (out)
        (copy-port (open-input-conversion-port
                     (open-input-file "unknown.txt")
                     "*jp"             ;guess code
                     :to-code "eucjp"
                     :owner? #t)       ;close unknown.txt afterwards
                   out)))
    

    Function: open-output-conversion-port sink to-code &keyword from-code buffer-size owner?
    文字のエンコーディングをfrom-codeからto-codeに変換して 出力ポートsinkに書き出すような出力変換ポートを作成して返します。 to-codeが省略された場合はネイティブのCESと見なされます。 from-codeにもto-codeにも、CES推測アルゴリズム名を 使用することはできません。

    buffer-sizeは内部で変換に使われるバッファサイズを指定します。 出力変換ポートに書き出された文字は、flushを使って明示的に フラッシュするか出力変換ポートが閉じられるまで、バッファ内に残っている可能性があります。

    通常、出力変換ポートがクローズされてもsinkはクローズされません。 owner?に真の値を与えれば、出力変換ポートのクローズ時にsinkを クローズするようにできます。

    Function: ces-convert string from-code &optional to-code
    from-codeでエンコーディングされた文字列stringto-codeでエンコーディングされた文字列に変換します。 to-codeがネイティブエンコーディングで無い場合、返される文字列は バイト文字列(不完全な文字列)であるかもしれません。

    from-codeにはCES推測アルゴリズム名("*JP"など)を与えることができます。 to-codeが省略された場合はネイティブエンコーディングと見なされます。

    9.2.4 拡張されたポート手続き

    Function: open-input-file filename &keyword encoding conversion-buffer-size ...
    Function: call-with-input-file filename proc &keyword encoding conversion-buffer-size ...
    Function: with-input-from-file filename thunk &keyword encoding conversion-buffer-size ...
    Function: open-output-file filename &keyword encoding conversion-buffer-size ...
    Function: call-with-output-file filename proc &keyword encoding conversion-buffer-size ...
    Function: with-output-to-file filename thunk &keyword encoding conversion-buffer-size ...
    これらのGauche組み込みの手続きは、encodingconversion-buffer-size という二つの追加のキーワード引数を取るように拡張されます。 (これらの手続きの元の動作についてはsection 6.18.3 ファイルポートを参照して下さい)。

    filenameの文字エンコーディング名をencodingに渡すと、 ファイルを読む際にencodingからGaucheの内部エンコーディングへの変換が 行われます。入力の場合はencodingにCES推測アルゴリズム名を渡すこともできます。

    conversion-buffer-sizeopen-input-conversion-port におけるbuffer-sizeと同じ意味を持ちます。

    9.3 gauche.collection - コレクションフレームワーク

    Module: gauche.collection
    このモジュールは、様々なコレクションに対して繰り返し処理を行う総称関数を提供します。 Schemeの規格はmapfor-eachなどの繰り返し手続きを定義しており、 またSRFI-1(section 10.2 srfi-1 - List library参照)は更に数多くの繰り返し手続きを提供しますが、 それらはリストに対してしか動作しません。

    このモジュールはオブジェクトシステムのメソッドディスパッチを利用して、 これらの手続きをベクタやハッシュテーブルのような一般のコレクションタイプに対しても 効率良く動作するように拡張します。また、ユーザ定義のクラスにこれらの操作を実装するための 簡単な方法も提供します。今のところ、次のような総称関数が提供されています。

    マッピング
    fold, map, map-to, for-each
    選択と探索
    find, filter, filter-to, remove, remove-to, partition, partition-to
    変換
    coerce-to
    その他
    size-of, lazy-size-of
    基礎的なイテレータ構築メソッド
    call-with-iterator, call-with-builder, with-iterator, with-builder, call-with-iterators.

    これらの操作は、コレクションとそのサブクラスである シーケンスに対して動作します。コレクションは、その要素を全て 訪れる方法が用意されているようなオブジェクトの集合です。 シーケンスは、要素間に全順序関係が定義されておりインデックスで要素を取り出すことが できるようなコレクションです。

    次にあげるGaucheの組み込みオブジェクトはシーケンスあるいはコレクションとして動作します。

    <list>
    シーケンス
    <vector>
    シーケンス
    <string>
    文字のシーケンス
    <hash-table>
    コレクション。各要素はキーと値のペア。
    <s8vector>, <u8vector>, ... <f64vector>
    シーケンス。メソッドはsrfi-4モジュール内で定義されます。 section 10.4 srfi-4 - 単一型のベクタ参照。

    section 9.18 gauche.sequence - シーケンスフレームワークも参照してください。シーケンス特有のメソッドが 追加されます。

    オブジェクトの集合を返すようなメソッド、すなわち mapfilterremoveおよびpartitionは、 リストを返します。対応する"-to"がつくメソッド (map-tofilter-toremove-topartition-to) はコレクションクラスも引数に取り、そのクラスのコレクションを返します。

    9.3.1 コレクションに対するマッピング

    Generic function: fold proc knil coll coll2 ...
    SRFI-1で定義されるfold (section 10.2.5 List fold, unfold & map参照) の自然な拡張です。

    コレクションcollの各要素Eiに対して、手続きprocが (proc Ei Ri-1) のように呼ばれます。ここで、 Ri-1i > 0 に対しては (i-1)番目のprocの呼び出しの 結果であり、R0knilです。最後のprocの戻り値を返します。

    (fold + 0 '#(1 2 3 4)) => 10
    (fold cons '() "abc")  => (#\c #\b #\a)
    

    collがシーケンスでもある場合、要素はシーケンスの順にprocに渡されます。 そうでなければ繰り返しの順序は未定義です。

    複数のコレクションをfoldに渡すこともできます (但し、その全てがシーケンスで なければあまり意味のある操作では無いでしょう)。 k番目のコレクションのi番目の要素をE(k, i)とするとき、 procは以下のように呼ばれます。

    (proc E(0,i) E(1,i) ... E(K-1,i) Ri-1)
    

    異なる型のコレクションを混ぜて扱うことができます。

    (fold acons '() "abc" '#(1 2 3))
      => ((#\c 3) (#\b 2) (#\a 1))
    
    ;; 二つのベクタの内積を計算
    (fold (lambda (a b r) (+ (* a b) r)) 0
          '#(3 5 7) '#(2 4 6))
      => 68
    

    複数のコレクションが与えられた場合、foldは少なくともひとつのコレクションが 終了した時点で終了します。

    Generic function: map proc coll coll2 ...
    組み込み手続きmap (section 6.15.1 手続き参照) を拡張します。 コレクションcollの各要素に手続きprocを適用し、その結果をリストにして 返します。

    collがシーケンスでもある場合、要素はシーケンスの順にprocに渡されます。 そうでなければ繰り返しの順序は未定義です。

    複数のコレクションが与えられた場合、procは各コレクションからの要素を引数として 呼び出されます。mapはひとつでもコレクションの最後に到達したら終了します。 複数のコレクションを渡すのは、コレクションの全てがシーケンスでないとあまり意味がないでしょう。

    (map (lambda (x) (* x 2)) '#(1 2 3))
      => #(2 4 6)
    
    (map char-upcase "abc")
      => (#\A #\B #\C)
    
    (map + '#(1 2 3) '#(4 5 6))
      => (5 7 9)
    

    mapは常にリストを返します。別のコレクション型で結果を得たい場合は、 次に示すmap-toを使って下さい。何故(map char-upcase "abc")"ABC"を返さないのか疑問なら、この最後にあるディスカッションを参照してください。

    Generic function: map-to class proc coll coll2 ...
    mapと同じように動作しますが、結果はクラスclassのインスタンスとして返されます。 classはコレクションクラスでなければなりません。 また、ビルダーインタフェースを持っている必要があります (section 9.3.4 基礎的なイテレータ構築メソッド参照).
    (map-to <vector> + '#(1 2 3) '#(4 5 6))
      => #(5 7 9)
    
    (map-to <string> char-upcase "def")
      => "DEF"
    
    (map-to <vector> char=? "bed" "pet")
      => #(#f #t #f)
    

    Generic function: for-each proc coll coll2 ...
    組み込み手続きfor-each (section 6.15.1 手続き参照) を拡張します。 コレクションcollの各要素に手続きprocを適用します。 procの結果は捨てられます。for-eachの結果は未定義です。

    collがシーケンスでもある場合、要素はシーケンスの順にprocに渡されます。 そうでなければ繰り返しの順序は未定義です。

    複数のコレクションが与えられた場合、procは各コレクションからの要素を引数として 呼び出されます。for-eachはひとつでもコレクションの最後に到達したら終了します。 複数のコレクションを渡すのは、コレクションの全てがシーケンスでないとあまり意味がないでしょう。

    Generic Function: fold$ proc
    Generic Function: fold$ proc knil
    Generic Function: map$ proc
    Generic Function: for-each$ proc
    foldmapfor-eachの部分評価版です。

    Discussion: mapがリスト以外に対して適用されたとき、どういう コレクション型を返すべきでしょう。 (map * '#(1 2) '#(3 4)) がベクタを返し、 (map char-upcase "abc") が文字列を返すようにするほうが「自然」でしょうか。

    そのようなインタフェースは単純な場合には動作するように思えますが、 一般的な拡張は困難です。文字列とベクタが同時に渡されたらどうします? 更に、コレクションクラスによっては繰り返しインタフェースは持っていても ビルダーインタフェースを持っていない場合があり、結果をそのコレクションクラスとして 返せない場合もあります (データベースレコードのコレクションに対してマップする、 といった用法を考えてみて下さい)。また、Schemeプログラマはmapが リストを返すという事実に慣れ親しんでおり、既存のコードもmapの戻り値を リストを受け取る手続きに渡すことがよく行われています。

    そこで、結果の型を明示的に指定するmap-toという別のメソッドを定義しました。 結果の型を渡すのは、CommonLispのmap関数にならっていますが、 Gaucheではクラスメタオブジェクトを渡すようにしたため、メソッドディスパッチを使って 拡張することが容易です。"-to" のつくメソッドは結果のコレクションのクラスを 取るというインタフェースはコレクションフレームワーク中で統一的に使われています。

    9.3.2 コレクションからの選択と探索

    Generic function: find pred coll
    predをコレクションcollの要素に適用してゆきます。predが 真の値を返したらそこで打ち切り、その要素を返します。predが真の値を返す 要素が無かった場合は#fを返します。

    collがシーケンスでもある場合、要素はシーケンスの順にprocに渡されます。 そうでなければ繰り返しの順序は未定義です。

    (find char-upper-case? "abcDe") => #\D
    (find even? '#(1 3 4 6)) => 4
    (find even? '(1 3 5 7))  => #F
    

    Generic function: filter pred coll
    コレクションcoll中の要素のうち、述語手続きpredが真の値を返したものの リストを返します。コレクションがシーケンスであれば、結果の要素の順序は元のシーケンスの 順序と同じになります。
    (filter char-upper-case? "Hello, World")
      => (#\H #\W)
    (filter even? '#(1 2 3 4)) => (2 4)
    

    Generic function: filter-to class pred coll
    filterと同じですが、結果のコレクションがclassのインスタンスで 返されます。
    (filter-to <vector> even? '#(1 2 3 4)) => #(2 4)
    (filter-to <string> char-upper-case? "Hello, World") 
      => "HW"
    

    Generic function: remove pred coll
    コレクションcoll中の要素のうち、述語手続きpredが偽の値を返したものの リストを返します。コレクションがシーケンスであれば、結果の要素の順序は元のシーケンスの 順序と同じになります。
    (remove char-upper-case? "Hello, World")
      => (#\e #\l #\l #\o #\, #\space #\o #\r #\l #\d)
    (remove even? '#(1 2 3 4)) => (1 3)
    

    Generic function: remove-to class pred coll
    removeと同じですが、結果のコレクションがclassのインスタンスで 返されます。
    (remove-to <vector> even? '#(1 2 3 4)) => #(1 3)
    (remove-to <string> char-upper-case? "Hello, World") 
      => "ello, orld"
    

    Generic function: partition pred coll
    filterremoveを同時に行います。 二つのリストを返します。最初のリストはコレクションcollの要素のうち 述語手続きpredが真の値を返したものから構成され、二つ目のリストは そうでない要素から構成されます。
    (partition char-upper-case? "PuPu")
      => (#\P #\P) and (#\u #\u)
    (partition even? '#(1 2 3 4))
      => (2 4) and (1 3)
    

    Generic function: partition-to class pred coll
    partitionと同じですが、結果がクラスclassのコレクションとして 返されます。
    (partition-to <string> char-upper-case? "PuPu")
      => "PP" and "uu"
    (partition-to <vector> even? '#(1 2 3 4))
      => #(2 4) and #(1 3)
    

    9.3.3 コレクションに対する様々な操作

    Generic function: size-of coll
    コレクションの要素数を返します。 デフォルトのメソッドは、コレクション中の要素をすべて数え上げるものですが、 あまり効率は良くないでしょう。また、無限個の要素を持つコレクションでは 帰ってきません。多くのコレクションクラスはより効率の良い方法でこのメソッドを定義しています。

    Generic function: lazy-size-of coll
    コレクションの要素数か、もしくはそれを計算するプロミスを返します。 このメソッドの目的は、要素数の計算が高価な場合にそれを避けることにあります。 しばしば、呼び出し側では最適化のための参考値として要素数が欲しい場合があり、 そういった場合は要素数を計算するために時間を費すのは望ましくありません。 このメソッドを代わりに呼び出して、結果がプロミスであればそれを使わない、 という選択ができます。

    Generic function: coerce-to class coll
    コレクションcollを、クラスclassのインスタンスである 別のコレクションへと変換します。collがシーケンスであり、 classがシーケンスクラスであれば、元のシーケンスの順序は保存されます。
    (coerce-to <vector> '(1 2 3 4))
      => #(1 2 3 4)
    
    (coerce-to <string> '#(#\a #\b #\c))
      => "abc"
    

    9.3.4 基礎的なイテレータ構築メソッド

    ここに挙げるメソッドは、他のコレクションメソッドの基礎となるものです。 メソッドのインタフェースは一般のコードで使われることよりも、 効率良く他の繰り返しメソッドを記述するのに便利なように設計されています。 何故このインタフェースを基礎のメソッドとして選んだかについてはこの章の最後に説明します。

    Generic function: call-with-iterator collection proc &keyword start
    基礎となるイテレータ構築メソッドです。このメソッドはコレクションcollection から繰り返しのための二つの手続きを作成し、それらを引数として手続きprocを 呼びます。作られる最初の手続きは終了判定手続きで、引数無しで呼び出され、繰り返しが 終了していれば#tを、まだ要素が残っていれば#fを返します。 作られる二番目の手続きはインクリメント手続きで、呼ばれる度に現在の要素を返し、 内部のポインタを次の要素へと進めます。終了判定手続きが#tを返した後に インクリメント手続きを呼んだ場合の動作は未定義です。

    コレクションがシーケンスでもある場合、インクリメント手続きはシーケンスの順番に要素を取り出します。 キーワード引数startが与えられていればイテレーションの範囲は start番目の要素から最後の要素までとなります。シーケンスでないコレクションに 対してはstart引数は意味を持ちません。

    call-with-iteratorのメソッド実装は、イテレータのエクステントを そのメソッドのダイナミックスコープ内に限ることを許されます。例えば、 メソッドはprocを呼ぶ前に何らかのリソースを確保し(データベースへのコネクションなど)、 procから戻った後でそれを解放するということができます。

    このメソッドは proc が返した値をそのまま返します。

    (call-with-iterator '(1 2 3 4 5)
      (lambda (end? next)
        (do ((odd-nums 0))
            ((end?) odd-nums)
          (when (odd? (next)) (inc! odd-nums)))))
     => 3
    

    下に示すwith-iteratorマクロも参照してください。

    Macro: with-iterator (collection end? next args ...) body ...
    call-with-iteratorを簡潔に呼び出すマクロです。
    (with-iterator (coll end? next args ...) body ...)
     ==
    (call-with-iterator coll
      (lambda (end? next) body ...)
       args ...)
    

    Function: call-with-iterators collections proc
    N-aryのイテレータメソッドを書くのに便利な手続きです。 この手続きはコレクションのリストcollectionsの各コレクションに対して call-with-iteratorを呼び、二つのリストを作ります。最初のリストには 終了判定手続きが順に集められており、二つ目のリストにはインクリメント手続きが 順に集められています。そして、これらのリストを引数としてprocを呼び出します。 procが返した値を返します。

    Generic function: call-with-builder collection-class proc &keyword size
    基礎的なビルダー構築メソッドです。ビルダーはコレクションをインクリメンタルに 作成する方法です。コレクションクラスによってはこの手続きを提供しないものもあります。

    Collection-classは作成されるコレクションのクラスです。 このメソッドは、追加手続きと結果手続きの二つの手続きを作成し、それらを 引数としてprocを呼びます。追加手続きは一つ引数を取り、それを作成中の コレクションに追加します。結果手続きは引数を取らず、作成されたコレクションを返します。 結果手続きが呼ばれた後で追加手続きを呼んだ場合の動作は未定義です。

    作られるコレクションのサイズが分かっている場合、キーワード引数sizeを与える ことができます。コレクションクラスによってはその情報を使って効率的にコレクションを 作成することができます。その情報を単に無視するコレクションクラスもあります。 size個より多くの要素が追加されたり、size個の要素が追加される前に 結果手続きが呼ばれたりした場合の動作は未定義です。

    コレクションクラスがシーケンスクラスであった場合、追加手続きは要素を シーケンスの順に追加してゆきます。

    コレクションクラスによっては、コレクションオブジェクトの初期化のために 他のキーワード引数を取るかもしれません。

    このメソッドはprocが返す値を返します。

    (call-with-builder <list>
      (lambda (add! get)
        (add! 'a) (add! 'b) (add! 'c) (get)))
     => (a b c)
    
    (call-with-builder <vector>
      (lambda (add! get)
        (add! 'a) (add! 'b) (add! 'c) (get)))
     => #(a b c)
    

    下に示すwith-builderマクロも参照してください。

    Macro: with-builder (collection add! get args ...) body ...
    call-with-builderを簡潔に呼び出すマクロです。
    (with-builder (coll add! get args ...) body ...)
     ==
    (call-with-builder coll
      (lambda (add! get) body ...)
      args ...)
    

    Discussion: 他のイテレータメソッドは全てこのcall-with-iteratorとcall-with-builderの上に構築可能です。 最低限これらのメソッドを定義すれば、そのクラスはコレクションとして振舞うことができます。 もちろん最適化のために他のイテレータメソッドを定義しても構いませんが。

    どの操作を基礎的なメソッドとするかには議論の余地があります。 Gaucheでは、作者がよく見るパターンで最も効率が良くなるように考えて現在のスタイルを 選びました。以下に、他の基礎的なメソッドの可能性を検討します。

    fold
    foldを最も基礎的なメソッドとして、他のイテレータメソッドをその上に 構築することも可能です。繰り返しの状態はスタックに置かれるので効率良く走ります。 foldを基礎とした繰り返し関数を最適化する方法は良く知られています。 しかし、foldを元にしてジェネレータスタイルのインタフェースを 作成するのは複雑です。また、複数のコレクションに対しての繰り返しを書くのも 面倒です。
    CPS
    繰り返しの中身の手続きに対し、繰り返しを続けるための継続手続きを渡す方法です。 繰り返しを続けたくなければ、手続きは継続を呼ばすにそのまま戻ります。 Oleg Kiselyovの記事(@xref{oleg2,,OLEG2})に指摘されているような、 リソース管理の問題があります。
    Iterator object
    C++のイテレータやCommon Lispのジェネレータのようなオブジェクトを使う方法です。 ループを書くのは容易ですが、終了判定や要素取り出しの度にメソッドディスパッチが 起こってしまいます。
    Series
    Common Lispのシリーズはコンパイラがシリーズの使われかたを追跡できれば 非常に効率の良いコードに変換できます。Gaucheのコンパイラはそこまでのデータフロー解析を 行っていません。また、それをやったとしても、コレクションクラスを拡張するための方法が Gaucheのオブジェクトシステムとはうまく調和しません。
    Macros
    効率を気にするなら、イテレータをマクロで書いてしまう方法もあります (例えばScheme48のiteratorマクロなど)。 効率は良いのですが、拡張するにはマクロを書くことが必要となり、 Gaucheのオブジェクトシステムとうまく調和しません。

    現在の実装はイテレータオブジェクトアプローチに近いですが、イテレータオブジェクトを 作る代わりにクロージャを使うことで内部のループでのメソッドディスパッチを 避けています。また、現在のインタフェースはリソース管理の問題を解決しています。

    9.3.5 コレクションの実装

    The minimum requirements of the collection class implementation is as follow:

    This makes iterator methods such as map, for-each, find and filter to work.

    In order to make the constructive methods (e.g. map-to to create your collection), you have to implement call-with-builder method as well. Note that call-with-builder method must work a sort of class method, dispatched by class, rather than normal method dispatched by instance. In Gauche, you can implement it by using a metaclass. Then the minimal code will look like this:

    (define-class <your-collection-meta> (<class>) ())
    
    (define-class <your-collection> (<collection>)
     (...) ;; slots
     :metaclass <your-collection-meta>)
    
    (define-method call-with-iterator
        ((coll <your-collection>) proc . options)
      ...
      )
    
    (define-method call-with-builder
         ((coll <your-collection-meta>) proc . options)
      ...
      )
    

    Optionally, you can overload other generic functions to optimize performance.

    9.4 gauche.config - コンフィグレーション情報

    Module: gauche.config
    This module provides a simple wrapper to obtain configuration parameters via gauche-config program.

    The gauche-config program is a simple shell script that records various parameters given at the configuration time of Gauche.

    Function: gauche-config option
    Calls gauche-config with the option option, and returns the string of the parameter value. It is an error to give the option gauche-config doesn't understand.

    See the manpage of gauche-config, or run gauche-config without any argument from the shell, to find out the valid options.

    (gauche-config "--cc")
      => "gcc"
    (gauche-config "-L")
      => "-L/usr/lib/gauche/0.6.5/i686-pc-linux-gnu"
    (gauche-config "-l")
      => "-ldl -lcrypt -lm -lpthread"
    

    9.5 gauche.fcntl - 低レベルファイル操作

    Module: gauche.fcntl
    Provides an interface to fcntl(2), including advisory file locking.

    Function: sys-fcntl port-or-fd operation &optional arg
    Performs certain operation on the file specfied by port-or-fd, which should be a port object or an integer that specifies a system file descriptor. If it is a port, it must be associated to the opened file.

    The operation is specified by an integer operation. Several variables are defined for valid operation.

    F_GETFD
    Returns flags associated to the file descriptor of port-or-fd. The optional argument arg is not used. The return value is an integer whose definition is system specific, except one flag, FD_CLOEXEC, which indicates the file descriptor should be closed on exec.
    F_SETFD
    Sets the file descriptor flags given as arg to port-or-fd. For example, the portable way of setting FL_CLOEXEC flag is as follows:
    (sys-fcntl port F_SETFD
              (logior FD_CLOEXEC
                      (sys-fcntl port F_GETFD)))
    
    F_GETFL
    Returns flags associated to the open files specified by port-or-fd. The flags includes the following information:
    • File access mode. When masked by O_ACCMODE, it's either one of O_RDONLY, O_WRONLY or O_RDWR.
    • File creation options. O_CREAT, O_EXCL and/or O_TRUNC.
    • Whether appending is allowed or not, by O_APPEND
    • Whether I/O is blocking or non-blocking, by O_NONBLOCK.
    • Whether it grabs terminal control, by O_NOCTTY.
    The system may define system-specific flags.
    F_SETFL
    Sets flags to the open files specified by port-or-fd. Among the flags listed above, only O_NONBLOCK and O_APPEND can be changed. Note that F_GETFD/F_SETFD concern flags associated to the file descriptor itself, while F_GETFL/F_SETFL concern flags associated to the opened file itself. This makes difference when more than one file descriptor points to the same opened file.
    F_DUPFD
    Creates new file descriptor that points to the same file referred by port-or-fd. An integer must be provided as arg, and that specifies the minimum value of file descriptor to be assigned.
    F_GETLK
    The third argument must be provided and be an instance of <sys-flock> object described below. It searches the lock information specified by arg, and modifies arg accordingly.
    F_SETLK
    F_SETLKW
    The third argument must be provided and be an instance of <sys-flock> object described below. Sets the advisory file lock according to arg. If the lock is successfully obtained, #t is returned. If the other process has the lock conflicting the request, F_SETLK returns #f, while F_SETLKW waits until the lock is available.

    Other value for operation causes an error.

    Builtin Class: <sys-flock>
    A structure represents POSIX advisory record locking. Advisory record locking means the system may not prevents the process from operating on files that it doesn't have an appropriate lock. All the processes are expected to use fcntl to check locks before it operates on the files that may be shared.

    The following slots are defined.

    Instance Variable: <sys-flock> type
    An integer represents lock type. Following variables are predefined for the valid values:
    F_RDLCK
    Read locking
    F_WRLCK
    Write locking
    F_UNLCK
    To remove a lock by F_SETLK, or to indicate the record is not locked by F_GETLK.

    Instance Variable: <sys-flock> whence
    Indicates from where start is measured.

    Instance Variable: <sys-flock> start
    The offset of beginning of the locked region.

    Instance Variable: <sys-flock> len
    The number of bytes to lock. Zero means "until EOF".

    Instance Variable: <sys-flock> pid
    An integer process id that holding the lock; used only by F_GETLK.

    9.6 gauche.interactive - インタラクティブセッション

    Module: gauche.interactive
    インタラクティブセッションで便利なユーティリティ手続きを提供します。

    goshをインタラクティブモードで起動した場合、このモジュールは自動的にロードされます。

    Macro: apropos pattern &optional module
    名前がpatternにマッチするような定義された変数のリストを表示します。 moduleにモジュールオブジェクトまたはモジュール名を与えた場合は、 そのモジュール内で定義されている変数のみが表示されます。moduleが 省略された場合は、カレントモジュールから「見える」変数が全て表示されます。

    patternはシンボルか正規表現オブジェクトでなければなりません。 シンボルの場合、そのシンボル名を部分文字列として名前に含むような変数が リストされます。正規表現オブジェクトの場合は、その正規表現にマッチする 名前を持つ変数がリストされます。

    いくつか例を示します。

    ;; "string"を名前に含む変数を表示
    (apropos 'string)
    
    ;; srfi-14モジュールの中のみを検索
    (apropos 'char 'srfi-14)
    

    Generic Function: describe obj
    Generic Function: d obj
    Schemeオブジェクトobjの詳細情報を表示します。 既定メソッドはobjのクラスを表示し、さらにobjがスロットを 持っていればその名前と内容をリストします。 このメソッドをスペシャライズすることによりクラス毎に表示をカスタマイズできます。

    Function: info symbol
    Gaucheのinfoドキュメント中から、 symbolで指定される手続きか構文要素の定義を含んでいるページを表示します。 infoドキュメントは、もし環境変数INFOPATHが定義されていればそこに 示されるディレクトリ中から探され、そうでなければgoshのライブラリディレクトリ から推測されるディレクトリ中から探されます。infoドキュメントが見付からなかったり、 見付かってもsymbolがIndexページ中に無かった場合はエラーとなります。 つまり、この手続きはinfoファイルがインストールされていないと動作しません。

    現在の出力ポートが端末である場合、infoドキュメントの該当ページは ページングプログラムを用いて表示されます。環境変数PAGERが指定されていれば それを用い、そうでなければコマンドサーチパスからless及びmoreを この順で探します。いずれも見付からなかった場合や、出力ポートが端末では ない場合には、単にページがそのまま出力されます。

    この手続きのセッション中での最初の呼び出しは、infoファイルをパーズするために 多少時間がかかります。

    9.7 gauche.listener - リスナー

    Module: gauche.listener
    このモジュールは、 複数のread-eval-printループ(repl)を並行して動作させるのに便利な機能を提供します。

    複数のreplを実現する自明な方法は、セッション毎にスレッドを生成して 各スレッド上でread-eval-print-loop (section 6.17 Eval and repl参照)を 呼ぶことですが、シングルスレッドでの実装が好ましい場合もあります。 例えばアプリケーションがMT-safeでないライブラリに大きく依存していたり、 既にアプリケーションがselectやpollをベースにしたディスパッチメカニズムを 持っているような場合です。

    シングルスレッドのselectionベースのアプリケーションでreplを実装するには、 通常、listenしているポートにデータが到着した時に呼ばれるハンドラを登録します。 ハンドラはポートからデータを読み、内部バッファに追加します。 そして内部バッファをスキャンし、データが完全な式を構成した場合は それをS式として読みだし、評価して結果をポートに流します。 このモジュールの<listener>クラスはこのハンドラのメカニズムを提供するので、 アプリケーション側はそれを自分のディスパッチメカニズムに登録するだけで済みます。

    註:場合によっては、出力もバッファリングする必要があるかもしれませんが、 現在はそれは実装されていません。

    Class: <listener>
    Replセッションの状態を維持するオブジェクトです。 オブジェクトのふるまいをカスタマイズするためにいくつもの外部スロットがあります。 これらのスロットの値は、スロットの名前と同名のキーワード引数を用いて オブジェクトの構築時に指定することもできますし、オブジェクト構築後に slot-set!で設定することもできますが、listener-read-handler を呼ぶ前に確定していなければなりません。

    Instance Variable: <listener> input-port
    Specifies the input port from which the listener get the input. The default value is the current input port when the object is constructed.

    Instance Variable: <listener> output-port
    Specifies the output port to which the listener output will go. The default value is the current output port when the object is constructed.

    Instance Variable: <listener> error-port
    Specifies the output port to which the listener's error messages will go. The default value is the current error port when the object is constructed.

    Instance Variable: <listener> reader
    A procedure with no arguments. It should read a Scheme expression from the current input port when called. The default value is system's read procedure.

    Instance Variable: <listener> evaluator
    A procedure that takes two arguments, a Scheme expression and an environment specifier. It should evaluate the expression in the given environment and returns zero or more value(s). The default value is system's eval procedure.

    Instance Variable: <listener> printer
    A procedure that takes zero or more argument(s) and prints them out to the current output port. The default value is a procedure that prints each value by write, followed by a newline.

    Instance Variable: <listener> prompter
    A procedure with no arguments. It should prints a prompt to the current output port. The output is flushed by the listener object so this procedure doesn't need to care about it. The default procedure prints "listener> ".

    Instance Variable: <listener> environment
    An environment specifier where the expressions will be evaluated. The default value is the value returned by (interaction-environment).

    Instance Variable: <listener> finalizer
    A thunk that will be called when EOF is read from input-port. It can be #f if no such procedure is needed. The default value is #f.

    Instance Variable: <listener> error-handler
    A procedure that takes one argument, an error exception. It is called when an error occurs during read-eval-print stage, with the same dynamic environment as the error is signalled. The default value is a procedure that simply prints the error exception by report-error.

    Method: listener-read-handler (listener <listener>)
    Returns a thunk that is to be called when a data is available from input-port of the listener.

    The returned thunk (read handler) does the following steps. Note that the first prompt is not printed by this procedure. See listener-show-prompt below.

    1. Reads available data from input-port and appends it to the listener's internal buffer.
    2. Scans the buffer to see if it has a complete S-expression. If not, returns.
    3. Reads the S-expression from the buffer. The read data is removed from the buffer.
    4. Evaluates the S-expression, then prints the result to output-port.
    5. Prints the prompt by prompter procedure to output-port, then flush output-port.
    6. Repeats from 2.

    Method: listener-show-prompt (listener <listener>)
    Shows a prompt to the listener's output port, by using listener's prompter procedure. Usually you want to use this procedure to print the first prompt, for instance, when the client is connected to the listener socket.

    Function: complete-sexp? str
    Returns #t if str contains a complete S-expression. This utility procedure is exported as well, since it might be useful for other purposes.

    Note that this procedure only checks syntax of the expressions, and doesn't rule out erroneous expressions (such as containing invalid character name, unregistered SRFI-10 tag, etc.). This procedure may raise an error if the input contains '#<' character sequence.

    The following code snippet opens a server socket, and opens a Scheme interactive session when a client is connected. (Note: this code is just for demonstration. Do not run this program on the machine accessible from outside network!)

    (use gauche.net)
    (use gauche.selector)
    (use gauche.listener)
    
    (define (scheme-server port)
      (let ((selector (make <selector>))
            (server   (make-server-socket 'inet port :reuse-addr? #t))
            (cid      0))
    
        (define (accept-handler sock flag)
          (let* ((client (socket-accept server))
                 (id     cid)
                 (input  (socket-input-port client :buffering :none))
                 (output (socket-output-port client))
                 (finalize (lambda ()
                             (selector-delete! selector input #f #f)
                             (socket-close client)
                             (format #t "client #~a disconnected\n" id)))
                 (listener (make <listener>
                             :input-port input
                             :output-port output
                             :error-port output
                             :prompter (lambda () (format #t "client[~a]> " id))
                             :finalizer finalize))
                 (handler (listener-read-handler listener))
                 )
            (format #t "client #~a from ~a\n" cid (socket-address client))
            (inc! cid)
            (listener-show-prompt listener)
            (selector-add! selector input (lambda _ (handler)) '(r))))
    
        (selector-add! selector
                       (socket-fd server)
                       accept-handler
                       '(r))
        (format #t "scheme server started on port ~s\n" port)
        (do () (#f) (selector-select selector))))
    

    9.8 gauche.logger - ユーザレベルのロギング

    Module: gauche.logger
    プログラムからログを書き出す簡単なインタフェースを提供します。 情報は指定されたファイルへ書き出されるか、もしくはsyslog(3)を 使ってシステムログへと送られます。 ファイルに書き出される場合は、 syslogに似たプレフィクスが各メッセージの前に追加されます。 プレフィクスはカスタマイズすることもできます。 ログファイルの排他制御は組み込まれています。

    Class: <log-drain>
    ログメッセージの行き先を表現するオブジェクトです。 デフォルトのログの行き先として、グローバルな<log-drain>のインスタンスが ひとつ作られます。 ログをいくつかにわけて出力する場合などはmakeメソッドを使って いくつでも<log-drain>のインスタンスを作ることができます。

    Instance Variable: <log-drain> path
    ログファイルのパス名か、#t#f、あるいはシンボルsyslog の値を取ります。このスロットが#tの場合、ログメッセージは現在のエラーポートに 書き出されます。#fの場合はlog-formatは ログを書き出すかわりにフォーマットされたログメッセージを文字列として返します。 シンボルsyslogの場合はメッセージがシステムログへと送られます。

    このスロットの初期値は#fです。

    Instance Variable: <log-drain> prefix
    各メッセージの前に追加されるプレフィクス文字列を指定します。 メッセージが複数行に渡る場合、プレフィクスは各行の頭に追加されます。 またこのスロットには手続きをセットすることもできます。 その場合、プレフィクス文字列が必要とされる度にその手続きが<log-drain> を引数として呼び出され、戻り値の文字列がプレフィクスとして使われます。

    pathスロットの値がシンボルsyslogの場合は、 このスロットの値は無視されます。システムのログ機構が適切なプレフィクスを付けるからです。

    prefixスロットの値が文字列の場合、以下に挙げる文字シーケンスは特別な意味を持ち、 log-formatによって置換されます。

    ~T
    現在の時刻を"Mmm DD hh:mm:ss"という形式で表したもの。 ここで"Mmm" は英語の月名の省略形、"DD" は日、"hh"、"mm"、 "ss" は時間(24時間制)、分、秒です。 このフォーマットはシステムログと同じです。
    ~Y
    4桁で表した現在の西暦。
    ~P
    プログラム名。初期値は*program-name*の値のbasenameが使われます (section 3.4 Schemeスクリプトを書く参照)。 下に述べるprogram-nameスロットの値を変えれば ここに現れる文字列を変えることができます。
    ~$
    このプログラムのプロセスID。
    ~U
    このプロセスの実行ユーザ名。
    ~H
    このプロセスが走っているホスト名。

    このスロットの初期値は"~T ~P[~$]: "です。例えば "this is a log message.\nline 2\nline 3"というメッセージが 与えられると、次のようなログが書き出されます。

    Sep  1 17:30:23 myprogram[441]: this is a log message
    Sep  1 17:30:23 myprogram[441]: line 2
    Sep  1 17:30:23 myprogram[441]: line 3
    

    Instance Variable: <log-drain> program-name
    プレフィクス文字列の~Pが置換されるプログラム名を指定します。

    Instance Variable: <log-drain> syslog-option
    Instance Variable: <log-drain> syslog-facility
    Instance Variable: <log-drain> syslog-priority
    これらのスロットの値は、ログの行き先がシステムログの場合にのみ使われます。 これらの値に関する説明はsection 9.19 gauche.syslog - Syslogを参照して下さい。 デフォルトの値はそれぞれLOG_PIDLOG_USERLOG_INFOです。

    Function: log-open path &keyword prefix program-name
    デフォルトのログの行き先をpathに指定します。 pathは文字列かboolean値あるいはシンボルsyslogで、 上のpathスロットで述べたものと おなじ意味を持ちます。またプレフィクスとプログラム名をキーワード引数で 指定することもできます。

    名前に"open"とありますが、この手続きは指定されたファイルをオープンしません。 ファイルはlog-formatが呼ばれるたびにオープンされクローズされます。

    Method: log-format (format <string>) arg ...
    Method: log-format (drain <log-drain>) (format <string>) arg ...
    ログメッセージをformat手続きでフォーマットし(section 6.18.7 出力参照)、 指定された行き先に書き出します。最初の形式ではデフォルトの行き先が使われます。

    ファイルはこの手続きが呼ばれるたびにオープンされクローズされます。 したがって、ログファイルに書き出すプログラムが走っている最中でも ログファイルをmoveすることができます。 また、log-formatsys-fcntl (section 9.5 gauche.fcntl - 低レベルファイル操作参照) を使ってファイルロックを獲得します。

    log-openが呼ばれる前にlog-formatが最初の形式で呼ばれた場合、 log-formatは何もしません。したがって、log-formatをデバッグに 活用し、必要なくなったらlog-openだけをコメントアウトする、というような 使用法も可能です。

    9.9 gauche.mop.singleton - Singleton

    Module: gauche.mop.singleton
    Provides a metaclass to define a singleton class.

    Class: <singleton-meta>
    Creates a singleton class. A singleton class is a class that is guaranteed to create only one instance. The first invocation of make creates the single instance, and further attempt of creation returns the same instance.
    (define-class single () () :metaclass <singleton-meta>)
    
    (define a (make single))
    (define b (make single))
    
    (eq? a b) => #t
    

    The slots of the instance are initialized at the first invocation of make. Initargs of make are effective only in the fist invocation, and ignored in the subsequent invocation.

    Method: instance-of (class <singleton-meta>) &rest initargs
    This method just calls make with the passed arguments. It is more obvious in the program that you're dealing with singleton.

    Class: <singleton-mixin>
    An instance of <singleton-meta>. Instead of specifying <singleton-meta> as the :metaclass argument of define-class, you can inherit this class to give your class the property of singleton.

    9.10 gauche.mop.validator - Validator付きスロット

    Module: gauche.mop.validator
    :validatorスロットオプションを追加するメタクラスを提供するモジュールです。

    Class: <validator-meta>
    このメタクラスは、スロットに対して値がセットされようとする時にその値の正当性を 検査する手続きを指定する機能を提供します。例えば、あるスロットに常に文字列のみが セットされているようにしたい場合、そのスロットに、slot-ref経由であれ アクセサメソッド経由であれ値がセットされようとした時に指定の手続きが呼ばれるように し、その手続きの中で、値が文字列でなかったらエラーとするか、強制的に値を 文字列に変換してしまうことができます。その手続きが返した値が実際にスロットに セットされます。

    検査手続きは:validatorスロットオプションによってスロット毎に指定できます。 手続きは、インスタンスとセットされようとしている値の二つを引数に取ります。 その手続きが返した値が実際にスロットにセットされる値となります。 下の例を参照して下さい。

    (define-class <v> ()
      ((a :accessor a-of
          :validator (lambda (obj value) (x->string value)))
       (b :accessor b-of
          :validator (lambda (obj value)
                       (if (integer? value)
                           value
                           (error "integer required for slot b")))))
      :metaclass <validator-meta>)
    
    (define v (make <v>))
    (slot-set! v 'a 'foo)
    (slot-ref v 'a) => "foo"
    
    (set! (a-of v) 1234)
    (a-of v) => "1234"
    
    (slot-set! v 'b 55)
    (slot-ref v 'b) => 55
    
    (slot-set! v 'b 3.4) => error
    (set! (b-of v) 3.4)  => error
    

    :validator が指定されたスロットにも、:init-value等を 使って既定の初期値を指定しておくことができます。その場合、インスタンスの初期化ルーチンは、 init-keywordによる初期値指定が無ければ既定の初期値を引数としてvalidator手続きを 呼び出します。

    (define-class <v> ()
      ((a :initform 'foo :init-keyword :a
          :validator (lambda (obj value) (x->string value)))))
    
    (slot-ref (make <v>) 'a)        => "foo"
    (slot-ref (make <v> :a 555) 'a) => "555"
    

    仮想スロットに似ていますが、validatorを持つスロットはインスタンス内に実際に 値を格納している点が異なります。

    このモジュールはまた、スロットのアクセスをメタオブジェクトプロトコルを使って カスタマイズする例でもあります。この機能はほんの12行ほどのコードで実現されています。

    9.11 gauche.net - ネットワーキング

    Module: gauche.net
    BSDソケットに基づいたネットワーキングに必要な手続きを提供するモジュールです。

    2つのレベルのAPIが定義されています。低レベルの手続きはbind(2)のような BSDソケットインタフェースに近いインタフェースを提供し、高レベルの手続きは 典型的なコネクション指向のクライアントサーバアプリケーションに便利な インタフェースを提供します。

    また、ホストネームやプロトコルに関する情報にアクセスするAPIも定義されます。

    9.11.1 ソケットアドレス

    Builtin Class: <sockaddr>
    ソケットアドレスの抽象ベースクラスです。 ソケットアドレスファミリはこのクラスのサブクラスとして実装されます。

    ソケットアドレスはビルトインクラスですが、makeメソッドで 特定のソケットアドレスファミリのインスタンスを作成することができます。

    Generic Function: sockaddr-family addr
    ソケットアドレスaddrのファミリを表すシンボルを返します。

    Generic Function: sockaddr-name addr
    ソケットアドレスaddrの名前を表す文字列を返します。

    Builtin Class: <sockaddr-in>
    AF_INETファミリのソケットアドレスです。このクラスのインスタンスを 作成するには、次のようにしてmakeメソッドを呼びます。
    (make <sockaddr-in> :host host :port port)
    

    hostは文字列か、 :any:broadcast:none:loopbackの いずれかのキーワードでなければなりません。 文字列の場合、それはホスト名かIPアドレスのドット表記です。 Gaucheはgethostbyname(3)を使って実際のIPアドレスを得ます。 この値がキーワード:any:broadcastなら、それぞれ INADDR_ANYINADDR_BROADCASTがアドレスとして使われます。 キーワード:loopbackはIPv4のループバックアドレス"127.0.0.1"を表します。

    portはポート番号を示す正の整数です。

    Method: sockaddr-family (addr <sockaddr-in>)
    シンボルinetを返します。

    Method: sockaddr-name (addr <sockaddr-in>)
    文字列"a.b.c.d:port"を返します。 コロンの前はIPアドレスのドット表記で、portはポート番号です。

    Builtin Class: <sockaddr-un>
    AF_UNIXファミリのソケットアドレスです。このクラスのインスタンスを作成するには、 makeメソッドを次のように呼んで下さい。
    (make <sockaddr-un> :path path)
    

    pathはソケットのパス名を表す文字列です。

    Method: sockaddr-family (addr <sockaddr-un>)
    シンボルunixを返します。

    Method: sockaddr-name (addr <sockaddr-un>)
    ソケットアドレスのパス名を返します。

    9.11.2 High-level network functions

    Builtin Class: <socket>
    コミュニケーション終端であるソケットを表すクラスです。

    コネクション型のソケットに対しては、2つのポート(入力用と出力用)を使って コミュニケーションチャネルにアクセスすることができます。 socket-input-portsocket-output-portがこれらのポートを それぞれ返します。

    以下の2つの手続きはコネクション型のソケットを作成する 便利な手続きです。これらは典型的な場合に対する簡単な方法を提供しますが、 細かい制御はできません。動作のより細かい制御が必要な場合は低レベルAPIを 見て下さい。

    Function: make-client-socket &optional address-spec ...
    引数address-spec ... によって指定されるアドレスと通信する クライアントソケットを作成して返します。
    (make-client-socket 'unix path)
    pathで待っているUnixドメインのサーバーソケットに接続します。
    (make-client-socket 'inet host port)
    ホストhostのポートportで待っているInetドメインのサーバーソケットに TCPを使って接続します。hostはIPアドレスのドット表記でもホスト名でも 構いません。portは正確な整数でなければなりません。
    (make-client-socket host port)
    上と同じです。この形式はSTkとの互換性のために提供されています。

    ソケットを作成できなかったり、指定されたアドレスに接続できなかった場合は エラーが報告されます。

    (make-client-socket 'inet "www.w3.com" 80)
      => ;a socket connected to www.w3.com, port 80
    (make-client-socket "127.0.0.1" 23)
      => ;a socket connected to localhost, port 23
    (make-client-socket 'unix "/tmp/.sock"
      => ;a socket connected to a unix domain socket "/tmp/.sock"
    

    Function: make-server-socket &optional address-spec ...
    address-specにて接続を待つサーバソケットを作成して返します。
    (make-server-socket 'unix path)
    パス名pathを持つUnixドメインソケットが作成されます。
    (make-server-socket 'inet port [:reuse-addr? flag])
    ポートportにて接続を待つInetドメインのTCPソケットが作成されます。 portが0の場合はシステムが適当なポート番号を割り当てます。 キーワード引数reuse-addr?に真の値が与えられた場合は、 ソケットにSO_REUSEADDRオプションがセットされます。 このオプションをセットすると、他のプロセスがそのポートを使わなくなったら直ちに このプロセスがそのポートを使うことができます。
    (make-server-socket port [:reuse-addr? flag])
    これは上の形式と同じ動作をします。STkのmake-server-socketとの 互換性のために提供されています。
    (make-server-socket 'inet 8080)
      => #<socket (listen "0.0.0.0:8080")>
    (make-server-socket 8080)
      => #<socket (listen "0.0.0.0:8080")>
    (make-server-socket 'inet 0)
      => #<socket (listen "0.0.0.0:35628")>
    (make-server-socket 'unix "/tmp/.sock")
      => #<socket (listen "/tmp/.sock")>
    

    返されたソケットオブジェクトに対して、以下のようなアクセサを適用することができます。

    Function: socket-address socket
    ソケットsocketのアドレスを返します。 ソケットにアドレスがまだバインドされていない場合は#fが返ります。

    Function: socket-input-port socket &keyword (buffering :modest)
    Function: socket-output-port socket &keyword (buffering :line)
    socketからデータを読みだす入力ポート、または socketにデータを書き出す出力ポートを返します。

    キーワード引数bufferingはポートのバッファリングモードを 指定します。バッファリングモードの説明はsection 6.18.3 ファイルポートを見て下さい。

    Function: socket-close socket
    ソケットsocketをクローズします。socketの入出力ポートも クローズされます。ソケットが接続されていた場合は、クローズの前に接続が シャットダウンされます。

    Function: call-with-client-socket socket proc
    socketは接続されたクライアントソケットでなければなりません。 procがソケットから読み出す入力ポートと、 ソケットに書き出す出力ポートを引数として呼ばれます。 procが正常終了するか、エラーを投げた場合にソケットは閉じられます。

    これは高レベルソケット手続きを使った、非常に単純なhttpクライアントです。

    #!/usr/bin/env gosh
    (use gauche.regexp)
    (use gauche.net)
    
    (define (usage)
      (display "Usage: swget url\n" (current-error-port))
      (exit 1))
    
    ;; Returns three values: host, port, and path.
    (define (parse-url url)
      (rxmatch-let (rxmatch #/^http:\/\/([-A-Za-z\d.]+)(:(\d+))?(\/.*)?/ url)
          (#f host #f port path)
        (values host port path)))
    
    (define (get url)
      (receive (host port path) (parse-url url)
        (call-with-client-socket
            (make-client-socket 'inet host (string->number (or port "80")))
          (lambda (in out)
            (format out "GET ~a HTTP/1.0\r\n" path)
            (format out "host: ~a\r\n\r\n" host)
            (flush out)
            (copy-port in (current-output-port))))))
    
    (define (main args)
      (if (= (length args) 2)
          (get (cadr args))
          (usage))
      0)
    

    9.11.3 低レベルソケットインタフェース

    These functions provide APIs similar to the system calls. Those who are familiar to programming with socket APIs will find these functions useful since you can have more detailed control over the sockets.

    Function: make-socket domain type &optional protocol
    Returns a socket with specified parameters.

    Variable: PF_UNIX
    Variable: PF_INET
    These variables are bound to PF_UNIX and PF_INET.

    Variable: AF_UNIX
    Variable: AF_INET
    These variables are bound to AF_UNIX and AF_INET.

    Variable: SOCK_STREAM
    Variable: SOCK_DGRAM
    Variable: SOCK_RAW
    These variables are bound to SOCK_STREAM, SOCK_DGRAM and SOCK_RAW.

    Function: socket-fd socket
    Returns an integer system file descriptor of the underlying socket.

    Function: socket-status socket
    Returns a internal status of socket, by one of the following symbols.
  • none The socket is just created.
  • bound The socket is bound to an address by socket-bind
  • listening The socket is listening a connection by socket-listen
  • connected The socket is connected by socket-connect or socket-accept.
  • shutdown The socket is shutdown by socket-shutdown
  • closed The socket is closed by socket-close.
  • Function: socket-bind socket address
    Binds socket to the local network address address. It is usually used to associate specific address to the server port. If binding failed, an error is signalled (most likely the address is already in use). For the inet domain address, you can pass address with port=0; the system assigns the port number and sets the actual address to the address slot of socket.
    Function: socket-listen socket backlog
    Listens socket. The socket must be already bound to some address. backlog specifies maximum number of connection requests to be queued.
    Function: socket-accept socket
    Accepts a connection request coming to socket. Returns a new socket that is connected to the remote entity. The original socket keeps waiting for further connections. If there's no connection requests, this call waits for one to come. You can use sys-select to check if there's a pending connection request.
    Function: socket-connect socket address
    Connects socket to the remote address address. This is the way for a client socket to connect to the remote entity.
    Function: socket-shutdown socket how
    Shuts down connection of socket. If how is 0, the receive channel of socket is disallowed. If how is 1, the send channel of socket is disallowed. If how is 2, both receive and send channels are disallowed. It is an error to call this function on a non-connected socket. If you shut down the send channel of the socket, the remote peer sees EOF from its receive channel. This is useful if the remote peer expects EOF before sending something back to you. Other than this kind of special cases, you don't usually need to call socket-shutdown explicitly; socket-close calls it anyway.
    Further control over sockets and protocol layers is possible by getsockopt/setsockopt interface, as described below.
    Function: socket-setsockopt socket level option value
    Function: socket-getsockopt socket level option rsize
    These are the interface to setsockopt() and getsockopt() calls. The interface is a bit clumsy, in order to allow full access to those low-level calls. socket must be a non-closed socket object. level and option is an exact integer to specify the level of protocol stack and the option you want to deal with. There are several variables pre-bound to system constants listed below. To set the socket option, you can pass either an exact integer or a string to value. If it is an integer, the value is passed to setsockopt(2) as C int value. If it is a string, the byte sequence is passed as is. The required type of value depends on the option, and Gauche can't know if the value you passed is expected by setsockopt(2); it is your responsibility to pass the correct values. To get the socket option, you need to tell the maximum length of expected result by rsize parameter, for Gauche doesn't know the amount of data each option returns. socket-getsockopt returns the option value as a byte string. If you know the option value is an integer, you can pass 0 to rsize; in that case socket-getsockopt returns the value as an exact integer. Note about the name: I tempted to name these function socket-{set|get}opt or socket-{set|get}-option, but I rather took the naming consistency. Hence duplicated "sock"s.
    The following predefined variables are provided. Note that some of them are not available on all platforms. See manpages socket(7), tcp(7) or ip(7) of your system to find out exact specification of those values. For "level" argument:
    Variable: SOL_SOCKET
    Variable: SOL_TCP
    Variable: SOL_IP
    These variables are bound to SOL_SOCKET, SOL_TCP and SOL_IP, respectively.
    For "option" argument:
    Variable: SO_KEEPALIVE
    Expects integer value. If it is not zero, enables sending of keep-alive messages on connection-oriented sockets.
    Variable: SO_OOBINLINE
    Expects integer value. If it is not zero, out-of-band data is directly placed into the receive data stream. Otherwise out-of-band data is only passed when the MSG_OOB flag is set during receiving.
    Variable: SO_REUSEADDR
    Expects integer value. If it is not zero, socket-bind allows to reuse local addresses, unless an active listening socket bound to the address.
    Variable: SO_TYPE
    Gets the socket type as an integer (like sock_stream). Can be only used with socket-getsockopt.
    Variable: SO_BROADCAST
    Expects integer value. If it is not zero, datagram sockets are allowed to send/receive broadcast packets.
    Variable: SO_PRIORITY
    Expects integer value, specifying the protocol-defined priority for all packets to be sent on this socket.
    Variable: SO_ERROR
    Gets and clears the pending socket error as an integer. Can be only used with socket-getsockopt.

    9.11.4 Netdbインタフェース

    Builtin Class: <sys-hostent>
    A class of objects for network hosts. Corresponding to struct hostent. The following slots are available read-only.

    Instance Variable: <sys-hostent> name
    The formal name of the host (string).
    Instance Variable: <sys-hostent> aliases
    A list of alias names of the host (list of strings).
    Instance Variable: <sys-hostent> addresses
    A list of addresses (list of strings). Only ipv4 address is supported currently. Each address is represented by dotted decimal notation.

    Function: sys-gethostbyname name
    Looks up a host named name. If found, returns a <sys-hostent> object. Otherwise, returns #f.
    (let ((host (sys-gethostbyname "www.w3c.org")))
      (list (slot-ref host 'name)
            (slot-ref host 'aliases)
            (slot-ref host 'addresses)))
      => ("www.w3.org" ("www.w3c.org") ("18.29.1.34" "18.29.1.35"))
    

    Function: sys-gethostbyaddr addr proto
    Looks up a host that has an address addr of protocol proto. addr is a natural string representation of the address; for ipv4, it is a dotted decimal notation. proto is a protocol number; only AF_INET is supported currently. If the host is found, returns a <sys-hostent> object. Otherwise, returns #f.
    (let ((host (sys-gethostbyaddr "127.0.0.1" AF_INET)))
      (list (slot-ref host 'name)
            (slot-ref host 'aliases)
            (slot-ref host 'addresses))
      => ("localhost" ("localhost.localdomain") ("127.0.0.1"))
    

    Builtin Class: <sys-servent>
    An entry of the network service database. Corresponding to struct servent. The following slots are available read-only.

    Instance Variable: <sys-servent> name
    The formal name of the service (string).
    Instance Variable: <sys-servent> aliases
    A list of alias names of the service (list of strings).
    Instance Variable: <sys-servent> port
    A port number registered for this service (exact integer).
    Instance Variable: <sys-servent> proto
    A protocol name for this service (string).

    Function: sys-getservbyname name proto
    Looks up the network service database with a service name name and a protocol proto. Both name and proto must be a string. If a service is found, an instance of <sys-servent> is returned. Otherwise, #f is returned.
    (let ((serv (sys-getservbyname "http" "tcp")))
      (list (slot-ref serv 'name)
            (slot-ref serv 'aliases)
            (slot-ref serv 'port)
            (slot-ref serv 'proto)))
      => ("http" () 80 "tcp")
    

    Function: sys-getservbyport port proto
    Looks up the network service database with a service port port and a protocol proto. port must be an exact integer, and proto must be a string. If a service is found, an instance of <sys-servent> is returned. Otherwise, #f is returned.
    (let ((serv (sys-getservbyport 6000 "tcp")))
      (list (slot-ref serv 'name)
            (slot-ref serv 'aliases)
            (slot-ref serv 'port)
            (slot-ref serv 'proto)))
      => ("x-server" () 6000 "tcp")
    

    Builtin Class: <sys-protoent>
    An entry of the protocol database. Corresponds to struct protoent in C. The following slots are available read-only.

    Instance Variable: <sys-servent> name
    The formal name of the protocol (string).
    Instance Variable: <sys-servent> aliases
    A list of alias names of the protocol (list of strings).
    Instance Variable: <sys-servent> proto
    A protocol number (exact integer).

    Function: sys-getprotobyname name
    Looks up the network protocol database with a name name, which must be a string. If a protocol is found, an instance of <sys-protoent> is returned. Otherwise, #f is returned.
    (let ((proto (sys-getprotobyname "icmp")))
      (list (slot-ref proto 'name)
            (slot-ref proto 'aliases)
            (slot-ref proto 'proto)))
      => ("icmp" ("ICMP") 1)
    

    Function: sys-getprotobynumber number
    Looks up the network protoice database with a protocol number number, which must be an exact integer. If a protocol is found, an instance of <sys-protoent> is returned. Otherwise, #f is returned.
    (let ((proto (sys-getprotobynumber 17)))
      (list (slot-ref proto 'name)
            (slot-ref proto 'aliases)
            (slot-ref proto 'proto)))
      => ("udp" ("UDP") 17)
    

    9.12 gauche.parameter - パラメータ

    Module: gauche.parameter
    「パラメータ」は基本的にゼロもしくは一個の引数を取る状態を持つ手続きです。 引数が与えられなかった場合、それは内部に保持した値を返します。 一つの引数が与えられた場合、その値が新たなパラメータ内部の値となります。 また、更新される値をチェックするフィルタ手続きを指定することもできます。 マクロparameterizeによって、特定の動的スコープの間だけ パラメータの値を変えることができます。

    この機能はChezScheme、Chicken、MzSchemeなどいくつかのScheme処理系で 組み込みとなっています。このモジュールはそれをエミュレートするものです。

    Function: make-parameter value &optional filter
    初期値がvalueであるパラメータを作成します。 もし省略可能な引数filterが与えられた場合、 それは一つの引数を取る手続きでなければなりません。 パラメータの値が変更されようとした時、filterは与えられた値を 引数として呼ばれ、filterが返した値がパラメータの新しい値と なります。filterはエラーを報告したりパラメータの値を変えずに置くことも 可能です。

    Macro: parameterize ((param value) ...) body ...
    body ...を評価します。 但し、body ... の実行中のみ、パラメータparamの値を valueに変更します。最後bodyの返した値を返します。

    例:

    (define a (make-parameter 1))
    (a) => 1
    (a 2)
    (a) => 2
    (parameterize ((a 3))
      (a)) => 3
    (a) => 2
    

    9.13 gauche.parseopt - コマンドライン引数の解析

    Module: gauche.parseopt
    This module defines a convenient way to parse command-line options. The interface is hinted by Perl, and conveniently handles long-format options with mutiple option arguments.

    Note that you can also use the standard getopt interface by SLIB, if you prefer.

    Macro: parse-options args (option-clause ...)
    args is an expression that contains a list of command-line arguments. This macro scans the command-line options (an argument that begins with `-') and processes it as specified in option-clauses, then returns the remaining arguments.

    Unlike typical getopt or getopt_long implementation in C, parse-options does not permute the given command-line arguments. It stops parsing when it encounters a non-option argument (argument without starting with a minus sign).

    If the parser encounters an argument with only two minus signs `--', it stops argument parsing and returns a list of arguments after `--'.

    Each option-clause is consisted by a pair of option-spec and its action.

    option-spec is a string that specifies the name of the option and how the option takes the arguments. An alphanumeric characters, underscore, plus and minus sign is allowed for option's names, except that minus sign can't be the first character, i.e. the valid option name matches a regexp #/[\w_+][-\w_+]*/. If the option takes argument(s), it can be specified by attaching equal character and the type of the argument after the name. The option can take more than one arguments.

    "name"
    Specifies option name, that doesn't take any argument.
    "name=s"
    Option name takes one argument, and it is passed as a string.
    "name=i"
    Option name takes one argument, and it is passed as an exact integer. If the given argument is not valid string for an exact integer, an error is signalled.
    "name=f"
    Option name takes one argument, and it is passed as a real number. If the given argument is not valid string for a real number, an error is signalled.
    "name=ss"
    Option name takes two arguments, both string.
    "name=iii"
    Option name takes three integer arguments.
    "name=sf"
    Option name takes two arguments, the first is a string and the second is a number.

    In the command line, the option may appear with preceding single or double minus signs. The option's argument may be comibined by the option itself with an equal sign. For example, all the following command line arguments match an option spec "prefix=s".

    -prefix /home/shiro
    -prefix=/home/shiro
    --prefix /home/shiro
    --prefix=/home/shiro
    

    If a given command-line option matches one of option-spec, then the associated action is evaluated. An action can be one of the following forms.

    bind-spec body ...
    bind-spec is a proper or dotted list of variables like lambda-list. The option's arguments are bound to bind-spec, then then body ... is evaluated.
    => proc
    If a command-line option matches option-spec, calls a procedure proc with a list of the option's arguments.

    Examples:

    (parse-options '("-file" "foo")
      (("file=s" (file)
         (format #t "file is ~s\n" file))))
     => ;``file is "foo"'' is printed
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" (xscale yscale)
         (format #t "scale is ~sx~s\n" xscale yscale))))
     => ;``scale is 1.5x2.2'' is printed
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" scales
         (format #t "scale is ~s\n" scales))))
     => ;``scale is (1.5 2.2)'' is printed
    
    (define (scales x y)
      (format #t "scale is ~sx~s\n" x y))
    
    (parse-options '("-scale" "1.5" "2.2")
      (("scale=ff" => scales)))
     => ;``scale is 1.5x2.2'' is printed
    

    If a symbol else is at the position of option-spec, the clause is selected when no other option clause matches a given command-line option. Three "arguments" are associated to the clause; the unmatched option, the rest of arguments, and a procedure that represents the option parser.

    (parse-options args
      (("file=s" => process-file)
       (else (option . _)  (error "unrecognized option:" option))))
    

    Unlike other clause, the else clause returns to the caller of parse-options, without looping further. In order to continue looping, you have to call the third argument of the else clause with the remaining arguments. This can be used to implement your own sub-parser. The following example just skips unrecognized option, with printing a warning, and continues parsing:

    (parse-options args
      (("file=s" => process-file)
       (else (option args continue)
         (format #t "warning: ignoring unrecognized option: ~a" option)
         (continue args))))
    

    Macro: make-option-parser (option-clause ...)
    This is a lower-level interface. option-clauses are the same as parse-options. This macro returns a procedure that can be used later to parse the command line options.

    The returned procedure takes one required argument and one optional argument. The required argument is a list of strings, for given command-line arguments. The optional argument may be a procedure that takes more than three arguments, and if given, the procedure is used as if it is the body of else option clause.

    9.14 gauche.process - 高レベルプロセスインタフェース

    Module: gauche.process
    This module provides a higher-level API of Unix process control, implemented on top of low-level system calls such as sys-fork and sys-exec. The interface is mostly compatible with STk's process library. This module also provides "process ports", a convenient way to send/receive information to/from subprocesses.

    To use this module, say (use gauche.process).

    9.14.1 Process object

    Class: <process>
    An object to keep the status of a child process. You can create the process object by run-process procedure described below.

    Function: run-process command arg ...
    Run command with arg in a subprocess, and returns a <process> object. command is searched from the command search path.

    Command line arguments args can include the following keyword arguments which specify special handling of the child process:

    :input file
    :output file
    :error file
    These arguments controls the subprocess' standard i/o. file may be either a string or a keyword :pipe. If it is a string, the process' standard input, output, or error goes to the named file. If it is :pipe, the process' corresponding standard i/o is connected to a pipe, and the other side of the pipe is available for the calling process.
    :wait flag
    If flag is true, run-process waits until the subprocess terminates. Othewise the subprocess runs asynchronously and run-process returns immediately, which is the default behavior. Note that if the subprocess is running asynchronously, it is the caller's responsibility to call process-wait at certain timing to correct its exit status.
    :fork flag
    If flag is true, run-process forks to run the subprocess, which is the default behavior. If flag is false, run-process directly calls sys-exec, so it never returns.

    Function: process? obj
    == (is-a? obj <process>)

    Method: process-pid (process <process>)
    Returns the process ID of the subprocess process.

    Method: process-command (process <process>)
    Returns the command invoked in the subprocess process.

    Method: process-input (process <process>)
    Method: process-output (process <process>)
    Method: process-error (process <process>)
    If the process' standard input, output or error is connected to a pipe, returns another end of the pipe, i.e. process-input returns an output port that can feed data to process' stdin, process-output an input port that can read data from process' stdout, and process-error an input port that can read data from process' stderr. If the corresponding i/o is not connected to the pipe, the function returns #f.
    (let* ((process (run-process "date" :output :pipe))
           (line (read-line (process-output process))))
      (process-wait process)
      line)
     => "Fri Jun 22 22:22:22 HST 2001"
    

    Function: process-alive? process
    Returns true if process is alive. Note that Gauche can't know the subprocess' status until it is explicitly checked by process-wait.

    Function: process-list
    Returns a list of active processes. The process remains active until its exit status is explicitly collected by process-wait.

    Function: process-wait process
    Obtains exit status of the subprocess process. This suspends execution until process exits.

    Function: process-send-signal process signal
    Sends a signal signal to the subprocess process. signal must be an exact integer for signal number. See section 6.21.6 シグナル, for predefined variables of signals.

    Function: process-kill process
    Function: process-stop process
    Function: process-continue process
    Sends SIGKILL, SIGSTOP and SIGCONT to process, respectively.

    9.14.2 Process ports

    Function: open-input-process-port command
    Runs command via /bin/sh asynchronously. An input port is returned, which is connected to the stdout of command. The stdin and stderr of command is redirected from/to /dev/null. If you need to get an error output, you can use shell's redirection.
    (define port (open-input-process-port "ls -l Makefile"))
    (read-line port)
     => "-rw-r--r--   1 shiro    users        1013 Jun 22 21:09 Makefile"
    
    (open-input-process-port "command 2>&1")
     => ;the port reads both stdout and stderr
    
    (open-input-process-port "command 2>&1 1>/dev/null")
     => ;the port reads stderr
    

    Metacharacters are interpreted by shell. You have to be careful if you pass the string provided from the outside world, for it may make a security flaw.

    The exit status of subprocess is not automatically collected. It is the caller's responsibility to issue process-wait, or the subprocess remains in a zombie state. If it bothers you, you can use one of the following functions.

    Function: call-with-input-process command proc
    Runs command via /bin/sh and pipes its stdout to an input port, then call proc with the port as an argument. When proc returns, it collects its exit status, then returns the result proc returned. The cleanup is done even if proc raises an error.
    (call-with-input-process "ls -l *"
      (lambda (p) (read-line p)))
    

    Function: with-input-from-process command thunk
    Runs command via /bin/sh, and calls thunk with its current input port connected to the command's stdout. The command is terminated and its exit status is collected when thunk returns, or it raises an error.
    (with-input-from-process "ls -l *" read-line)
    

    Function: open-output-process-port command
    Runs command via /bin/sh, and returns an output port which is connected to the stdin of the command. The stdout and stderr of the command is redirected to /dev/null.

    The exit status of the subprocess is not automatically collected. The caller should call process-wait on the subprocess at appropriate time.

    Function: call-with-output-process command proc
    Runs command via /bin/sh, and calls proc with an output port which is conected to the stdin of the command. The exit status of the command is collected after proc returns, or it raises an error.
    (call-with-output-process "/usr/sbin/sendmail"
      (lambda (out) (display mail-body out)))
    

    Function: with-output-to-process command thunk
    Same as call-with-output-process, except that the output port which is connected to the stdin of the command is set to the current output port while executing thunk.

    Function: call-with-process-io command proc
    Runs command via /bin/sh, and calls proc with two arguments; the first argument is an input port which is connected to the command's stdout, and the second is an output port connected to the command's stdin. The error output from the command is redirected to /dev/null.

    The exit status of the command is collected when proc returns or raises an error.

    Function: process-output->string command
    Function: process-output->string-list command
    Runs command and collects its output (to stdout) to return them. process-output->string concatenates all the output from command to one string, replacing any sequence of whitespace characters to single space. The action is similar to "command substitution" in shell scripts. process-output->string-list collects the output from command line-by-line and returns the list of them. Newline characters are stripped.

    Internally, command is run by call-with-input-process.

    (process-output->string "uname -smp")
      => "Linux i686 unknown"
    
    (process-output->string "ls")
      => "a.out foo.c foo.c~ foo.o"
    
    (process-output->string-list "ls")
      => ("a.out" "foo.c" "foo.c~" "foo.o")
    

    9.15 gauche.regexp - 正規表現ユーティリティ

    Module: gauche.regexp
    This module defines some macros and utilities useful in regexp match. See section 6.11 正規表現 for builtin regexp features.

    As of release 0.4.11, this module is set to be autoloaded in gosh, so you don't usually need to say (use gauche.regexp).

    The interface of some of the macros is borrowed from scsh (if-match, let-match and match-cond), but I changed the name of macros since scsh's match-cond can be confusing (e.g. Bigloo has match-lambda and match-case in pattern match library, that sounds too similar).

    In the following macros, match-expr is an expression which produces a match object or #f. Typically it is a call of rxmatch, but it can be any expression.

    Macro: rxmatch-let match-expr (var ...) form ...

    Evaluates match-expr, and if matched, binds var ... to the matched strings, then evaluates forms. The first var receives the entire match, and subsequent variables receive submatches. If the number of submatches are smaller than the number of variables to receive them, the rest of variables will get #f.

    It is possible to put #f in variable position, which says you don't care that match.

    (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                          "Jan  1 23:59:58, 2001")
       (time hh mm ss)
      (list time hh mm ss))
     => ("23:59:58" "23" "59" "58")
    
    (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                          "Jan  1 23:59:58, 2001")
       (#f hh mm)
      (list hh mm))
     => ("23" "59")
    

    This macro corresponds to scsh's let-match.

    Macro: rxmatch-if match-expr (var ...) then-form else-form
    Evaluates match-expr, and if matched, binds var ... to the matched strings and evaluate then-form. Otherwise evaluates else-form. The rule of binding vars is the same as rxmatch-let.
    (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11:22:33")
        (time)
      (format #f "time is ~a" time)
      "unknown time")
     => "time is 11:22"
    
    (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11-22-33")
        (time)
      (format #f "time is ~a" time)
      "unknown time")
     => "unknown time"
    

    This macro corresponds to scsh's if-match.

    Macro: rxmatch-cond clause ...
    Evaluate condition in clauses one by one. If a condition of a clause satisfies, rest portion of the clause is evaluated and becomes the result of rxmatch-cond. Clause may be one of the following pattern.
    (match-expr (var ...) form ...)
    Evaluate match-expr, which may return a regexp match object or #f. If it returns a match object, the matches are bound to vars, like rxmatch-let, and forms are evaluated.
    (test expr form ...)
    Evaluates expr. If it yields true, evaluates forms.
    (test expr => proc)
    Evaluates expr and if it is true, calls proc with the result of expr as the only argument.
    (else form ...)
    If this clause exists, it must be the last clause. If other clauses fail, forms are evaluated.

    If no else clause exists, and no other clause matched the string-expr, an undefined value is returned.

    ;; parses several possible date format
    (define (parse-date str)
      (rxmatch-cond
        ((rxmatch #/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ str)
            (#f mm dd yyyy)
          (map string->number (list yyyy mm dd)))
        ((rxmatch #/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ str)
            (#f yyyy mm dd)
          (map string->number (list yyyy mm dd)))
        ((rxmatch #/^\d+\/\d+\/\d+$/ str)
            (#f)
         (error "ambiguous: ~s" str))
        (else (error "bogus: ~s" str))))
    
    (parse-date "2001/2/3") => (2001 2 3)
    (parse-date "12/25/1999") => (1999 12 25)
    

    This macro corresponds to scsh's match-cond.

    Macro: rxmatch-case string-expr clause ...
    String-expr is evaluated, and clauses are interpreted one by one. A clause may be one of the following pattern.
    (re (var ...) form ...)
    Re must be either a literal string describing a regexp, or a regexp object. If it matches with the result of string-expr, the match result is bound to vars and forms are evaluated, and rxmatch-case returns the result of the last form. If re doesn't match the result of string-expr, string-expr yields non-string value, the interpretation proceeds to the next clause.
    (test proc form ...)
    A procedure proc is applied on the result of string-expr. If it yields true value, forms are evaluated, and rxmatch-case returns the result of the last form. If proc yieds #f, the interpretation proceeds to the next clause.
    (test proc => proc2)
    A procedure proc is applied on the result of string-expr. If it yields true value, proc2 is applied on the result, and its result is returned as the result of rxmatch-case. If proc yieds #f, the interpretation proceeds to the next clause.
    (else form ...)
    This form must appear at the end of clauses, if any. If other clauses fail, forms are evaluated, and the result of the last form becomes the result of rxmatch-case.

    If no else clause exists, and no other clause matched the string-expr, an undefined value is returned.

    The parse-date example above becomes simpler if you use rxmatch-case

    (define (parse-date2 str)
      (rxmatch-case str
        (test (lambda (s) (not (string? s))) #f)
        (#/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ (#f mm dd yyyy)
         (map string->number (list yyyy mm dd)))
        (#/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ (#f yyyy mm dd)
         (map string->number (list yyyy mm dd)))
        (#/^\d+\/\d+\/\d+$/                (#f)
         (error "ambiguous: ~s" str))
        (else (error "bogus: ~s" str))))
    

    Function: regexp-replace regexp string substitution
    Function: regexp-replace-all regexp string substitution
    Replaces the part of string that matched to regexp for substitution. regexp-replace just replaces the first match of regexp, while regexp-replace-all repeats the replacing throughout entire string.

    substitution may be a string or a procedure. If it is a string, it can contain a digit sequence preceded by a backslash (e.g. \2) that refers the submatch. \0 refers to the entire match. Note that you need two backslashes to include backslash character in the literal string; if you want to include a backslash character itself in the substitution, you need four backslashes.

    (regexp-replace #/def|DEF/ "abcdefghi" "...")
      => "abc...ghi"
    (regexp-replace #/def|DEF/ "abcdefghi" "|\\0|")
      => "abc|def|ghi"
    (regexp-replace #/def|DEF/ "abcdefghi" "|\\\\0|")
      => "abc|\\0|ghi"
    (regexp-replace #/c(.*)g/ "abcdefghi" "|\\1|")
      => "ab|def|hi"
    

    If substitution is a procedure, for every match in string it is called with one argument, regexp-match object. The returned value from the procedure is inserted to the output string using display.

    (regexp-replace #/c(.*)g/ "abcdefghi" 
                    (lambda (m)
                      (list->string
                       (reverse
                        (string->list (rxmatch-substring m 1))))))
     => "abfedhi"
    

    9.16 gauche.reload - Reloading modules

    Module: gauche.reload
    In the development cycle, you often have to reload modules frequently. This module supports it.

    Note that some part of semantics of the program depends on the order of loading modules, so reloading arbitrary modules may change the program behavior unexpectedly. This module is for developers who knows what they are doing.

    Redefinition rules: Reloading a module resets all the binding in the module by default. Sometimes it is not desirable, however. For example, you might have a large list of objects that takes time to rebuild. You can specify rules for the reloading procedure to determine which binding to keep.

    The rule is described in the following syntax.

      <module-rules> : (<module-rule> ...)
      <module-rule>  : (<module-pattern> <rule> ...)
      <module-pattern> : a symbol module name, or a symbol containing glob pattern
      <rule>         : procedure | symbol | regexp
                     | (and <rule> ...)
                     | (or  <rule> ...)
                     | (not <rule>)
    

    <module-rules> is the global rule to determine per-module rules. <module-pattern> is either a symbol module name or a symbol that contains glob pattern (e.g. mylib.*). If <rule> is a procedure, it is used as a predicate and the bindings whose value satisfies the predicate are kept from redefinition. If <rule> is a symbol, the binding of the variable whose name is the symbol is kept. If <rule> is a regexp, the bindings of the variable whose name matches the regexp are kept.

    Note that the mechanism to prevent redefinition is kind of ad-hoc hack and semantically unclean. It's just for your convenience. Take a look at the code if you want to know the exact behavior.

    Function: reload module-name &optional rule ...
    Reloads the specified module. You can optionally specify redefinition rules by rule ..., where each rule is the term <rule> defined above.

    Function: reload-modified-modules &optional module-rules
    Reloads module(s) that have been modified since they are loaded last time. If optional module-rules is given, it is used to determine the redefinition rules for reloaded modules. If module-rules is omitted, the current rules are used. The default of current rules is empty. You can set the current rules by module-reload-rules.

    Function: module-reload-rules &optional module-rules
    This is a parameter (See section 9.12 gauche.parameter - パラメータ) that keeps the default module rules for reload-modified-modules. If called without arguments, returns the current module rules. If called with module-rules, sets the argument to the current module rules.

    Function: reload-verbose &optional flag
    This is a parameter to control verbosity of the reloading procedures. If called without arguments, returns the current verbosity flag. If called with flag, it is set to the current verbosity flag.

    9.17 gauche.selector - 簡単なディスパッチャ

    Module: gauche.selector
    This module provides a simple interface to dispatch I/O events to registered handlers, based on sys-select (See section 6.21.10 I/Oの多重化).

    Class: <selector>
    A dispatcher instance that keeps watching I/O ports with associated handlers. A new instance can be created by make method.

    Method: selector-add! (self <selector>) port-or-fd proc flags
    Add a handler proc to the selector. proc is called when port-or-fd, which should be a port object or an integer that specifies a system file descriptor, meets a certain condition specified by flags. flags must be a list of one or more of the following symbols.
    r
    Calls proc when data is available at port-or-fd to read.
    w
    Calls proc when port-or-fd is ready to be written.
    x
    Calls proc when an exceptional condition occurs on port-or-fd.

    proc is called with two arguments. The first one is port-or-fd itself, and the second one is a symbol r, w or x, indicating the condition.

    If a handler is already associated with port-or-fd under the same condition, the previous handler is replaced by proc.

    Method: selector-delete! (self <selector>) port-or-fd proc flags
    Deletes the handler entries that matches port-or-fd, proc and flags. One or more of the arguments may be #f, meaning "don't care". For example,
    (selector-delete! selector the-port #f #f)
    

    deletes all the handlers associated to the-port, and

    (selector-delete! selector #f #f '(w))
    

    delets all the handlers waiting for writable condition.

    Method: selector-select (self <selector>) &optional (timeout #f)
    Dispatcher body. Waits for the conditions registered in self, and when it occurs, calls the associated handler.

    If the timeout argument is omitted or false, this method waits indefinitely. Alternatively you can give a timeout value, that can be a real number in microseconds, or a list of two integers that represents seconds and microseconds.

    Returns the number of handlers called. Zero means the selector has been timed out.

    It is safe to modify self inside handler. The change will be effective from the next call of selector-select

    This is a simple example of "echo" server:

    (use gauche.net)
    (use gauche.selector)
    
    (define (echo-server port)
      (let ((selector (make <selector>))
            (server   (make-server-socket 'inet port :reuse-addr? #t)))
    
        (define (accept-handler sock flag)
          (let* ((client (socket-accept server))
                 (output (socket-output-port client)))
            (selector-add! selector
                           (socket-input-port client :buffered? #f)
                           (lambda (input flag)
                             (echo client input output))
                           '(r))))
    
        (define (echo client input output)
          (let ((str (read-block 4096 input)))
            (if (eof-object? str)
                (begin (selector-delete! selector input #f #f)
                       (socket-close client))
                (begin (display str output)
                       (flush output)))))
    
        (selector-add! selector
                       (socket-fd server)
                       accept-handler
                       '(r))
        (do () (#f) (selector-select selector))))
    

    9.18 gauche.sequence - シーケンスフレームワーク

    Module: gauche.sequence
    シーケンスに関するジェネリックな操作を提供するモジュールです。 シーケンスとは、コレクションのうち0から始まる整数インデックスで アクセスできるものです。

    このモジュールはgauche.collectionを継承しています (section 9.3 gauche.collection - コレクションフレームワーク参照)。 コレクションに使えるジェネリックな操作は全てシーケンスに対しても適用可能です。

    Gauche組み込みクラスのうち、リスト、ベクター、そして文字列は シーケンスであり、このモジュールでメソッドが定義されます。 またgauche.uvectorのユニフォームベクタ等、 いくつかの拡張データタイプはシーケンスとなっています。

    9.18.1 基本的なシーケンスのアクセサ

    Generic function: ref (seq <sequence>) index &optional fallback
    シーケンスseqindex番目の要素を返します。 このメソッドによって、全てのシーケンスが統一的にアクセスできます。

    indexが負値だったりシーケンスのサイズ以上だった場合は、 fallbackが与えられていればそれが返され、 そうでなければエラーとなります。

    (ref '(a b c) 1)  => b
    (ref '#(a b c) 1) => b
    (ref "abc" 1)     => #\b
    

    Generic function: (setter ref) (seq <sequence>) index value
    統一的なシーケンスの変更メソッドです。 シーケンスseqindex番目の要素にvalueをセットします。
    (let ((x (list 'a 'b 'c)))
      (set! (ref x 1) 'z)
      x) => (a z c)
    
    (let ((x (vector 'a 'b 'c)))
      (set! (ref x 1) 'z)
      x) => #(a z c)
    
    (let ((x (string #\a #\b #\c)))
      (set! (ref x 1) #\z)
      x) => "azc"
    

    Generic function: referencer (seq <sequence>)

    Generic function: modifier (seq <sequence>)

    9.18.2 シーケンスのスライス

    Generic function: subseq (seq <sequence>) &optional start end
    シーケンスseqの、start番目の要素からend番目の要素の直前 までの部分シーケンスを返します。endが省略された場合はシーケンスの 最後までが取られます。返されるシーケンスの型はseqと同じになります。
    (subseq '(a b c d e) 1 4)   => (b c d)
    (subseq '#(a b c d e) 1 4)  => #(b c d)
    (subseq "abcde" 1 4)        => "bcd"
    
    (subseq '(a b c d e) 3)     => (d e)
    

    Generic function: (setter subseq) (seq <sequence>) start end value-seq
    Generic function: (setter subseq) (seq <sequence>) start value-seq
    value-seqの各要素を、シーケンスseqstart番目から end番目の直前まで順にセットします。 value-seqはどんなシーケンスでも構いませんが、 (end - start) よりは長くなくてはなりません。

    2番目の形式では、endvalue-seqの長さから算出されます。

    (define s '#(a b c d e))
    (set! (subseq s 1 4) '(4 5 6))
    s => #(a 4 5 6 e)
    (set! (subseq s 0)   "ab")
    s => #(#\a #\b 5 6 e)
    

    9.18.3 Implementing sequence

    9.19 gauche.syslog - Syslog

    Module: gauche.syslog
    This module provides syslog(3) system logger interface.

    For the common applications, you might find gauche.logger module easier to use (See section 9.8 gauche.logger - ユーザレベルのロギング). This module is for those who need direct access to the syslog API.

    The procedures are only defined if the undelying system supports them.

    Function: sys-openlog ident option facility
    [POSIX] Opens a connection to the system logger. A string argument ident is used for the prefix of the log, and usually is the program name. Option is an integer flag to control the behavior of logging, and facility is an integer that specify the type of the program.

    The flag for option can be composed by logior-ing one or more of the following integer constants: LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY, LOG_PERROR and LOG_PID. (Some of the constants may not be defined if the underlying system doesn't support them).

    The facility argument can be one of the following integer constants: LOG_AUTH, LOG_AUTHPRIV, LOG_CRON, LOG_DAEMON, LOG_FTP, LOG_KERN, LOG_LOCAL0 through LOG_LOCAL7, LOG_LPR, LOG_MAIL, LOG_NEWS, LOG_SYSLOG, LOG_USER and LOG_UUCP. (Some of the constants may not be defined if the underlying system doesn't support them).

    See your system's manpage of openlog(3) for detail description about these constants.

    Function: sys-syslog priority message
    [POSIX] Log the string message. Unlike syslog(3), this procedure doesn't do formatting--you can use format (See section 6.18.7 出力) to create a formatted message, or use higher-level routine log-format (See section 9.8 gauche.logger - ユーザレベルのロギング).

    An integer argument priority can be composed by logior-ing one of the facility constants described above and the level constants: LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG.

    Function: sys-closelog
    [POSIX] Closes the connection to the logging system.

    Function: sys-setlogmask mask
    [POSIX] Sets the process's log priority mask that determines which calls to sys-syslog may be logged. An priority mask can be composed by logior-ing bitmasks corresponding to the level argument of sys-syslog. You can use sys-logmask below to obtain a bitmask from the level.

    Function: sys-logmask level
    [POSIX] Returns an integer bitmask for sys-setlogmask from the log level level.

    9.20 gauche.termios - Termios

    Module: gauche.termios
    This module defines POSIX termios interface, which controls terminal attributes. This module also provides pseudo tty interface, if the system provides it.

    Builtin Class: <sys-termios>
    POSIX termios(7) structure.

    Instance Variable: <sys-termios> iflag
    Instance Variable: <sys-termios> oflag
    Instance Variable: <sys-termios> cflag
    Instance Variable: <sys-termios> lflag

    Throughout this section, argument port-or-fd refers to either a port object or a small integer representing system's file descriptor. If port is not associated to the system terminal, an error is signalled. (You can check if port has an associated terminal by sys-isatty?. See section 6.21.3.5 他のファイル操作).

    Function: sys-tcgetattr port-or-fd
    Returns terminal parameters in a <sys-termios> object, associated to port-or-fd.

    Function: sys-tcsetattr port-or-fd when termios
    Sets terminal parameters associated to port-or-fd by termios, which must be an instance of <sys-termios>.

    An integer argument when specifies when the changes take effect. Three variables are pre-defined for the argument:

    TCSANOW
    The change is reflected immediately.
    TCSADRAIN
    The change is reflected after all pending output is flushed.
    TCSAFLUSH
    The change is reflected after all pending output is flushed, and all pending input is discarded.

    Function: sys-tcsendbreak port-or-fd duration
    Transmits a zero stream for the specified duration to the terminal associated to port-or-fd. The unit of duration depends on the system; see man tcsendbreak(3) of your system for details.

    Function: sys-tcdrain port-or-fd
    Waits until all output written to port-or-fd is transmitted.

    Function: sys-tcflush port-or-fd queue
    Discards data in the buffer of port-or-fd, specified by queue, which may be one of the following values.
    TCIFLUSH
    Discards data received but not read.
    TCOFLUSH
    Discards data written but not transmitted.
    TCIOFLUSH
    Do both TCIFLUSH and TCOFLUSH action.

    Function: sys-tcflow port-or-fd action
    Controls data flow of port-or-fd by action, which may be one of the following values:
    TCOOFF
    Suspends output transmission.
    TCOON
    Restarts output transmission.
    TCIOFF
    Transmits a STOP character to make the terminal device stop transmitting data to the system.
    TCION
    Transmits a START character to make the terminal device resume transmitting data to the system.

    Function: sys-tcgetpgrp port-or-fd
    Returns process group ID of the terminal associated to port-or-fd.

    Function: sys-tcsetpgrp port-or-fd pgrp
    Sets process group ID of the terminal associated to port-or-fd to pgrp.

    Function: sys-cfgetispeed termios
    Function: sys-cfsetispeed termios speed
    Function: sys-cfgetospeed termios
    Function: sys-cfsetospeed termios speed
    Gets/sets input/output speed (baud rate) parameter stored in termios object. Speed is represented by the following predefined numbers: B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800, B9600, B19200, B38400. Some system may support higher baud rate, such as B57600, B115200 or B230400. You can use symbol-bound? to check these options are defined. B0 is used to terminate the connection.

    Function: sys-openpty &optional term
    Openes a pair of pseudo ttys, one for master and the other for slave, then returns two integers which are their file descriptors. An optional argument term must be, if passed, a <sys-termios> object; it sets the slave pty's parameters.

    You can use open-input-fd-port and/or open-output-fd-port to create a port around the returned file descriptor (See section 6.18.3 ファイルポート). To obtain pseudo tty's name, use sys-ttyname (See section 6.21.3.5 他のファイル操作).

    This function is available only if the system supports openpty(3).

    Function: sys-forkpty &optional term
    Openes a pair of pseudo ttys, one for master and the other for slave, sets the slave pty suitable for login terminal, then fork(2).

    Returns two integers; the first value is a child pid for the parent process, and 0 for the child process. The second value is a file descriptor of the master pty.

    An optional argument term must be, if passed, a <sys-termios> object; it sets the slave pty's parameters.

    This function is available only if the system supports forkpty(3).

    The following example shows how to get a password from the user without echoing:

    (use gauche.termios)
    
    (define (get-password prompt)
      (let* ((port (current-input-port))
             (attr (sys-tcgetattr port))
             (lflag (slot-ref attr 'lflag)))
        ;; Show prompt
        (display prompt)
        (flush)
        ;; Turn off echo during reading.
        (dynamic-wind
         (lambda ()
           (slot-set! attr 'lflag (logand lflag (lognot ECHO)))
           (sys-tcsetattr port TCSAFLUSH attr))
         (lambda ()
           (read-line port))
         (lambda ()
           (slot-set! attr 'lflag lflag)
           (sys-tcsetattr port TCSANOW attr)))))
    

    9.21 gauche.test - 単体テスト

    Module: gauche.test
    テストスクリプトを書くための手続きを提供します。 テストスクリプトは次のような形になります。
    (use gauche.test)
    (test-start "my feature")
    (load "my-feature")  ; テストすべきプログラムをロード
    (import my-feature)  ; モジュールを定義している場合はインポート
    
    (test-section "feature group 1")
    (test "feature 1-1" EXPECT (lambda () TEST-BODY))
    (test "feature 1-2" EXPECT (lambda () TEST-BODY))
     ...
    
    (test-section "feature group 2")
    (define test-data ...)
    (test "feature 2-1" EXPECT (lambda () TEST-BODY))
     ...
    
    (test-end)
    

    このテストスクリプトは、バッチ処理でもインタラクティブセッションからでも 実行できます。インタラクティブセッションの場合はこのテストスクリプトを ただロードすれば、各テストの結果とサマリーが報告されます。 バッチテストの場合は、標準出力を別のファイルにリダイレクトしておくと良いでしょう。 標準出力が端末でない場合、テスト手続きは詳しい結果をstdoutに出力し、簡単な メッセージを標準エラー出力に書き出します。

    モジュールやプログラムを書いたら、Makefileに"test"ターゲットを作ることを お薦めします。ルールはこんな感じになるでしょう:

    test :
            gosh my-feature-test.scm > test.log
    

    Function: test name expected thunk &optional =
    thunkを呼び、その結果をexpectedと比較します。 比較手続きには、引数=が与えられていればそれを用い、そうでなければequal? を用います。nameはログに残すためのテストの名前です。

    Function: test-start module-name
    テストの状態を初期化して、ヘッダをログに書き出します。テストを呼ぶ前に呼んで下さい。 module-nameはログのために使われる文字列です。

    Function: test-section section-name
    一群のテストの開始をマークします。単にログに使われるだけです。

    Function: test-end
    失敗したテストのリストを報告します。

    9.22 gauche.threads - スレッド

    If enabled at compilation time, Gauche can use threads built on top of POSIX threads (pthreads).

    Module: gauche.threads
    Provides thread API. You can 'use' this module regardless whether the thread support is compiled in or not; if threads are not supported, many thread-related procedures simply signals a "not supported" error.

    To check if threads are available in the running Gauche program, use the following procedure.

    Function: gauche-thread-type
    Returns a symbol that indicates the supported thread type. In the current version, the return value may be pthread when threads on top of POSIX threads are available, or none when threads are not available.

    Scheme-level thread API conforms SRFI-18, "Multithreading support" (@xref{srfi-18,,[SRFI-18]}), wrapped around Gauche's object interface.

    9.22.1 Thread procedures

    Builtin Class: <thread>
    A thread. Each thread has an associated thunk which is evaluated by a POSIX thread. When thunk returns normally, the result is stored in the internal 'result' slot, and can be retrieved by thread-join!. When thunk terminates abnormally, either by raising an exception or terminated by thread-terminate!, the exception condition is stored in ther internal 'result exception' slot, and will be passed to the thread calling thread-join! on the terminated thread.

    Each thread has its own dynamic environment and dynamic handler stack. When a thread is created, its dynamic environment is initialized by the creator's dynamic environment. The thread's dynamic handler stack is initially empty.

    Access to the resouces shared by multiple threads must be protected explicitly by synchronization primitives. See section 9.22.2 Synchronization primitives.

    Access to ports are serialized by Gauche. If multiple threads attempt to write to a port, their output may be interleaved but no output will be lost, and the state of the port is kept consistent. If multiple threads attempt to read from a port, a single read primitive (e.g. read, read-char or read-line) works atomically.

    Signal handlers are shared by all threads, but each thread has its own signal mask. See section 6.21.6.5 シグナルとスレッド, for details.

    A thread object has the following external slots.

    Instance Variable: <thread> name
    A name can be associated to a thread. This is just for the convenience of the application. The primordial thread has the name "root".

    Instance Variable: <thread> specific
    A thread-local slot for use of the application.

    Function: current-thread
    [SRFI-18], [SRFI-21] Returns the current thread.

    Function: thread? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a thread, #f otherwise.

    Function: make-thread thunk &optional name
    [SRFI-18], [SRFI-21] Creates and returns a new thread. To run the thread, you need to call thread-start!.

    You can provide the name of the thread by the optional argument name.

    Internally, this procedure just allocates and initializes a Scheme thread object; the POSIX thread is not created until thread-start! is called.

    Function: thread-name thread
    [SRFI-18], [SRFI-21] Returns the value of name slot of thread.

    Function: thread-specific thread
    Function: thread-specific-set! thread value
    [SRFI-18], [SRFI-21] Gets/sets the value of the thread's specific slot.

    Function: thread-start! thread
    [SRFI-18], [SRFI-21] Starts the thread. It is an error if thread is already started. Returns thread.

    Function: thread-yield!
    [SRFI-18], [SRFI-21] Suspends the execution of the calling thread and yields CPU to other waiting runnable threads, if any.

    Function: thread-sleep! timeout
    [SRFI-18], [SRFI-21] Suspends the calling thread for the period specified by timeout, which must be either a <time> object (See section 6.21.8.2 SRFI time) that specifies absolute point of time, or a real number that specifies relative point of time from the time this procedure is called in number of seconds.

    After the specified time passes, thread-sleep! returns with unspecified value.

    If timeout points a past time, thread-sleep! returns immediately.

    Function: thread-terminate! thread
    [SRFI-18], [SRFI-21] Terminates the specified thread thread. The thread is terminated and an instance of <terminated-thread-exception> is stored in the result exception field of thread.

    If thread is the same as the calling thread, this procedure won't return. Otherwise, this procedure returns unspecified value.

    This procedure should be used with care, since thread won't have a chance to call cleanup procedures (such as 'after' thunks of dynamic-wind) If thread is in the critical section, it leaves some state inconsistent. However, once a thread is terminated, any mutex that the thread has kept becomes 'abandoned' state, and an attempt to lock such a mutex by other thread raises an 'abandoned mutex exception', so that you will know the situation. See section 9.22.2 Synchronization primitives.

    Function: thread-join! thread &optional timeout timeout-val
    [SRFI-18], [SRFI-21] Waits termination of thread, or until the timeout is reached if timeout is given.

    Timeout must be either a <time> object (See section 6.21.8.2 SRFI time) that specifies absolute point of time, or a real number that specifies relative point of time from the time this procedure is called in number of seconds, or #f that indicates no timeout (default).

    If thread terminates normally, thread-join! returns a value which is stored in the result field of thread. If thread terminates abnormally, thread-join! raises an exception which is stored in the result exception field of thread.

    If the timeout is reached, thread-join! returns timeout-val if given, or raises <join-timeout-exception>.

    9.22.2 Synchronization primitives

    Builtin Class: <mutex>
    A primitive synchronization device. It can take one of four states: locked/owned, locked/not-owned, unlocked/abandoned and unlocked/not-abandoned. A mutex can be locked (by mutex-lock!) only if it is in unlocked state. An 'owned' mutex keeps a thread that owns it. Typically an owner thread is the one that locked the mutex, but you can make a thread other than the locking thread own a mutex. A mutex becomes unlocked either by mutex-unlock! or the owner thread terminates. In the former case, a mutex becomes unlocked/not-abandoned state. In the latter case, a mutex becomes unlocked/abandoned state.

    A mutex has the following external slots.

    Instance Variable: <mutex> name
    The name of the mutex.

    Instance Variable: <mutex> state
    The state of the mutex. This is a read-only slot. See the descrption of mutex-state below.

    Instance Variable: <mutex> specific
    A slot an application can keep arbitrary data. For example, an application can implement a 'recursive' mutex using the specific field.

    Function: mutex? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a mutex, #f otherwise.

    Function: make-mutex &optional name
    [SRFI-18], [SRFI-21] Creates and returns a new mutex object. When created, the mutex is in unlocked/not-abandoned state. Optionally, you can give a name to the mutex.

    Function: mutex-name mutex
    [SRFI-18], [SRFI-21] Returns the name of the mutex.

    Function: mutex-specific mutex
    Function: mutex-specific-set! mutex value
    [SRFI-18], [SRFI-21] Gets/sets the specific value of the mutex.

    Function: mutex-state mutex
    [SRFI-18], [SRFI-21] Returns the state of mutex, which may be one of the followings:
    a thread
    The mutex is locked/owned, and the owner is the returned thread.
    symbol not-owned
    The mutex is locked/not-owned.
    symbol abandoned
    The mutex is unlocked/abandoned.
    symbol not-abandoned
    The mutex is unlocked/not-abandoned.

    Function: mutex-lock! mutex &optional timeout thread
    [SRFI-18], [SRFI-21] Locks mutex. If mutex is in unlocked/not-abandoned state, this procedure changes its state to locked state exclusively. By default, mutex becomes locked/owned state, owned by the calling thread. You can give other owner thread as thread argument. If thread argument is given and #f, the mutex becomes locked/not-owned state.

    If mutex is in unlocked/abandoned state, that is, some other thread has been terminated without unlocking it, this procedure signals 'abandoned mutex exception' (See section 9.22.3 Thread exceptions) after changing the state of mutex.

    If mutex is in locked state and timeout is omitted or #f, this procedure blocks until mutex becomes unlocked. If timeout is specified, mutex-lock! returns when the specified time reaches in case it couldn't obtain a lock. You can give timeout an absolute point of time (by <time> object, See section 6.21.8.2 SRFI time), or a relative time (by a real number).

    Mutex-lock! returns #t if mutex is successfully locked, or #f if timeout reached.

    Note that mutex itself doesn't implements a 'recursive lock' feature; that is, if a thread that has locked mutex tries to lock mutex again, the thread blocks. It is not difficult, however, to implement a recursive lock semantics on top of this mutex. The following example is taken from SRFI-18 document:

    (define (mutex-lock-recursively! mutex)
      (if (eq? (mutex-state mutex) (current-thread))
          (let ((n (mutex-specific mutex)))
            (mutex-specific-set! mutex (+ n 1)))
          (begin
            (mutex-lock! mutex)
            (mutex-specific-set! mutex 0))))
    
    (define (mutex-unlock-recursively! mutex)
      (let ((n (mutex-specific mutex)))
        (if (= n 0)
            (mutex-unlock! mutex)
            (mutex-specific-set! mutex (- n 1)))))
    

    Function: mutex-unlock! mutex &optional condition-variable timeout
    [SRFI-18], [SRFI-21] Unlocks mutex. The state of mutex becomes unlocked/not-abandoned. It is allowed to unlock a mutex that is not owned by the calling thread.

    If optional condition-variable is given, mutex-unlock! serves the "condition variable wait" operation (e.g. pthread_cond_wait in POSIX threads). The current thread atomically wait on condition-variable and unlocks mutex. The thread will be unblocked when other thread signals on condition-variable (see condition-variable-signal! and condition-variable-broadcast! below), or timeout reaches if it is supplied. The timeout argument can be either a <time> object to represent an absolute time point (See section 6.21.8.2 SRFI time), a real number to represent a relative time in seconds, or #f which means never. The calling thread may be unblocked prematurely, so it should reacquire the lock of mutex and checks the condition, as in the follwing example (it is taken from SRFI-18 document):

    (let loop ()
      (mutex-lock! m)
      (if (condition-is-true?)
          (begin
            (do-something-when-condition-is-true)
            (mutex-unlock! m))
          (begin
            (mutex-unlock! m cv)
            (loop))))
    

    Builtin Class: <condition-variable>
    A condition variable keeps a set of threads that are waiting for a certain condition to be true. When a thread modifies the state of the concerned condition, it can call condition-variable-signal! or condition-variable-broadcast!, which unblock one or more waiting threads so that they can check if the condition is satisfied.

    A condition variable object has the following slots.

    Instance Variable: <mutex> name
    The name of the condition variable.

    Instance Variable: <mutex> specific
    A slot an application can keep arbitrary data.

    Function: condition-variable? obj
    [SRFI-18], [SRFI-21] Returns #t if obj is a condition variable, #f otherwise.

    Function: make-condition-variable &optional name
    [SRFI-18], [SRFI-21] Returns a new condition variable. You can give its name by optional name argument.

    Function: condition-variable-name cv
    [SRFI-18], [SRFI-21] Returns the name of the condition variable.

    Function: condition-variable-specific cv
    Function: condition-variable-specific-set! cv value
    [SRFI-18], [SRFI-21] Gets/sets the specific value of the condition variable.

    Function: condition-variable-signal! cv
    [SRFI-18], [SRFI-21] If there are threads waiting on cv, causes the scheduler to select one of them and to make it runnable.

    Function: condition-variable-broadcast! cv
    [SRFI-18], [SRFI-21] Unblocks all the threads waiting on cv.

    9.22.3 Thread exceptions

    Some types of exceptions may be thrown from thread-related procedures. These exceptions can be handled by Gauche's exception mechanism (See section 6.16 例外).

    Builtin Class: <thread-exception>
    A base class of thread-related exceptions. Inherits <exception> class. It has one slot.

    Instance Variable: <thread-exception> thread
    A thread that threw this exception.

    Builtin Class: <join-timeout-exception>
    An exception thrown by thread-join! when a timeout reaches before the waited thread returns. Inherits <thread-exception>.

    Builtin Class: <abandoned-mutex-exception>
    An exception thrown by mutex-lock! when a mutex to be locked is in unlocked/abandoned state. Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <abandoned-mutex-exception> mutex
    A mutex that caused this exception.

    Builtin Class: <terminated-thread-exception>
    An exception thrown by thread-join! when the waited thread is terminated abnormally (by thread-terminate!). Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <terminated-thread-exception> terminator
    A thread that terminated the thread that causes this exception.

    Builtin Class: <uncaught-exception>
    An exception thrown by thread-join! when the waited thread is terminated by an uncaught exception. Inherits <thread-exception>. It has one additional slot.

    Instance Variable: <uncaught-exception> reason
    An exception that caused the termination of the thread.

    Function: join-timeout-exception? obj
    Function: abandoned-mutex-exception? obj
    Function: terminated-thread-exception? obj
    Function: uncaught-exception? obj
    [SRFI-18], [SRFI-21] These procedures checks if obj is a certain type of exception. Provided for the compatibility to SRFI-18.

    Function: uncaught-exception-reason exc
    [SRFI-18], [SRFI-21] Returns the value of reason slot of <uncaught-exception> object. Provided for the compatibility to SRFI-18.

    9.23 gauche.time - 時間の計測

    Module: gauche.time
    Schemeコードの実行時間を測る2つの単純な方法を提供します。 インタラクティブな使用に便利なtimeマクロ及び、 プログラム中に埋め込んで使える<time-counter>オブジェクトです。

    Macro: time expr expr2 ...
    expr expr2 ... を順に評価し、最後の式の結果を返します。 結果が返される前に、全ての式の評価にかかった実(経過)時間および ユーザースペース、カーネルスペースで費されたCPU時間がカレントエラーポートに 報告されます。

    現在の実装は、経過時間に対してはsys-gettimeofday (section 6.21.8.1 POSIX time参照)を、CPU時間に対してはsys-times (section 6.21.7 システムへの問い合わせ参照)を用いています。従って、 それぞれの数値の分解能はこれらの手続きが用いているシステムコールに依存します。 CPU時間は10ms単位で、経過時間はそれより細かいことが多いです。 但しgettimeofday(2)コールをサポートしていないOSでは経過時間が最悪の場合 秒単位になります。

    gosh> (time (length (sort (call-with-input-file "/usr/share/dict/words" port->string-list))))
    ;(time (length (sort (call-with-input-file "/usr/share/dict/words" port- ...
    ; real   0.357
    ; user   0.350
    ; sys    0.000
    45427
    

    Class: <time-counter>
    時間カウンタの抽象クラスです。時間カウンタは 時間の経過と共にその値が増加してゆく一種のタイマーです。 何度でもカウントを止めたり開始したりできます。 カウンタの値はカウントが止まっている時に読み出すことができます。 複数の時間カウンタを使えば、 例えばループ中の二つの部分について費される時間を別々に計測することもできます。

    具体的なサブクラスが、どの時間をカウントするかを決定します。 時間カウンタを使うには、下に挙げるサブクラスのいずれかを インスタンシエイトしなければなりません。

    Class: <real-time-counter>
    Class: <user-time-counter>
    Class: <system-time-counter>
    Class: <process-time-counter>
    それぞれ、実経過時間、ユーザースペースCPU時間、カーネルスペースCPU時間、 総CPU時間 (ユーザー+カーネル)を計測する時間カウンタのクラスです。

    Method: time-counter-start! (counter <time-counter>)
    Method: time-counter-stop! (counter <time-counter>)
    時間カウンタcounterを開始/停止します。カウンタが走っている間の時間が、 カウンタが停止した時点でカウンタの値に加算されます。

    開始/停止の対はネストすることができます。その場合は、一番外側の対のみが 有効です。 つまり、既に走っているカウンタに対しtime-counter-start!を呼んでも 何も起こりませんが、一度余分にtime-counter-stop!を呼ばないと カウンタは止まりません。 これは、内部に既に開始/停止の対を含んでいるかもしれない大きなコードブロックの 全体の時間を計測したいというような場合に便利です。

    既に停止しているカウンタに対してtime-counter-stop!を呼んでも 何も起こりません。

    Method: time-counter-reset! (counter <time-counter>)
    カウンタcounterの値をリセットします。既にcounterが走っている 場合は、リセットの前にカウンタは停止させられます。

    Method: time-counter-value (counter <time-counter>)
    カウンタcounterの現在の値(秒数)を実数で返します。 分解能はそれぞれのカウンタが用いているシステムコールに依存します。

    Macro: with-time-counter counter expr ...
    expr ...が評価される間だけcounterを走らせる、 便利なマクロです。最後の式の結果を返します。このマクロは次のように 定義されます。
    (define-syntax with-time-counter
      (syntax-rules ()
        ((_ counter . exprs)
         (dynamic-wind
          (lambda () (time-counter-start! counter))
          (lambda () . exprs)
          (lambda () (time-counter-stop! counter))))
        ))
    

    下の例では、ループ内でのprocess-Aとprocess-Bにて費された 概略の時間をそれぞれ計測します。

    (let ((ta (make <real-time-counter>))
          (tb (make <real-time-counter>)))
      (dotimes (i 100000)
        (with-time-counter ta
          (process-A))
        (with-time-counter tb
          (process-B)))
      (format #t "Time spent in process-A: ~s\n" (time-counter-value ta))
      (format #t "Time spent in process-B: ~s\n" (time-counter-value tb))
      )
    

    9.24 gauche.uvector - ユニフォームベクタ

    Module: gauche.uvector
    SRFI-4(@xref{srfi-4,,SRFI-4})に定義されている、 要素が同一の数値型であるようなベクタを提供します。

    Gaucheの実装は、SRFI-4の仕様を次のように拡張しています。

    • いくつかの手続きはSRFI-4に無い省略可能な引数を取ります。 TAGvector->listは省略可能なstartとendのインデックスを取り、 TAGvector-refは省略可能なデフォルト値を取ります。
    • 追加の手続き: コピー(TAGvector-copy, TAGvector-copy!)、 変換 (TAGvector->vector, vector->TAGvector)、 及び各種算術演算(TAGvector-add等)。
    • コレクションフレームワーク (section 9.3 gauche.collection - コレクションフレームワーク参照)と シーケンスフレームワーク (section 9.18 gauche.sequence - シーケンスフレームワーク参照)の実装。 例えば map, for-each, ref, subseq等の メソッドがSRFI-4ベクタに対して使えます。

    通常のベクタではなくSRFI-4ベクタを使うことにより得られる利点がいくつかあります。 まず、SRFI-4ベクタは通常のベクタよりもコンパクトです。 いくつかのオペレーション(特に、Gaucheの拡張仕様であるベクタ上の数値演算)では、 型検査と型変換を個々の要素に対して行わなくても良いため、 極めて効率の良い演算が可能です。さらに、 数値の配列を扱う外部のライブラリとのインタフェースが容易です。 例えば、GaucheのOpenGLバインディングではSRFI-4ベクタを多用しています。

    以下の10タイプのベクタが定義されます。
    s8vector
    要素が -2^7 から 2^7-1 の間の正確な整数であるベクタ
    u8vector
    要素が 0 から 2^8-1 の間の正確な整数であるベクタ
    s16vector
    要素が -2^15 から 2^15-1 の間の正確な整数であるベクタ
    u16vector
    要素が 0 から 2^16-1 の間の正確な整数であるベクタ
    s32vector
    要素が -2^31 から 2^31-1 の間の正確な整数であるベクタ
    u32vector
    要素が 0 から 2^32-1 の間の正確な整数であるベクタ
    s64vector
    要素が -2^63 から 2^63-1 の間の正確な整数であるベクタ
    u64vector
    要素が 0 から 2^64-1 の間の正確な整数であるベクタ
    f32vector
    要素が、GaucheをコンパイルしたCコンパイラのfloatで表現し得るような 不正確な実数(通常IEEE単精度浮動少数点数)であるベクタ
    f64vector
    要素が、GaucheをコンパイルしたCコンパイラのdoubleで表現し得るような 不正確な実数(通常IEEE倍精度浮動少数点数)であるベクタ

    ベクタの型が許す範囲外の値を格納しようとした場合、通常はエラーとなります。 いくつかの手続きは省略可能な引数clampによって、 そのような場合に別のふるまいを指定することができます。 clampには以下のいずれかの値を与えることが出来ます。

    #f
    デフォルト (エラーを通知)
    high
    高い方の値をクランプ、すなわち、格納しようとする値が許される値の最大値より大きかった 場合は、可能な最大値を代わりに格納します。
    low
    低い方の値をクランプ、すなわち、格納しようとする値が許される値の最小値より大きかった 場合は、可能な最小値を代わりに格納します。
    both
    高いほうと低いほうの両方の値をクランプします。
    (list->u8vector '(-1))         => error
    (list->u8vector '(-1) 'low)    => #u8(0)
    (list->u8vector '(-1) 'high)   => error
    (list->u8vector '(3000) 'high) => #u8(255)
    (list->u8vector '(-100 20 300) 'both) => #u8(0 20 255)
    

    以下の記述では、TAGs8, u8, s16, u16, s32, u32, s64, u64, f32, f64 のいずれにも置き換えて読むことができるものとします。

    9.24.1 ユニフォームベクタの基本操作

    Builtin Class: <TAGvector>
    TAGvectorのクラス。<sequence>を継承します。

    Reader Syntax: #TAG(n ...)
    リテラルの単一型のベクタを記述します。
    #s8(3 -2 4)
    #u32(4154 88357 2 323)
    #f32(3.14 0.554525 -3.342)
    

    Function: TAGvector? obj
    [SRFI-4] objTAGvectorなら#tを、そうでなければ#fを返します。

    Function: TAGvector x ...
    [SRFI-4] 数値x ... を要素に持つTAGvectorを作成して返します。 正確な整数のベクタに対しては、数値は正確な整数でなければならず、 また有効な範囲内の値でなければなりません。
    (s8vector 1 2 3) => #s8(1 2 3)
    

    Function: make-TAGvector len &optional fill
    [SRFI-4] 長さlenTAGvectorを作成して返します。各要素はfillで 初期化されます。正確な整数のベクタに対しては、fillは正確な整数でなければならず、 また有効な範囲内の値でなければなりません。 fillが省略された場合、各要素の初期値は不定です。
    (make-u8vector 4 0) => #u8(0 0 0 0)
    

    Function: TAGvector-length vec
    [SRFI-4] TAGvector vecの長さを返します。

    モジュールgauche.collectionをインポートしていれば、 vecの長さを知るのに、総称関数size-ofを使うこともできます (section 9.3 gauche.collection - コレクションフレームワーク参照)。

    (s16vector-length '#s16(111 222 333)) => 3
    
    (use gauche.collection)
    (size-of '#s16(111 222 333)) => 3
    

    Function: TAGvector-ref vec k &optional fallback
    [SRFI-4+] TAGvector veck番目の要素を返します。

    kが有効な範囲外であった場合、通常はエラーが通知されますが、 省略可能な引数fallbackが与えられている場合はそれが返されます。

    モジュールgauche.collectionをインポートしていれば、 総称関数refを使うこともできます。

    (u16vector-ref '#u16(111 222 333) 1) => 222
    
    (use gauche.collection)
    (ref '#u16(111 222 333) 1) => 222
    

    Function: TAGvector-set! vec k n &optional clamp
    [SRFI-4+] TAGvector veck番目の要素に数値nをセットします。 省略可能な引数clampが、nが正しい範囲外の数であった場合の動作を指定します。 デフォルトではエラーが通知されます。

    モジュールgauche.collectionをインポートしていれば、 総称関数refのsetter手続きを使うこともできます。

    (let ((v (s32vector -439 852 8933)))
      (s32vector-set! v 1 4)
      v)
     => #s32vector(-439 4 8933)
    
    (use gauche.collection)
    (let ((v (s32vector -439 852 8933)))
      (set! (ref v 1) 4)
      v)
     => #s32vector(-439 4 8933)
    

    Function: TAGvector-copy vec &optional start end
    ベクタvecをコピーします。 省略可能な引数startendが与えられた場合、 それらは取り出される要素の範囲を制限します。
    (u8vector-copy '#u8(1 2 3 4))     => #u8(1 2 3 4)
    (u8vector-copy '#u8(1 2 3 4) 2)   => #u8(3 4)
    (u8vector-copy '#u8(1 2 3 4) 1 3) => #u8(2 3)
    

    Function: TAGvector-copy! dstvec srcvec

    コレクションやシーケンスフレームワークを使うと、さらに様々な操作を 行うことができます。

    (use gauche.collection)
    (use gauche.sequence)
    
    (fold + 0 '#s32(1 2 3 4)) => 10
    
    (map-to <f32vector> * '#f32(3.2 1.1 4.3) '#f32(-4.3 2.2 9.4))
      => #f32(-13.760001 2.420000 40.420002)
    
    (subseq #u32(1 4 3 4 5) 2 4) => #u32(3 4)
    

    9.24.2 ユニフォームベクタの変換

    Function: TAGvector->list vec &optional start end
    [SRFI-4+] TAGvector vecをリストに変換します。 省略可能な引数startendが与えられた場合、 それらは取り出される要素の範囲を制限します。

    モジュールgauche.collectionをインポートしていれば、 総称関数coerce-toを使うこともできます。

    (u32vector->list '#u32(9 2 5)) => (9 2 5)
    
    (use gauche.collection)
    (coerce-to <list> '#u32(9 2 5)) => (9 2 5)
    

    Function: TAGvector->vector vec &optional start end
    TAGvector vecをベクタに変換します。 省略可能な引数startendが与えられた場合、 それらは取り出される要素の範囲を制限します。

    モジュールgauche.collectionをインポートしていれば、 総称関数coerce-toを使うこともできます。

    (f32vector->vector '#f32(9.3 2.2 5.5))   => #(9.3 2.2 5.5)
    (f32vector->vector '#f32(9.3 2.2 5.5) 2) => #(5.5)
    
    (use gauche.collection)
    (coerce-to <vector> '#f32(9.3 2.2 5.5)) => #(9.3 2.2 5.5)
    

    Function: list->TAGvector list &optional clamp
    [SRFI-4+] リストlistTAGvectorに変換します。 省略可能な引数clampが、リスト内の要素が正しい範囲外の数であった場合の 動作を指定します。

    モジュールgauche.collectionをインポートしていれば、 総称関数coerce-toを使うこともできます。

    (list->s64vector '(9 2 5)) => #s64(9 2 5)
    
    (use gauche.collection)
    (coerce-to <s64vector> '(9 2 5)) => #s64(9 2 5)
    

    Function: vector->TAGvector vec &optional start end clamp
    ベクタvecTAGvectorに変換します。 省略可能な引数startendが与えられた場合、 それらは取り出される要素の範囲を制限します。 省略可能な引数clampが、ベクタ内の要素が正しい範囲外の数であった場合の 動作を指定します。

    モジュールgauche.collectionをインポートしていれば、 総称関数coerce-toを使うこともできます。

    (vector->f64vector '#(3.1 5.4 3.2)) => #f64(3.1 5.4 3.2)
    
    (use gauche.collection)
    (coerce-to <f64vector> '#(3.1 5.4 3.2)) => #f64(3.1 5.4 3.2)
    

    Function: string->s8vector string &optional start end
    Function: string->u8vector string &optional start end
    与えられた文字列の内部表現のバイト列と同じバイト列を持つs8vectorもしくは u8vectorを返します。省略可能な範囲引数startendは、 変換される文字列中の文字位置を指定します。

    これらの手続きは、文字を構成するバイト列をランダムにアクセスしたい場合などに 有用です。

    (string->u8vector "abc") => #u8(97 98 99)
    
    ;; 内部コードがEUCの場合
    (string->u8vector "いろは") => #u8(164 164 164 237 164 207)
    

    Function: s8vector->string vec &optional start end
    Function: u8vector->string vec &optional start end
    与えられたs8vectorもしくはu8vector vecのバイト列と同じ内部バイト列を 持つ文字列を作成して返します。省略可能な範囲引数startendは、 vec中の変換されるべき範囲をバイト位置で指定します。

    vec中のバイト列が文字列の内部表現として不正な値を持っていた場合は、 不完全な文字列が返されます。

    Function: string->s32vector string &optional start end
    Function: string->u32vector string &optional start end
    与えられた文字列stringの各文字の内部コードを値として持つ s32vectorもしくはu32vectorを返します。 省略可能な範囲引数startendは、 変換される文字列中の文字位置を指定します。

    これらの手続きは、文字列中の文字をランダムにアクセスする場合に便利です。

    Function: s32vector->string vec &optional start end
    Function: u32vector->string vec &optional start end
    startendを考えなければ、 これらの手続きは次のコードのような動作をします:
    (lambda (vec) (map-to <string> integer->char vec)))
    

    省略可能な範囲引数startendは、 vec中の変換されるべき範囲を指定します。

    Function: uvector-alias uvector-class vec &optional start end
    この手続きは、クラスがuvector-classであり、 ユニフォームベクタvecのメモリ領域を共有するような 新しいユニフォームベクタを作成して返します。 省略可能な引数startendが与えられた場合は vecの内容のうちそれらのインデックスで指定される範囲のみが使われます。 メモリ領域が共有されているので、vecに加える変更は 新しいベクタから見えますし、その逆も可能です。

    クラスuvector-classはユニフォームベクタのクラスでなければなりませんが、 vecのクラスと一致している必要はありません。 そのような場合は、新しいベクタはvecと同じメモリ領域の値を 異なる値と解釈するかもしれません。 例えば、次のコードはGaucheが走っているマシンが リトルエンディアンであるかビッグエンディアンであるかを判定します。

    (let ((u8v (uvector-alias <u8vector> #u32(1))))
      (if (zero? (u8vector-ref u8v 0))
          'big-endian 
          'little-endian))
    

    uvector-classがs8vectorかu8vector以外の場合、 新しいベクタが指す領域は、そのベクタの要素のアラインメントの要請に したがっていなければなりません。 ユニフォームベクタの開始点は常に全てのユニフォームベクタのアラインメント要請を 満たします。したがって、例えばu8vectorからu32vectorを作成する場合、 startおよびendは4の倍数でなければなりません (あるいは、start/endが省略された場合、vecの長さが 4の倍数でなければなりません)。 与えられたパラメータでアラインメントの要請が満たせない場合はエラーが通知されます。

    9.24.3 ユニフォームベクタの数値演算

    Function: TAGvector-add vec val &optional clamp
    Function: TAGvector-add! vec val &optional clamp
    Function: TAGvector-sub vec val &optional clamp
    Function: TAGvector-sub! vec val &optional clamp
    Function: TAGvector-mul vec val &optional clamp
    Function: TAGvector-mul! vec val &optional clamp
    要素毎の計算手続きです。vecTAGvectorでなければなりません。 また、valvecと同じ長さのTAGvectorかベクタかリスト、 あるいは数値(整数ベクタに対しては正確な整数、実数ベクタに対しては実数) でなければなりません。

    valTAGvectorの場合、 vecと対応する要素毎に加算、減算、乗算が行われ、 結果がTAGvectorとして返されます。 破壊的なバージョン(名前に`!'がついているもの)では、vecが 結果を格納するために再利用されます。 演算の結果がTAGvectorの要素の値域外になった場合の動作は 省略可能な引数clampによって指定されます。 (f32vectorとf64vectorでは、値域外になった要素にはinfinityが格納され、 clampの値は無視されます)。

    valが数値である場合、vecの各要素とその数値の間で演算が行われます。

    (s8vector-add '#s8(1 2 3 4) '#s8(5 6 7 8)) => #s8(6 8 10 12)
    (u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2)) => error
    (u8vector-sub '#u8(1 2 3 4) '#u8(2 2 2 2) 'both) => #u8(0 0 1 2)
    
    (f32vector-mul '#f32(3.0 2.0 1.0) 1.5) => #f32(4.5 3.0 1.5)
    

    Function: TAGvector-div vec val
    Function: TAGvector-div! vec val
    要素毎の除算です。これらはf32vectorとf64vectorのみに対して定義されます。 valvecと同じ大きさのTAGvectorかベクタかリスト、 あるいは実数でなければなりません。
    (f32vector-div '#f32(1.0 2.0 3.0) 2.0) => #f32(0.5 1.0 1.5)
    

    Function: TAGvector-and vec val
    Function: TAGvector-and! vec val
    Function: TAGvector-ior vec val
    Function: TAGvector-ior! vec val
    Function: TAGvector-xor vec val
    Function: TAGvector-xor! vec val
    要素毎の論理(ビット)演算です。 これらの手続きは整数ベクタに対してのみ定義されています。 valvecと同じ大きさのTAGvectorかベクタかリスト、 あるいは正確な整数でなければなりません。vecの各要素と、対応するvalの要素 (valが非スカラー値の場合)もしくはval自身 (valが整数の場合)とのビット毎のand, inclusive orまたはexclusive or が計算され、結果がTAGvectorで返されます。 破壊的なバージョン(名前に`!'がついているもの)では、vecが 結果を格納するために再利用されます。

    Function: TAGvector-dot vec0 vec1
    ふたつのTAGvectorの内積を計算します。 vec0vec1の長さは等しくなければなりません。

    Function: TAGvector-range-check vec min max
    vecTAGvectorでなければなりません。 minmaxはそれぞれ、vecと同じ長さのTAGvector、 ベクタ、リストのいずれかか、実数もしくは#fでなければなりません。

    vecの各要素に対して、この手続きはそれが対応するminvalmaxval の間にあるかどうかを検査します。minvalmaxvalも範囲に含みます。 ここで、minvalmaxvalは、min/maxが非スカラー値 であればvecの要素に対応するそれぞれの要素、 min/maxが数値であればその数値そのものです。 min#fの場合、最小値はマイナス無限大と考えられます。 max#fの場合、最大値はプラス無限大と考えられます。

    vecの全ての要素が範囲内であった場合は#fが返されます。 そうでなければ、範囲を外れた要素のうちもっとも左のもののvec内での インデックスが返されます。

    (u8vector-range-check '#u8(3 1 0 2) 0 3)  => #f
    (u8vector-range-check '#u8(3 1 0 2) 1 3)  => 2
    
    (u8vector-range-check '#u8(4 32 64 98) 0 '#u8(10 40 70 90))
      => 3
    
    ;; Range check in a program
    (cond
     ((u8vector-range-check u8v 1 31)
      => (lambda (i)
          (errorf "~sth vector element is out of range: ~s"
                  i (u8vector-ref u8v i))))
     (else (do-something u8v)))
    

    Function: TAGvector-clamp vec min max
    Function: TAGvector-clamp! vec min max
    vecTAGvectorでなければなりません。 minmaxはそれぞれ、vecと同じ長さのTAGvector、 ベクタ、リストのいずれかか、実数もしくは#fでなければなりません。

    TAGvector-range-checkと同じように、この手続きはvecの各要素が minおよびmaxで指定される最小値と最大値の間にあるかどうかを 検査します。要素が最小値より小さかった場合はそれが最小値に置き換えられます。 要素が最大値より大きかった場合はそれが最大値に置き換えられます。

    TAGvector-clampはvecのコピーを作ってそれに対して クランプ操作を行います。TAGvector-clamp!はvecを直接 変更します。どちらもクランプ操作が行われた後のTAGvectorを返します。

    (s8vector-clamp '#s8(8 14 -3 -22 0) -10 10) => #s8(8 10 -3 -10 0)
    

    9.24.4 ユニフォームベクタのブロック入出力

    ユニフォームベクタは、メモリの固まりを抽象化しているものと考えることも できます。それなら、それをバイナリI/Oに使えないでしょうか。もちろんできます。

    Function: read-block! vec &optional iport start end
    与えられた入力ポートiportからデータの固まりを読みだし、それを ユニフォームベクタvecに格納します。 どんな種類のユニフォームベクタでも与えることができます。 省略可能な引数startendが与えられた場合は、 それらがvec中でデータが格納されるべき領域のインデックスの範囲を 示します。その範囲外のvecの値は変更されません。 startendが与えられなかった場合はvec全体が使われます。 iportが省略された場合はカレント入力ポートが使われます。

    要求された領域を埋め終る前に入力がEOFに達した場合は、ベクタの残りの部分は 変更されません。

    read-block!が呼ばれた時既にiportがEOFに達していた場合は EOFが、そうでなければ読まれた要素の数 (バイト数ではありません) が返されます。

    iportがバッファードポートであり、そのバッファリングモードが `modest' か `none' であった場合、read-block!iportが EOFに達していなくても、vecを埋める前に戻ることがあります (バッファリングモードについてはsection 6.18.3 ファイルポート)を参照して下さい。 パイプやネットワークに接続されたポートはデフォルトでそのように振舞います。 もし、十分なデータが到着することがわかっており、vecを確実に埋めたい場合は ポートのバッファリングモードを`full'に変更して下さい。

    データはバイトストリームとして読まれるので、 s8vectorとu8vector以外のユニフォームベクタを与えた場合は 結果がプラットフォームのエンディアンに影響を受けることに注意して下さい。 例えば入力が#x01, #x02, #x03, #x04というバイトシーケンスだったと します。これをu32vectorに読み込んだ場合、最初の要素は ビッグエンディアンアーキテクチャでは#x01020304になりますが、 リトルエンディアンアーキテクチャでは#x04030201となるでしょう。

    Function: write-block vec &optional oport start end
    ユニフォームベクタvecの内容を「そのまま」oportに書き出します。 oportが省略された場合はカレント出力ポートが使われます。 省略可能な引数startendが与えられた場合は、 それらのインデックスの範囲が示すvecの内容のみが出力されます。 この手続きの返す値は未定義です。

    s8vectoru8vector以外のユニフォームベクタを与えた場合、 read-block!と同じようにエンディアンの影響を受けることに注意して 下さい。u32vector中の数値#x01020304は、 プラットフォームによってバイトシーケンス#x01, #x02, #x03, #x04と なるかもしれませんし、#x04, #x03, #x02, #x01となるかもしれません。

    9.25 gauche.version - バージョン番号の比較

    Module: gauche.version
    このモジュールは、バージョン番号(リリース番号)を比較する便利な手続きを提供します。 ここでのバージョン番号とはソフトウェアのリリースにつけられる "0.5.1"、"3.2-3"、"8.2pl1"といった文字列で、 通常これらの番号間には順序関係が定義できます。 例えば "1.2.3" は "1.2" より新しいが "2.1" より古い、といった具合です。 以下のようにこれらの文字列の順序を比較することができるようになります。
    (version<? "2.2.3" "2.2.11")     => #t
    (version<? "2.3.1" "2.3")        => #f
    (version<? "2.3.1-1" "2.3.1-10") => #t
    (version<? "13a" "5b")           => #f
    

    バージョン番号の付け方には特に標準というものはありませんが、 よく使われている方法を採用しました。全ての場合に使えるとはいきませんが、 大抵の場合はカバーできるのではないかと思います。

    厳密に言えば、分岐などの場合があるのでバージョン番号間の関係は半順序関係にしかなりません。 このモジュールでは単純な定義を使って、全順序関係があるものとして扱います。

    まず、ここでのバージョン番号は以下の構文に従うものとします。

     <version> : <principal-release>
               | <version> <post-subrelease>
               | <version> <pre-subrelease>
     <principal-release> : <relnum>
     <post-subrelease>   : [.-] <relnum>
     <pre-subrelease>    : _ <relnum>
     <relnum>            : [0-9A-Za-z]+
    

    通常<relnum>は数字部分と、それに続く省略可能な拡張部分とからなります。 例えば "23a" は数字部分23と拡張部分"a"からなります。 もし<relnum>が数字で始まらない場合、その数字部分は-1であると考えることにします。

    <relnum>の順序関係を次のように定義します。

    1. relnum Aとrelnum Bが異なる数字部分を持っている場合、拡張部分を無視して 数字部分を数値として比較します。例:"3b" < "4a"。
    2. relnum Aとrelnum Bの数字部分が等しい場合、拡張部分を辞書順に比較します。 例:"4c" < "4d"、"5" < "5a"。

    <relnum>間の順序が定義できたところで、バージョン番号の順序を次のように定義します。

    1. Decompose each version number into a list of <principal-release> and subsequence subrelease components. We call each element of the list "release components".
    2. If the first release component of both lists are the same, remove it from both. Repeat this until the head of the lists differ.
    3. Now we have the following cases.
      1. Both lists are empty: versions are the same.
      2. One list (A) is empty and the other list (B) has post-subrelease at head: A is prior to B
      3. One list (A) is empty and the other list (B) has pre-subrelease at head: B is prior to A
      4. List A's head is post-subrelease and list B's head is pre-subrelease: B is prior to A
      5. Both lists have post-subrelease or pre-subrelease at head: compare their relnums.

    Here are some examples:

    "1" < "1.0" < "1.1" < "1.1.1" < "1.1.2" < "1.2" < "1.11"
    "1.2.3" < "1.2.3-1" < "1.2.4"
    "1.2.3" < "1.2.3a" < "1.2.3b"
    "1.2_rc0" < "1.2_rc1" < "1.2" < "1.2-pl1" < "1.2-pl2"
    "1.1-patch112" < "1.2_alpha"
    

    The reason of having <pre-subrelease> is to allow "release candidate" or "pre-release" version.

    Function: version=? ver1 ver2
    Function: version<? ver1 ver2
    Function: version<=? ver1 ver2
    Function: version>? ver1 ver2
    Function: version>=? ver1 ver2
    Returns a boolean value depending on the order of two version number string ver1 and ver2. If the arguments contain invalid strings as the defined version number, an error is signalled.

    Function: version-compare ver1 ver2
    Compares two version number strings ver1 and ver2, and returns either -1, 0, or 1, depending whether ver1 is prior to ver2, ver1 is the same as ver2, or ver1 is after ver2, respectively.

    Function: relnum-compare rel1 rel2
    This is lower-level procedure of version-compare. Compares two release numbers (relnums) rel1 and rel2, and returns either -1, 0, or 1 depending whether rel1 is prior to rel2, rel1 is the same as rel2, or rel1 is after rel2, respectively.

    10. ライブラリモジュール - SRFI

    この章ではSRFIの機能を提供するモジュールをリストします。 一部のSRFIはGaucheのコアに組み込まれており、 この章には挙げられていないことに注意して下さい。 サポートされている全てのSRFIのリストはsection 2.1 標準への準拠にあります。

    10.1 srfi-0 - Feature conditional

    Module: srfi-0
    Provides SRFI-0 cond-expand macro form. Now this module is autoloaded when cond-expand is used, so you don't need to say (use srfi-0) explicitly; it is required to write a portable Scheme program.

    Macro: cond-expand (feature-requirement command-or-definition ...) ...
    [SRFI-0] This macro expands to command-or-definition ... if Gauche supports feature-requirement. In a way, it can be used to absorb the different feature sets supported by different Scheme implementations.

    feature-requiremnt must be in the following syntax:

    feature-requirement
      : feature-identifier
      | (and feature-requirement ...)
      | (or  feature-requirement ...)
      | (not feature-requirement)
    

    feature-identifier is a symbol that indicates a feature. If such a feature is supported in Gauche, it satisfies the feature-requirement. You can do boolean combination of feature-requirements to compose more complex conditions.

    The macro tests each feature-requirement in order, and if one is satisfied, the macro itself expands to the corresponding command-or-definition ....

    The last clause may begin with a symbol else instead of feature-requirement. If no condition is fulfilled before it, then the macro expands to the command-or-definitions of the else clause. If there's no else clause and no condition is fulfilled, an error is signalled.

    Currently, Gauche recognizes srfi names (e.g. srfi-1) that it supports (See section 2.1 標準への準拠, for the list of supported SRFIs), and a symbol gauche as feature-identifier.

    Suppose you are writing a program that requires srfi-13 (string library). In Gauche, the standard way to use srfi-13 is like this:

    (use srfi-13)
    
    ;; ... your program ...
    

    However, the 'use' macro is Gauche specific and won't work on other Scheme implementations. You can write instead:

    (cond-expand
      (srfi-13
        ;; ... your program ...
      ))
    

    If the implementation supports srfi-13, the form expands to your program. Note that Gauche issues (use srfi-13) for you in this case.

    The above form signals an error if the implementation doesn't support srfi-13. However, you might want to run your program on such implentations as well, by providing alternative library definitions.

    (cond-expand
     (srfi-13
       ;; ... your program ...
     )
     (else
       (load "my-srfi-13-implementation")
       ;; ... your program ...
     ))
    

    10.2 srfi-1 - List library

    Module: srfi-1
    SRFI-1 is a rich collection of list manipulation library (@xref{srfi-1,[SRFI-1],SRFI-1}). It is available by saying (use srfi-1). The implementation is based on Olin Shivers's reference implementation. I splitted it into number of subfiles that will be autoloaded on demand.

    10.2.1 リストの作成

    Function: xcons cd ca
    [SRFI-1] Equivalent to (cons ca cd). Useful to pass to higher-order procedures.

    Function: cons* elt1 elt2 ...
    [SRFI-1] Like list, but the last argument provides the tail of the constructed list. This is just a synonym of Gauche built-in procedure list*.
    (cons* 1 2 3 4) => (1 2 3 . 4)
    (cons* 1) => 1
    

    Function: list-tabulate n init-proc
    [SRFI-1] Constructs an n-element list, in which each element is generated by (init-proc i).
    (list-tabulate 4 values) => (0 1 2 3)
    

    Function: circular-list elt1 elt2 ...
    [SRFI-1] Constructs a circular list of the elements.
    (circular-list 'z 'q) => (z q z q z q ...)
    

    Function: iota count &optional (start 0) (step 1)
    [SRFI-1] Returns a list of numbers, starting from start, increasing by step.
    (iota 5) => (0 1 2 3 4)
    (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)
    

    10.2.2 リストに関する述語

    Function: proper-list? x
    [SRFI-1] Returns #t if x is a proper list.

    Function: circular-list? x
    [SRFI-1] Returns #t if x is a circular list.

    Function: dotted-list? x
    [SRFI-1] Returns #t if x is a finite, non-nil-terminated list. This includes non-pair, non-() values (e.g. symbols, numbers), which are considered to be dotted lists of length 0.

    Function: null-list? list
    [SRFI-1] Returns #t if list is the empty list (), and #f if list is a non-null, proper or circular list. This procedure signals an error if list is not a proper or circular list.

    Function: not-pair? x
    [SRFI-1] (lambda (x) (not (pair? x))).

    SRFI-1 says: Provided as a procedure as it can be useful as the termination condition for list-processing procedures that wish to handle all finite lists, both proper and dotted.

    Function: list= elt= list ...
    [SRFI-1] Determines list equality by comparing every n-th element of given lists by the procedure elt=.

    It is an error to apply list= to anything except proper lists.

    The equality procedure must be consistent with eq?, i.e.

    (eq? x y) => (elt= x y).
    

    10.2.3 List selectors

    Function: first pair
    Function: second pair
    Function: third pair
    Function: fourth pair
    Function: fifth pair
    Function: sixth pair
    Function: seventh pair
    Function: eighth pair
    Function: ninth pair
    Function: tenth pair
    [SRFI-1] Returns n-th element of the (maybe improper) list.

    Function: car+cdr pair
    [SRFI-1] Returns two values, (car pair) and (cdr pair).

    Function: take x i
    Function: drop x i
    [SRFI-1] take returns the first i elements of list x. drop returns all but the first i elements of list x.
    (take '(a b c d e)  2) => (a b)
    (drop '(a b c d e)  2) => (c d e)
    

    x may be any value:

    (take '(1 2 3 . d) 2) => (1 2)
    (drop '(1 2 3 . d) 2) => (3 . d)
    (drop '(1 2 3 . d) 3) => d
    

    drop is exactly equivalent to performing i cdr operations on x. The returned value shares a common tail with x. On the other hand, take always allocates a new list for result if the argument is a list of non-zero length.

    Function: take-right flist i
    Function: drop-right flist i
    [SRFI-1] take-right returns the last i elements of flist. drop-right returns all but the last i elements of flist.
    (take-right '(a b c d e) 2) => (d e)
    (drop-right '(a b c d e) 2) => (a b c)
    

    flist may be any finite list.

    (take-right '(1 2 3 . d) 2) => (2 3 . d)
    (drop-right '(1 2 3 . d) 2) => (1)
    (take-right '(1 2 3 . d) 0) => d
    (drop-right '(1 2 3 . d) 0) => (1 2 3)
    

    take-right's return value always shares a common tail with flist. drop-right always allocates a new list if the argument is a list of non-zero length.

    Function: take! x i
    Function: drop-right! x i
    [SRFI-1] Linear update variants of take and drop-right. Those procedures may destructively modifies x.

    If x is circular, take! may return a list shorter than expected.

    Function: split-at x i
    Function: split-at! x i
    [SRFI-1] split-at splits the list x at index i, returning a list of the first i elements, and the remaining tail.
    (split-at '(a b c d e) 2) => (a b) (c d e)
    

    split-at! is the linear-update variant. It may destructively modifes x to produce the result.

    Function: last pair
    [SRFI-1] Returns the last element of the non-empty, finite list pair. It is equivalent to (car (last-pair pair)). Note that last-pair is Gauche built-in procedure.

    10.2.4 List miscellaneous routines

    Function: length+ x
    [SRFI-1] If x is a proper list, returns its length. Otherwise, returns #f.

    Function: concatenate list-of-lists
    Function: concatenate! list-of-lists!
    [SRFI-1] Equivalent to (apply append list-of-lists) and (apply append! list-of-lists), respectively.

    Function: append-reverse rev-head tail
    Function: append-reverse! rev-head tail
    [SRFI-1] append-reverse returns (append (reverse rev-head) tail). append-reverse! is the linear-update variant.

    Function: zip clist1 clist2 ...
    [SRFI-1] Equivalent to (map list clist1 clist2 ...). If zip is passed n lists, it returns a list as long as the shortest of these lists, each element of which is an n-element list comprised of the corresponding elements from the parameter lists.
    (zip '(one two three) 
         '(1 2 3)
         '(odd even odd even odd even odd even))
         => ((one 1 odd) (two 2 even) (three 3 odd))
    
    (zip '(1 2 3)) => ((1) (2) (3))
    

    At least one of the argument lists must be finite:

    (zip '(3 1 4 1) (circular-list #f #t)) 
         => ((3 #f) (1 #t) (4 #f) (1 #t))
    

    Function: unzip1 list
    Function: unzip2 list
    Function: unzip3 list
    Function: unzip4 list
    Function: unzip5 list
    [SRFI-1] unzip1 takes a list of lists, where every list must contain at least one element, and returns a list containing the initial element of each such list. unzip2 takes a list of lists, where every list must contain at least two elements, and returns two values: a list of the first elements, and a list of the second elements. unzip3 does the same for the first three elements of the lists, and so on.
    (unzip2 '((1 one) (2 two) (3 three))) =>
       (1 2 3) and
       (one two three)
    

    Function: count pred clist1 clist2 ...
    [SRFI-1] A procedure pred is applied to the n-th element of given lists, from n is zero to the length of the the shortest finite list in the given lists, and the count of times pred returned true is returned.
    (count even? '(3 1 4 1 5 9 2 5 6)) => 3
    (count < '(1 2 4 8) '(2 4 6 8 10 12 14 16)) => 3
    

    At least one of the argument lists must be finite:

    (count < '(3 1 4 1) (circular-list 1 10)) => 2
    

    Function: count$ pred
    Partial application version of count
    ((count$ pred) arg ...) === (count pred arg ...)
    

    10.2.5 List fold, unfold & map

    Function: fold kons knil clist1 clist2 ...
    [SRFI-1] The fundamental list iterator. When it is given a single list clist1 = (e1 e2 ... en), then this procedure returns
    (kons en ... (kons e2 (kons e1 knil)) ... ) 
    

    If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

    Examples:

    (fold + 0 '(3 1 4 1 5 9)) => 23 ;sum up the elements
    (fold cons '() '(a b c d e)) => (e d c b a) ;reverse
    (fold cons* '() '(a b c) '(1 2 3 4 5))
        => (c 3 b 2 a 1) ;n-ary case
    

    Function: fold-right kons knil clist1 clist2 ...
    [SRFI-1] The fundamental list recursion operator. When it is given a single list clist1 = (e1 e2 ... en), then this procedure returns
    (kons e1 (kons e2 ... (kons en knil)))
    

    If n list arguments are provided, then the kons function must take n+1 parameters: one element from each list, and the "seed" or fold state, which is initially knil. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

    Examples:

    (fold-right cons '() '(a b c d e))
       => (a b c d e) ;copy list
    (fold-right cons* '() '(a b c) '(1 2 3 4 5))
       => (a 1 b 2 c 3) ;n-ary case
    

    Function: pair-fold kons knil clist1 clist2 ...
    Function: pair-fold-right kons knil clist1 clist2 ...
    [SRFI-1] Like fold and fold-right, but the procedure kons gets each cdr of the given clists, instead of car.

    Function: reduce f ridentity list
    Function: reduce-right f ridentity list
    [SRFI-1] Variant of fold and fold-right. F must be a binary operator, and ridentity is the value such that for any value x that is valid as f's input,
     (f x ridentity) == ridentity
    

    These functions effectively do the same thing as fold or fold-right, respectively, but omit application of f when list contains exactly one element, using the nature of ridentity.

    Function: unfold p f g seed &optional tail-gen
    [SRFI-1] Fundamental recursive list constructor. Defined by the following recursin.
    (unfold p f g seed tail-gen) ==
       (if (p seed)
           (tail-gen seed)
           (cons (f seed)
                 (unfold p f g (g seed))))
    

    That is, p determines where to stop, g is used to generate successive seed value from the current seed value, and f is used to map each seed value to a list element.

    Function: unfold-right p f g seed &optional tail
    [SRFI-1] Fundamental iterative list constructor. Defined by the following recursin.
    (unfold-right p f g seed tail) ==
      (let lp ((seed seed) (lis tail))
        (if (p seed)
            lis
            (lp (g seed) (cons (f seed) lis))))
    

    Function: append-map f clist1 clist2 ...
    Function: append-map! f clist1 clist2 ...
    [SRFI-1] Equivalent to
      (apply append (map f clist1 clist2 ...))
      (apply append! (map f clist1 clist2 ...))
    

    At least one of the list arguments must be finite.

    Function: map! f list1 clist2 ...
    [SRFI-1] The procedure f is applied to each element of list1 and corresponding elements of clists, and the result is collected to a list. Celss in list1 is reused to construct the result list.

    Function: map-in-order f clist1 clist2 ...
    [SRFI-1] A variant of map, but it guarantees to apply f on each elements of arguments in a left-to-right order. Since Gauche's map implementation follows the same order, this function is just a synonym of map.

    Function: pair-for-each f clist1 clist2 ...
    [SRFI-1] Like for-each, but the procedure f is applied on each cdr of clists.

    Function: filter-map f clist1 clist2 ...
    [SRFI-1] Like map, but only true values are saved. At least one of the list arguments must be finite.
    (filter-map (lambda (x) (and (number? x) (* x x)))
                '(a 1 b 3 c 7))
      => (1 9 49)
    

    Function: fold$ kons &optional knil
    Function: fold-right$ kons &optional knil
    Function: reduce$ f &optional ridentity
    Function: reduce-right$ f &optional ridentity
    Partial application versions of fold, fold-right, reduce, and reduce-right.

    10.2.6 List filtering & partitioning

    Function: filter pred list
    Function: filter! pred list
    [SRFI-1] A procedure pred is applied on each element of list, and a list of elements that pred returned true on it is returned.
    (filter odd? '(3 1 4 5 9 2 6)) => (3 1 5 9)
    

    filter! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: remove pred list
    Function: remove! pred list
    [SRFI-1] A procedure pred is applied on each element of list, and a list of elements that pred returned false on it is returned.
    (remove odd? '(3 1 4 5 9 2 6)) => (4 2 6)
    

    remove! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: partition pred list
    Function: partition! pred list
    [SRFI-1] filter and remove simultaneously, i.e. returns two lists, the first is the result of filtering elements of list by pred, and the second is the result of removing elements of list by pred.
    (partition odd? '(3 1 4 5 9 2 6))
      => (3 1 5 9) (4 2 6)
    

    partition! is the linear-update variant. It may destructively modifies list to produce the result.

    Function: filter$ pred
    Function: remove$ pred
    Function: partition$ pred
    Partial application versions of filter, remove and partition.

    10.2.7 List searching

    Function: find pred clist
    [SRFI-1] Applies pred for each element of clist, from left to right, and returns the first element that pred returns true on.

    Function: find-tail pred clist
    [SRFI-1] Applies pred for each element of clist, from left to right, and when pred returns a true value, returns the pair whose car is the element.

    Function: take-while pred clist
    Function: take-while! pred list
    [SRFI-1] Returns the longest initial prefix of clist whose elements all satisfy pred.

    Function: drop-while pred clist
    [SRFI-1] Drops the longest initial prefix of clist whose elements all satisfy pred, and returns the rest.

    Function: span pred clist
    Function: span! pred list
    Function: break pred clist
    Function: break! pred list
    [SRFI-1] span is equivalent to (values (take-while pred clist) (drop-while pred clist)). break inverts the sense of pred.

    Function: any pred clist1 clist2 ...
    [SRFI-1] Applies pred across each element of clists, and returns true if any application of pred returns true. The returned value is the true value pred returned.

    Function: every pred clist1 clist2 ...
    [SRFI-1] Applies pred across each element of clists, and returns true if every application of pred returns true. If all applications returns a true value until one of the lists is exhausted, every returns the value the last pred returned.

    Function: list-index pred clist1 clist2 ...
    [SRFI-1] Returns the index of the leftmost element that satisfies pred.

    Function: member$ item
    Function: find$ pred
    Function: find-tail$ pred
    Function: any$ pred
    Function: every$ pred
    Partial application version of member, find, find-tail, any and every.

    10.2.8 List deletion

    Function: delete x list &optional elt=
    Function: delete! x list &optional elt=
    [SRFI-1] Equivalent to
      (remove (lambda (y) (elt= x y)) list)
      (remove! (lambda (y) (elt= x y)) list)
    

    The comparison procedure, elt=, defaults to equal?.

    Function: delete$ x
    Partial application version of delete.

    Function: delete-duplicates list &optional elt=
    Function: delete-duplicates! list &optional elt=
    [SRFI-1] Removes duplicate elements from list. If there are multiple equal elements in list, the result list only contains the first or leftmost of these elements in the result. The order of these surviving elements is the same as in the original list. The comparison procedure, elt=, defaults to equal?.

    10.2.9 Association lists

    Function: alist-cons key datum alist
    [SRFI-1] Returns (cons (cons obj1 obj2) obj3). This is an alias of the Gauche builtin procedure acons.

    Function: alist-copy alist
    [SRFI-1] Returns a fresh copy of alist.

    Function: alist-delete key alist &optional =
    Function: alist-delete! key alist &optional =
    [SRFI-1]

    Function: assoc$ item
    Partial application version of assoc.

    10.2.10 Lists as sets

    These procedures use lists as a set.

    Function: lset<= elt= list1 ...
    [SRFI-1]

    Function: lset= elt= list1 list2 ...
    [SRFI-1]

    Function: lset-adjoin elt= list elt ...
    [SRFI-1]

    Function: lset-union elt= list1 ...
    [SRFI-1]

    Function: lset-intersection elt= list1 list2 ...
    [SRFI-1]

    Function: lset-difference elt= list1 list2 ...
    [SRFI-1]

    Function: lset-xor elt= list1 ...
    [SRFI-1]

    Function: lset-diff+intersection elt= list1 list2 ...
    [SRFI-1]

    Function: lset-union! elt= list ...
    Function: lset-intersection! elt= list1 list2 ...
    Function: lset-difference! elt= list1 list2 ...
    Function: lset-xor! elt= list1 ...
    Function: lset-diff+intersection! elt= list1 list2 ...
    [SRFI-1] Linear update variant of the corresponding procedures. The cells in the first list argument may be reused to construct the result.

    10.3 srfi-2 - And-let*

    Module: srfi-2
    SRFI-2のand-let*マクロを提供します。

    Macro: and-let* (binding ...) body ...
    [SRFI-2] 簡単に言うと、このフォームはlet*のように動作しますが、 bindings中の式が#fに評価されたらそこで評価を打ち切り #fを返します。

    bindingは以下のいずれかの形式でなければなりません。

    (variable expression)
    expressionが評価されます。それが真の値を返したら、その値がvariable に束縛され、次のbindingへと進みます。もうbindingが無ければ body ...が評価されます。もしexpression#fを返したら、 評価を打ち切り、and-let*から#fを返します。
    (expression)
    この形式ではvariableが省略されています。Expressionが評価され、 その結果は評価を続行するか打ち切るかを判断するためにのみ使われます。

    いくつか例を挙げます。次のコードは連想リストalistからkeyを 探し、見つかったらその値を返します。

    (and-let* ((entry (assoc key alist))) (cdr entry))
    

    もしargが正確な整数の文字列表現だった場合はnumを返し、そうでなければ 0を返します:

    (or (and-let* ((num (string->number arg))
                   ((exact? num))
                   ((integer? num)))
          num)
        0)
    

    以下のコードはとあるサーバーのポート番号をいくつかの可能性 (環境変数、設定ファイル…)の中から探す仮想的なコードです。

    (or (and-let* ((val (sys-getenv "SERVER_PORT")))
          (string->number val))
        (and-let* ((portfile (expand-path "~/.server_port"))
                   ((file-exists? portfile))
                   (val (call-with-input-string portfile port->string)))
          (string->number val))
        8080) ; default
    

    10.4 srfi-4 - 単一型のベクタ

    Module: srfi-4
    SRFI-4 is now implemented in gauche.uvector module See section 9.24 gauche.uvector - ユニフォームベクタ. This module simply inherits gauche.uvector for backward-compatibility.

    10.5 srfi-9 - Record types

    Module: srfi-9
    Contains a macro to use record types. A record type is implemented on top of Gauche's object system.

    The SRFI-9 record type is not as powerful as the object system, but it will be useful if you want your program to be portable.

    Macro: define-record-type name (constructor init-tag ...) predicate (field accessor [modifier]) ...
    Creates a record type and binds it to name. In Gauche, a record type is just a subclass of <record>.

    constructor is bound to a procedure that creates an instance of the record type, which takes as many arguments as init-tag .... Each init-tag corresponds to one of the field name, and the fields of the created record instance is initialized accordingly. Not all of fields need to appear in init-tag; uninitialized fields remain unbound.

    predicate is bound to a procedure that takes one argument, and returns #t if the argument is an instance of the defined record type, #f otherwise.

    Followings are field specifications. The record has fields field ..., and each field can be accessed by a method accessor. If modifier is given to the field, it is bound to a method that sets the value to the field.

    Example:

    (define-record-type pare
      (kons x y) pare?
      (x kar set-kar!)
      (y kdr))
     => #<class pare>
    
    (pare? (kons 2 3)) => #t
    (pare? (cons 2 3)) => #f
    
    (kar (kons 2 3)) => 2
    (kdr (kons 2 3)) => 3
    
    (let ((x (kons 2 3)))
      (set-kar! x -1)
      (kar x)) => -1
    

    Conceptually, the above example is expanded into the following sequence of forms.

    (define-class pare (<record>) (x y))
    (define (kons x y)
      (let ((obj (make pare)))
        (slot-set! obj 'x x) 
        (slot-set! obj 'y y)
        obj))
    (define (pare? obj) (is-a? obj pare))
    (define-method kar ((obj pare))
      (slot-ref obj 'x))
    (define-method set-kar! ((obj pare) value)
      (slot-set! obj 'x value))
    (define-method kdr ((obj pare))
      (slot-ref obj 'y))
    

    10.6 srfi-11 - Let-values

    Module: srfi-11
    Defines two macros, let-values and let*-values. They are convenient to use with multiple values (@xref{srfi-11,,[SRFI-11]}).

    Macro: let-values ((vars expr) ...) body ...
    [SRFI-11] vars are a list of variables. expr is evaluated, and its first return value is bound to the first variable in vars, its second return value to the second variable, and so on, then body is evaluated. The scope of exprs are the outside of let-values form, like let.
    (let-values (((a b) (values 1 2))
                 ((c d) (values 3 4)))
      (list a b c d)) => (1 2 3 4)
    
    (let ((a 1) (b 2) (c 3) (d 4))
      (let-values (((a b) (values c d))
                   ((c d) (values a b)))
        (list a b c d))) => (3 4 1 2)
    

    vars can be a dotted list or a single symbol, like the lambda parameters.

    (let-values (((x . y) (values 1 2 3 4)))
      y) => (2 3 4)
    
    (let-values ((x (values 1 2 3 4)))
      x) => (1 2 3 4)
    

    If the number of values returned by expr doesn't match what vars expects, an error is signalled.

    Macro: let*-values ((vars expr) ...) body ...
    [SRFI-11] Same as let-values, but each expr's scope includes the preceding vars.
    (let ((a 1) (b 2) (c 3) (d 4))
      (let*-values (((a b) (values c d))
                    ((c d) (values a b)))
        (list a b c d))) => (3 4 3 4)
    

    10.7 srfi-13 - String library

    Module: srfi-13
    Defines a large set of string-related functions. In Gauche, those functions are splitted to number of files and the form (use srfi-13) merely sets up autoloading of those files. So it is not likely to slow down the script startup.

    See SRFI-13 (@xref{srfi-13, [SRFI-13], SRFI-13}) for the detailed specification and discussion of design issues. This manual serves as a reference of function API. Some SRFI-13 functions are Gauche built-in and not listed here.

    Note: SRFI-13 documents suggests the name of the module that implements these functions to be "string-lib" and "string-lib-internals". Gauche uses the name "srfi-13" for consistency.

    10.7.1 General conventions

    There are a few common factors in string library API, which I don't repeat in each function description

    argument convention
    The following argument names imply their types.
    s, s1, s2
    Those arguments must be strings.
    char/char-set/pred
    This argument can be a character, a character-set object, or a predicate that takes a single character and returns a boolean value. "Applying char/char-set/pred to a character" means, if char/char-set/pred is a character, it is compared to the given character; if char/char-set/pred is a character set, it is checked if the character set contains the given character; if char/char-set/pred is a procedure, it is applied to the given character. "A character satisfies char/char-set/pred" means such application to the character yields true value.
    start, end
    Lots of SRFI-13 functions takes these two optional arguments, which limit the area of input string from start-th character (inclusive) to end-th character (exclusive), where the operation is performed. When specified, the condition 0 <= start <= end <= length of the string must be satisfied. Default value of start and end is 0 and the length of the string, respectively.
    `shared' variant
    Some functions have variants with "/shared" attached to its name. SRFI-13 defines those functions to allow to share the part of input string, for better performance. Gauche doesn't have a concept of shared string, and these functions are mere synonyms of their non-shared variants. However, Gauche internally shares the storage of strings, so generally you don't need to worry about the overhead of copying substrings.
    `right' variant
    Most functions works from left to right of the input string. Some functions have variants with "-right" to its name, that works from right to left.

    10.7.2 String predicates

    Function: string-null? s
    [SRFI-13] Returns #t if s is an empty string, "".

    Function: string-every char/char-set/pred s &optional start end
    [SRFI-13] Sees if every character in s satisfies char/char-set/pred. If so, string-every returns the value that is returned at the last application of char/char-set/pred. If any of the application returns #f, string-every returns #f immediately.

    Function: string-any char/char-set/pred s &optional start end
    [SRFI-13] Sees if any character in s satisfies char/char-set/pred. If so, string-any returns the value that is returned by the application. If no character satisfies char/char-set/pred, #f is returned.

    10.7.3 文字列の作成

    Function: string-tabulate proc len
    [SRFI-13] proc must be a procedure that takes an integer argument and returns a character. string-tabulate creates a string, whose i-th character is calculated by (proc i).
    (string-tabulate
      (lambda (i) (integer->char (+ i #x30))) 10)
     => "0123456789"
    

    Function: reverse-list->string char-list
    [SRFI-13] == (list->string (reverse char-list)).

    10.7.4 String selection

    Function: substring/shared s start &optional end
    [SRFI-13] In Gauche, this is the same as substring, except that the end argument is optional.
    (substring/shared "abcde" 2) => "cde"
    

    Function: string-copy! target tstart s &optional start end
    [SRFI-13] Copies a string s into a string target from the position tstart. Optional start and end arguments limits the range of s. If the copied string run over the end of target, an error is signalled.
    (define s (string-copy "abcde"))
    (string-copy! s 2 "ZZ")
    s => "abZZe"
    

    Function: string-take s nchars
    Function: string-drop s nchars
    Function: string-take-right s nchars
    Function: string-drop-right s nchars
    [SRFI-13] Returns the first nchars-character string of s (string-take) or the string without first nchars (string-drop). The *-right variation counts from the end of string. It is guaranteed that the returned string is always a copy of s, even no character is dropped.
    (string-take "abcde" 2) => "ab"
    (string-drop "abcde" 2) => "cde"
    
    (string-take-right "abcde" 2) => "cde"
    (string-drop-right "abcde" 2) => "ab"
    

    Function: string-pad s len &optional char start end
    Function: string-pad-right s len &optional char start end
    [SRFI-13]

    Function: string-trim s &optional char/char-set/pred start end
    Function: string-trim-right s &optional char/char-set/pred start end
    Function: string-trim-both s &optional char/char-set/pred start end
    [SRFI-13]

    10.7.5 String comparison

    Function: string-compare s1 s2 proc< proc= proc> &optional start1 end1 start2 end2
    Function: string-compare-ci s1 s2 proc< proc= proc> &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string= s1 s2 &optional start1 end1 start2 end2
    Function: string<> s1 s2 &optional start1 end1 start2 end2
    Function: string< s1 s2 &optional start1 end1 start2 end2
    Function: string<= s1 s2 &optional start1 end1 start2 end2
    Function: string> s1 s2 &optional start1 end1 start2 end2
    Function: string>= s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-ci= s1 s2 &optional start1 end1 start2 end2
    Function: string-ci<> s1 s2 &optional start1 end1 start2 end2
    Function: string-ci< s1 s2 &optional start1 end1 start2 end2
    Function: string-ci<= s1 s2 &optional start1 end1 start2 end2
    Function: string-ci> s1 s2 &optional start1 end1 start2 end2
    Function: string-ci>= s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-hash s &optional bound start end
    Function: string-hash-ci s &optional bound start end
    [SRFI-13]

    10.7.6 String Prefixes & Suffixes

    Function: string-prefix-length s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-length s1 s2 &optional start1 end1 start2 end2
    Function: string-prefix-length-ci s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-length-ci s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    Function: string-prefix? s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix? s1 s2 &optional start1 end1 start2 end2
    Function: string-prefix-ci? s1 s2 &optional start1 end1 start2 end2
    Function: string-suffix-ci? s1 s2 &optional start1 end1 start2 end2
    [SRFI-13]

    10.7.7 String searching

    Function: string-index s char/char-set/pred &optional start end
    Function: string-index-right s char/char-set/pred &optional start end
    [SRFI-13] Looks for the first element in a string s that matches char/char-set/pred, and returns its index. If char/char-set/pred is not found in s, returns #f. Optional start and end limit the range of s to search.
    (string-index "Aloha oe" #\a) => 4
    (string-index "Aloha oe" #[Aa]) => 0
    (string-index "Aloha oe" #[\s]) => 5
    (string-index "Aloha oe" char-lower-case?) => 1
    (string-index "Aloha oe" #\o 3) => 6
    

    See also the Gauche built-in procedure string-scan (section 6.10.7 文字列を扱うその他の手続き), if you need speed over portability.

    Function: string-skip s char/char-set/pred &optional start end
    Function: string-skip-right s char/char-set/pred &optional start end
    [SRFI-13] Looks for the first element that does not match char/char-set/pred and returns its index. If such element is not found, returns #f. Optional start and end limit the range of s to search.

    Function: string-count s char/char-set/pred &optional start end
    [SRFI-13] Counts the number of elements in s that matches char/char-set/pred. Optional start and end limit the range of s to search.

    Function: string-contains s1 s2 &optional start1 end1 start2 end2
    Function: string-contains-ci s1 s2 &optional start1 end1 start2 end2
    [SRFI-13] Looks for a string s2 inside another string s1. If found, returns an index in s1 from where the maching string begins. Returns #f otherwise. Optional start1, end1, start2 and end2 limits the range of s1 and s2.

    See also the Gauche built-in procedure string-scan (section 6.10.7 文字列を扱うその他の手続き), if you need speed over portability.

    10.7.8 String case mapping

    Function: string-titlecase s &optional start end
    Function: string-titlecase! s &optional start end
    [SRFI-13]

    Function: string-upcase s &optional start end
    Function: string-upcase! s &optional start end
    [SRFI-13]

    Function: string-downcase s &optional start end
    Function: string-downcase! s &optional start end
    [SRFI-13]

    10.7.9 String reverse & append

    Function: string-reverse s &optional start end
    Function: string-reverse! s &optional start end
    [SRFI-13] Returns a string in which the character posisions are reversed from s. string-reverse! modifies s.
    (string-reverse "mahalo") => "olaham"
    (string-reverse "mahalo" 3) => "ola"
    (string-reverse "mahalo" 1 4) => "aha"
    
    (let ((s (string-copy "mahalo")))
      (string-reverse! s 1 5)
      s)
      => "mlahao"
    

    Function: string-concatenate string-list
    [SRFI-13] Concatenates list of strings.
    (string-concatenate '("humuhumu" "nukunuku" "apua" "`a"))
      => "humuhumunukunukuapua`a"
    

    Function: string-concatenate/shared string-list
    Function: string-append/shared s ...
    [SRFI-13] "Shared" version of string-concatenate and string-append. In Gauche, these are just synonyms of them.

    Function: string-concatenate-reverse string-list
    Function: string-concatenate-reverse/shared string-list
    [SRFI-13] Reverses string-list before concatenation. "Shared" version works the same in Gauche.

    10.7.10 String mapping

    Function: string-map proc s &optional start end
    Function: string-map! proc s &optional start end
    [SRFI-13] string-map applies proc on every character of s, and collects the results into a string and returns it. On the other hand, string-map! modifies s.
    (string-map char-upcase "wikiwiki") => "WIKIWIKI"
    (string-map char-upcase "wikiwiki" 4) => "WIKI"
    
    (let ((s (string-copy "wikiwiki")))
      (string-map! char-upcase s 4)
      s)
      => "wikiWIKI"
    

    Function: string-fold kons knil s &optional start end
    Function: string-fold-right kons knil s &optional start end
    [SRFI-13]

    Function: string-unfold p f g seed &optional base make-final
    [SRFI-13]

    Function: string-unfold-right p f g seed &optional base make-final
    [SRFI-13]

    Function: string-for-each proc s &optional start end
    [SRFI-13]

    Function: string-for-each-index proc s &optional start end
    [SRFI-13]

    10.7.11 String rotation

    Function: xsubstring s from &optional to start end
    [SRFI-13]

    Function: string-xcopy! target tstart s sfrom &optional sto start end
    [SRFI-13]

    10.7.12 Other string operations

    Function: string-replace s1 s2 start1 end2 &optional start2 end2
    [SRFI-13]

    Function: string-tokenize s &optional token-set start end
    [SRFI-13]

    10.7.13 String filtering

    Function: string-filter s char/char-set/pred &optional start end
    Function: string-delete s char/char-set/pred &optional start end
    [SRFI-13]

    10.7.14 Low-level string procedures

    Function: string-parse-start+end proc s args
    Function: string-parse-final-start+end proc s args
    [SRFI-13]

    Macro: let-string-start+end (start end [rest]) proc-exp s-exp args-exp body ...
    [SRFI-13]

    Function: check-substring-spec proc s start end
    Function: substring-spec-ok? s start end
    [SRFI-13]

    Function: make-kmp-restart-vector s &optional c= start end
    [SRFI-13]

    Function: kmp-step pat rv c i c= p-start
    [SRFI-13]

    Function: string-kmp-partial-search pat rv s i &optional c= p-start s-start s-end
    [SRFI-13]

    10.8 srfi-14 - Character-set library

    Module: srfi-14
    SRFI-14で定義された文字セットライブラリを実装します (@xref{srfi-14,,SRFI-14})。 基本的な文字セットの操作はGauche組み込みになっています(section 6.9 文字集合参照)。 このモジュールでは多くのユーティリティ手続きが追加されます。

    10.8.1 Character-set constructors

    Function: list->char-set char-list &optional base-cs
    Function: list->char-set! char-list base-cs
    [SRFI-14] 与えられた文字のリストchar-listから文字セットを構築して返します。 文字セットbase-csが与えられていた場合、返される文字セットは その文字セットにchar-list中の文字を追加したものとなります。 list->char-set!は、結果を格納するためにbase-csを 変更するかもしれません。

    Function: string->char-set s &optional base-cs
    Function: string->char-set! s base-cs
    [SRFI-14] 追加する文字をリストでなく文字列sで与えることを除けば list->char-setlist->char-set!と同じです。

    Function: char-set-filter pred char-set &optional base-cs
    Function: char-set-filter! pred char-set base-cs
    [SRFI-14] char-set内の文字のうち、(pred c) が真の値を 返すようなcからなる文字セットを作成して返します。 文字セットbase-csが与えられた場合は、その内容が結果に追加されます。 char-set-filter!は、結果を格納するためにbase-csを変更するかも しれません。

    Function: ucs-range->char-set lower upper &optional error? base-cs
    Function: ucs-range->char-set! lower upper error? base-cs
    [SRFI-14]

    Function: integer-range->char-set lower upper &optional error? base-cs
    Function: integer-range->char-set! lower upper error? base-cs

    Function: ->char-set x
    [SRFI-14]

    10.8.2 Character-set comparison

    Function: char-set= char-set1 ...
    [SRFI-14]

    Function: char-set<= char-set1 ...
    [SRFI-14]

    Function: char-set-hash char-set &optional bound
    [SRFI-14]

    10.8.3 Character-set iteration

    Function: char-set-cursor char-set
    [SRFI-14]

    Function: char-set-ref char-set cursor
    [SRFI-14]

    Function: char-set-cursor-next char-set cursor
    [SRFI-14]

    Function: end-of-char-set? ccursor
    [SRFI-14]

    Function: char-set-fold kons knil char-set
    [SRFI-14]

    Function: char-set-unfold pred fun gen seed &optional base-char-set
    Function: char-set-unfold! pred fun gen seed base-char-set
    [SRFI-14]

    Function: char-set-for-each proc char-set
    [SRFI-14]

    Function: char-set-map proc char-set
    [SRFI-14]

    10.8.4 Character-set query

    Function: char-set-size char-set
    [SRFI-14]

    Function: char-set-count pred char-set
    [SRFI-14]

    Function: char-set->list char-set
    [SRFI-14]

    Function: char-set->string char-set
    [SRFI-14]

    Function: char-set-every pred char-set
    [SRFI-14]

    Function: char-set-any pred char-set
    [SRFI-14]

    10.8.5 Character-set algebra

    Function: char-set-adjoin char-set char1 ...
    Function: char-set-adjoin! char-set char1 ...
    [SRFI-14]

    Function: char-set-delete char-set char1 ...
    Function: char-set-delete! char-set char1 ...
    [SRFI-14]

    Function: char-set-complement char-set
    Function: char-set-complement! char-set
    [SRFI-14]

    Function: char-set-union char-set ...
    Function: char-set-union! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-intersection char-set ...
    Function: char-set-intersection! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-difference char-set1 char-set2 ...
    Function: char-set-difference! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-xor char-set ...
    Function: char-set-xor! char-set1 char-set2 ...
    [SRFI-14]

    Function: char-set-diff+intersection char-set1 char-set2 ...
    Function: char-set-diff+intersection! char-set1 char-set2 char-set3 ...
    [SRFI-14]

    10.8.6 Predefined character-set

    Variable: char-set:letter
    [SRFI-14]

    Variable: char-set:blank
    [SRFI-14]

    Variable: char-set:iso-control
    [SRFI-14]

    Variable: char-set:digit
    Variable: char-set:hex-digit
    [SRFI-14]

    Variable: char-set:graphic
    [SRFI-14]

    Variable: char-set:lower-case
    Variable: char-set:upper-case
    Variable: char-set:title-case
    [SRFI-14]

    Variable: char-set:printing
    [SRFI-14]

    Variable: char-set:punctuation
    [SRFI-14]

    Variable: char-set:whitespace
    [SRFI-14]

    Variable: char-set:symbol
    [SRFI-14]

    Variable: char-set:ascii
    [SRFI-14]

    Variable: char-set:empty
    [SRFI-14]

    Variable: char-set:full
    [SRFI-14]

    10.9 srfi-19 - 時間のデータ型と手続き

    このSRFIは、時間と日付に関する様々な表現と、それらの間の変換メソッドを提供します。

    Gaucheでは、timeオブジェクトは<time>クラスとして組み込みで サポートされています(section 6.21.8.2 SRFI time参照)。dateオブジェクトは以下で説明する <date>クラスとしてサポートされます。

    10.9.1 時間のタイプ

    時間のタイプはシンボルで表現されます。 このモジュールでは以下の定数が自分の名前に束縛された形で提供されています。

    Constant: time-utc
    [SRFI-19] UTC timeです。Gaucheの組み込みのcurrent-timeは常にこのタイプの時間を 返します (section 6.21.8.2 SRFI time参照)。

    Constant: time-tai
    [SRFI-19] International Atomic Time。この時間は閏秒を計算に入れており、 UTCより若干大きな値を取ります。

    Constant: time-monotonic
    [SRFI-19] 実装依存の、単調増加する時間。Gaucheの実装ではこれはtime-taiと同じです。

    Constant: time-duration
    [SRFI-19] 二つの絶対的な時点の間の期間。

    Constant: time-process
    [SRFI-19] 現在のプロセスのCPU時間。 Gaucheは、POSIX time(3)コールが返すユーザ時間とシステム時間の合計からこの値を 計算します。

    Constant: time-thread
    [SRFI-19] 現在のスレッドのCPU時間。 現在の実装ではこれはtime-processと同じです。

    10.9.2 時間に関する問い合わせ

    Function: current-time &optional time-type
    [SRFI-19] Gauche組み込みのcurrent-time (section 6.21.8.2 SRFI time参照)を拡張して、 必要な時間のタイプを省略可能な引数time-typeで指定できるようにしています。 可能なtime-typeの値はsection 10.9.1 時間のタイプで説明されているものです。

    Function: current-date &optional tz-offset
    [SRFI-19] 現在の日付を<date>クラスのインスタンスとして返します(section 10.9.4 日付参照)。 tz-offsetが与えられた場合、それがUTCからのオフセットを表す秒数として 使われます。tz-offsetが与えられなかった場合はローカルタイムゾーンで 表現された日付が返されます。

    Function: current-julian-day
    [SRFI-19] 現在のJulian dayを返します。Julian dayは -4714-11-24T12:00:00Z (November 24, -4714 at noon, UTC) からの日数を 実数で表現したものです。

    Function: current-modified-julian-day
    [SRFI-19] 現在のModified julian dayを返します。Modified julian dayは 1858-11-17T00:00:00Z (November 17, 1858 at midnight, UTC) からの日数を実数で表現したものです。

    Function: time-resolution
    [SRFI-19]

    10.9.3 時間に関する手続き

    Function: make-time type seconds nanoseconds
    [SRFI-19] 与えられた初期値を持つ<time>クラスのインスタンスを返します。 (make <time> :type type :second seconds :nanosecond nanoseconds) と等価です。

    Function: time-type time
    Function: time-second time
    Function: time-nanosecond time
    Function: set-time-type! time type
    Function: set-time-second! time second
    Function: set-time-nanosecond! time nanosecond
    [SRFI-19] <time>オブジェクトのスロットのアクセサです。

    Function: copy-time time
    [SRFI-19] 与えられたtimeと同じ内容の新しい<time>オブジェクトを返します。

    Function: time=? time0 time1
    Function: time<? time0 time1
    Function: time<=? time0 time1
    Function: time>? time0 time1
    Function: time>=? time0 time1
    [SRFI-19] 二つの時間を比較します。時間のタイプは一致していなければなりません。

    Function: time-difference time0 time1
    Function: time-difference! time0 time1
    [SRFI-19] 二つの時間の差をtime-durationタイプの時間として返します。 二つの時間のタイプは一致していなければなりません。 Time-difference!は結果を格納するためにtime0を変更します。

    Function: add-duration time0 time-duration
    Function: add-duration! time0 time-duration
    Function: subtract-duration time0 time-duration
    Function: subtract-duration! time0 time-duration
    [SRFI-19] time-durationtime0に加算、またはtime0から減算します。 返される時間のタイプはtime0と同じです。time-durationのタイプは time-durationでなければなりません。 add-duration!subtract-duration!は結果を格納するのに time0を再利用します。

    10.9.4 日付

    Class: <date>

    Function: make-date nanosecond second minute hour day month year zone-offset
    [SRFI-19]

    Function: date?
    [SRFI-19]

    Function: date-nanosecond date
    Function: date-second date
    Function: date-minute date
    Function: date-hour date
    Function: date-day date
    Function: date-month date
    Function: date-year date
    Function: date-zone-offset date
    [SRFI-19]

    Function: date-year-day date
    Function: date-week-day date
    Function: date-week-number date day-of-week-starting-week
    [SRFI-19]

    Function: date->julian-day date
    Function: date->modified-julian-day date
    Function: date->time-monotonic date
    Function: date->time-tai date
    Function: date->time-utc date
    [SRFI-19] Conversions from date to various date/time types.

    Function: julian-day->date jd &optional tz-offset
    Function: julian-day->time-monotonic jd
    Function: julian-day->time-tai jd
    Function: julian-day->time-utc jd
    [SRFI-19] Conversions from julian-day to various date/time types.

    Function: modified-julian-day->date jd &optional tz-offset
    Function: modified-julian-day->time-monotonic jd
    Function: modified-julian-day->time-tai jd
    Function: modified-julian-day->time-utc jd
    [SRFI-19] Conversions from modified julian-day to various date/time types.

    Function: time-monotonic->date time &optional tz-offset
    Function: time-monotonic->julian-day time
    Function: time-monotonic->modified-julian-day time
    Function: time-monotonic->time-tai time
    Function: time-monotonic->time-tai! time
    Function: time-monotonic->time-utc time
    Function: time-monotonic->time-utc! time
    [SRFI-19] Conversions from time-monotonic to various date/time types.

    Function: time-tai->date time &optional tz-offset
    Function: time-tai->julian-day time
    Function: time-tai->modified-julian-day time
    Function: time-tai->time-monotonic time
    Function: time-tai->time-monotonic! time
    Function: time-tai->time-utc time
    Function: time-tai->time-utc! time
    [SRFI-19] Conversions from time-tai to various date/time types.

    Function: time-utc->date time &optional tz-offset
    Function: time-utc->julian-day time
    Function: time-utc->modified-julian-day time
    Function: time-utc->time-monotonic time
    Function: time-utc->time-monotonic! time
    Function: time-utc->time-tai time
    Function: time-utc->time-tai! time
    [SRFI-19] Conversions from time-utc to various date/time types.

    10.9.5 日付の読み書き

    Function: date->string date &optional format-string
    [SRFI-19]

    Function: string->date string template-string
    [SRFI-19]

    10.10 srfi-27 - ランダムビットのソース

    Module: srfi-27
    This module provides SRFI-27 pseudo random generator interface, using Mersenne Twister algorithm (See section 11.8 math.mt-random - Mersenne Twister乱数発生器) as the backbone.

    Function: random-integer n
    [SRFI-27] Returns a random exact integer between [0, n-1], inclusive, using the default random source. To set a random seed for this procedure, use random-source-randomize! or random-source-pseudo-randomize! on default-random-source.

    Function: random-real
    [SRFI-27] Returns a random real number between (0, 1), exclusive, using the default random source. To set a random seed for this procedure, use random-source-randomize! or random-source-pseudo-randomize! on default-random-source.

    Variable: default-random-source
    [SRFI-27] Keeps the default random source that is used by random-integer and random-real.

    Function: make-random-source
    [SRFI-27] Creates and returns a new random source. In the current Gauche implementation, it is just a <mersenne-twister> object. It may be changed in the future implementation.

    Function: random-source? obj
    [SRFI-27] Returns #t if obj is a random source object.

    Function: random-source-state-ref s
    Function: random-source-state-set! s state
    [SRFI-27] Gets and sets the "snapshot" of the state of the random source s. State is an opaque object whose content depends on the backbone generator.

    Function: random-source-randomize! s
    [SRFI-27] Makes an effort to set the state of the random source s to a truly random state. The current implementation uses the current time and the process ID to set the random seed.

    Function: random-source-pseudo-randomize! s i j
    [SRFI-27] Changes the state of the random source s into the initial state of the (i, j)-th independent random source, where i and j are non-negative integers. This procedure can be used to reuse a random source s as large number of independent random source, indexed by two non-negative integers. Note that this procedure is entirely deterministic.

    Function: random-source-make-integers s
    [SRFI-27] Returns a procedure, that takes one integer argument n and returns a random integer between 0 and n-1 inclusive for every invocation, from the random source s.

    Function: random-source-make-reals s &optional unit
    [SRFI-27] Returns a procedure, that takes no argument and returns a random real between 0 and 1 exclusive for every invocation, from the random source s. If unit is given, the random real the returned procedure generates will be quantized by the given unit, where 0 < unit < 1.

    11. ライブラリモジュール - ユーティリティ

    11.1 dbm - 汎用DBMインタフェース

    Module: dbm
    DBM系のライブラリはキーでインデックスされた値をファイルに格納する簡単な方法を 提供します。一種の永続的な連想記憶と言えるでしょう。

    このモジュールが定義する抽象クラス<dbm>は、DBM系ライブラリへの 統一されたインタフェースを提供します。dbmモジュールだけをインポートすれば、 既にオープンされたデータベースを操作することができます。

    データベースをオープンしたり作成したりするには、dbmインタフェースを実装した モジュールが必要になります。今のところGaucheでは以下の実装が使えます。 それぞれのモジュールは、dbmインタフェース共通の手続きの他に、 直接実装を操作できる低レベルの手続きも提供します。 システムによっては以下のインタフェースの全てが実装されているわけではないことに 注意してください。Gaucheではシステムが提供する実装のみを定義します。

    dbm.gdbm
    GDBMライブラリ (See section 11.2 dbm.gdbm - GDBM interface).
    dbm.ndbm
    NDBMライブラリ (See section 11.3 dbm.ndbm - NDBM interface).
    dbm.odbm
    DBMライブラリ (See section 11.4 dbm.odbm - Original DBM interface).

    以下にdbmデータベースの使用例を示します。

    (use dbm)         ; dbm abstract interface
    (use dbm.gdbm)    ; dbm concrete interface
    
    ; open the database
    (define *db* (dbm-open <gdbm> :path "mydb" :rw-mode :write))
    
    ; put the value to the database
    (dbm-put! *db* "key1" "value1")
    
    ; get the value from the database
    (define val (dbm-get *db* "key1"))
    
    ; iterate over the database
    (dbm-for-each *db* (lambda (key val) (foo key val)))
    
    ; close the database
    (dbm-close *db*)
    

    11.1.1 DBMデータベースのオープンとクローズ

    Class: <dbm>
    DBM系のデータベースのための抽象クラスです。データベースへの共通のオペレーションを 定義します。以下のインスタンススロットを持ちます。これらのスロットの値は dbm-openによってデータベースがオープンされる前にセットされて いなければなりません。

    具体クラスは、データベースの操作をより細かく行うための追加のスロット(例えばロックを 行うかどうか)を持つかもしれません。

    Instance Variable: <dbm> path
    データベースファイルのパス名。dbmの実装によっては、このパスにサフィックスが追加されます。

    Instance Variable: <dbm> rw-mode
    読み書きのモードを指定します。以下の値のいずれかを取ります。
    :read
    データベースはdbm-openによって読みだし専用モードでオープンされます。 オープンされる時点でデータベースは存在していなければなりません。
    :write
    データベースはdbm-openによって読み書き可能なモードでオープンされます。 データベースが存在しなければ、dbm-openは新しいデータベースを作成します。
    :create
    dbm-openによって新しいデータベースが作成され、読み書き可能なモードでオープンされます。 既にデータベースが存在していた場合、その内容はクリアされます。

    Instance Variable: <dbm> file-mode
    データベースが作成されるときのファイルパーミッションを指定します。 デフォルトは#o664です。

    Instance Variable: <dbm> key-convert
    Instance Variable: <dbm> value-convert
    デフォルトでは、dbmデータベースはキーにも値にも文字列しか使うことはできません。 これらのスロットによって、それ以外のSchemeオブジェクトを取り扱う方法を指定することが できます。以下の値のいずれかが可能です。
    #f
    デフォルトの値です。キーあるいは値は変換されません。それらは文字列でなければなりません。
    #t
    キーあるいは値はwriteを使って文字列に変換されデータベースに格納されます。 そしてreadを使って文字列からSchemeオブジェクトへと変換されます。 後でreadで読みこめるようなキーあるいは値のみを扱うことができます。 (但し、dbmライブラリは書き込み時にそれが後で読み込めるかどうかのチェックは行いません)。 キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列表現を 持つ必要があります。
    二つの手続きのリスト
    どちらの手続きも一つの引数を取ります。最初の手続きはSchemeオブジェクトを受け取り、 文字列を返します。キーあるいは値をデータベースに格納する時に呼ばれます。 二つ目の手続きは文字列を受け取りSchemeオブジェクトを返します。データベースから キーあるいは値を取り出す時に呼ばれます。 キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列に 変換される必要があります。

    Metaclass: <dbm-meta>
    <dbm>クラス及びそのサブクラスのメタクラスです。

    Method: dbm-open (dbm <dbm>)
    DBMデータベースをオープンします。dbmは、<dbm>クラスを継承した 具体クラスのインスタンスでなければなりません。また、そのスロットには適切な値が セットされている必要があります。オープンに成功したらdbm自身が返されます。 失敗した場合はエラーが報告されます。

    Method: dbm-open (dbm-class <dbm-meta>) options ...
    DBMインスタンスを作成してオープンするための便利なメソッドです。 次のように定義されます。
    (define-method dbm-open ((class <class>) . initargs)
      (dbm-open (apply make class initargs)))
    

    データベースファイルはガベージコレクトされる際にクローズされますが、 変更を正しくデータベースに反映するには、明示的にクローズした方が良いでしょう。

    Method: dbm-close (dbm <dbm>)
    データベースdbmをクローズします。データベースがクローズされると、 それ以降のアクセスオペレーションはエラーとなります。

    Method: dbm-closed? (dbm <dbm>)
    データベースdbmが既にクローズされていたら#tを返します。

    11.1.2 DBMデータベースのアクセス

    データベースがオープンされたら、以下のアクセスメソッドが使えます。

    Method: dbm-put! (dbm <dbm>) key value
    valueをキーkeyと関連付けて保存します。

    Method: dbm-get (dbm <dbm>) key &optional default
    キーkeyに関連付けられた値を返します。もし値が存在しなければ、defaultが 与えられていればそれを返し、そうでなければエラーを報告します。

    Method: dbm-exists? (dbm <dbm>) key
    キーkeyに関連付けられた値が存在すれば#tを返します。

    Method: dbm-delete! (dbm <dbm>) key
    キーkeyに関連付けられた値を消去します。値が存在しない場合は何もしません。

    11.1.3 DBMデータベース上の繰り返し処理

    全データベースを渡り歩く処理のために、以下のメソッドが用意されています。

    Method: dbm-fold (dbm <dbm>) procedure knil
    基本的な繰り返し処理です。データベース内の各キー/値のペアに関して、手続き procedure(procedure key value r), のように呼ばれます。ここでrは、最初のprocedureの呼び出しの時にはknil が、以降の呼び出しの時にはその直前のprocedureが返した値が渡されます。 最後のprocedureの戻り値がdbm-foldの戻り値となります。 データベース中にデータがひとつもなければknilがそのまま返されます。

    次の例は、データベース中の整数の値を全て加算します。

    (dbm-fold dbm (lambda (k v r) (if (integer? v) (+ v r) r) 0))
    

    Method: dbm-for-each (dbm <dbm>) procedure
    データベース内の各キー/値のペアに関して、手続きprocedureを呼び出します。 procedureにはキーと値が渡されます。procedureの戻り値は捨てられます。

    Method: dbm-map (dbm <dbm>) procedure
    データベース内の各キー/値のペアに関して、手続きprocedureを呼び出します。 procedureにはキーと値が渡されます。procedureの戻り値はリストに 集められてdbm-mapの戻り値となります。

    11.2 dbm.gdbm - GDBM interface

    Module: dbm.gdbm

    Class: <gdbm>
    Inherits <dbm>. Provides an implementation for GDBM library. This module is only installed when your system already has GDBM (1.8.0 is preferred, but works with older 1.7.x with some limitations).

    Instance Variable: <gdbm> sync
    Instance Variable: <gdbm> nolock
    Instance Variable: <gdbm> bsize

    Besides the unified DBM interface (See section 11.1 dbm - 汎用DBMインタフェース), this module provides the following low-level functions that provides direct access to the gdbm API. See gdbm manual for details of these APIs.

    Function: gdbm-open path &optional size rwmode fmode error-callback

    Variable: GDBM_READER

    Variable: GDBM_WRITER

    Variable: GDBM_WRCREAT

    Variable: GDBM_NEWDB

    Variable: GDBM_FAST

    Variable: GDBM_SYNC

    Variable: GDBM_NOLOCK

    Function: gdbm-close gdbm-object

    Function: gdbm-closed? gdbm-object

    Function: gdbm-store key value &optional flag

    Variable: GDBM_INSERT

    Variable: GDBM_REPLACE

    Function: gdbm-fetch gdbm-object key

    Function: gdbm-delete gdbm-object key

    Function: gdbm-firstkey gdbm-object

    Function: gdbm-nextkey gdbm-object key

    Function: gdbm-reorganize gdbm-object

    Function: gdbm-sync gdbm-object

    Function: gdbm-exists gdbm-object key

    Function: gdbm-strerror errno

    Function: gdbm-setopt gdbm-object option value

    Variable: GDBM_CACHESIZE

    Variable: GDBM_FASTMODE

    Variable: GDBM_SYNCMODE

    Variable: GDBM_CENTFREE

    Variable: GDBM_COALESCEBLKS

    Function: gdbm-version

    Function: gdbm-errno

    11.3 dbm.ndbm - NDBM interface

    Module: dbm.ndbm

    Class: <ndbm>
    Inherits <dbm>. Provides an implementation for NDBM library. This module is only installed when your system already has NDBM.

    Besides the unified DBM interface (See section 11.1 dbm - 汎用DBMインタフェース), this module provides the following low-level functions that provides direct access to the ndbm API. See ndbm manual for details of these APIs.

    Function: ndbm-open path flags mode

    Function: ndbm-close ndbm-object

    Function: ndbm-closed? ndbm-object

    Function: ndbm-store ndbm-object key content &optional flag

    Function: ndbm-fetch ndbm-object key

    Function: ndbm-delete ndbm-object key

    Function: ndbm-firstkey ndbm-object

    Function: ndbm-nextkey ndbm-object

    Function: ndbm-error ndbm-object

    Function: ndbm-clear-error ndbm-object

    11.4 dbm.odbm - Original DBM interface

    Module: dbm.odbm

    Class: <odbm>
    Inherits <dbm>. Provides an implementation for legacy DBM library. This module is only installed when your system already has DBM.

    The biggest limitation of the legacy DBM is that you can only open one database at a time. You can create a multiple <odbm> instances, but you can open at most one of it at a time, or you'll get an error.

    Besides the unified DBM interface (See section 11.1 dbm - 汎用DBMインタフェース), this module provides the following low-level functions that provides direct access to the dbm API. See dbm manual for details of these APIs.

    Function: odbm-init path

    Function: odbm-close

    Function: odbm-store key value

    Function: odbm-fetch key

    Function: odbm-delete key

    Function: odbm-firstkey

    Function: odbm-nextkey key

    11.5 file.filter - ファイルのフィルタ

    Module: file.filter
    このモジュールは、フィルター型のコマンド、 すなわち入力を読み込み、処理をして結果を書き出すような場合に 共通するパターンに使えるユーティリティ手続きを提供します。 共通するパターンとは:
    • 入力は指定されたファイルかポートで、デフォルトはカレント入力ポート。
    • 出力は指定されたファイルかポートで、デフォルトはカレント出力ポート。
    • 出力は一時ファイルに書き出すこともできて、 その場合は処理が終了した時点で指定されたファイルにリネーム。
    • 処理途中でエラーが起こった場合に出力ファイルを削除

    Function: file-filter proc &keyword input output temporary-file keep-output?
    二つの引数、入力ポートと出力ポートを引数としてprocを呼び出し、 その結果を返します。 入力ポートと出力ポートはキーワード引数により決定されます。
    input
    この引数は入力ポートかファイル名を示す文字列でなければなりません。 入力ポートの場合、それはそのままprocに渡されます。 文字列が渡された場合は、そのファイル名を持つファイルを入力用にオープンし、 そのポートがprocに渡され、またこのポートはprocが戻った時に閉じられます。 この引数が省略された場合は、現在の入力ポートが渡されます。
    output
    この引数は入力ポートかファイル名を示す文字列でなければなりません。 出力ポートの場合、それはそのままprocに渡されます。 文字列が渡された場合は、そのファイル名を持つファイルを出力用にオープンし、 そのポートがprocに渡されます (但し、temporary-file 引数が渡された時はそれに指定されるファイルが一時ファイルとしてオープンされます)。 オープンされたポートはprocが戻った時に閉じられます。 この引数が省略された場合は、現在の出力ポートが渡されます。
    temporary-file
    文字列でファイル名が渡された場合、処理の間の出力先としてoutputに指定された ファイルのかわりにそのファイルがオープンされます。 procにはその一時ファイルへの出力ポートが渡されます。 procが正常に返って来た時点で、一時ファイルはoutputに指定された ファイルへとリネームされます。 もし一時ファイル名が"/""./""../"以外の 文字で始まっていた場合は、outputに与えられたファイル名のディレクトリが 一時ファイルの前に追加されます。さらに、ユニークなサフィックスが一時ファイルの後に 追加されます(一時ファイルはsys-mkstempを使ってオープンされます)。 この引数は、outputにファイル名が与えられなかった場合は無視されます。
    keep-output?
    真の値が与えられた場合、procがエラーになった場合でも出力ファイルを削除しません。 デフォルトでは、出力ファイル(もしくはtemporary-fileが与えられた場合は そのファイル)はエラーの場合には削除されます。

    11.6 file.util - ファイルシステムユーティリティ

    Module: file.util
    ファイルやディレクトリを扱う便利な手続き群を提供します。 これらの手続きはsection 6.21.3 ファイルシステムで述べられたプリミティブなシステム手続きの上に 構築されています。

    このモジュール内の多くの手続きはfollow-link?というキーワード引数を取ります。 これは手続きがシンボリックリンクに出会ったときの動作を指定します。follow-link?が 真であれば、手続きはリンクの指す先のファイルに作用します。これがデフォルトの振舞いです。 follow-link?#fが渡された場合は手続きはリンクそのものに作用します。

    名前つけ規則に関する注記:ファイルやディレクトリを 作成するのに"create"という語を使う処理系と"make"を 使う処理系があります。ファイルやディレクトリを削除するのにも"remove""delete"の流派があります。どちらも同じくらい広く使われているようなので、 Gaucheでは両方の名前を提供することにしました。

    11.6.1 ディレクトリユーティリティ

    Function: current-directory &optional new-directory
    引数無しで呼ばれた場合、カレントディレクトリを返します。 文字列new-directoryが与えられた場合はプロセスのカレントディレクトリを new-directoryに変更します。変更が出来なかった場合はエラーとなります。

    この関数はChezSchemeやMzSchemeなどいくつかのScheme処理系に見られます。

    Function: home-directory &optional user
    名前または整数のユーザidで与えられたユーザuserのホームディレクトリを 返します。userが省略された場合はカレントユーザが使われます。 与えられたユーザが見付けられないか、ホームディレクトリを決定できなかった場合は #fが返されます。

    Function: directory-list path &keyword children? add-path? filter
    ディレクトリpath中のエントリのリストを返します。 リストは文字列順にソートされます。

    デフォルトではエントリのベースネーム(パスの最後のコンポーネント)のみが 返されますが、キーワード引数add-path?に真の値が与えられた時は pathが各エントリの前に追加されます。 children?に真の値が与えられた時は、カレントディレクトリと親ディレクトリが リストから除かれます。filter引数は、もし与えられれば、一つの引数を取る 手続きでなければなりません。ディレクトリ中の各エントリを引数としてその手続きが呼ばれ、 真を返したエントリのみが結果に含まれます。

    pathがディレクトリでない場合はエラーが報告されます。

    (directory-list "test")
     => ("." ".." "test.scm" "test.scm~")
    
    (directory-list "test" :add-path? #t)
     => ("test/." "test/.." "test/test.scm" "test/test.scm~")
    
    (directory-list "test" :children? #t)
     => ("test.scm" "test.scm~")
    
    (directory-list "test" :children? #t :add-path? #t
       :filter (lambda (e) (not (string-suffix? "~" e))))
     => ("test/test.scm")
    

    Function: directory-list2 path &keyword children? add-path? filter follow-link?
    directory-listに似ていますが、ふたつの値を返します。最初の値は path内にあるサブディレクトリのリストで、次の値はそれ以外のエントリのリストです。 キーワード引数children?add-path?filterdirectory-listと同じ意味をもちます。

    偽の値をfollow-link?に与えると、path内のシンボリックリンクを 辿りません;すなわち、path内にディレクトリへのシンボリックリンクがあった場合、 デフォルト、もしくはfollow-link?に真の値が与えられた場合は それは最初のリスト(サブディレクトリ)に入りますが、follow-link? に偽の値が与えられた場合は後者のリスト(その他のエントリ)に入ります。

    Function: directory-fold path proc knil &keyword lister follow-link?
    ディレクトリ探索の最も基本的な手続きです。基本的な動作は以下に示すような再帰的なものです。
    • pathがディレクトリでない場合は(proc path knil) を 評価し、結果を返します。
    • pathがディレクトリであった場合、まず (lister path knil) を評価します。 手続きlisterはパス名のリストを返さなければなりません。 続いて、directory-foldが各パス名に対して再帰的に呼ばれます。 各呼び出しの結果が次の再帰呼び出しのknilの値に使われます。

    デフォルトのlisterdirectory-listを次のように呼び出すものです。

    (lambda (path knil)
      (directory-list path :add-path? #t :children? #t)))))
    

    listerpath自身への参照 (".") やその親ディレクトリへの参照を 返してはなりません。また、listerの戻り値は現在のディレクトリからアクセス可能な パス名でなければなりません。例えばpath"/usr/lib/foo"であり、 そのディレクトリが"libfoo.a""libfoo.so"を含んでいた場合、 lister'("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so") のようなリストを返す必要があります。

    キーワード引数follow-link?はディレクトリを指しているシンボリックリンクに対して listerを呼ぶかどうかを決定します。follow-link?が真(デフォルト値)である 場合はそのようなシンボリックリンクに対してもlisterが呼ばれます。 一方、follow-link?が偽であればシンボリックリンクに対してはprocが呼ばれます。

    次の例は、与えられたpath以下からemacsのバックアップファイル ("~"で終る名を持つファイル) のリストを返します。

    (use srfi-13) ;; for string-suffix?
    (directory-fold path
                    (lambda (entry result) 
                      (if (string-suffix? "~" entry)
                          (cons entry result)
                          result))
                    '())
    

    Function: make-directory* name &optional perm
    Function: create-directory* name &optional perm
    ディレクトリnameを作成します。nameに至るパスが存在しない 場合は必要なディレクトリが作成されます (Unixのmkdir -pコマンドと 同様です)。ディレクトリnameが既に存在していた場合は何もしません。 permは作成されるディレクトリのパーミッションビットを指定します。

    Function: remove-directory* name
    Function: delete-directory* name
    ディレクトリnameとその内容を再帰的に消去します (Unixのrm -rコマンドと同様です)。シンボリックリンクは辿られません。

    11.6.2 パスネームユーティリティ

    Function: build-path base-path component ...
    パス名のコンポーネントcomponentbase-pathに追加します。 Componentはシンボルupまたはsameであっても 構いません; Unixではそれらは".."または"."と等価です。 このAPIはMzSchemeから採られました。

    Function: absolute-path? path
    Function: relative-path? path
    pathがそれぞれ絶対パスまたは相対パスならば#tを返します。

    Function: expand-path path
    pathがチルダ表記を含んでいたらそれを展開したものを返します。 そうでなければpathそのものを返します。この手続きはpathが 存在しアクセス可能であるかどうかはチェックしません。

    Function: resolve-path path
    pathexpand-pathと同様に展開し、 続いてpathの各コンポーネントに対してそれがシンボリックリンクであればリンク先の ものに置き換えてゆきます。pathが存在しないパスを指していたり、 シンボリックリンクの先が存在しなかったり、読み出せないディレクトリがあった場合は エラーとなります。

    Function: simplify-path path
    pathから、親ディレクトリへの参照("..")と自分自身への参照(".")を 出来る限り取り除きます。この手続きはファイルシステムへはアクセスしません。

    Function: find-file-in-paths name &keyword paths pred
    名前nameを持ち、述語predを満たすファイルをパス名のリストpaths から探します。見つかった場合はファイルの絶対パス名を、見つからなかった場合は #fを返します。

    nameが絶対パス名で与えられた場合はそれが存在するかどうかと predを満たすかどうかのみがチェックされます。

    pathsのデフォルト値は環境変数PATHから取られます。また、 predのデフォルト値はfile-is-executable? (section 11.6.3 ファイル属性ユーティリティ参照)です。すなわち、デフォルトでは この手続きはコマンドサーチパスから実行可能ファイルを探すのに使えます。

    (find-file-in-paths "ls")
      => "/bin/ls"
    
    ;; アプリケーション"myapp"のユーザプレファレンスファイルを探す例
    (find-file-in-paths "userpref"
      :paths `(,(expand-path "~/.myapp")
               "/usr/local/share/myapp"
               "/usr/share/myapp")
      :pred  file-is-readable?)
    

    11.6.3 ファイル属性ユーティリティ

    Function: file-type path &keyword follow-link?
    Function: file-perm path &keyword follow-link?
    Function: file-mode path &keyword follow-link?
    Function: file-ino path &keyword follow-link?
    Function: file-dev path &keyword follow-link?
    Function: file-rdev path &keyword follow-link?
    Function: file-nlink path &keyword follow-link?
    Function: file-uid path &keyword follow-link?
    Function: file-gid path &keyword follow-link?
    Function: file-size path &keyword follow-link?
    Function: file-atime path &keyword follow-link?
    Function: file-mtime path &keyword follow-link?
    Function: file-ctime path &keyword follow-link?
    これらの手続きはpathで示されるファイルやディレクトリのアトリビュートを 返します。アトリビュート名は<sys-stat>のスロット名に対応しています。 section 6.21.3.4 ファイルの状態を参照して下さい。pathで示されるファイルが 存在しなければ#fが返されます。

    pathがシンボリックリンクだった場合、オプショナルな引数 follow-link? に偽の値が与えられていない限り、これらの手続きは リンクの指す先のファイルに関する情報を返します。

    MzSchemeとChickenにはfile-sizeがあります。 Chickenにはfile-modification-timeがあり、これはfile-mtimeと 同じです。

    Function: file-is-readable? path
    Function: file-is-writable? path
    Function: file-is-executable? path
    pathが存在して、現在の実効ユーザがそれぞれ読み取り/書き込み/実行可能なら#tを 返します。 このAPIはSTkから取られました。

    Function: file-eq? path1 path2
    Function: file-eqv? path1 path2
    Function: file-equal? path1 path2
    path1path2で示されるファイルを比較します。 file-eq?file-eqv?path1path2が 全く同一のファイルを参照しているかどうか、すなわち、同じデバイス上にあり同じ inode番号を持つかどうかをチェックします。二つの手続きの違いは、 path1path2の最後のコンポーネントがシンボリックリンクで あった場合に、file-eq?はリンクそのものの比較をするが file-eqv?はリンクを辿った先のファイルの比較をする、という点です。

    file-equal?path1path2をその内容まで考慮して比較します。 すなわち、二つのファイルがfile-eqv?の意味で同一でなかった場合、 file-equal?はファイルの内容を比較し、全てが一致した場合に#tを返します。

    path1path2ともにディレクトリが与えられた場合の file-equal?の動作は未定義です。将来、ディレクトリ内容を スキャンするような拡張が加えられるかもしれません。

    Generic Function: file-mtime=? f1 f2
    Generic Function: file-mtime<? f1 f2
    Generic Function: file-mtime<=? f1 f2
    Generic Function: file-mtime>? f1 f2
    Generic Function: file-mtime>=? f1 f2
    二つのファイルの変更時間を比較します。それぞれの引数に対して、 次のような型のオブジェクトが渡せるようなメソッドが定義されています。
    • 文字列のパス名。そのパス名で示されるファイルから変更時間が取られます。
    • <sys-stat>オブジェクト (See section 6.21.3.4 ファイルの状態)。 stat構造体から変更時間が取られます。
    • <time>オブジェクト。その示す時間が変更時間と考えられます。
    • 数値。変更時間をUnix Epochからの秒数で表したものと見なされます。
    ;; "foo.c" より "foo.o" が新しいかどうか調べる
    (file-mtime>? "foo.c" "foo.o")
    
    ;; "foo.log"が過去24時間以内に更新されたかどうかを調べる
    (file-mtime>? "foo.c" (- (sys-time) 86400))
    

    Generic Function: file-ctime=? f1 f2
    Generic Function: file-atime=? f1 f2
    file-mtime=?と同じですが、ファイルの属性変更時間とアクセス時間に 関して比較します。 <, <=, >, >=を使う関数も同様に定義されています。

    11.6.4 ファイル操作

    Function: touch-file path
    pathのタイムスタンプを現在の時刻に更新します。 pathが存在しなかった場合はそのファイルを作成します。 section 6.21.3.4 ファイルの状態sys-utimeも参照して下さい。

    Function: copy-file src dst &keyword if-exists backup-suffix safe keep-timestamp
    ファイルsrcdstへコピーします。コピー元ファイルsrcは 存在していなければなりません。コピー先ファイルdstが存在していた場合の ふるまいはキーワード引数if-existsによって以下のように指定されます。
    :error
    (デフォルト) dstが存在していたらエラーを通知する。
    :supersede
    dstsrcのコピーで置き換える。
    :backup
    dstの名前を変えてキープする。
    #f
    dstが存在していたらコピーをせず#fを返す。

    copy-fileはコピーが完了したら#tを返します。

    if-exists:backupである場合、 dstがリネームされる名前は dstにキーワード引数backup-suffixで指定されるサフィックスを 付けたものとなります。デフォルト値は".orig"です。

    デフォルトではcopy-fileは直接dstにコピーを行いますが、 キーワード引数safeに真の値が与えられた場合は、dstと同じディレクトリ 内の一時ファイルにまずコピーし、それが完了した時点でdstへとリネームします。 コピーが何らかの理由で中断された場合、ファイルシステムはコピー前の状態へと 「ロールバック」されます。

    キーワード引数keep-timestampに真の値が与えられた場合は、 copy-fileはコピー後にコピー先のファイルのタイムスタンプを コピー元のタイムスタンプに合わせます。

    Function: move-file src dst &keyword if-exists backup-suffix
    ファイルsrcdstへ移動します。移動元ファイルsrcは 存在していなければなりません。移動先ファイルdstが存在した場合の ふるまいはキーワード引数if-existsによって以下のように指定されます。
    :error
    (デフォルト) dstが存在していたらエラーを通知する。
    :supersede
    dstsrcで置き換える。
    :backup
    dstの名前を変えてキープする。
    #f
    dstが存在していたら移動をせず#fを返す。

    move-fileは移動が完了したら#tを返します。

    if-exists:backupである場合、dstがリネームされる 名前はdstにキーワード引数backup-suffixで指定されるサフィックスを 付けたものとなります。デフォルト値は".orig"です。

    ファイルsrcdstは別のファイルシステム上にあっても構いません。 その場合、move-fileはまずsrcdstと同じディレクトリの 一時ファイルにコピーし、それをdstにリネームし、それから srcを消去します。

    11.7 math.const - 定数

    Module: math.const
    This module defines several commonly-used mathematic constants.

    Constant: pi
    Constant: pi/2
    Constant: pi/4
    Constant: pi/180
    Constant: 1/pi
    Constant: 180/pi
    それぞれ、π、π/2、π/4、π/180、1/π、180/πです。

    Constant: e
    e.

    11.8 math.mt-random - Mersenne Twister乱数発生器

    Module: math.mt-random
    Provides a pseudo random number generator (RNG) based on "Mersenne Twister" algorithm developed by Makoto Matsumoto and Takuji Nishimura. It is fast, and has huge period of 2^19937-1. See @xref{MT,,MT}, for details about the algorithm.

    Class: <mersenne-twister>
    A class to encapsulate the state of Mersenne Twister RNG. Each instance of this class has its own state, and can be used as an independent source of random bits if initialized by individual seed.

    The random seed value can be given at the instantiation time by :seed initialization argument, or by using mt-random-set-seed! described below.

    (define m (make <mersenne-twister> :seed (sys-time)))
    
    (mt-random-real m) => 0.10284287848537865
    (mt-random-real m) => 0.463227748348805
    (mt-random-real m) => 0.8628500643709712
    ...
    

    Function: mt-random-set-seed! mt seed
    Sets random seed value seed to the Mersenne Twister RNG mt. Seed can be an arbitrary positive exact integer, or arbitrary length of u32vector (See section 10.4 srfi-4 - 単一型のベクタ). If it is an integer, the lower 32bits are used for initialization. If it is a u32vector, up to 624 elements are used for initialization.

    Function: mt-random-get-state mt
    Function: mt-random-set-state! mt state
    Retrieves and reinstalls the state of Mersenne Twister RNG mt. The state is represented by a u32vector of 625 elements. The state can be stored elsewhere, and then restored to an instance of <mersenne-twister> to continue to generate the pseudo random sequence.

    Function: mt-random-real mt
    Function: mt-random-real0 mt
    Returns a random real number between 0.0 and 1.0. 1.0 is not included in the range. Mt-random-real doesn't include 0.0 either, while mt-random-real0 does. Excluding 0.0 is from the draft SRFI-27.

    Function: mt-random-integer mt range
    Returns a random exact positive integer between 0 and range-1. Range can be any positive exact integer.

    Function: mt-random-fill-u32vector! mt u32vector
    Function: mt-random-fill-f32vector! mt f32vector
    Function: mt-random-fill-f64vector! mt f64vector
    Fills the given uniform vector by the random numbers. For mt-random-fill-u32vector!, the elements are filled by exact positive integers between 0 and 2^32-1. For mt-random-fill-f32vector! and mt-random-fill-f64vector!, it is filled by an inexact real number between 0.0 and 1.0, exclusive.

    If you need a bunch of random numbers at once, these are much faster than getting one by one.

    11.9 rfc.822 - RFC822メッセージ形式

    Module: rfc.822
    Defines a set of functions that parses and constructs the "Internet Message Format", a text format used to exchange e-mails. The most recent specification can be found in RFC2822 (@xref{rfc2822,[RFC2822],RFC2822}). The format was originally defined in RFC 822, and people still call it "RFC822 format", hence I named this module. In the following document, I also refer to the format as "RFC822 format".

    Say (use rfc.822) to use this module.

    Function: rfc822-header->list iport &optional strict?
    Reads RFC822 format message from an input port iport, until it reaches the end of the message header. The header fields are unfolded, and broken into a list of the following format:
    ((name body) ...)
    

    Name ... are the field names, and body ... are the corresponding field body, both as strings. Field names are converted to lower-case characters. Field bodies are not modified, except the folded line is concatenated, CRLFs removed. The order of fields are preserved.

    Function: rfc822-parse-date string
    Takes RFC-822 type date string, and returns eight values:
    year, month, day-of-month, hour, minutes, seconds, timezone, day-of-week.
    

    Timezone is an offset from UT in minutes. Day-of-week is a day from sunday, and may be #f if that information is not available. If the string is not parsable, all the elements are #f.

    Note: This function follows the new definition of date format in RFC2822, but may fail to recognize "obsolete" format, which allows arbitrary comments appear between words.

    11.10 rfc.base64 - Base64エンコーディング

    Module: rfc.base64
    This module defines a few functions to encode/decode Base64 format, defined in RFC 2045 (@xref{rfc2045, [RFC2045], RFC2045}), section 6.3.

    Function: base64-encode
    Reads byte stream from the current input port, encodes it in Base64 format and writes the result character stream to the current output port. The conversion ends when it reads EOF from the current input port.

    Function: base64-encode-string string
    Converts contents of string to Base64 encoded format. Input string can be either complete or incomplete string; it is always interpreted as a byte sequence.

    Function: base64-decode
    Reads character stream from the current input port, decodes it from Base64 format and writes the result byte stream to the current output port. The conversion ends when it reads EOF or the termination character (=). The characters which does not in legal Base64 encoded character set are silently ignored.

    Function: base64-decode-string string
    Decodes a Base64 encoded string string and returns the result as a string. The conversion terminates at the end of string or the termination character (=). The characters which does not in legal Base64 encoded character set are silently ignored.

    11.11 rfc.cookie - HTTPクッキー

    Module: rfc.cookie
    Defines a set of functions to parse and construct a "cookie" information defined in RFC 2965 (@xref{rfc2965,,RFC2965}).

    Function: parse-cookie-string string &optional version
    Parse a cookie string string, which is the value of "Cookie" request header. Usually, the same information is available to CGI program via the environemnt variable HTTP_COOKIE.

    If the cookie version is known, via "Cookie2" request header, the integer version must be passed to version. Otherwise, parse-cookie figures out the version from string.

    The result has the following format.

    ((<name> <value> [:path <path>] [:domain <domain>] [:port <port>])
     ...)
    

    where <name> is the attribute name, and <value> is the corresponding value. If the attribute doesn't have value, <value> is #f. (Note that it differs from the attribute having null value, "".) If the attribute has path, domain or port options, it is given as a form of keyword-value pair.

    Function: construct-cookie-string specs &optional version
    Given list of cookie specs, creates a cookie string suitable for Set-cookie2 or Set-cookie header.

    Optional version argument specifies cookie protocol version. 0 for the old Netscape style format, and 1 for RFC2965 style format. When omitted, version 1 is assumed.

    Each cookie spec has the following format.

    (<name> <value> [:comment <comment>] [:comment-url <url>]
                    [:discard <bool>] [:domain <domain>]
                    [:max-age <age>] [:path <path>]
                    [:port <port-list>] [:secure <bool>]
                    [:version <version>] [:expires <date>])
    

    Where,

    <name>
    A string. Name of the cookie.
    <value>
    Value of the cookie. May be a string, or #f if no value is needed.
    <comment> <url> <domain> <path> <port-list>
    Strings.
    <bool>
    Boolean value
    <age> <version>
    Integers
    <date>
    Either an integer (seconds since Epoch) or a formatted date string following the netscape cookie specification.

    The attribute values are quoted appropriately. If the specified attribute is irrelevant for the version, it is ignored. So you can pass the same specs to generate both old-style and new-style cookie strings.

    Return value is a list of cookie strings, each of which stands for each cookie. For old-style protocol (using Set-cookie header) you must send each of them by individual header. For new-style protocol (using Set-cookie2 header), you can join them with comma and send it at once. See RFC2965 for further details.

    Some examples:

    (construct-cookie-string
       '(("name" "foo" :domain "foo.com :path "/"
                       :expires (+ (sys-time) 86400) :max-age 86400)))
     => ("name=foo;Domain=foo.com;Path=/;Max-age=86400")
    
    (construct-cookie-string
       '(("name" "foo" :domain "foo.com :path "/"
                       :expires (+ (sys-time) 86400) :max-age 86400))
       0)
     =>
     ("name=foo;Domain=foo.com;Path=/;Expires=Sun, 09-Sep-2001 01:46:40 GMT")
    

    11.12 rfc.http - HTTP

    Module: rfc.http
    This module provides a simple client API for HTTP/1.1, defined in RFC2616, "Hypertext Transfer Protocol -- HTTP/1.1" (@xref{rfc2616, [RFC2616], RFC2616}).

    Current API implements only a part of the protocol. Only GET, HEAD, and POST requests are supported, it doesn't talk with HTTP/1.0 server yet, and it doesn't support HTTP/1.1 advanced features such as persistent connection. Support for those features may be added in the future versions.

    Function: http-get server request-uri &keyword sink flusher no-redirect ...
    Function: http-head server request-uri &keyword no-redirect ...
    Function: http-post server request-uri body &keyword sink flusher no-redirect ...

    Send http GET, HEAD and POST requests to the http server, and returns the server's reply.

    If the server returns "3xx" redirection reply, these procedures try to follow the URI returned in the "location" reply message header by default. See the "keyword arguments" heading below to suppress redirection following.

    Required arguments: The server argument specifies http server name in a string. A server name can be optionally followed by colon and a port number. Examples: "w3c.org", "mycompany.com:8080".

    The request-uri argument is the request-uri specified in RFC2616; usually, this is the path part of http url.

    Http-post takes the third argument, body, which is a string to be posted to the server. The body is sent "as is"; the caller has to take care of necessary escaping or encoding.

    So, the most simple form of retrieving the content will be something like this:

    (http-get "www.shiro.dreamhost.com" "/scheme/index.html")
    

    Access via proxy can be done by specifying proxy server to server and passing the entire URI to request-uri, but the author haven't tested yet.

    Return values: All procedures return three values.

    The first value is the status code defined in RFC2616 in a string (such as "200" for success, "404" for "not found").

    The second value is a list of parsed headers--each element of list is a list of (header-name value ...), where header-name is a string name of the header (such as "content-type" or "location"), and value is the corresponding value in a string. The header name is converted to lowercase letters. The value is untouched except that "soft line breaks" are removed, as defined in RFC2822. If the server returns more than one headers with the same name, their values are consolidated to one list. Except that, the order of the header list in the second return value is the same as the order in the server's reply.

    The third value is for the message body of the server's reply. By default, it is a message body itself in a string. If the server's reply doesn't have a body, the third value is #f. You can change how the message body is handled by keyword arguments; for example, you can directly store the returned message body to a file without creating intermediate string. The details are explained below.

    Keyword arguments: By default, these procedures only attaches "Host" header field to the request message. You can give keyword arguments to add more header fields.

    (http-get "foo.bar.com" "/index.html"
      :accept-language "ja"
      :user-agent "My Scheme Program/1.0")
    

    The following keyword arguments are recognized by the procedure and do not appear in the request headers.

    no-redirect
    If a true value is given, suppress the redirection tracking; i.e. the procedures return "3xx" message as is.
    sink, flusher
    You can customize how the message body is handled by these keyword arguments. You have to pass an output port to sink, and a procedure that takes two arguments to flusher. When the procedure starts receiving the message body, it feeds the received chunk to sink. When the procedure receives entire message body, flusher method is called with sink and a list of message header fields (in the same format to be returned in the second value from the procedure). The return value of flusher becomes the third return value from the procedure. So, the default value of sink is a newly opened string port and the default value of flusher is (lambda (sink headers) (get-output-string sink)). The following example saves the message body directly to a file, without allocating (potentially very big) string buffer.
    (call-with-output-file "page.html"
      (lambda (out)
        (http-get "www.schemers.org" "/"
           :sink out :flusher (lambda _ #t))))
    

    11.13 rfc.quoted-printable - Quoted-printableエンコーディング

    Module: rfc.quoted-printable
    This module defines a few functions to encode/decode Quoted-printable format, defined in RFC 2045 (@xref{rfc2045, [RFC2045], RFC2045}), section 6.7.

    Function: quoted-printable-encode
    Reads byte stream from the current input port, encodes it in Quoted-printable format and writes the result character stream to the current output port. The conversion ends when it reads EOF from the current input port.

    Function: quoted-printable-encode-string string
    Converts contents of string to Quoted-printable encoded format. Input string can be either complete or incomplete string; it is always interpreted as a byte sequence.

    Function: quoted-printable-decode
    Reads character stream from the current input port, decodes it from Quoted-printable format and writes the result byte stream to the current output port. The conversion ends when it reads EOF. If it encounters illegal character sequence (such as '=' followed by non-hexadecimal characters), it copies them literally to the output.

    Function: quoted-printable-decode-string string
    Decodes a Quoted-printable encoded string string and returns the result as a string.

    11.14 rfc.uri - URIの解析と作成

    Module: rfc.uri
    Provides a set of functions to parse Uniform Resource Identifiers defined in RFC 2396 (@xref{rfc2396, [RFC2396], RFC2396}).

    Function: uri-scheme&specific uri
    Function: uri-decompose-hierarchical specific
    Function: uri-decompose-authority authority
    General parser of URI. These functions does not decode URI encoding.

    uri-scheme&specific takes a URI uri, and returns two values, its scheme part and its scheme-specific part. If uri doesn't have a scheme part, #f is returned for it.

    (uri-scheme&specific "mailto:sclaus@north.pole")
      => "mailto" and "sclaus@north.pole"
    (uri-scheme&specific "/icons/new.gif")
      => #f and "/icons/new.gif"
    

    If the URI scheme uses hierarchical notation, i.e. "//authority/path?query#fragment", you can pass the scheme-specific part to uri-decompose-hierarchical and it returns four values, authority, path, query and fragment.

    (uri-decompose-hierarchical "//www.foo.com/about/company.html")
      => "www.foo.com", "/about/company.html", #f and #f
    (uri-decompose-hierarchical "//zzz.org/search?key=%3fhelp")
      => "zzz.org", "/search", "key=%3fhelp" and #f
    (uri-decompose-hierarchical "//jjj.jp/index.html#whatsnew")
      => "jjj.jp", "/index.html", #f and "whatsnew"
    (uri-decompose-hierarchical "my@address")
      => #f, #f, #f and #f
    

    Furthermore, you can parse authority part of the hierarchical URI by uri-decompose-authority. It returns userinfo, host and port.

    (uri-decompose-authority "yyy.jp:8080")
      => #f, "yyy.jp" and "8080"
    (uri-decompose-authority "mylogin@yyy.jp")
      => "mylogin", "yyy.jp" and #f
    

    Function: uri-compose &keyword scheme userinfo host port authority path path* query fragment specific
    Compose a URI from given components. There can be various combinations of components to create a valid URI--the following diagram shows the possible 'paths' of combinations:
            /-----------------specific-------------------\
            |                                            |
     scheme-+------authority-----+-+-------path*---------+-
            |                    | |                     |
            \-userinfo-host-port-/ \-path-query-fragment-/
    

    If #f is given to a keyword argument, it is equivalent to the absense of that keyword argument. It is particulary useful to pass the results of parsed uri.

    If a component contains a character that is not appropriate for that component, it must be properly escaped before being passed to url-compose.

    Some examples:

    (uri-compose :scheme "http" :host "foo.com" :port 80
                 :path "/index.html" :fragment "top")
      => "http://foo.com:80/index.html#top"
    
    (uri-compose :scheme "http" :host "foo.net"
                 :path* "/cgi-bin/query.cgi?keyword=foo")
      => "http://foo.net/cgi-bin/query.cgi?keyword=foo"
    
    (uri-compose :scheme "mailto" :specific "a@foo.org")
      => "mailto:a@foo.org"
    
    (receive (authority path query fragment)
       (uri-decompose-hierarchical "//foo.jp/index.html#whatsnew")
     (uri-compose :authority authority :path path
                  :query query :fragment fragment))
      => "//foo.jp/index.html#whatsnew"
    

    Function: uri-decode &keyword :cgi-decode
    Function: uri-decode-string string &keyword :cgi-decode
    Decodes "URI encoding", i.e. %-escapes. uri-decode takes input from the current input port, and writes decoded result to the current output port. uri-decode-string takes input from string and returns decoded string.

    If cgi-decode is true, also replaces + to a space character.

    Function: uri-encode &keyword :noescape
    Function: uri-encode-string string &keyword :noescape
    Encodes unsafe characters by %-escape. uri-encode takes input from the current input port and writes the result to the current output port. uri-encode-string takes input from string and returns the encoded string.

    By default, characters that are not specified "unreserved" in RFC2396 are escaped. You can pass different character set to noescape argument to keep from being encoded.

    The multibyte characters are encoded as the octed stream of Gauche's native multibyte representation.

    11.15 slib - SLIB interface

    Module: slib
    このモジュールはAubrey Jaffer氏のSLIBへのインタフェースです。 SLIBがインストールされている場合、(use slib) とすれば SLIBの機能が使えるようになります。 SLIBそのものはGaucheのディストリビューションには含まれていません。 あなたのシステムにまだインストールされていない場合は http://www-swiss.ai.mit.edu/~jaffer/SLIB.htmlから入手することができます。

    このモジュールはrequireを再定義し、Gaucheオリジナルのrequireを シャドウします。requireにシンボルが渡された場合はSLIBのrequire のように動作します。requireに文字列が渡された場合はGaucheのrequire のように動作します。provideprovided?についても同様です。

    requireでロードされる、SLIBで導入されるすべての定義は、 slibモジュール内で行われます。

    (use slib)         ; load and set up slib
    (require 'getopt)  ; load SLIB's getopt module
    (require "foo")    ; load Gauche's foo module
    

    11.16 text.csv - CSV tables

    Module: text.csv
    Provides a function to parse/generate CSV (comma separated value) tables. Actually, the separater is not limited to comma; you can customize it.

    CSV format is widely used to exchange table-type data in plain text, although there are apparently no "formal" specification.

    CSV table is consisted by a series of records, separated by a newline. Each record contains number of fields, separated by a separator character (by default, a comma). A field can contain comma or newline if quoted, i.e. surrounded by double-quote characters. To include double-quote character in a quoted field, use two consecutive double-quote character. Usually, the whitespaces around the field are ignored.

    Right now, the following two low-level procedures are exported. A plan is to provide higher features, such as labelling fields and automatic conversions.

    Function: make-csv-reader separator
    Returns a procedure with one argument, input port. When the procedure is called, it reads one record from the port, and returns a list of fields. If input reaches EOF, it returns EOF.

    Function: make-csv-writer separator &optional newline
    Returns a procedure with two arguments, output port and a list of fields. When the procedure is called, it outputs a separater-separated fields with proper escapes, to the output port. You can also specify the record delimiter string by newline; for example, you can pass "\r\n" to prepare a file to be read by Windows programs.

    11.17 text.html-lite - Simple HTML document construction

    Module: text.html-lite
    Provides procedures to construct an HTML document easily. For example, you can construct an HTML table by the following code:
    (html:table
      (html:tr (html:th "Item No") (html:th "Quantity"))
      (html:tr (html:td 1) (html:td 120))
      (html:tr (html:td 2) (html:td 30))
      (html:tr (html:td 3) (html:td 215)))
    

    See the description of html:element below for details.

    This module does little check for the constructed html documents, such as whether the attributes are valid, and whether the content of the element matches DTD. It does not provide a feature to parse the html document neither. Hence the name `lite'.

    Function: html-escape
    Function: html-escape-string string
    Escapes the "unsafe" characters in HTML. html-escape reads input string from the current input port and writes the result to the current output port. html-escape-string takes the input from string and returns the result in a string.

    Function: html-doctype &keyword type
    Returns a doctype declaration for an HTML document. type can be either one of :strict, :transitional, or :frameset, corresponding HTML4.01 strict, transitional or frameset DTD, respectively.

    Function: html:element args ...
    Construct an HTML element element. Right now, the following elements are provided. (The elements defined in HTML 4.01 DTD, http://www.w3.org/TR/html4/sgml/dtd.html).
    a        abbr       acronym    address     area      b
    base     bdo        big        blockquote  body      br
    button   caption    cite       code        col       colgroup
    dd       del        dfn        div         dl        dt
    em       fieldset   form       h1          h2        h3
    h4       h5         h6         head        hr        html
    i        img        input      ins         kbd       label
    legend   li         link       map         meta      noscript
    object   ol         optgroup   option      p         param
    pre      q          samp       script      select    small
    span     strong     style      sub         sup       table
    tbody    td         textarea   tfoot       th        thead
    title    tr         tt         ul          var
    

    The result of these functions is a tree of text segments, which can be written out to a port by write-tree or can be converted to a string by tree->string (See section 11.20 text.tree - Lazy text construction).

    You can specify attributes of the element by using a keyword-value notation before the actual content.

    (tree->string (html:a :href "http://foo/bar" "foobar"))
      =>
      "<a href=\"http://foo/bar\">foobar</a>\n"
    
    (tree->string
      (html:table :width "100%" :cellpading 0 "content here"))
      =>
      "<table width=\"100%\" cellpadding=\"0\">content here</table>\n"
    

    The boolean value given to the attribute has a special meaning. If #t is given, the attribute is renfered without a value. If #f is given, the attribute is not rendered.

    (tree->string (html:table :border #t))
      => "<table border></table>\n"
    
    (tree->string (html:table :border #f))
      => "<table></table>\n"
    

    Special characters in attribute values are escaped by the function, but the ones in the content are not. It is caller's responsibility to escape them.

    The functions signal an error if a content is given to the HTML element that doesn't take a content. They do not check if the given attribute is valid, neither if the given content is valid for the element.

    11.18 text.parse - Parsing input stream

    Module: text.parse
    A collection of utilities that does simple parsing from the input port. The API is inspired, and compatible with Oleg Kiselyov's input parsing library (@xref{oleg1,,OLEG1}). His library is used in lots of other libraries, notably, a full-Scheme XML parser/generator SSAX (@xref{ssax,,SSAX}).

    You can use this module in place of his input-parse.scm and look-for-str.scm.

    I reimplemented the functions to be efficient on Gauche. Especially, usage of string-set! is totally avoided. I extended the interface a bit so that they can deal with character sets and predicates, as well as a list of characters.

    These functions work sequentially on the given input port, that is, they read from the port as much as they need, without buffering extra characters.

    Function: find-string-from-port? str in-port &optional max-no-chars
    Looks for a string str from the input port in-port. The optional argument max-no-chars limits the maximum number of characters to be read from the port; if omitted, the search span is until EOF.

    If str is found, this function returns the number of characters it has read. The next read from in-port returns the next char of str. If str is not found, it returns #f.

    Note: Although this procedure has `?' in its name, it may return non-boolean value, contrary to the Scheme convention.

    Function: peek-next-char &optional port
    Discards the current character and peeks the next character from port. Useful to look ahead one character. If port is omitted, the current input port is used.

    In the following functions, char-list refers to one of the followings:

    That denotes a set of characters. If a symbol *eof* is included, the EOF condition is also included. Without *eof*, the EOF condition is regarded as an error.

    Function: assert-curr-char char-list string &optional port
    Reads a character from port. If it is included in char-list, returns the character. Otherwise, signals an error with a message containing string. If port is omitted, the current input port is used.

    Function: skip-until char-list/number &optional port
    char-list/number is either a char-list or a number. If it is a number; it reas that many characters and returns #f. If the input is not long enough, an error is signalled. IF char-list/number is a char-list, it reads from port until it sees a character that belongs to the char-list. Then the character is returned. If port is omitted, the current input port is used.

    Function: skip-while char-list &optional port
    Reads from port until it sees a character that does not belong to char-list. The character remains in the stream. If it reaches EOF, an EOF is returned. If port is omitted, the current input port is used.

    This example skips whitespaces from input. Next read from port returns the first non-whitespace character.

    (skip-while #[\s] port)
    

    Function: next-token prefix-char-list break-char-list &optional comment port
    Skips any number of characters in prefix-char-list, then collects the characters until it sees break-char-list. The collected characters are returned as a string. The break character remains in the port.

    If the function encounters EOF and *eof* is not included in break-char-list, an error is signalled with comment is included in the message.

    Function: next-token-of char-list/pred &optional port
    Reads and collects the characters as far as it belongs to char-list/pred, then returns them as a string. The first character that doesn't belong to char-list/pred remains on the port.

    char-list/pred may be a char-list or a predicate that takes a character. If it is a predicate, each character is passed to it, and the character is regarded to "belong to" char-list/pred when it returns a true value.

    Function: read-string n &optional port
    Reads up to n characters, collects them into a string, and returns it. If the input stream contains less characters, the returns string contains as many characters available.

    11.19 text.tr - 文字変換

    Module: text.tr
    このモジュールは、入力ストリームから指定の文字を置き換えて出力する、 文字変換(transliterate)機能を提供します。 Unixのtr(1)コマンドで実装され、sedperlにも 採り入れられている機能です。

    Gaucheのtrはマルチバイト文字/文字列を正しく扱います。

    Function: tr from-list to-list &keyword :complement :delete :squeeze :table-size :input :output
    inputから文字を読み込み、その文字がfrom-list内にあれば 対応するto-list内の文字に置き換えて、outputへと書き出します。 from-listに無い文字はそのままoutputへと渡されます。

    inputoutputの既定値はそれぞれ現在の入力ポートと 出力ポートです。

    from-listto-listは文字列でなければなりません。 その中には次のような表記を使うことができます。それ以外の文字はそのまま使われます。

    x-y
    文字xから文字yまでの文字の昇順の並びと解釈されます。 xyは含まれます。文字の並びはGaucheの内部文字エンコーディングに よって決定されるので、一般にはxyは同じキャラクタクラスの中に 止めておいた方が安全でしょう。xyより小さくなければなりません。
    x*n
    文字xn個の並び。nは10進数で表記された数値です。 これはto-listでのみ有効で、from-listで使うとエラーになります。 nが省略されるか0の場合、xto-listの長さがfrom-list の長さに達するまで繰り返されます(その場合、to-listの残りは無視されます)。
    \x
    文字xそれ自身。特殊文字そのものを埋め込みたい場合に使います。 文字列のリーダも\を解釈するので、\\と書かねばならないことに注意 して下さい。 グラフィカルでない文字のための構文はありません。文字列リーダの構文を使って そのような文字を文字列に含めることができます。

    いくつか例を挙げます。

    ;; 大文字と小文字を交換します
    (tr "A-Za-z" "a-zA-Z")
    
    ;; ひらがなとかたかなを交換します
    (tr "ぁ-んァ-ン" "ァ-ンぁ-ん")
    
    ;; 7ビットのノングラフィカルな文字を`?'に変換します
    (tr "\x00-\x19\x7f" "?*")
    

    to-listfrom-listより短い場合、動作はキーワード引数deleteに 依存します。もし真の値がdeleteに与えられれば、from-listに現われて to-listに対応するものがない文字は入力から取り除かれます。そうでなければ そのような文字はそのまま出力されます。

    真の値がcomplementに与えられた場合、from-listの文字の 補集合がfrom-listとして使われます。この文字集合は極めて大きくなる 可能性があることに注意してください。従って、一般にこのオプションは to-listに`*'を使ってそれらの文字を一文字にマッピングするか、 deleteオプションと併用するかしないとあまり意味がありません。

    真の値がsqueezeに与えられた場合、同じ文字への置換が2つ以上並ぶ場合に 2つめ以降の文字が削除されます。to-listが空の場合は、from-list に含まれる文字で同一文字が並んだ場合に2つめ以降の文字が削除されます。

    内部的に、trはキャラクタのマッピングのためにテーブルを使用します。 但し、Gaucheでは極めて大きな文字セットを扱うため、テーブルはキャラクタコードの 小さい文字のみに対して使われます(デフォルトではコード255以下の文字)。 もし、より大きな文字を頻繁に変換することが分かっていて、メモリを余分に使っても 速度を上げたい場合は、このテーブルの大きさをtable-sizeキーワード引数で 指定することができます。例えばEUC-JPコードで大量の平仮名と片仮名を変換する場合は、 table-sizeを42483以上にすると、全ての変換がテーブルルックアップで 行われます。

    trが変換テーブルを計算するのにいくらかオーバーヘッドがあることに 注意して下さい。内側のループでtrを繰り返し呼ぶような場合は 下に示すbuild-transliteratorを使った方が良いでしょう。

    Function: string-tr string from-list to-list &keyword :complement :delete :squeeze :table-size
    入力をstringから取って変換結果を文字列で返す以外はtrと同じです。

    Function: build-transliterator from-list to-list &keyword :complement :delete :squeeze :table-size :input :output
    実際の変換動作をする手続きを作成して返します。内部データのセットアップを済ませるため、 同じ文字変換セットに対してtrを繰り返し呼ぶような場合は、この手続きを用いることで 初期化のオーバヘッドを軽減することができます。
    (with-input-from-file "huge-file.txt"
      (lambda ()
        (let loop ((line (read-line)))
          (unless (eof-object? line) (tr "A-Za-z" "a-zA-Z")))))
    
    ;; 以下の方が効率良く動作します...
    
    (with-input-from-file "huge-file.txt"
      (lambda ()
        (let ((ptr (build-transliterator "A-Za-z" "a-zA-Z")))
          (let loop ((line (read-line)))
            (unless (eof-object? line) (ptr))))))
    

    11.20 text.tree - Lazy text construction

    Module: text.tree
    テキストを生成する場合によく使われるシンプルな手続きを定義します。

    プログラムでテキストを生成する場合、テキストの断片をつなぎ合わせて行く操作が 非常に多く現われます。しかし単純にstring-appendを繰り返し 呼んでしまうと、中間結果の文字列を保持するためだけにメモリアロケーションが多発しますし、 途中でエラーが発生した場合にその中間結果は結局捨てられてしまうかもしれません (例えば、CGIスクリプト中でHTMLドキュメントを構築してゆくような場合を考えてみて下さい)。

    よく知られた効率の良い方法は、テキストの断片をつなぎ合わせるのを本当に必要に なるまで遅らせることです。Schemeではそれは非常に簡単です。単に断片をコンス していって木構造を作り、最後にそれをトラバースしてテキストを作成するのです。 場合によっては、トラバースしながらテキストを出力すれば事足りてしまうので、 中間結果のバッファを持つ必要さえありません。 (Hans Boehmのガベージコレクションライブラリに附属している "cord" ライブラリ はこのテクニックを実装したもので、エディタ等のアプリケーションで非常に効率良く 動作することが知られています)。

    木構造をトラバースする手続きなどほんの2〜3行で書けてしまいますが、 「一度、そして一度だけ」の精神の下に、このモジュールを提供します。 インタフェースが統一されてたほうが便利ですしね。

    Generic Function: write-tree tree &optional out
    treeをテキストの木構造とみなして、出力ポートoutに出力します。 outが省略された場合は現在の出力ポートが使われます。

    下に示す2つのメソッドが定義されています。より複雑な動作をさせたい場合は、 単純なリストの替わりにノードとなるクラスを定義して、それにメソッドを定義するようにすれば 動作をカスタマイズできます。

    Method: write-tree ((tree <list>) out)
    Method: write-tree ((tree <top>) out)
    write-treeの既定の動作です。treeがリストなら、その要素それぞれに ついてwrite-treeを呼び出します。それ以外のオブジェクトに関しては displayを呼んで出力します。

    Function: tree->string tree
    出力文字列ポートを作成してwrite-treeを呼び、生成された文字列を返します。

    11.21 util.isomorph - 同型判定

    Module: util.isomorph
    二つの構造が同型かどうかを判定する手続きを提供するモジュールです。

    Function: isomorphic? obj1 obj2 &optional context
    obj1obj2が同型であれば#tを返します。

    省略可能な引数contextは、下で説明するobject-isomorphic? の中からisomorphic?を再帰的に呼び出す場合に使います。

    (isomorphic? '(a b) '(a b)) => #t
    
    (define x (cons 0 0))
    (define y (cons 0 0))
    (isomorphic? (cons x x)
                 (cons x y))
     => #f
    (isomorphic? (cons x x)
                 (cons y y))
     => #t
    

    Generic Function: object-isomorphic? obj1 obj2 context
    このメソッドで、二つのオブジェクトの同型判定処理をカスタマイズできます。 基本的には、オブジェクトのトラバースしたいスロットに対してisomorphic?を順に適用し、 全てが成功すれば#tを、一つでも失敗すれば#fを返すようにします。 contextはトラバースのコンテクストを保持しているオブジェクトです。そのまま isomorphic?に渡して下さい。

    デフォルトメソッドは、obj1obj2equal?の意味で等しければ #tを返します。

    11.22 util.queue - キュー

    Module: util.queue
    キュー(FIFO)機能を提供します。この実装は安全さよりスピードに重点を置いています。 キューは単に先頭と末尾のpairで表現され、多くのオペレーションでキューが正しいかどうかは チェックされません。

    SLIB (section 11.15 slib - SLIB interface参照)にはより安全なキューの実装があります。 このAPIはSLIBの実装の上位互換です。特定の手続きや構造体の中だけで使うため、 厳しいチェックが必要でない場合にはこのモジュールを使うのが良く、そうでない場合は SLIBのものが良いでしょう。要求仕様によって使い分けて下さい。

    Function: make-queue
    空のキューを作って返します。

    Function: queue? obj
    objがキューであれば#tを返します。この操作に限り、objが 本当にキューの構造をしているかどうかのチェックがなされます。

    Function: queue-empty? queue
    objが空のキューであれば#tを返します。

    Function: queue-length queue
    キューの中にあるアイテムの数を返します。

    Function: enqueue! queue obj &optional more-objs ...
    objをキューqueueの末尾に追加します。 一つ以上のobjを与えることができ、その場合はそれらが順にenqueueされます。 (註:SLIBのenqueue!はオプショナルな引数を取りません)。

    Function: queue-push! queue obj &optional more-objs ...
    objをキューqueueの先頭に追加します。 一つ以上のobjを与えることができ、その場合はそれらが順にpushされます。 (註:SLIBのqueue-push!はオプショナルな引数を取りません)。

    Function: dequeue! queue
    Function: queue-pop! queue
    キューqueueの先頭からひとつ要素を取って返します。 二つの手続きは全く同じ動作をします。queue-pop!queue-push!と ペアで使われていることを強調したいときに使うと良いでしょう。キューが空の場合は エラーが報告されます。

    Function: dequeue-all! queue
    キューの全ての内容をリストにして返します。キューそのものは空になります。 キューが既に空の場合は空リストが返されます。 下のqueue->listも参照してください。

    Function: queue-front queue
    Function: queue-rear queue
    キューqueueの先頭もしくは末尾の要素を返します。キューそのものは変更されません。 キューが空の場合はエラーが報告されます。

    Function: list->queue list
    与えられたリストlistの各要素をその順で持つようなキューを作成して返します。

    Function: queue->list queue
    キューqueueの内容をリストにして返します。 dequeue-all!と異なり、キューそのものの内容は変化しません。

    Gaucheではqueue->listは新しいリストをアロケートしてキューの 内容をコピーします (dequeue-all!はコピーをせずにキューの内部の リストをそのまま返します)。組込みでqueue->listを持っているScheme 実装がいくつかありますが、その中にはqueue->listがキューの 内容をコピーすることを保証していないものがあるので、それらの処理系と 共有するコードではqueue->listがリストをコピーすることを あてにしない方が良いでしょう。

    Function: find-in-queue pred queue
    キュー内の要素のうち述語predを満たす最初の要素を返します。 引数の順序はSRFI-1のfindに揃えました (section 10.2.7 List searching参照)。

    Function: remove-from-queue! pred queue
    キューから、述語predを満たす要素を全て取り除きます。 要素が削除された場合は#tが、そうでなければ#fが返されます。 引数の順序はSRFI-1のremoveに揃えました (section 10.2.6 List filtering & partitioning参照)。

    移植性に関する註:Scheme48には、述語ではなく削除するオブジェクトそのものを取る delete-from-queue!がありますが、引数の順序が逆(キューが先)になっています。 まぎらわしい衝突を避けるため、敢えてdelete-from-queue!は 提供しませんでした。remove-from-queue!を使えば、Scheme48互換の方法でも、 あるいはSRFI-1と一貫性のある方法でもdelete-from-queue!をすぐ書けるでしょう。

    11.23 util.toposort - トポロジカルソート

    Module: util.toposort
    トポロジカルソートのアルゴリズムを実装します。

    Function: topological-sort graph &optional eqproc
    Graphは有向非循環グラフ(DAG)を表現するリストです。 リストの各要素は次の形をしています。
    (<node> <downstream> <downstream2> ...)
    

    これで、ノード<node>から別のノード<downstream>等への接続が あることを表現します。<node>はどんなオブジェクトであっても構いませんが、 同一性の判定がeqprocで行えなければなりません。eqprocの既定値は eqv?です (section 6.1 等価参照)。 トポロジカルにソートされたノードのリストを返します。

    グラフに循環が検出された場合はエラーとなります。

    11.24 www.cgi - CGIユーティリティ

    Module: www.cgi
    CGIスクリプトを書くのに便利ないくつかの基本的な手続きを提供します。

    CGIスクリプトを手軽に書くにはこのモジュールの他に、 rfc.uri (section 11.14 rfc.uri - URIの解析と作成)、 text.html-lite (section 11.17 text.html-lite - Simple HTML document construction)、 text.tree (section 11.20 text.tree - Lazy text construction) 等のモジュールを併せて 使うとよいでしょう。

    注:現在有効な、CGIに関する「正式な」仕様というのはどうも無いようです。 http://w3c.org/CGI/あたりを参照して下さい。

    Function: cgi-parse-parameters &keyword :query-string :merge-cookies
    CGIプログラムに渡されたquery stringをパーズして、パラメータの連想リストにして 返します。文字列がキーワード引数query-stringに与えられればそれがパーズすべき query stringとなります。その引数が渡されなければこの手続きは環境変数REQUEST_METHODを 参照し、その値によって標準入力もしくは 環境変数QUERY_STRINGからquery stringが取られます。 そのような環境変数が定義されておらず、かつ現在の入力ポートが端末である場合、 インタラクティブにデバッグをしているものと考えて、 この手続きはプロンプトを出してユーザにパラメータの入力を促します。

    キーワード引数merge-cookiesに真の値が与えられた場合は、 環境変数HTTP_COOKIEからクッキーの値が読まれ、解析されて 結果に追加されます。

    パラメータは複数の値を取り得るため、結果のパラメータに対応する値は常にリストになります。 パラメータに値が与えられていなければ、結果のパラメータに対する値には#tが置かれます。 次の例を参照して下さい。

    (cgi-parse-parameters
      :query-string "foo=123&bar=%22%3f%3f%22&bar=zz&buzz")
     => (("foo" "123") ("bar "\"??\"" "zz") ("buzz #t))
    

    Function: cgi-get-parameter name params &keyword :default :list :convert
    cgi-parse-parametersが返す、パーズされたQuery文字列paramsから、 名前nameを持つパラメータの値を簡単に取り出すための手続きです。

    キーワード引数listに真の値が与えられていなければ、 返される値はスカラー値です。パラメータnameに複数の値が与えられた場合でも、 最初の値のみが返されます。listに真の値が与えられれば、返されるのは 常に値のリストとなります。

    キーワード引数convertに手続きを与えると、対応する値が取り出された後でその 手続きが値を引数として呼ばれます。これによって値を文字列から必要な型へと変換することが できます。listに真の値が与えられている場合、変換手続きは各値に対して呼ばれ、 その結果のリストがcgi-get-parameterから返されます。

    パラメータnameに対応する値が無ければ、defaultに与えられた値がそのまま 返されます。defaultが省略された場合、listが偽であれば#fが、 真であれば()が返されます。

    Function: cgi-header &keyword content-type location cookies
    HTTPリプライメッセージのヘッダを、テキストツリー形式(section 11.20 text.tree - Lazy text construction参照) で作成して返します。最も簡単な呼び出しでは次のようになります。
    (tree->string (cgi-header))
      => "Content-type: text/html\r\n\r\n"
    

    キーワード引数content-typeによってContent typeを指定できます。 また、cookiesにクッキー文字列のリストを渡すことにより、 クライアントにクッキーを設定できます。クッキー文字列を構築するには手続き construct-cookie-string (section 11.11 rfc.cookie - HTTPクッキー参照) が使えます。

    キーワード引数locationは、Locationヘッダを作成して クライアントを別のURIに誘導するのに使えます。

    Function: cgi-main proc &keyword on-error merge-cookies
    CGIスクリプトのための便利なラッパー手続きです。 この手続きは、まずcgi-parse-parametersを呼び出してCGIスクリプトに 渡されたパラメータを解析し、続いてその結果を引数としてprocを呼び出します。 キーワード引数merge-cookiesは、与えられればそのまま cgi-parse-parametersに渡されます。

    手続きprocはHTTPヘッダを含むドキュメントを テキストツリー構造(section 11.20 text.tree - Lazy text construction参照)で 返さなければなりません。cgi-mainはそれをwrite-treeを使って 現在の出力ポートに書き出し、0を返します。

    もしproc内でエラーが起こった場合、そのエラーは捕捉されて、エラーを報告する HTMLページが作成されて出力されます。このエラーページは、on-errorキーワード引数に 手続きを渡すことでカスタマイズできます。on-errorに渡された手続きは エラー発生時に<exception>オブジェクト(section 6.16.3 例外オブジェクト参照) を引数として呼ばれ、HTTPヘッダを含むドキュメントをテキストツリー構造で返さねばなりません。

    以下の例はCGIに渡されたパラメータ全てをテーブルにして表示します。

    #!/usr/local/bin/gosh
    
    (use text.html-lite)
    (use www.cgi)
    
    (define (main args)
      (cgi-main
        (lambda (params)
          `(,(cgi-header)
            ,(html-doctype)
            ,(html:html
              (html:head (html:title "Example"))
              (html:body
               (html:table
                :border 1
                (html:tr (html:th "Name") (html:th "Value"))
                (map (lambda (p)
                       (html:tr
                        (html:td (html-escape-string (car p)))
                        (html:td (html-escape-string (x->string (cdr p))))))
                     params))))
           ))))
    

    A. 参考文献

    @anchor{r5rs}
    [R5RS]
    R. Kelsey, W. Clinger, J. Rees (eds.), Revised^5 Report on the Algorithmic Language Scheme, Higher-Order and Symbolic Computation, 11(1), September, 1998 and ACM SIGPLAN Notices, 33(9), October, 1998.
    http://www.schemers.org/Documents/Standards/R5RS/. @anchor{onecont}
    [1CC]
    Carl Bruggeman, Oscar Waddell and R. Kent Dybvig, Representing control in the presence of one-shot continuations, in Proceedings of SIGPLAN '96, pp. 99--107, 1996. @anchor{mop}
    [MOP]
    Gregor Kiczales, Jim Des Rivieres, Daniel Bobrow, The Art of Metaobject Protocol, The MIT Press. @anchor{rfc2045}
    [RFC2045]
    N. Freed, N. Borenstein: Multipurpose Internet Mail Extension (MIME) Part One: Format of Internet Message Bodies, November 1996.
    ftp://ftp.isi.edu/in-notes/rfc2045.txt. @anchor{rfc2396}
    [RFC2396]
    T. Berners-Lee, R. Fielding, L. Masinter, Uniform Resource Identifiers (URI): Generic Syntax, August 1998.
    ftp://ftp.isi.edu/in-notes/rfc2396.txt. @anchor{rfc2616}
    [RFC2616]
    R. Fielding et al, Hypertext Transfer Protocol -- HTTP/1.1, June 1999.
    ftp://ftp.isi.edu/in-notes/rfc2616.txt. @anchor{rfc2822}
    [RFC2822]
    P. Resnick (ed.), Internet Message Format, April 2001.
    ftp://ftp.isi.edu/in-notes/rfc2822.txt. @anchor{rfc2965}
    [RFC2965]
    D. Kristol, L. Montulli, HTTP State Management Mechanism, October 2000.
    ftp://ftp.isi.edu/in-notes/rfc2965.txt. @anchor{srfi-0}
    [SRFI-0]
    Marc Feeley, Feature-based conditional expansion construct, May 1999.
    http://srfi.schemers.org/srfi-0/srfi-0.html. @anchor{srfi-1}
    [SRFI-1]
    Olin Shivers, List Library, October 1999.
    http://srfi.schemers.org/srfi-1/srfi-1.html. @anchor{srfi-2}
    [SRFI-2]
    Oleg Kiselyov, AND-LET*: an AND with local bindings, a guarded LET* special form, March 1998.
    http://srfi.schemers.org/srfi-2/srfi-2.html. @anchor{srfi-4}
    [SRFI-4]
    Marc Feeley, Homogeneous numeric vector types, May 1999.
    http://srfi.schemers.org/srfi-4/srfi-4.html. @anchor{srfi-6}
    [SRFI-6]
    William D Clinger, Basic String Ports, July 1999.
    http://srfi.schemers.org/srfi-6/srfi-6.html. @anchor{srfi-8}
    [SRFI-8]
    John David Stone, receive: Binding to multiple values, August 1999.
    http://srfi.schemers.org/srfi-8/srfi-8.html. @anchor{srfi-9}
    [SRFI-9]
    Richard Kelsey, Defining Record Types, September 1999.
    http://srfi.schemers.org/srfi-9/srfi-9.html. @anchor{srfi-10}
    [SRFI-10]
    Oleg Kiselyov, #, external form, January 2000.
    http://srfi.schemers.org/srfi-10/srfi-10.html. @anchor{srfi-11}
    [SRFI-11]
    Lars T Hansen, Syntax for receiving multiple values, March 2000.
    http://srfi.schemers.org/srfi-11/srfi-11.html. @anchor{srfi-13}
    [SRFI-13]
    Olin Shivers, String Libraries, December 2000.
    http://srfi.schemers.org/srfi-13/srfi-13.html. @anchor{srfi-14}
    [SRFI-14]
    Olin Shivers, Character-set Library, December 2000.
    http://srfi.schemers.org/srfi-14/srfi-14.html. @anchor{srfi-17}
    [SRFI-17]
    Per Bothner, Generalized set!, July 2000.
    http://srfi.schemers.org/srfi-17/srfi-17.html. @anchor{srfi-18}
    [SRFI-18]
    Marc Feeley, Multithreading Support, April 2000.
    http://srfi.schemers.org/srfi-18/srfi-18.html. @anchor{srfi-19}
    [SRFI-19]
    Will Fitzgerald, Time Data Types and Procedures, August 2000.
    http://srfi.schemers.org/srfi-19/srfi-19.html. @anchor{srfi-21}
    [SRFI-21]
    Marc Feeley, Readl-time Multithreading Support, April 2000.
    http://srfi.schemers.org/srfi-21/srfi-21.html. @anchor{srfi-22}
    [SRFI-22]
    Martin Gasbichler and Michael Sperber, Running Scheme Scripts on Unix, January 2002.
    http://srfi.schemers.org/srfi-22/srfi-22.html. @anchor{srfi-23}
    [SRFI-23]
    Stephan Housen, Error reporting mechanism, April 2001.
    http://srfi.schemers.org/srfi-23/srfi-23.html. @anchor{srfi-25}
    [SRFI-25]
    Jussi Piitulainen, Multi-dimensional Array Primitives, June 2002.
    http://srfi.schemers.org/srfi-25/srfi-25.html. @anchor{srfi-26}
    [SRFI-26]
    Sebastian Egner, Notation for Specializing Parameters without Currying, June 2002.
    http://srfi.schemers.org/srfi-26/srfi-26.html. @anchor{srfi-27}
    [SRFI-27]
    Sebastian Egner, Sources of Random Bits, June 2002.
    http://srfi.schemers.org/srfi-27/srfi-27.html. @anchor{srfi-28}
    [SRFI-28]
    Scott G. Miller, Basic Format Strings, June 2002.
    http://srfi.schemers.org/srfi-28/srfi-28.html. @anchor{ssax}
    [SSAX]
    Oleg Kiselyov, XML and Scheme,
    http://pobox.com/~oleg/ftp/Scheme/xml.html.
    The SSAX distribution is also available at sourceforge:
    http://ssax.sourceforge.net/. @anchor{MT}
    [MT]
    M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-dimensionally equidistributed uniform pseudorandom number generator", ACM Trans. on Modeling and Computer Simulation Vol. 8, No. 1, Januray pp.3-30 1998.
    http://www.math.keio.ac.jp/~matumoto/emt.html @anchor{oleg1}
    [OLEG1]
    Oleg Kiselyov, Making sense of an input stream,
    http://pobox.com/~oleg/ftp/Scheme/parsing.html. @anchor{oleg2}
    [OLEG2]
    Oleg Kiselyov, General ways to traverse collections,,
    http://pobox.com/~oleg/ftp/Scheme/enumerators-callcc.html. 2000.

    B. CとSchemeの関数の対応

    Cに馴染んだプログラマのために、Cのオペレータとライブラリ関数からSchemeの関数への 対応表を示しておきます。

    +
    R5RS arithmetic procedure +. See section 6.2.4 数値の演算.
    +=
    Gauche inc! macro. See section 4.4 代入.
    -
    R5RS arithmetic procedure -. See section 6.2.4 数値の演算.
    -=
    Gauche dec! macro. See section 4.4 代入.
    ->
    Gauche slot-ref is something close to this. See section 7.5 インスタンスへのアクセス.
    * (binary)
    R5RS arithmetic procedure *. See section 6.2.4 数値の演算.
    * (unary)
    No equivalent procedure. Scheme doesn't have explicit notation of pointers.
    *=
    No equivalent procedure.
    /
    R5RS arithmetic procedure /. See section 6.2.4 数値の演算.
    /=
    No equivalent procedure.
    & (binary)
    Gauche logand. See section 6.2.6 ビット演算.
    & (unary)
    No equivalent procedure. Scheme doesn't have explicit notation of pointers.
    &&
    R5RS syntax and. See section 4.5 条件式.
    &=
    No equivalent procedure.
    |
    Gauche logior. See section 6.2.6 ビット演算.
    ||
    R5RS syntax or. See section 4.5 条件式.
    |=
    No equivalent procedure.
    ^
    Gauche logxor. See section 6.2.6 ビット演算.
    =
    R5RS syntax set!. See section 4.4 代入.
    ==
    R5RS equivalence procedure, eq?, eqv? and equal?. See section 6.1 等価.
    <
    <=
    R5RS arithmetic procedure < and <=. See section 6.2.3 数値の比較. Unlike C operator, Scheme version is transitive.
    <<
    Gauche ash. See section 6.2.6 ビット演算.
    <<=
    No equivalent procedure.
    >
    >=
    R5RS arithmetic procedure > and >=. See section 6.2.3 数値の比較. Unlike C operator, Scheme version is transitive.
    >>
    Gauche ash. See section 6.2.6 ビット演算.
    >>=
    No equivalent procedure.
    %
    R5RS operator modulo and remainder. See section 6.2.4 数値の演算.
    %=
    No equivalent procedure.
    []
    R5RS vector-ref (See section 6.12 ベクター) is something close. Or you can use Gauche's generic function ref (See section 9.18 gauche.sequence - シーケンスフレームワーク) for arbitrary sequences.
    .
    Gauche slot-ref is something close to this. See section 7.5 インスタンスへのアクセス.
    ~
    Gauche lognot. See section 6.2.6 ビット演算.
    ~=
    No equivalent procedure.
    !
    R5RS procedure not. See section 6.3 論理値.
    !=
    No equivalent procedure.
    abort
    Gauche sys-abort. See section 6.21.1 プログラムの終了
    abs
    R5RS abs. See section 6.2.4 数値の演算.
    access
    Gauche sys-access. See section 6.21.3.4 ファイルの状態.
    acos
    R5RS acos. See section 6.2.4 数値の演算.
    alarm
    Gauche sys-alarm. See section 6.21.11 その他のシステムコール.
    asctime
    Gauche sys-asctime. See section 6.21.8 時間.
    asin
    R5RS asin. See section 6.2.4 数値の演算.
    assert
    No equivalent function in Gauche.
    atan
    atan2
    R5RS atan. See section 6.2.4 数値の演算.
    atexit
    No equivalent function in Gauche, but the "after" thunk of active dynamic handlers are called when exit is called. See section 6.21.1 プログラムの終了, and See section 6.15.3 継続.
    atof
    atoi
    atol
    You can use string->number. See section 6.2.5 数値の変換.
    bsearch
    No equivalent function in Gauche.
    calloc
    Allocation is handled automatically in Scheme.
    ceil
    R5RS ceiling. See section 6.2.4 数値の演算.
    cfgetispeed
    cfgetospeed
    cfsetispeed
    cfsetospeed
    Gauche sys-cfgetispeed, sys-cfgetospeed, sys-cfsetispeed, sys-cfsetospeed. See section 9.20 gauche.termios - Termios.
    chdir
    Gauche sys-chdir. See section 6.21.3.5 他のファイル操作.
    chmod
    Gauche sys-chmod. See section 6.21.3.4 ファイルの状態.
    chown
    Gauche sys-chown. See section 6.21.3.4 ファイルの状態
    clearerr
    Not supported yet.
    clock
    No equivalent function in Gauche. You can use sys-times to get information about CPU time.
    close
    You can't directly close the file descriptor, but when you use close-input-port or close-output-port, underlying file is closed. Some port-related functions, such as call-with-output-file, automatically closes the file when operation is finished. The file is also closed when its governing port is garbage collected. See section 6.18.2 ポート共通の操作.
    closedir
    No equivalent function in Gauche. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 ディレクトリ.
    cos
    cosh
    cos and cosh. See section 6.2.4 数値の演算.
    creat
    A file is implictly created by default when you open it for writing. See section 6.18.3 ファイルポート for more control over the creation of files.
    ctermid
    Gauche sys-ctermid. See section 6.21.7 システムへの問い合わせ.
    ctime
    Gauche sys-ctime. See section 6.21.8 時間.
    cuserid
    No equivalent function. This is removed from the newer POSIX. You can use alternative functions, such as sys-getlogin or sys-getpwuid with sys-getuid.
    difftime
    Gauche sys-difftime. See section 6.21.8 時間.
    div
    You can use R5RS quotient and remainder. See section 6.2.4 数値の演算.
    dup
    dup2
    No equivalent function. If you want to use this function to set up I/Os for the child process, you can use `iomap' argument of sys-exec. See section 6.21.9.1 forkとexec.
    execl
    execle
    execlp
    execv
    execve
    execvp
    Gauche sys-exec. See section 6.21.9.1 forkとexec. For higher level interface, section 9.14 gauche.process - 高レベルプロセスインタフェース.
    exit
    _exit
    Use exit or sys-exit, depends on what you need. See section 6.21.1 プログラムの終了.
    exp
    R5RS exp. See section 6.2.4 数値の演算.
    fabs
    R5RS abs. See section 6.2.4 数値の演算.
    fclose
    You can't directly close the file stream, but when you use close-input-port or close-output-port, underlying file is closed. Some port-related functions, such as call-with-output-file, automatically closes the file when operation is finished. The file is also closed when its governing port is garbage collected.
    fcntl
    Implented as sys-fcntl in gauche.fcntl module. See section 9.5 gauche.fcntl - 低レベルファイル操作.
    fdopen
    Gauche's open-input-fd-port or open-output-fd-port. See section 6.18.3 ファイルポート.
    feof
    Not supported yet.
    ferror
    Not supported yet.
    fflush
    Gauche's flush. See section 6.18.7 出力.
    fgetc
    Use read-char or read-byte. See section 6.18.6 入力.
    fgetpos
    Not supported yet.
    fgets
    Use read-line or read-block. See section 6.18.6 入力.
    fileno
    port-file-numer. See section 6.18.2 ポート共通の操作.
    floor
    R5RS floor. See section 6.2.4 数値の演算.
    fmod
    Gauche's fmod.
    fopen
    R5RS open-input-file or open-output-file corresponds to this operation. See section 6.18.3 ファイルポート.
    fork
    Gauche's sys-fork. See section 6.21.9.1 forkとexec.
    forkpty
    Use sys-forkpty. See section 9.20 gauche.termios - Termios.
    fpathconf
    Not supported.
    fprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 出力. SLIB has printf implementation.
    fputc
    Use write-char or write-byte. See section 6.18.7 出力.
    fputs
    Use display. See section 6.18.7 出力.
    fread
    Not directly supported. If you want to read a chunk of bytes, you may be able to use read-block.
    free
    You don't need this in Scheme.
    freopen
    Not supported.
    frexp
    Gauche's frexp
    fscanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 正規表現, also section 9.15 gauche.regexp - 正規表現ユーティリティ.
    fseek
    Not implemented yet.
    fsetpos
    Not implemented yet.
    fstat
    Gauche's sys-stat. See section 6.21.3.4 ファイルの状態.
    ftell
    Not implemented yet.
    fwrite
    Not directly supported. If you want to write a chunk of bytes, you can simply use display. See section 6.18.7 出力.
    getc
    getchar
    Use read-char or read-byte. See section 6.18.6 入力.
    getcwd
    Gauche's sys-getcwd. See section 6.21.7 システムへの問い合わせ.
    getdomainname
    Gauche's sys-getdomainname. See section 6.21.7 システムへの問い合わせ.
    getegid
    Gauche's sys-getegid. See section 6.21.7 システムへの問い合わせ.
    getenv
    Gauche's sys-getenv. See section 6.21.2 環境の問い合わせ.
    geteuid
    Gauche's sys-geteuid. See section 6.21.7 システムへの問い合わせ.
    gethostname
    Gauche's sys-gethostname. See section 6.21.7 システムへの問い合わせ.
    getgid
    Gauche's sys-getgid. See section 6.21.7 システムへの問い合わせ.
    getgrgid
    getgrnam
    Gauche's sys-getgrgid and sys-getgrnam. See section 6.21.4.1 Unixのグループ.
    getgroups
    Gauche's sys-getgroups. See section 6.21.7 システムへの問い合わせ.
    getlogin
    Gauche's sys-getlogin. See section 6.21.7 システムへの問い合わせ.
    getpgrp
    Gauche's sys-getpgrp. See section 6.21.7 システムへの問い合わせ.
    getpid
    getppid
    Gauche's sys-getpid. See section 6.21.7 システムへの問い合わせ.
    getpwnam
    getpwuid
    Gauche's sys-getpwnam and sys-getpwuid. See section 6.21.4.2 Unixのユーザ.
    gets
    Use read-line or read-block. See section 6.18.6 入力.
    gettimeofday
    Gauche's sys-gettimeofday. See section 6.21.8 時間.
    getuid
    Gauche's sys-getuid. See section 6.21.7 システムへの問い合わせ.
    gmtime
    Gauche's sys-gmtime. See section 6.21.8 時間.
    isalnum
    Not directly supported, but you can use R5RS char-alphabetic? and char-numeric?. See section 6.8 文字. You can also use character set. See section 6.9 文字集合, also section 10.8 srfi-14 - Character-set library.
    isalpha
    R5RS char-alphabetic?. See section 6.8 文字. See also section 6.9 文字集合 and section 10.8 srfi-14 - Character-set library.
    isatty
    Gauche's sys-isatty. See section 6.21.3.5 他のファイル操作.
    iscntrl
    Not directly supported, but you can use (char-set-contains? char-set:iso-control c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isdigit
    R5RS char-numeric?. See section 6.8 文字. You can also use (char-set-contains? char-set:digit c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isgraph
    Not directly supported, but you can use (char-set-contains? char-set:graphic c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    islower
    R5RS char-lower-case?. See section 6.8 文字. You can also use (char-set-contains? char-set:lower-case c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isprint
    Not directly supported, but you can use (char-set-contains? char-set:printing c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    ispunct
    Not directly supported, but you can use (char-set-contains? char-set:punctuation c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isspace
    R5RS char-whitespace?. See section 6.8 文字. You can also use (char-set-contains? char-set:whitespace c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isupper
    R5RS char-upper-case?. See section 6.8 文字. You can also use (char-set-contains? char-set:upper-case c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    isxdigit
    Not directly supported, but you can use (char-set-contains? char-set:hex-digit c) with srfi-14. See section 10.8 srfi-14 - Character-set library.
    kill
    Gauche's sys-kill. See section 6.21.6 シグナル.
    labs
    R5RS abs. See section 6.2.4 数値の演算.
    ldexp
    Gauche's ldexp.
    ldiv
    Use R5RS quotient and remainder. See section 6.2.4 数値の演算.
    link
    Gauche's sys-link. See section 6.21.3.2 ディレクトリ操作.
    localeconv
    Gauche's sys-localeconv. See section 6.21.5 ロケール.
    localtime
    Gauche's sys-localtime. See section 6.21.8 時間.
    log
    R5RS log. See section 6.2.4 数値の演算.
    log10
    Not directly supported. log10(z) == (/ (log z) (log 10)).
    longjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 継続.
    lseek
    Not supported yet.
    malloc
    Not necessary in Scheme.
    mblen
    mbstowcs
    mbtowc
    Gauche handles multibyte strings internally, so generally you don't need to care about multibyte-ness of the string. string-length always returns a number of characters for a string in supported encoding. If you want to convert the character encoding, see section 9.2 gauche.charconv - 文字コード変換.
    memcmp
    memcpy
    memmove
    memset
    No equivalent functions.
    mkdir
    Gauche's sys-mkdir. See section 6.21.3.2 ディレクトリ操作.
    mkfifo
    Gauche's sys-mkfifo.
    mkstemp
    Gauche's sys-mkstemp. See section 6.21.3.2 ディレクトリ操作. Use this instead of tmpnam.
    mktime
    Gauche's sys-mktime. See section 6.21.8 時間.
    modf
    Gauche's modf.
    open
    Not directly supported. R5RS open-input-file or open-output-file corresponds to this operation. See section 6.18.3 ファイルポート.
    opendir
    Not directly supported. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 ディレクトリ.
    openpty
    Use sys-openpty. See section 9.20 gauche.termios - Termios.
    pathconf
    Not supported.
    pause
    Gauche's sys-pause. See section 6.21.11 その他のシステムコール.
    perror
    No equivalent function in Gauche. System calls generally throws an error (<system-error>), including the description of the reason of failure.
    pipe
    Gauche's sys-pipe. See section 6.21.3.5 他のファイル操作.
    pow
    R5RS expt. See section 6.2.4 数値の演算.
    printf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 出力. SLIB has printf implementation.
    putc
    putchar
    Use write-char or write-byte. See section 6.18.7 出力.
    puts
    Use display. See section 6.18.7 出力.
    qsort
    Gauche's sort and sort! provides a convenient way to sort list of items. See section 6.20 比較とソート.
    raise
    No equivalent function in Gauche. Scheme function raise (SRFI-18) is to raise an exception. You can use (sys-kill (sys-getpid) SIG) to send a signal SIG to the current process.
    rand
    Not supported directly, but on most platforms a better RNG is available as sys-random. See section 6.21.11 その他のシステムコール.
    read
    Not supported directly, but you may be able to use read-block (See section 6.18.6 入力) or read-block! (See section 9.24.4 ユニフォームベクタのブロック入出力).
    readdir
    Not supported directly. Gauche's sys-readdir reads the directly at once. See section 6.21.3.1 ディレクトリ.
    readlink
    Gauche's sys-readlink. See section 6.21.3.2 ディレクトリ操作. This function is available on systems that support symbolink links.
    realloc
    Not necessary in Scheme.
    remove
    Gauche's sys-remove. See section 6.21.3.2 ディレクトリ操作.
    rename
    Gauche's sys-rename. See section 6.21.3.2 ディレクトリ操作.
    rewind
    Not supported yet.
    rewinddir
    Not supported directly. You can use sys-readdir to read the directory entries at once. See section 6.21.3.1 ディレクトリ.
    rmdir
    Gauche's sys-rmdir. See section 6.21.3.2 ディレクトリ操作.
    scanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 正規表現, also section 9.15 gauche.regexp - 正規表現ユーティリティ.
    select
    Gauche sys-select. See section 6.21.10 I/Oの多重化.
    setbuf
    Not necessary.
    setgid
    Gauche's sys-setgid.
    setjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 継続.
    setlocale
    Gauche's sys-setlocale. See section 6.21.5 ロケール.
    setpgid
    Gauche's sys-setpgid. See section 6.21.7 システムへの問い合わせ.
    setsid
    Gauche's sys-setsid. See section 6.21.7 システムへの問い合わせ.
    setuid
    Gauche's sys-setuid. See section 6.21.7 システムへの問い合わせ.
    setvbuf
    Not necessary.
    sigaction
    You can use with-signal-handlers to install signal handlers. See section 6.21.6.3 シグナルの処理.
    sigaddset
    sigdelset
    sigemptyset
    sigfillset
    Gauche's sys-sigset-add! and sys-sigset-delete!. See section 6.21.6.1 シグナルとシグナルセット.
    sigismember
    Not supported yet.
    siglongjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 継続.
    signal
    You can use with-signal-handlers to install signal handlers. See section 6.21.6.3 シグナルの処理.
    sigpending
    Not supported yet.
    sigprocmask
    Signal mask is handled internally. See See section 6.21.6.3 シグナルの処理.
    sigsetjmp
    R5RS call/cc provides similar (superior) mechanism. See section 6.15.3 継続.
    sigsuspend
    Not supported yet.
    sin
    sinh
    Use sin and sinh. See section 6.2.4 数値の演算.
    sleep
    Gauche's sys-sleep. See section 6.21.11 その他のシステムコール.
    sprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 出力. SLIB has printf implementation.
    sqrt
    R5RS sqrt. See section 6.2.4 数値の演算.
    srand
    Not supported directly, but on most platforms a better RNG is available as sys-srandom. See section 6.21.11 その他のシステムコール.
    sscanf
    Not supported. For general case, you have to write a parser. If you can keep the data in S-exp, you can use read. If the syntax is very simple, you may be able to utilize string-tokenize in srfi-14 (section 10.7 srfi-13 - String library), and/or regular expression stuff (section 6.11 正規表現, also section 9.15 gauche.regexp - 正規表現ユーティリティ.
    stat
    Gauche's sys-stat. See section 6.21.3.4 ファイルの状態.
    strcasecmp
    R5RS string-ci=? and other comparison functions. See section 6.10.6 文字列の比較.
    strcat
    R5RS string-append. See section 6.10.7 文字列を扱うその他の手続き.
    strchr
    SRFI-13 string-index. See section 10.7.7 String searching.
    strcmp
    R5RS string=? and other comparison functions. See section 6.10.6 文字列の比較.
    strcoll
    Not supported yet.
    strcpy
    R5RS string-copy. See section 6.10.7 文字列を扱うその他の手続き.
    strcspn
    Not directly supported, but you can use SRFI-13 string-skip with a character set. See section 10.7.7 String searching.
    strerror
    Not supported.
    strftime
    Gauche's sys-strftime. See section 6.21.8 時間.
    strlen
    R5RS string-length. See section 6.10.5 文字列のアクセスと変更.
    strncat
    Not directly supported, but you can use string-append and substring.
    strncasecmp
    SRFI-13 string-compare-ci provides the most flexible (but a bit difficult to use) functionality. See section 10.7.5 String comparison. If what you want is just to check the fixed-length prefixes of two string matches, you can use SRFI-13 string-prefix-ci?.
    strncmp
    SRFI-13 string-compare provides the most flexible (but a bit difficult to use) functionality. See section 10.7.5 String comparison. If what you want is just to check the fixed-length prefixes of two string matches, you can use SRFI-13 string-prefix?. See section 10.7.6 String Prefixes & Suffixes.
    strncpy
    SRFI-13 substring. See section 6.10.7 文字列を扱うその他の手続き.
    strpbrk
    Not directly supported, but you can use SRFI-13 string-skip with a character set. See section 10.7.7 String searching.
    strrchr
    SRFI-13 string-index-right. See section 10.7.7 String searching.
    strspn
    Not directly supported, but you can use SRFI-13 string-index with a character set. See section 10.7.7 String searching.
    strstr
    SRFI-13 string-contains. See section 10.7.7 String searching.
    strtod
    You can use R5RS string->number. See section 6.2.5 数値の変換.
    strtok
    SRFI-13 string-tokenize. See section 10.7.12 Other string operations.
    strtol
    strtoul
    You can use R5RS string->number. See section 6.2.5 数値の変換.
    strxfrm
    Not supported yet.
    symlink
    Gauche's sys-symlink. See section 6.21.3.2 ディレクトリ操作. This function is available on systems that support symbolink links.
    sysconf
    Not supported yet.
    system
    Gauche sys-system. See section 6.21.9.1 forkとexec. It is generally recommended to use the process library (section 9.14 gauche.process - 高レベルプロセスインタフェース).
    tan
    tanh
    R5RS tan and Gauche tanh. See section 6.2.4 数値の演算.
    tcdrain
    tcflow
    tcflush
    tcgetattr
    tcgetpgrp
    tcsendbreak
    tcsetattr
    tcsetpgrp
    Corresponding functions are: sys-tcdrain, sys-tcflow, sys-tcflush, sys-tcgetattr, sys-tcgetpgrp, sys-tcsendbreak, sys-tcsetattr, sys-tcsetpgrp. See section 9.20 gauche.termios - Termios
    time
    Gauche's sys-time. See section 6.21.8 時間.
    times
    Gauche's sys-times. See section 6.21.7 システムへの問い合わせ.
    tmpfile
    Not exactly supported.
    tmpnam
    Gauche's sys-tmpnam. This function is provided since it is in POSIX, but its use is discouraged for the potential security risk. Use sys-mkstemp instead. See section 6.21.3.2 ディレクトリ操作.
    tolower
    toupper
    R5RS char-upcase and char-downcase. See section 6.8 文字.
    ttyname
    Gauche's sys-ttyname. See section 6.21.3.5 他のファイル操作.
    tzset
    Not supported yet.
    umask
    Gauche's sys-umask. See section 6.21.3.2 ディレクトリ操作.
    uname
    Gauche's sys-uname. See section 6.21.7 システムへの問い合わせ.
    ungetc
    Not directly supported. You can use peek-char to look one character ahead, instead of pushing back.
    unlink
    Gauche's sys-unlink. See section 6.21.3.2 ディレクトリ操作.
    utime
    Not supported yet.
    va_arg
    va_end
    va_start
    Not necessary, for Scheme handles variable number of arguments naturally.
    vfprintf
    vprintf
    vsprintf
    Not directly supported, but Gauche's format provides similar functionality. See section 6.18.7 出力. SLIB has printf implementation.
    wait
    Gauche's sys-wait. See section 6.21.9.2 Wait.
    waitpid
    Gauche's sys-waitpid. See section 6.21.9.2 Wait.
    wcstombs
    wctomb
    Gauche handles multibyte strings internally, so generally you don't need to care about multibyte-ness of the string. string-length always returns a number of characters for a string in supported encoding. If you want to convert the character encoding, see section 9.2 gauche.charconv - 文字コード変換.
    write
    R5RS display (See section 6.18.7 出力). Or write-block (See section 9.24.4 ユニフォームベクタのブロック入出力).

    C. 索引

    C.1 手続きと構文索引

    Jump to: % - ( - * - + - - - / - < - = - > - a - b - c - d - e - f - g - h - i - j - k - l - m - n - o - p - q - r - s - t - u - v - w - x - z

    %

  • %macroexpand
  • %macroexpand-1
  • (

  • (setter object-apply)
  • (setter port-buffering)
  • (setter ref)
  • (setter subseq), (setter subseq)
  • *

  • *
  • +

  • +
  • -

  • -
  • ->char-set
  • /

  • /
  • <

  • <
  • <=
  • =

  • =
  • >

  • >
  • >=
  • a

  • abandoned-mutex-exception?
  • abs
  • absolute-path?
  • acons
  • acos
  • acosh
  • add-duration
  • add-duration!
  • add-load-path
  • alist-cons
  • alist-copy
  • alist-delete
  • alist-delete!
  • all-modules
  • and
  • and-let*
  • angle
  • any
  • any$
  • any-pred
  • append
  • append!
  • append-map
  • append-map!
  • append-reverse
  • append-reverse!
  • apply
  • apply$
  • apply-generic
  • apply-method
  • apply-methods
  • apropos
  • arity
  • arity-at-least-value
  • arity-at-least?
  • array
  • array->list
  • array->vector
  • array-end
  • array-for-each-index
  • array-length
  • array-map, array-map
  • array-map!, array-map!
  • array-rank
  • array-ref, array-ref
  • array-retabulate!, array-retabulate!
  • array-set!, array-set!
  • array-shape
  • array-size
  • array-start
  • array?
  • ash
  • asin
  • asinh
  • assert-curr-char
  • assoc
  • assoc$
  • assq
  • assv
  • atan, atan
  • atanh
  • autoload
  • b

  • base64-decode
  • base64-decode-string
  • base64-encode
  • base64-encode-string
  • begin
  • begin0
  • bignum?
  • bit-field
  • boolean?
  • break
  • break!
  • build-path
  • build-transliterator
  • c

  • caaaar
  • caaadr
  • caaar
  • caadar
  • caaddr
  • caadr
  • caar
  • cadaar
  • cadadr
  • cadar
  • caddar
  • cadddr
  • caddr
  • cadr
  • call-with-builder
  • call-with-client-socket
  • call-with-current-continuation
  • call-with-input-file, call-with-input-file
  • call-with-input-process
  • call-with-input-string
  • call-with-iterator
  • call-with-iterators
  • call-with-output-file, call-with-output-file
  • call-with-output-process
  • call-with-output-string
  • call-with-process-io
  • call-with-string-io
  • call-with-values
  • call/cc
  • car
  • car+cdr
  • case
  • cdaaar
  • cdaadr
  • cdaar
  • cdadar
  • cdaddr
  • cdadr
  • cdar
  • cddaar
  • cddadr
  • cddar
  • cdddar
  • cddddr
  • cdddr
  • cddr
  • cdr
  • ceiling
  • ces-conversion-supported?
  • ces-convert
  • ces-guess-from-string
  • cgi-get-parameter
  • cgi-header
  • cgi-main
  • cgi-parse-parameters
  • char->integer
  • char->ucs
  • char-alphabetic?
  • char-ci<=?
  • char-ci<?
  • char-ci=?
  • char-ci>=?
  • char-ci>?
  • char-downcase
  • char-lower-case?
  • char-numeric?
  • char-ready?
  • char-set
  • char-set->list
  • char-set->string
  • char-set-adjoin
  • char-set-adjoin!
  • char-set-any
  • char-set-complement
  • char-set-complement!
  • char-set-contains?
  • char-set-copy
  • char-set-count
  • char-set-cursor
  • char-set-cursor-next
  • char-set-delete
  • char-set-delete!
  • char-set-diff+intersection
  • char-set-diff+intersection!
  • char-set-difference
  • char-set-difference!
  • char-set-every
  • char-set-filter
  • char-set-filter!
  • char-set-fold
  • char-set-for-each
  • char-set-hash
  • char-set-intersection
  • char-set-intersection!
  • char-set-map
  • char-set-ref
  • char-set-size
  • char-set-unfold
  • char-set-unfold!
  • char-set-union
  • char-set-union!
  • char-set-xor
  • char-set-xor!
  • char-set<=
  • char-set=
  • char-set?
  • char-upcase
  • char-upper-case?
  • char-whitespace?
  • char<=?
  • char<?
  • char=?
  • char>=?
  • char>?
  • char?
  • check-substring-spec
  • circular-list
  • circular-list?
  • clamp
  • class-direct-slots
  • class-direct-supers
  • class-name
  • class-of
  • class-precedence-list
  • class-slot-accessor
  • class-slot-definition
  • class-slot-ref
  • class-slot-set!
  • class-slots
  • close-input-port
  • close-output-port
  • coerce-to
  • compare
  • complete-sexp?
  • complex?
  • compose
  • compute-get-n-set
  • compute-slots
  • concatenate
  • concatenate!
  • cond
  • cond-expand
  • condition-variable-broadcast!
  • condition-variable-name
  • condition-variable-signal!
  • condition-variable-specific
  • condition-variable-specific-set!
  • condition-variable?
  • cons
  • cons*
  • construct-cookie-string
  • copy-bit
  • copy-bit-field
  • copy-file
  • copy-port
  • copy-time
  • cos
  • cosh
  • count
  • count$
  • create-directory*
  • current-date
  • current-directory
  • current-error-port
  • current-exception-handler
  • current-input-port
  • current-julian-day
  • current-load-history
  • current-load-next
  • current-load-port
  • current-modified-julian-day
  • current-module
  • current-output-port
  • current-thread
  • current-time, current-time
  • cut
  • cute
  • d

  • d
  • date->julian-day
  • date->modified-julian-day
  • date->string
  • date->time-monotonic
  • date->time-tai
  • date->time-utc
  • date-day
  • date-hour
  • date-minute
  • date-month
  • date-nanosecond
  • date-second
  • date-week-day
  • date-week-number
  • date-year
  • date-year-day
  • date-zone-offset
  • date?
  • dbm-close
  • dbm-closed?
  • dbm-delete!
  • dbm-exists?
  • dbm-fold
  • dbm-for-each
  • dbm-get
  • dbm-map
  • dbm-open, dbm-open
  • dbm-put!
  • dec!
  • decode-float
  • define, define
  • define-class
  • define-constant, define-constant
  • define-generic
  • define-in-module, define-in-module
  • define-macro, define-macro
  • define-method
  • define-module
  • define-read-ctor
  • define-record-type
  • define-syntax
  • define-values
  • delay
  • delete
  • delete!
  • delete$
  • delete-directory*
  • delete-duplicates
  • delete-duplicates!
  • denominator
  • dequeue!
  • dequeue-all!
  • describe
  • digit->integer
  • directory-fold
  • directory-list
  • directory-list2
  • display
  • do
  • dolist
  • dotimes
  • dotted-list?
  • drop
  • drop-right
  • drop-right!
  • drop-while
  • dynamic-load
  • dynamic-wind
  • e

  • eighth
  • end-of-char-set?
  • enqueue!
  • eof-object?
  • eq?
  • equal?
  • eqv?
  • error
  • errorf
  • eval
  • even?
  • every
  • every$
  • every-pred
  • exact->inexact
  • exact?
  • exit
  • exp
  • expand-path
  • export
  • export-all
  • expt
  • extend
  • f

  • f32vector
  • f32vector->list
  • f32vector->vector
  • f32vector-add
  • f32vector-add!
  • f32vector-clamp
  • f32vector-clamp!
  • f32vector-copy
  • f32vector-copy!
  • f32vector-div
  • f32vector-div!
  • f32vector-dot
  • f32vector-length
  • f32vector-mul
  • f32vector-mul!
  • f32vector-range-check
  • f32vector-ref
  • f32vector-set!
  • f32vector-sub
  • f32vector-sub!
  • f32vector?
  • f64vector
  • f64vector->list
  • f64vector->vector
  • f64vector-add
  • f64vector-add!
  • f64vector-clamp
  • f64vector-clamp!
  • f64vector-copy
  • f64vector-copy!
  • f64vector-div
  • f64vector-div!
  • f64vector-dot
  • f64vector-length
  • f64vector-mul
  • f64vector-mul!
  • f64vector-range-check
  • f64vector-ref
  • f64vector-set!
  • f64vector-sub
  • f64vector-sub!
  • f64vector?
  • fifth
  • file-atime
  • file-atime<=?
  • file-atime<?
  • file-atime=?
  • file-atime>=?
  • file-atime>?
  • file-ctime
  • file-ctime<=?
  • file-ctime<?
  • file-ctime=?
  • file-ctime>=?
  • file-ctime>?
  • file-dev
  • file-eq?
  • file-equal?
  • file-eqv?
  • file-exists?
  • file-filter
  • file-gid
  • file-ino
  • file-is-directory?
  • file-is-executable?
  • file-is-readable?
  • file-is-regular?
  • file-is-writable?
  • file-mode
  • file-mtime
  • file-mtime<=?
  • file-mtime<?
  • file-mtime=?
  • file-mtime>=?
  • file-mtime>?
  • file-nlink
  • file-perm
  • file-rdev
  • file-size
  • file-type
  • file-uid
  • filter, filter
  • filter!
  • filter$
  • filter-map
  • filter-to
  • find, find
  • find$
  • find-file-in-paths
  • find-in-queue
  • find-module
  • find-string-from-port?
  • find-tail
  • find-tail$
  • first
  • fixnum?
  • floor
  • flush
  • flush-all-ports
  • fmod
  • fold, fold
  • fold$, fold$, fold$
  • fold-right
  • fold-right$
  • for-each, for-each
  • for-each$, for-each$
  • force
  • format, format
  • fourth
  • frexp
  • g

  • gauche-architecture
  • gauche-architecture-directory
  • gauche-character-encoding
  • gauche-config
  • gauche-library-directory
  • gauche-site-architecture-directory
  • gauche-site-library-directory
  • gauche-thread-type
  • gauche-version
  • gcd
  • gdbm-close
  • gdbm-closed?
  • gdbm-delete
  • gdbm-errno
  • gdbm-exists
  • gdbm-fetch
  • gdbm-firstkey
  • gdbm-nextkey
  • gdbm-open
  • gdbm-reorganize
  • gdbm-setopt
  • gdbm-store
  • gdbm-strerror
  • gdbm-sync
  • gdbm-version
  • gensym
  • get-keyword
  • get-keyword*
  • get-optional
  • get-output-string
  • get-signal-handler
  • get-signal-handlers
  • getter-with-setter
  • h

  • hash-table-delete!
  • hash-table-exists?
  • hash-table-for-each
  • hash-table-get
  • hash-table-keys
  • hash-table-map
  • hash-table-pop!
  • hash-table-push!
  • hash-table-put!
  • hash-table-values
  • hash-table?
  • home-directory
  • html-doctype
  • html-escape
  • html-escape-string
  • html:a
  • html:abbr
  • html:acronym
  • html:address
  • html:area
  • html:b
  • html:base
  • html:bdo
  • html:big
  • html:blockquote
  • html:body
  • html:br
  • html:button
  • html:caption
  • html:cite
  • html:code
  • html:col
  • html:colgroup
  • html:dd
  • html:del
  • html:dfn
  • html:div
  • html:dl
  • html:dt
  • html:em
  • html:fieldset
  • html:form
  • html:h1
  • html:h2
  • html:h3
  • html:h4
  • html:h5
  • html:h6
  • html:head
  • html:hr
  • html:html
  • html:i
  • html:img
  • html:input
  • html:ins
  • html:kbd
  • html:label
  • html:legend
  • html:li
  • html:link
  • html:map
  • html:meta
  • html:noscript
  • html:object
  • html:ol
  • html:optgroup
  • html:option
  • html:p
  • html:param
  • html:pre
  • html:q
  • html:samp
  • html:script
  • html:select
  • html:small
  • html:span
  • html:strong
  • html:style
  • html:sub
  • html:sup
  • html:table
  • html:tbody
  • html:td
  • html:textarea
  • html:tfoot
  • html:th
  • html:thead
  • html:title
  • html:tr
  • html:tt
  • html:ul
  • html:var
  • http-get
  • http-head
  • http-post
  • i

  • identifier->symbol
  • identifier?
  • if, if
  • imag-part
  • import
  • inc!
  • inexact->exact
  • inexact?
  • info
  • initialize
  • input-port?
  • instance-of
  • integer->char
  • integer->digit
  • integer-length
  • integer-range->char-set
  • integer-range->char-set!
  • integer?
  • interaction-environment
  • iota
  • is-a?
  • isomorphic?
  • j

  • join-timeout-exception?
  • julian-day->date
  • julian-day->time-monotonic
  • julian-day->time-tai
  • julian-day->time-utc
  • k

  • keyword->string
  • keyword?
  • kmp-step
  • l

  • lambda
  • last
  • last-pair
  • lazy-size-of
  • lcm
  • ldexp
  • length
  • length+
  • let, let
  • let*
  • let*-values
  • let-keywords*
  • let-optionals*, let-optionals*
  • let-string-start+end
  • let-syntax
  • let-values
  • let1
  • letrec
  • letrec-syntax
  • list
  • list*
  • list->char-set
  • list->char-set!
  • list->f32vector
  • list->f64vector
  • list->queue
  • list->s16vector
  • list->s32vector
  • list->s64vector
  • list->s8vector
  • list->string
  • list->u16vector
  • list->u32vector
  • list->u64vector
  • list->u8vector
  • list->vector
  • list-copy
  • list-index
  • list-ref
  • list-tabulate
  • list-tail
  • list=
  • list?
  • listener-read-handler
  • listener-show-prompt
  • load
  • load-from-port
  • log
  • log-format, log-format
  • log-open
  • logand
  • logbit?
  • logcount
  • logior
  • lognot
  • logtest
  • logxor
  • lset-adjoin
  • lset-diff+intersection
  • lset-diff+intersection!
  • lset-difference
  • lset-difference!
  • lset-intersection
  • lset-intersection!
  • lset-union
  • lset-union!
  • lset-xor
  • lset-xor!
  • lset<=
  • lset=
  • m

  • macroexpand
  • macroexpand-1
  • magnitude
  • make, make, make, make, make, make
  • make-array
  • make-client-socket
  • make-condition-variable
  • make-csv-reader
  • make-csv-writer
  • make-date
  • make-directory*
  • make-f32vector
  • make-f64vector
  • make-hash-table
  • make-keyword
  • make-kmp-restart-vector
  • make-list
  • make-mutex
  • make-option-parser
  • make-parameter
  • make-polar
  • make-queue
  • make-random-source
  • make-rectangular
  • make-s16vector
  • make-s32vector
  • make-s64vector
  • make-s8vector
  • make-server-socket
  • make-socket
  • make-string
  • make-string-pointer
  • make-thread
  • make-time
  • make-u16vector
  • make-u32vector
  • make-u64vector
  • make-u8vector
  • make-vector
  • make-weak-vector
  • map, map
  • map!
  • map$, map$
  • map-in-order
  • map-to
  • max
  • member
  • member$
  • memq
  • memv
  • method-more-specific?
  • min
  • min&max
  • modf
  • modified-julian-day->date
  • modified-julian-day->time-monotonic
  • modified-julian-day->time-tai
  • modified-julian-day->time-utc
  • modifier
  • module-exports
  • module-imports
  • module-name
  • module-parents
  • module-precedence-list
  • module-reload-rules
  • module-table
  • module?
  • modulo
  • move-file
  • mt-random-fill-f32vector!
  • mt-random-fill-f64vector!
  • mt-random-fill-u32vector!
  • mt-random-get-state
  • mt-random-integer
  • mt-random-real
  • mt-random-real0
  • mt-random-set-seed!
  • mt-random-set-state!
  • mutex-lock!
  • mutex-name
  • mutex-specific
  • mutex-specific-set!
  • mutex-state
  • mutex-unlock!
  • mutex?
  • n

  • ndbm-clear-error
  • ndbm-close
  • ndbm-closed?
  • ndbm-delete
  • ndbm-error
  • ndbm-fetch
  • ndbm-firstkey
  • ndbm-nextkey
  • ndbm-open
  • ndbm-store
  • negative?
  • newline
  • next-token
  • next-token-of
  • ninth
  • not
  • not-pair?
  • null-environment
  • null-list?
  • null?
  • number->string
  • number?
  • numerator
  • o

  • object-apply
  • object-compare
  • object-equal?
  • object-isomorphic?
  • odbm-close
  • odbm-delete
  • odbm-fetch
  • odbm-firstkey
  • odbm-init
  • odbm-nextkey
  • odbm-store
  • odd?
  • open-input-buffered-port
  • open-input-conversion-port
  • open-input-fd-port
  • open-input-file, open-input-file
  • open-input-process-port
  • open-input-string
  • open-output-buffered-port
  • open-output-conversion-port
  • open-output-fd-port
  • open-output-file, open-output-file
  • open-output-process-port
  • open-output-string
  • or
  • output-port?
  • p

  • pa$
  • pair-fold
  • pair-fold-right
  • pair-for-each
  • pair?
  • parameterize
  • parse-cookie-string
  • parse-options
  • partition, partition
  • partition!
  • partition$
  • partition-to
  • peek-char
  • peek-next-char
  • pop!
  • port->list
  • port->sexp-list
  • port->string
  • port->string-list
  • port-buffering
  • port-closed?
  • port-current-line
  • port-file-number
  • port-fold
  • port-fold-right
  • port-for-each
  • port-map
  • port-name
  • port-type
  • port?
  • positive?
  • print
  • procedure-arity-includes?
  • procedure?
  • process-alive?
  • process-command
  • process-continue
  • process-error
  • process-input
  • process-kill
  • process-list
  • process-output
  • process-output->string
  • process-output->string-list
  • process-pid
  • process-send-signal
  • process-stop
  • process-wait
  • process?
  • proper-list?
  • provide
  • provided?
  • push!
  • q

  • quasiquote
  • queue->list
  • queue-empty?
  • queue-front
  • queue-length
  • queue-pop!
  • queue-push!
  • queue-rear
  • queue?
  • quote
  • quoted-printable-decode
  • quoted-printable-decode-string
  • quoted-printable-encode
  • quoted-printable-encode-string
  • quotient
  • quotient&remainder
  • r

  • raise
  • random-integer
  • random-real
  • random-source-make-integers
  • random-source-make-reals
  • random-source-pseudo-randomize!
  • random-source-randomize!
  • random-source-state-ref
  • random-source-state-set!
  • random-source?
  • rational?
  • read
  • read-block
  • read-block!
  • read-byte
  • read-char
  • read-eval-print-loop
  • read-from-string
  • read-line
  • read-string
  • real-part
  • real?
  • receive
  • reduce
  • reduce$
  • reduce-right
  • reduce-right$
  • ref
  • referencer
  • regexp->string
  • regexp-replace
  • regexp-replace-all
  • regexp?
  • relative-path?
  • relnum-compare
  • reload
  • reload-modified-modules
  • reload-verbose
  • remainder
  • remove, remove
  • remove!
  • remove$
  • remove-directory*
  • remove-from-queue!
  • remove-to
  • require
  • resolve-path
  • reverse
  • reverse!
  • reverse-list->string
  • rfc822-header->list
  • rfc822-parse-date
  • round
  • run-process
  • rxmatch
  • rxmatch-after
  • rxmatch-before
  • rxmatch-case
  • rxmatch-cond
  • rxmatch-end
  • rxmatch-if
  • rxmatch-let
  • rxmatch-start
  • rxmatch-substring
  • s

  • s16vector
  • s16vector->list
  • s16vector->vector
  • s16vector-add
  • s16vector-add!
  • s16vector-and
  • s16vector-and!
  • s16vector-clamp
  • s16vector-clamp!
  • s16vector-copy
  • s16vector-copy!
  • s16vector-dot
  • s16vector-ior
  • s16vector-ior!
  • s16vector-length
  • s16vector-mul
  • s16vector-mul!
  • s16vector-range-check
  • s16vector-ref
  • s16vector-set!
  • s16vector-sub
  • s16vector-sub!
  • s16vector-xor
  • s16vector-xor!
  • s16vector?
  • s32vector
  • s32vector->list
  • s32vector->string
  • s32vector->vector
  • s32vector-add
  • s32vector-add!
  • s32vector-and
  • s32vector-and!
  • s32vector-clamp
  • s32vector-clamp!
  • s32vector-copy
  • s32vector-copy!
  • s32vector-dot
  • s32vector-ior
  • s32vector-ior!
  • s32vector-length
  • s32vector-mul
  • s32vector-mul!
  • s32vector-range-check
  • s32vector-ref
  • s32vector-set!
  • s32vector-sub
  • s32vector-sub!
  • s32vector-xor
  • s32vector-xor!
  • s32vector?
  • s64vector
  • s64vector->list
  • s64vector->vector
  • s64vector-add
  • s64vector-add!
  • s64vector-and
  • s64vector-and!
  • s64vector-clamp
  • s64vector-clamp!
  • s64vector-copy
  • s64vector-copy!
  • s64vector-dot
  • s64vector-ior
  • s64vector-ior!
  • s64vector-length
  • s64vector-mul
  • s64vector-mul!
  • s64vector-range-check
  • s64vector-ref
  • s64vector-set!
  • s64vector-sub
  • s64vector-sub!
  • s64vector-xor
  • s64vector-xor!
  • s64vector?
  • s8vector
  • s8vector->list
  • s8vector->string
  • s8vector->vector
  • s8vector-add
  • s8vector-add!
  • s8vector-and
  • s8vector-and!
  • s8vector-clamp
  • s8vector-clamp!
  • s8vector-copy
  • s8vector-copy!
  • s8vector-dot
  • s8vector-ior
  • s8vector-ior!
  • s8vector-length
  • s8vector-mul
  • s8vector-mul!
  • s8vector-range-check
  • s8vector-ref
  • s8vector-set!
  • s8vector-sub
  • s8vector-sub!
  • s8vector-xor
  • s8vector-xor!
  • s8vector?
  • scheme-report-environment
  • second
  • seconds->time
  • select-module
  • selector-add!
  • selector-delete!
  • selector-select
  • set!, set!
  • set!-values
  • set-car!
  • set-cdr!
  • set-signal-handler!
  • set-time-nanosecond!
  • set-time-second!
  • set-time-type!
  • setter
  • seventh
  • shape
  • shape-for-each
  • share-array
  • simplify-path
  • sin
  • sinh
  • sixth
  • size-of
  • skip-until
  • skip-while
  • slot-bound?
  • slot-defininion-setter
  • slot-definition-accessor
  • slot-definition-allocation
  • slot-definition-getter
  • slot-definition-name
  • slot-definition-option
  • slot-definition-options
  • slot-exists?
  • slot-missing, slot-missing
  • slot-ref
  • slot-ref-using-accessor
  • slot-set!
  • slot-set-using-accessor
  • slot-unbound, slot-unbound
  • sockaddr-family, sockaddr-family, sockaddr-family
  • sockaddr-name, sockaddr-name, sockaddr-name
  • socket-accept
  • socket-address
  • socket-bind
  • socket-close
  • socket-connect
  • socket-fd
  • socket-getsockopt
  • socket-input-port
  • socket-listen
  • socket-output-port
  • socket-setsockopt
  • socket-shutdown
  • socket-status
  • sort
  • sort!
  • sort-applicable-methods
  • span
  • span!
  • split-at
  • split-at!
  • sqrt
  • standard-error-port
  • standard-input-port
  • standard-output-port
  • string
  • string->char-set
  • string->char-set!
  • string->date
  • string->list
  • string->number
  • string->regexp
  • string->s32vector
  • string->s8vector
  • string->symbol
  • string->u32vector
  • string->u8vector
  • string-any
  • string-append
  • string-append/shared
  • string-byte-ref
  • string-byte-set!
  • string-ci<
  • string-ci<=
  • string-ci<=?
  • string-ci<>
  • string-ci<?
  • string-ci=
  • string-ci=?
  • string-ci>
  • string-ci>=
  • string-ci>=?
  • string-ci>?
  • string-compare
  • string-compare-ci
  • string-complete->incomplete
  • string-concatenate
  • string-concatenate-reverse
  • string-concatenate-reverse/shared
  • string-concatenate/shared
  • string-contains
  • string-contains-ci
  • string-copy
  • string-copy!
  • string-count
  • string-delete
  • string-downcase
  • string-downcase!
  • string-drop
  • string-drop-right
  • string-every
  • string-fill!
  • string-filter
  • string-fold
  • string-fold-right
  • string-for-each
  • string-for-each-index
  • string-hash
  • string-hash-ci
  • string-immutable?
  • string-incomplete->complete
  • string-incomplete?
  • string-index
  • string-index-right
  • string-join
  • string-kmp-partial-search
  • string-length
  • string-map
  • string-map!
  • string-null?
  • string-pad
  • string-pad-right
  • string-parse-final-start+end
  • string-parse-start+end
  • string-pointer-byte-index
  • string-pointer-copy
  • string-pointer-index
  • string-pointer-next!
  • string-pointer-prev!
  • string-pointer-set!
  • string-pointer-substring
  • string-pointer?
  • string-prefix-ci?
  • string-prefix-length
  • string-prefix-length-ci
  • string-prefix?
  • string-ref
  • string-replace
  • string-reverse
  • string-reverse!
  • string-scan
  • string-set!
  • string-size
  • string-skip
  • string-skip-right
  • string-split
  • string-suffix-ci?
  • string-suffix-length
  • string-suffix-length-ci
  • string-suffix?
  • string-tabulate
  • string-take
  • string-take-right
  • string-titlecase
  • string-titlecase!
  • string-tokenize
  • string-tr
  • string-trim
  • string-trim-both
  • string-trim-right
  • string-unfold
  • string-unfold-right
  • string-upcase
  • string-upcase!
  • string-xcopy!
  • string<
  • string<=
  • string<=?
  • string<>
  • string<?
  • string=
  • string=?
  • string>
  • string>=
  • string>=?
  • string>?
  • string?
  • subseq
  • substring
  • substring-spec-ok?
  • substring/shared
  • subtract-duration
  • subtract-duration!
  • supported-character-encodings
  • symbol->string
  • symbol?
  • syntax-error
  • syntax-errorf
  • syntax-rules
  • sys-abort
  • sys-access
  • sys-alarm
  • sys-asctime
  • sys-basename
  • sys-cfgetispeed
  • sys-cfgetospeed
  • sys-cfsetispeed
  • sys-cfsetospeed
  • sys-chdir
  • sys-chmod
  • sys-chown
  • sys-closelog
  • sys-crypt
  • sys-ctermid
  • sys-ctime
  • sys-difftime
  • sys-dirname
  • sys-exec
  • sys-exit
  • sys-fcntl
  • sys-fdset-max-fd
  • sys-fdset-ref
  • sys-fdset-set!
  • sys-fork
  • sys-forkpty
  • sys-fstat
  • sys-getcwd
  • sys-getdomainname
  • sys-getegid
  • sys-getenv
  • sys-geteuid
  • sys-getgid
  • sys-getgrgid
  • sys-getgrnam
  • sys-getgroups
  • sys-gethostbyaddr
  • sys-gethostbyname
  • sys-gethostname
  • sys-getlogin
  • sys-getpgid
  • sys-getpgrp
  • sys-getpid
  • sys-getppid
  • sys-getprotobyname
  • sys-getprotobynumber
  • sys-getpwnam
  • sys-getpwuid
  • sys-getservbyname
  • sys-getservbyport
  • sys-gettimeofday
  • sys-getuid
  • sys-gid->group->name
  • sys-glob
  • sys-gmtime
  • sys-group-name->gid
  • sys-isatty
  • sys-kill
  • sys-link
  • sys-localeconv
  • sys-localtime
  • sys-logmask
  • sys-lstat
  • sys-mkdir
  • sys-mkfifo
  • sys-mkstemp
  • sys-mktime
  • sys-nanosleep
  • sys-normalize-pathname
  • sys-openlog
  • sys-openpty
  • sys-pause
  • sys-pipe
  • sys-putenv
  • sys-random
  • sys-readdir
  • sys-readlink
  • sys-remove
  • sys-rename
  • sys-rmdir
  • sys-select
  • sys-select!
  • sys-setgid
  • sys-setlocate
  • sys-setlogmask
  • sys-setpgid
  • sys-setsid
  • sys-setuid
  • sys-sigmask
  • sys-signal-name
  • sys-sigset-add!
  • sys-sigset-delete!
  • sys-sigset-empty!
  • sys-sigset-fill!
  • sys-sigsuspend
  • sys-sleep
  • sys-srandom
  • sys-stat
  • sys-stat->atime
  • sys-stat->ctime
  • sys-stat->dev
  • sys-stat->file-type
  • sys-stat->gid
  • sys-stat->ino
  • sys-stat->mode
  • sys-stat->mtime
  • sys-stat->nlink
  • sys-stat->rdev
  • sys-stat->size
  • sys-stat->uid
  • sys-strftime
  • sys-symlink
  • sys-syslog
  • sys-system
  • sys-tcdrain
  • sys-tcflow
  • sys-tcflush
  • sys-tcgetattr
  • sys-tcgetpgrp
  • sys-tcsendbreak
  • sys-tcsetattr
  • sys-tcsetpgrp
  • sys-time
  • sys-times
  • sys-tm->alist
  • sys-tmpnam
  • sys-ttyname
  • sys-uid->user-name
  • sys-umask
  • sys-uname
  • sys-unlink
  • sys-user-name->uid
  • sys-utime
  • sys-wait
  • sys-wait-exit-status
  • sys-wait-exited?
  • sys-wait-signaled?
  • sys-wait-stopped?
  • sys-wait-stopsig
  • sys-wait-termsig
  • sys-waitpid
  • t

  • tabulate-array
  • take
  • take!
  • take-right
  • take-while
  • take-while!
  • tan
  • tanh
  • tenth
  • terminated-thread-exception?
  • test
  • test-end
  • test-section
  • test-start
  • third
  • thread-join!
  • thread-name
  • thread-sleep!
  • thread-specific
  • thread-specific-set!
  • thread-start!
  • thread-terminate!
  • thread-yield!
  • thread?
  • time
  • time->seconds
  • time-counter-reset!
  • time-counter-start!
  • time-counter-stop!
  • time-counter-value
  • time-difference
  • time-difference!
  • time-monotonic->date
  • time-monotonic->julian-day
  • time-monotonic->modified-julian-day
  • time-monotonic->time-tai
  • time-monotonic->time-tai!
  • time-monotonic->time-utc
  • time-monotonic->time-utc!
  • time-nanosecond
  • time-resolution
  • time-second
  • time-tai->date
  • time-tai->julian-day
  • time-tai->modified-julian-day
  • time-tai->time-monotonic
  • time-tai->time-monotonic!
  • time-tai->time-utc
  • time-tai->time-utc!
  • time-type
  • time-utc->date
  • time-utc->julian-day
  • time-utc->modified-julian-day
  • time-utc->time-monotonic
  • time-utc->time-monotonic!
  • time-utc->time-tai
  • time-utc->time-tai!
  • time<=?
  • time<?
  • time=?
  • time>=?
  • time>?
  • time?
  • topological-sort
  • touch-file
  • tr
  • tree->string
  • truncate
  • u

  • u16vector
  • u16vector->list
  • u16vector->vector
  • u16vector-add
  • u16vector-add!
  • u16vector-and
  • u16vector-and!
  • u16vector-clamp
  • u16vector-clamp!
  • u16vector-copy
  • u16vector-copy!
  • u16vector-dot
  • u16vector-ior
  • u16vector-ior!
  • u16vector-length
  • u16vector-mul
  • u16vector-mul!
  • u16vector-range-check
  • u16vector-ref
  • u16vector-set!
  • u16vector-sub
  • u16vector-sub!
  • u16vector-xor
  • u16vector-xor!
  • u16vector?
  • u32vector
  • u32vector->list
  • u32vector->string
  • u32vector->vector
  • u32vector-add
  • u32vector-add!
  • u32vector-and
  • u32vector-and!
  • u32vector-clamp
  • u32vector-clamp!
  • u32vector-copy
  • u32vector-copy!
  • u32vector-dot
  • u32vector-ior
  • u32vector-ior!
  • u32vector-length
  • u32vector-mul
  • u32vector-mul!
  • u32vector-range-check
  • u32vector-ref
  • u32vector-set!
  • u32vector-sub
  • u32vector-sub!
  • u32vector-xor
  • u32vector-xor!
  • u32vector?
  • u64vector
  • u64vector->list
  • u64vector->vector
  • u64vector-add
  • u64vector-add!
  • u64vector-and
  • u64vector-and!
  • u64vector-clamp
  • u64vector-clamp!
  • u64vector-copy
  • u64vector-copy!
  • u64vector-dot
  • u64vector-ior
  • u64vector-ior!
  • u64vector-length
  • u64vector-mul
  • u64vector-mul!
  • u64vector-range-check
  • u64vector-ref
  • u64vector-set!
  • u64vector-sub
  • u64vector-sub!
  • u64vector-xor
  • u64vector-xor!
  • u64vector?
  • u8vector
  • u8vector->list
  • u8vector->string
  • u8vector->vector
  • u8vector-add
  • u8vector-add!
  • u8vector-and
  • u8vector-and!
  • u8vector-clamp
  • u8vector-clamp!
  • u8vector-copy
  • u8vector-copy!
  • u8vector-dot
  • u8vector-ior
  • u8vector-ior!
  • u8vector-length
  • u8vector-mul
  • u8vector-mul!
  • u8vector-range-check
  • u8vector-ref
  • u8vector-set!
  • u8vector-sub
  • u8vector-sub!
  • u8vector-xor
  • u8vector-xor!
  • u8vector?
  • ucs->char
  • ucs-range->char-set
  • ucs-range->char-set!
  • uncaught-exception-reason
  • uncaught-exception?
  • unfold
  • unfold-right
  • unless
  • unwrap-syntax
  • unzip1
  • unzip2
  • unzip3
  • unzip4
  • unzip5
  • update!
  • uri-compose
  • uri-decode
  • uri-decode-string
  • uri-decompose-authority
  • uri-decompose-hierarchical
  • uri-encode
  • uri-encode-string
  • uri-scheme&specific
  • use
  • uvector-alias
  • v

  • values
  • vector
  • vector->f32vector
  • vector->f64vector
  • vector->list
  • vector->s16vector
  • vector->s32vector
  • vector->s64vector
  • vector->s8vector
  • vector->u16vector
  • vector->u32vector
  • vector->u64vector
  • vector->u8vector
  • vector-copy
  • vector-fill!
  • vector-length
  • vector-ref
  • vector-set!
  • vector?
  • version-compare
  • version<=?
  • version<?
  • version=?
  • version>=?
  • version>?
  • w

  • weak-vector-length
  • weak-vector-ref
  • weak-vector-set!
  • when
  • with-builder
  • with-error-handler
  • with-error-to-port
  • with-exception-handler
  • with-input-from-file, with-input-from-file
  • with-input-from-port
  • with-input-from-process
  • with-input-from-string
  • with-iterator
  • with-module
  • with-output-to-file, with-output-to-file
  • with-output-to-port
  • with-output-to-process
  • with-output-to-string
  • with-signal-handlers
  • with-string-io
  • with-time-counter
  • write
  • write*
  • write-block
  • write-byte
  • write-char
  • write-object
  • write-to-string
  • write-tree, write-tree, write-tree
  • x

  • x->integer
  • x->number
  • x->string
  • xcons
  • xsubstring
  • z

  • zero?
  • zip
  • C.2 モジュール索引

    Jump to: d - f - g - m - n - r - s - t - u - w

    d

  • dbm
  • dbm.gdbm
  • dbm.ndbm
  • dbm.odbm
  • f

  • file.filter
  • file.util
  • g

  • gauche
  • gauche.array
  • gauche.charconv
  • gauche.collection
  • gauche.config
  • gauche.fcntl
  • gauche.interactive
  • gauche.listener
  • gauche.logger
  • gauche.mop.singleton
  • gauche.mop.validator
  • gauche.net
  • gauche.parameter
  • gauche.parseopt
  • gauche.process
  • gauche.regexp
  • gauche.reload
  • gauche.selector
  • gauche.sequence
  • gauche.syslog
  • gauche.termios
  • gauche.test
  • gauche.threads
  • gauche.time
  • gauche.uvector
  • gauche.version
  • m

  • math.const
  • math.mt-random
  • n

  • null
  • r

  • rfc.822
  • rfc.base64
  • rfc.cookie
  • rfc.http
  • rfc.quoted-printable
  • rfc.uri
  • s

  • scheme
  • slib
  • srfi-0
  • srfi-1
  • srfi-11
  • srfi-13
  • srfi-14
  • srfi-2
  • srfi-27
  • srfi-4
  • srfi-9
  • t

  • text.csv
  • text.html-lite
  • text.parse
  • text.tr
  • text.tree
  • u

  • user
  • util.isomorph
  • util.queue
  • util.toposort
  • w

  • www.cgi
  • C.3 クラス索引

    For readability, the surrounding < and > are stripped off.

    Jump to: a - b - c - d - e - f - g - h - i - j - k - l - m - n - o - p - r - s - t - u - v - w

    a

  • abandoned-mutex-exception
  • array
  • b

  • boolean
  • c

  • char
  • char-set
  • class
  • complex
  • condition-variable
  • d

  • date
  • dbm
  • dbm-meta
  • e

  • exception
  • f

  • f32vector
  • f64vector
  • g

  • gdbm
  • generic
  • h

  • hash-table
  • i

  • identifier
  • integer
  • j

  • join-timeout-exception
  • k

  • keyword
  • l

  • list
  • log-drain
  • m

  • mersenne-twister
  • method
  • module
  • mutex
  • n

  • ndbm
  • null
  • number
  • o

  • object
  • odbm
  • p

  • pair
  • port
  • procedure
  • process
  • process-time-counter
  • r

  • real
  • real-time-counter
  • regexp
  • regmatch
  • s

  • s16vector
  • s32vector
  • s64vector
  • s8vector
  • selector
  • singleton-meta
  • singleton-mixin
  • slot-accessor
  • sockaddr
  • sockaddr-in
  • sockaddr-un
  • socket
  • string
  • string-pointer
  • symbol
  • sys-fdset
  • sys-flock
  • sys-group
  • sys-hostent
  • sys-passwd
  • sys-protoent
  • sys-servent
  • sys-sigset
  • sys-stat
  • sys-termios
  • sys-tm
  • system-time-counter
  • t

  • terminated-thread-exception
  • thread
  • thread-exception
  • time
  • time-counter
  • top
  • u

  • u16vector
  • u32vector
  • u64vector
  • u8vector
  • uncaught-exception
  • user-time-counter
  • v

  • validator-meta
  • vector
  • w

  • weak-vector
  • C.4 変数索引

    Jump to: * - 1 - a - b - c - d - e - f - g - h - i - k - l - m - n - o - p - r - s - t - u - v - w - x - y

    *

  • *argv*
  • *load-path*
  • *program-name*
  • 1

  • 1/pi
  • 180/pi
  • a

  • addresses
  • AF_INET
  • AF_UNIX
  • aliases, aliases, aliases
  • atime
  • b

  • bsize
  • c

  • cflag
  • char-set:ascii
  • char-set:blank
  • char-set:digit
  • char-set:empty
  • char-set:full
  • char-set:graphic
  • char-set:hex-digit
  • char-set:iso-control
  • char-set:letter
  • char-set:lower-case
  • char-set:printing
  • char-set:punctuation
  • char-set:symbol
  • char-set:title-case
  • char-set:upper-case
  • char-set:whitespace
  • class
  • ctime
  • d

  • default-random-source
  • dev
  • dir
  • e

  • e
  • environment
  • error-handler
  • error-port
  • evaluator
  • f

  • F_DUPFD
  • F_GETFD
  • F_GETFL
  • F_GETLK
  • F_OK
  • F_RDLCK
  • F_SETFD
  • F_SETFL
  • F_SETLK
  • F_SETLKW
  • F_UNLCK
  • F_WRLCK
  • FD_CLOEXEC
  • file-mode
  • finalizer
  • g

  • GDBM_CACHESIZE
  • GDBM_CENTFREE
  • GDBM_COALESCEBLKS
  • GDBM_FAST
  • GDBM_FASTMODE
  • GDBM_INSERT
  • GDBM_NEWDB
  • GDBM_NOLOCK
  • GDBM_READER
  • GDBM_REPLACE
  • GDBM_SYNC
  • GDBM_SYNCMODE
  • GDBM_WRCREAT
  • GDBM_WRITER
  • gecos
  • gid, gid, gid
  • h

  • hour
  • i

  • iflag
  • ino
  • input-port
  • isdst
  • k

  • key-convert
  • l

  • LC_ALL
  • LC_COLLATE
  • LC_CTYPE
  • LC_MONETARY
  • LC_NUMERIC
  • LC_TIME
  • len
  • lflag
  • m

  • mday
  • mem
  • message
  • min
  • mode
  • mon
  • mtime
  • mutex
  • n

  • name, name, name, name, name, name, name, name
  • nanosecond
  • nlink
  • nolock
  • o

  • O_ACCMODE
  • O_APPEND
  • O_CREAT
  • O_EXCL
  • O_NOCTTY
  • O_NONBLOCK
  • O_RDONLY
  • O_RDWR
  • O_TRUNC
  • O_WRONLY
  • oflag
  • output-port
  • p

  • passwd, passwd
  • path, path
  • perm
  • PF_INET
  • PF_UNIX
  • pi
  • pi/180
  • pi/2
  • pi/4
  • pid
  • port
  • prefix
  • printer
  • program-name
  • prompter
  • proto, proto
  • r

  • R_OK
  • RAND_MAX
  • rdev
  • reader
  • reason
  • rw-mode
  • s

  • sec
  • second
  • shell
  • SIGABRT
  • SIGALRM
  • SIGBUS
  • SIGCHLD
  • SIGCONT
  • SIGFPE
  • SIGHUP
  • SIGILL
  • SIGINT
  • SIGIO
  • SIGIOT
  • SIGKILL
  • SIGPIPE
  • SIGPOLL
  • SIGPROF
  • SIGPWR
  • SIGQUIT
  • SIGSEGV
  • SIGSTKFLT
  • SIGSTOP
  • SIGTERM
  • SIGTRAP
  • SIGTSTP
  • SIGTTIN
  • SIGTTOU
  • SIGURG
  • SIGUSR1
  • SIGUSR2
  • SIGVTALRM
  • SIGWINCH
  • SIGXCPU
  • SIGXFSZ
  • size
  • SO_BROADCAST
  • SO_ERROR
  • SO_KEEPALIVE
  • SO_OOBINLINE
  • SO_PRIORITY
  • SO_REUSEADDR
  • SO_TYPE
  • SOCK_DGRAM
  • SOCK_RAW
  • SOCK_STREAM
  • SOL_IP
  • SOL_SOCKET
  • SOL_TCP
  • specific, specific, specific
  • start
  • state
  • sync
  • syslog-facility
  • syslog-option
  • syslog-priority
  • t

  • TCIFLUSH
  • TCIOFF
  • TCIOFLUSH
  • TCION
  • TCOFLUSH
  • TCOOFF
  • TCOON
  • TCSADRAIN
  • TCSAFLUSH
  • TCSANOW
  • terminator
  • thread
  • time-duration
  • time-monotonic
  • time-process
  • time-tai
  • time-thread
  • time-utc
  • type, type, type
  • u

  • uid, uid
  • v

  • value-convert
  • w

  • W_OK
  • wday
  • whence
  • x

  • X_OK
  • y

  • yday
  • year

  • This document was generated on 29 November 2002 using texi2html 1.56k.