Library modules - Utilities
***************************

binary.io - Binary I/O
======================

 -- Module: binary.io
     This module provides basic procedures to perform binary I/O of numeric data.  Each datum can be read from or written to a port, and got from or put to a uniform vector (see Uniform vectors). For structured binary data I/O, more convenient pack utility is implemented on top of this module (see Packing binary data). You might want to use this module directly if you need speed or want a flexible control of endianness.

     See also Uniform vectors, which provides binary block I/O. このモジュールは数値データを読み書きするバイナリ入出力用の基本手続きを提供します。各データはポートあるいはユニフォームベクタ (Uniform vectors参照)から読み込み、あるいはそれらへ書き出すことができます。構造をもつバイナリデータの入出力については、便利な packユーティリティがこのモジュールを使って実装されています (Packing binary dataを参照してください)。スピードあるいはエンディアンの柔軟な制御などをやりたいときにこのモジュールが使えます。

     バイナリのブロック入出力についてはUniform vectorsを参照してください。

Endianness
----------

Most procedures of this module take an optional ENDIAN argument, specifying the byte order of the binary input. It must be either one of symbols big-endian, little-endian, or arm-little-endian. If the endian argument is omitted, the current value of the builtin parameter default-endian is used (see Endianness). (For 8-bit I/O procedures like read-u8 the endian argument has no effect, but is accepted for consistency).

エンディアン
------

このモジュールのほとんどの手続はオプション引数としてENDIAN引数をとります。これはbig-endian、little-endian、 arm-little-endianのいずれかのシンボルでなければなりません。エンディアン引数が省略された場合には、組込みパラメータdefault-endian の現在値が使われます (Endianness参照)。 (read-u8の ような 8ビット入出力手続ではエンディアン引数は意味がありませんが、一貫性のため受け入れるようにしてあります。)

I/O using port
--------------

ポートを用いたI/O
----------

 -- Function: read-u8 :optional port endian
 -- Function: read-u16 :optional port endian
 -- Function: read-u32 :optional port endian
 -- Function: read-u64 :optional port endian
     Reads 8, 16, 32 or 64 bit unsigned integer from PORT with specified endian, respectively.  If PORT is omitted, current input port is used.  If PORT reaches EOF before a complete integer is read, EOF is returned. それぞれ指定したエンディアンでPORTから8、16、32、64ビット符号無整数を読み込みます。PORTが省略された場合は、現在の入力ポートが使われます。PORTが整数の読み込みが完了する前にEOFに到達してしまった場合にはEOFが返ります。

 -- Function: read-s8 :optional port endian
 -- Function: read-s16 :optional port endian
 -- Function: read-s32 :optional port endian
 -- Function: read-s64 :optional port endian
     Reads 8, 16, 32 or 64 bit 2's complement signed integer from PORT with specified endian, respectively.  If PORT is omitted, current input port is used.  If PORT reaches EOF before a complete integer is read, EOF is returned. それぞれ指定したエンディアンでPORTから8、16、32、64ビット、2の補数符号付き整数を読み込みます。PORTが省略された場合は、現在の入力ポートが使われます。PORTが整数の読み込みが完了する前にEOFに到達してしまった場合にはEOFが返ります。

 -- Function: read-uint size :optional port endian
 -- Function: read-sint size :optional port endian
     More flexible version.  Reads SIZE-octet unsigned or signed integer from PORT with specified endian. If PORT reaches EOF before a complete integer is read, EOF is returned. さらに柔軟性が高く、SIZEオクテットの符号無しあるいは符号付き整数をPORTから指定のエンディアンで読み込みます。 PORTが整数の読み込みが完了する前にEOFに到達してしまった場合にはEOFが返ります。

 -- Function: read-ber-integer :optional port
     Reads BER compressed integer a la X.209. A BER compressed integer is an unsigned integer in base 128, most  significant digit first, where the high bit is set on all but the final (least significant) byte. X.209のBER圧縮形式整数を読み込みます。BER圧縮形式整数は128進符号無し整数です。最上位桁が最初にきます。最下位桁のバイトをのぞき、すべてのバイトの最上位ビットはオンになっています。

 -- Function: write-u8 val :optional port endian
 -- Function: write-u16 val :optional port endian
 -- Function: write-u32 val :optional port endian
 -- Function: write-u64 val :optional port endian
     Writes a nonnegative integer VAL as 8, 16, 32 or 64 bit unsigned integer to PORT with specified endian, respectively.  VAL must be within the range of integers representable by the specified bits. When PORT is omitted, current output port is used. それぞれ指定したエンディアンでPORTへ 8、16、32、64ビット、符号無し整数として表現されている非負整数VALを書き出します。 VALはそれぞれ指定したビット数の範囲で表現できる値でなければなりません。PORTが省略された場合は、現在の出力ポートが使われます。

 -- Function: write-s8 val :optional port endian
 -- Function: write-s16 val :optional port endian
 -- Function: write-s32 val :optional port endian
 -- Function: write-s64 val :optional port endian
     Writes an integer VAL as 8, 16, 32 or 64 bit as 2's complement signed integer to PORT with specified endian, respectively.  VAL must be within the range of integers representable by the specified bits. When PORT is omitted, current output port is used. それぞれ指定したエンディアンでPORTへ 8、16、32、64ビット、2の補数符号付き整数として表現されている整数VALを書き出します。 VALはそれぞれ指定したビット数の範囲で表現できる値でなければなりません。PORTが省略された場合は、現在の出力ポートが使われます。

 -- Function: write-uint size val :optional port endian
 -- Function: write-sint size val :optional port endian
     More flexible version.  Writes an integer VAL as unsigned or signed integer of SIZE bytes to PORT with specified endian. When PORT is omitted, current output port is used. さらに柔軟性が高く、SIZEオクテットの符号無しあるいは符号付き整数 VALをPORTへ、指定のエンディアンで書き出します。 PORTが省略された場合は、現在の出力ポートが使われます。

 -- Function: write-ber-integer val :optional port
     Writes a nonnegative integer VAL in BER compressed integer to PORT.  See read-ber-integer above for BER format. BER圧縮形式の非負整数VALをPORTへ書き出します。 BER圧縮形式については前述のread-ber-integerを見てください。

 -- Function: read-f16 :optional port endian
 -- Function: read-f32 :optional port endian
 -- Function: read-f64 :optional port endian
     Reads 16, 32, or 64-bit floating point numbers, respectively. 32bit is IEEE754 single-precision, and 64bit is IEEE754 double-precision numbers.  16-bit floating point number consists of 1-bit sign, 5-bit exponent and 10-bit mantissa, as used in some HDR image format.

     If PORT is omitted, current input port is used.  If PORT reaches EOF before a complete number is read, EOF is returned. それぞれ、16、32、64ビットの浮動小数点数を読み込みます。 32ビットはIEEE754単精度、64ビットは倍精度の浮動小数点数です。 16ビット浮動小数点数は、1ビットの符号、5ビットの指数、10ビットの仮数からなる、 HDRイメージフォーマット等に使われている形式です。

     PORTが省略された場合には、現在の入力ポートが使われます。PORTが数値の読み込みが完了する前に EOFに到達してしまった場合にはEOFが返ります。

 -- Function: write-f16 val :optional port endian
 -- Function: write-f32 val :optional port endian
 -- Function: write-f64 val :optional port endian
     Writes a real number VAL to PORT in 16, 32, or 64-bit floating point number, respectively. If PORT is omitted, current output port is used. 実数値VALを、それぞれ16、32、64ビットの浮動小数点数として書き出します。 PORTが省略された場合には、現在の出力ポートが使われます。

I/O using uniform vectors
-------------------------

ユニフォームベクタを用いたI/O
----------------

In the following routines, the argument UV can be any type of uniform vector; if it is not a u8vector, it is treated as if (uvector-alias <u8vector> UV) is called---that is, it reads directly from the memory image that holds the uvector's content.  The POS argument specifies the byte position from the beginning of the memory area (it is always byte position, regardless of the uniform vector's element size). 以下のルーチンでは、引数 UV は任意の型のユニフォームベクタをとりえます。u8vector ではない場合には (uvector-alias <u8vector> UV) が呼ばれたのと同様の扱いになります。すなわち、 uvectorの内容を保持するメモリイメージから直接読み込まれます。POS 引数は当該のメモリ領域の最初からのバイト位置を指定するのに使います(これはユニフォームベクタの要素のサイズにかかわらず、つねにバイト位置です)。

 -- Function: get-u8 uv pos :optional endian
 -- Function: get-u16 uv pos :optional endian
 -- Function: get-u32 uv pos :optional endian
 -- Function: get-u64 uv pos :optional endian
 -- Function: get-s8 uv pos :optional endian
 -- Function: get-s16 uv pos :optional endian
 -- Function: get-s32 uv pos :optional endian
 -- Function: get-s64 uv pos :optional endian
 -- Function: get-f16 uv pos :optional endian
 -- Function: get-f32 uv pos :optional endian
 -- Function: get-f64 uv pos :optional endian
     Reads a number of a specific format from a uniform vector UV, starting at a byte position POS.  An error is signaled if the specified position makes reference outside of the uniform vector's content.  Returns the read number. ユニフォームベクタ UV のバイト位置 POS から指定したフォーマットで数値を読み込み、その数値を返します。指定した位置が当該ユニフォームベクタの内容のある範囲外を参照するものであった場合、エラーを示すシグナルがあがります。

 -- Function: get-u16be uv pos
 -- Function: get-u16le uv pos
 -- Function: get-u32be uv pos
 -- Function: get-u32le uv pos
 -- Function: get-u64be uv pos
 -- Function: get-u64le uv pos
 -- Function: get-s16be uv pos
 -- Function: get-s16le uv pos
 -- Function: get-s32be uv pos
 -- Function: get-s32le uv pos
 -- Function: get-s64be uv pos
 -- Function: get-s64le uv pos
 -- Function: get-f16be uv pos
 -- Function: get-f16le uv pos
 -- Function: get-f32be uv pos
 -- Function: get-f32le uv pos
 -- Function: get-f64be uv pos
 -- Function: get-f64le uv pos
     These are big-endian (be) or little-endian (le) specific versions of get-* procedures.  In speed-sensitive code, you might want to use these to avoid the overhead of optional-argument handling. これらは、get-* 手続のエンディアン(ビッグエンディアン be あるいはリトルエンディアン le)を指定した版です。スピードを要求されるコードではオプション引数処理のオーバーヘッドを避けるためこちらを使うのがいいでしょう。

 -- Function: get-uint size uv pos :optional endian
 -- Function: get-sint size uv pos :optional endian
     Read SIZE octets from uvector UV, starting from POS-th octet, as an unsigned or signed integer, respectively. ユニフォームベクタUVのPOS番目のオクテットからSIZEオクテットを、それぞれ符号無し、符号つき整数として読み取ります。

          (get-uint 3 '#u8(1 2 3 4) 1 'big-endian)
            => 131884 ; #x020304

          (get-sint 3 '#u9(1 2 3 #xff) 1 'little-endian)
            => -64766 ; sign extended #xff0302

 -- Function: put-u8! uv pos val :optional endian
 -- Function: put-u16! uv pos val :optional endian
 -- Function: put-u32! uv pos val :optional endian
 -- Function: put-u64! uv pos val :optional endian
 -- Function: put-s8! uv pos val :optional endian
 -- Function: put-s16! uv pos val :optional endian
 -- Function: put-s32! uv pos val :optional endian
 -- Function: put-s64! uv pos val :optional endian
 -- Function: put-f16! uv pos val :optional endian
 -- Function: put-f32! uv pos val :optional endian
 -- Function: put-f64! uv pos val :optional endian
     Writes a number VAL into a uniform vector UV in a specific format, starting at a byte position POS. An error is signaled if the specified position makes reference outside of the uniform vector's content. 数値 VAL をユニフォームベクタ UV のバイト位置 POS から指定されたフォーマットで書き出します。指定した位置が当該ユニフォームベクタの内容のある範囲外を参照するものであった場合、エラーを示すシグナルがあがります。

 -- Function: put-u16be! uv pos val
 -- Function: put-u16le! uv pos val
 -- Function: put-u32be! uv pos val
 -- Function: put-u32le! uv pos val
 -- Function: put-u64be! uv pos val
 -- Function: put-u64le! uv pos val
 -- Function: put-s16be! uv pos val
 -- Function: put-s16le! uv pos val
 -- Function: put-s32be! uv pos val
 -- Function: put-s32le! uv pos val
 -- Function: put-s64be! uv pos val
 -- Function: put-s64le! uv pos val
 -- Function: put-f16be! uv pos val
 -- Function: put-f16le! uv pos val
 -- Function: put-f32be! uv pos val
 -- Function: put-f32le! uv pos val
 -- Function: put-f64be! uv pos val
 -- Function: put-f64le! uv pos val
     These are big-endian (be) or little-endian (le) specific versions of put-* procedures.  In speed-sensitive code, you might want to use these to avoid the overhead of optional-argument handling. これらは、put-* 手続のエンディアン(ビッグエンディアン be あるいはリトルエンディアン le)を指定した版です。スピードを要求されるコードではオプション引数処理のオーバーヘッドを避けるためこちらを使うのがいいでしょう。

 -- Function: put-uint! size uv pos val :optional endian
 -- Function: put-sint! size uv pos val :optional endian
     Write an unsigned or signed integer VAL into an uvector UV starting from POS-th octet, for SIZE octets, respectively. それぞれ符号無しまたは符号つき整数VALを、ユニフォームベクタUVのPOS番目のオクテットからSIZEオクテット分に書き込みます。

Compatibility notes
-------------------

互換性への注
------

read-u8 etc. were called read-binary-uint8 etc., and read-f32 and read-f64 were called read-binary-float and read-binary-double, respectively. These old names are still supported for the backward compatibility but their use is deprecated.  The reason of the changes is for brevity and for consistency with the uniform vectors. read-u8 などは read-binary-uint8 と呼ばれていたもので、 read-f32 や read-f64 はそれぞれ read-binary-float、 read-binary-double と呼ばれていたものです。これらの古い名前は後方互換のためいまのところサポートされていますが、使用については非推奨とします。この変更は名前の短縮とユニフォームベクタとの一貫性維持のために行われました。

binary.pack - Packing binary data
=================================

 -- Module: binary.pack
     This module provides an interface for packing and unpacking (writing and reading) binary data with templates.  The functionality was inspired largely by the Perl pack/unpack functions, with comparison of similar features from other languages, however an effort was made to make it more general and more efficient, to be usable for database-like processing.  To that end, the most notable differences are that any packable value is unpackable (and vice versa), and the default behavior is to pack and unpack using port I/O, so you can seek in a large file and unpack from it.  Also, templates may be stored as dispatch closures to pack, unpack or even skip over values without re-parsing the template. このモジュールは、バイナリデータをテンプレートを使ってパック/アンパック(読み書き)するためのインタフェースを提供します。この機能は、その多くをPerlのpack/unpack関数から着想し、他の言語での同じような機能と比較しながら、しかし、データベースライクな処理に便利なように、より一般的でより効率が良くなるように実装しました。これを受けて、最も大きな相違点は、全てのパック可能な値はアンパック可能で(逆も同様)、パック/アンパックのデフォルトの振る舞いはポートI/Oを使うので、巨大なファイルを読みながらそこからアンパックすることができます。また、テンプレートはディスパッチクロージャとして格納でき、パック、アンパック、あるいは値のスキップさえも、テンプレートをパーズし直すことなく行えます。

 -- Function: pack template list :key output to-string?
     Writes the values in LIST to the current output port, according to the format specified by the string TEMPLATE.  The template string is a series of single character codes, optionally followed by a numeric count (which defaults to 1). LISTにある値を、文字列TEMPLATEで指定されたフォーマットにしたがって、現在の出力ポートに書き出します。テンプレート文字列は、 1文字のコードの連続で、オプションで(デフォルトが1である)カウント用の数字が続きます。

     The format characters can generally be divided into string types, which interpret the count as a string byte size, and object types, which treat the count as a repetition indicator.  The count may be specified as the character *, which means to use the full size of the string for string types, and use all remaining values for object types. フォーマット文字は一般的に、カウントを文字のバイト数と解釈する文字列型と、カウントを繰り返し指示子と解釈するオブジェクト型に分けられます。カウントは文字*で指定され、文字列型では文字列の全体の長さを、オブジェクト型では残りの全ての値を使うことを意味します。

     Counts may also be specified as a template enclosed in brackets, which means the count is the byte size of the enclosed template.  For example, x[L] skips a long. カウントは大括弧に囲まれたテンプレートとしても指定でき、その場合カウントはその大括弧を囲んでいるテンプレートのバイト数を意味します。例えば、x[L]はlongをスキップします。

     The special format character / may be used to indicate a structure where the packed data contains a dynamic count followed by the value itself.  The template is written as <count-item>/<value-item>, where <count-item> is any template character to be interpreted as a numeric count, and <value-item> is any other template character to use this count. If a normal count is given after <value-item> it is ignored. 特別なフォーマット文字/は、パックされたデータが、値に続く動的なカウント分を含むという構造を表すために使われます。テンプレートは、<count-item>/<value-item>のように書かれ、ここでは<count-item>は数値のカウントと解釈されるいかなるテンプレート文字、<value-item>はこのカウントを使ういかなる他のテンプレート文字です。 <value-item>の後に通常のカウントが与えられても、無視されます。

     The format character @ may be used with a count to pad to an absolute position since the start of the template. フォーマット文字@は、カウントとともに使われ、テンプレートの最初からの絶対位置までパディングします。

     Sub-templates may be grouped inside parentheses.  If angle-brackets are used, then they also behave as group operators but recursively operate on nested lists. サブテンプレートは、括弧の中にグループ化されます。<>が使われると、ネストされたリストに再帰的に適用されるグループ化オペレータとしても振舞います。

     The string types: 文字列型:

     a
          An arbitrary incomplete string, null padded. 任意の不完全文字列。NULLでパディングされます。

     A
          A text string, space padded. テキスト文字列。空白スペースでパディングされます。

     Z
          A null terminated (ASCIZ) string, null padded. NULL終端(ASCIZ)文字列。NULLでパディングされます。

     b
          A bit string (ascending bit order inside each byte). ビット文字列(それぞれのバイトにおけるビットオーダーは昇順)。

     B
          A bit string (descending bit order inside each byte). ビット文字列(それぞれのバイトにおけるビットオーダーは降順)。

     h
          A hex string (low nybble first). 16進文字列(低いニブルが先)。

     H
          A hex string (high nybble first). 16進文字列(高いニブルが先)。

     The object types: オブジェクト型:

     c
          A signed 8bit integer. 符号付き8ビット整数。

     C
          An unsigned 8bit integer. 符号なし8ビット整数。

     s
          A signed short (16 bit) value. 符号付き16ビット整数。

     S
          An unsigned short (16 bit) value. 符号なし16ビット整数。

     i
          A signed integer (>= 32 bit) value. 符号付き整数(>= 32ビット)。

     I
          An unsigned integer (>= 32 bit) value. 符号なし整数(>= 32ビット)。

     l
          A signed long (32 bit) value. 符号付きlong(32ビット)。

     L
          An unsigned long (32 bit) value. 符号なしlong(32ビット)。

     n, n!
          An unsigned and signed short (16 bit) in "network" (big-endian) order. ネットワークオーダー(ビッグエンディアン)での符号なし/符号つきshort(16ビット)。

     N, N!
          An unsigned and signed long (32 bit) in "network" (big-endian) order. ネットワークオーダー(ビッグエンディアン)での符号なし/符号つきlong(32ビット)。

     v, v!
          An unsigned and signed short (16 bit) in "VAX" (little-endian) order. VAXオーダー(リトルエンディアン)での符号なし/符号つきshort(16ビット)。

     V, V!
          An unsigned and signed long (32 bit) in "VAX" (little-endian) order. VAXオーダー(リトルエンディアン)での符号なし/符号つきlong(32ビット)。

     q
          A signed quad (64 bit) value. 符号付きquad(64ビット)。

     Q
          An unsigned quad (64 bit) value. 符号なしquad(64ビット)。

     f
          A single-precision float in the native format. ネイティブ形式の単精度float。

     d
          A double-precision float in the native format. ネイティブ形式の倍精度float。

     w
          A BER compressed integer.  An unsigned integer in base 128, most significant digit first, where the high bit is set on all but the final (least significant) byte.  Thus any size integer can be encoded, but the encoding is efficient and small integers don't take up any more space than they would in normal char/short/int encodings. BER圧縮された整数。ベース128における符号なし整数で、最も大きな桁が最初で、高いビットが最後の(一番小さな)バイト以外にセットされる。したがって、どのような大きさの整数もエンコードできるが、エンコーディングは効率的で、小さな整数は通常のchar/short/int エンコーディングの場合よりも占有する空間が少ない。

     x
          A null byte. NULLバイト。

     o
          An sexp, handled with read and write. S式。readとwriteで扱われる。

     If the optional keyword :OUTPUT is given that port is used instead of the current output port.  If :TO-STRING? is given and true, then pack accumulates and returns the output as a string.

     Note that the returned string may be an incomplete string if the packed string contains a byte sequence invalid as a character sequence. オプションのキーワード:OUTPUTが与えられると、現在の出力ポートの代わりにそのポートが使われます。 :TO-STRING?が与えられそれが真である場合は、パックは蓄積され、その出力は文字列として返ります。

          (pack "CCCC" '(65 66 67 68) :to-string? #t)
           => "ABCD"

          (pack "C/a*" '("hello") :to-string? #t)
           => "\x05hello"

 -- Function: unpack template :key :input :from-string
     The complement of pack, unpack reads values from the current input port assuming they've been packed according to the string template and returns the values as a list.  unpack accepts the same format strings as pack.  Further, the following tautology holds: packの逆を行うもので、unpackは現在の入力ポートから、値が文字列の templateでパックされているものとして読み込み、その値をリストとして返します。unpackはpackと同じフォーマット文字列を受け付けます。また、いかなるリストXとフォーマット文字列FMTにおいても、次のようなトートロジーが維持されます。

          (equal? x (unpack fmt :from-string (pack fmt x :to-string? #t)))

     for any list X and format string FMT.  The only exceptions to this are when the template includes a * and when the o template is used, since Scheme numeric literals cannot be reliably delimited (though future versions of pack may circumvent this by registering a new read syntax).

     If the optional keyword :INPUT is given that port is used instead of the current input port.  If :FROM-STRING is given, then pack reads input from that string. ただ一つの例外は、テンプレートが*を含み、oテンプレートが使われている場合です。これは、Schemeの数値リテラルは確実に区切られることができないからです(packの将来のバージョンでは、新しいread構文を登録することによってこれは回避されるでしょう)。

     オプションのキーワード:INPUTが与えられると、現在の入力ポートの代わりにそのポートが使われます。:FROM-STRINGが与えられると、 packはその文字列を入力とします。

          (unpack "CCCC" :from-string "ABCD")
           => '(65 66 67 68)

          (unpack "C/a*" :from-string "\x05hello")
           => '("hello")

     Note: in the current version, @ in unpack template has a bug and does not work as supposed.  It will be fixed in the future version. 註: 現在のバージョンには、unpackのテンプレートの @が想定したように動かないというバグがあります。将来のバージョンでfixされます。

 -- Function: unpack-skip template :key :input
     unpack-skip is the same as unpack except it does not return the values.  In some cases, particularly with fixed-size templates, this can be much more efficient when you just want to skip over a value. unpack-skipは、値を返さないことを除いてunpackと同じです。いくつかのケースでは、特に固定サイズのテンプレートを使うときには、単に値を読み飛ばしたいときにより効率的です。

 -- Function: make-packer template
     The low-level interface.  This function returns a dispatch closure that can be used to pack, unpack and skip over the same cached template.  The dispatch closure accepts symbol methods as follows: 低レベルなインタフェースです。この関数は、pack、unpackやキャッシュされた同じテンプレートを読み飛ばす時に使われるディスパッチクロージャを返します。ディスパッチクロージャは、以下のようにシンボルメソッドを受け付けます。

     'pack list
          pack the items in list to the current output port. listにあるアイテムを、現在の出力ポートへpackします。

     'unpack
          unpack items from the current input port. 現在の入力ポートからアイテムをunpackします。

     'skip
          skip items from the current input port. 現在の入力ポートからのアイテムをスキップします。

     'packer
          return the cached 'pack closure キャッシュされた'packクロージャを返します。

     'unpacker
          return the cached 'unpack closure. キャッシュされた'unpackクロージャを返します。

     'skipper
          return the cached 'skip closure. キャッシュされた'skipクロージャを返します。

     'length
          return the known fixed length of the template. テンプレートの知られている固定された長さを返します。

     'variable-length?
          return #t if the template has variable length elements. テンプレートが可変長の要素を持っている場合に#tを返します。

compat.chibi-test - Running Chibi-scheme test suite
===================================================

 -- Module: compat.chibi-test
     Quite a few srfis come with test suites that's to be run with Chibi Scheme test framework.  This module enables Gauche to run the test code as is. 多くのsrfiには、Chibi Schemeのテストフレームワークで実行できるテストコードが付いてきます。このモジュールはGaucheでそのテストコードを実行できるようにします。

 -- Macro: chibi-test code ...
     Run CODE ..., while translating Chibi test framework to Gauche's. ChibiのテストフレームワークをGaucheのそれに置き換えながら、 code ...を実行します。

     A typical usage is to write a wrapper that includes the original test code (suppose it's called test-suite.scm): 典型的な使い方は、元のテストコード(test-suite.scmとします)を includeするラッパーを書くことです。

          (use gauche.test)
          (test-start "running test-suite.scm")
          (chibi-test
            (include "test-suite.scm"))
          (test-end)

     Chibi's test directives are translated to Gauche's test directives (see Unit testing, for Gauche's test framework). Chibiのテストディレクティブは、Gaucheのテストフレームワークのテストディレクティブへと変換されます(Unit testing参照)。

     The main thing is that Chibi allows expressions and definitions to be intermingled within a body, while Gauche only allows all definitions before expressions within a body. We expand such body into nested let by chibi-test macro. Chibi test macros (e.g. test-assert) are defined as local macros in chibi-test expansion, which expand into gauche.test macros. Chibiはボディ中に式と定義が交互に現れることを許していますが、Gaucheではボディ中で全ての定義が式に先立たねばなりません。そこで、chibi-testマクロは code ...をネストしたletに変換します。また、Chibiテストマクロ(test-assert等)は変換後のコードではローカルマクロとして定義され、そのローカルマクロはgauche.testマクロへと展開されます。

     Note that we ignore use forms inside chibi-test; we might want to use different modules that work better in Gauche.  Necessary modules need to be use'd before you call chibi-test. なお、chibi-test中のuseフォームは無視されます。これは、Gaucheで実行するのに別のモジュールを使った方が良い場合があるからです。必要なモジュールはchibi-testを呼ぶ前にuseしておいてください。

     You may want to check out test/srfi.scm in Gauche source tree for the use case. Gaucheのソースツリーのtest/srfi.scmに実際の使用例を見ることができます。

compat.norational - Rational-less arithmetic
============================================

 -- Module: compat.norational

     Until release 0.8.7, Gauche didn't have exact rational numbers. It was able to read the rational number literals such as 2/3, but they are immediately coerced to inexact real numbers (except when it represents a whole integer). And if you divided an exact integer by another exact integer, the result could be coerced to an inexact real if the result wasn't a whole integer. リリース 0.8.7 までは、Gauche は正確な有理数をサポートしていませんでした。2/3のような有理数リテラルを読み込むことはできていましたが、約分して整数になる場合をのぞいては、その場で不正確な実数に変換されていました。正確な整数を正確な整数で割った場合も約分して整数になる場合をのぞき、結果は不正確な実数になりました。

     As of 0.8.8, this is not the case anymore.  Exact division always yields exact result, except when the divisor is zero. リリース 0.8.8 ではもうこのようなことはありません。正確な数同士の割り算の結果は常に正確な数になります。ゼロで割ったときはもちろん例外です。

          (/ 2 3)  => 2/3
          (/ 5)    => 1/5
          (/ 4 2)  => 2

     This is more precise, but has one drawback: exact rational arithmetic is much slower than the integer and inexact real arithmetic.  If you inadvertently produce a rational number in the early stage of calculation, and continue to apply exact arithmetic, performance would be degraded miserably. 計算は正確な値でできますが、ひとつ欠点もあります。正確有理数演算は整数演算や不正確実数同士の演算にくらべてはるかに遅いのです。意図せず、計算の初期段階で有理数を生成してしまうとその後の計算にはすべて正確な演算が適用されてしまい性能は悲惨なことになります。

     The proper way to solve this is to insert exact->inexact to appropriate places.  However, to ease the transition, you can just import this module and the division / behaves in the way it used to. この問題を解決する適切は方法は適切な場所にexact->inexactを挿入することです。しかし、この変換を簡単におこなうには、このモジュールをインポートし、割り算に/を使うだけですみます。

          (use compat.norational)

          (/ 2 3)  => 0.6666666666666666
          (/ 5)    => 0.2
          (/ 4 2)  => 2

     The effect is not global, but only to the modules you explicitly import compat.norational. 効果はグローバルには起こらず、明示的にcompat.norationalをインポートしたモジュールでのみ有効です。

     This module only redefines /.  So if your code has exact rational literals, they are treated as exact rationals rather than coerced to inexact reals.  You should prefix rational literals with #i to force Gauche to coerce them to inexact reals: このモジュールは/を再定義しているだけです。したがって、コードに正確な有理数のリテラルが含まれていても、それは不正確な実数に変換されることはなく、正確な有理数としてあつかわれます。Gaucheに不正確な実数として有理数リテラルを扱わせるには、#iという接頭辞を追加しなければなりません。

          gosh> 1/3
          1/3
          gosh> #i1/3
          0.3333333333333333

control.job - A common job descriptor for control modules
=========================================================

 -- Module: control.job
     This module provides a job record type, a lightweight structure to be used in the control flow subsystems (control.* modules). Currently the only user is control.thread-pool, but some other modules are planned to use job records. このモジュールは、制御フローサブシステム(control.*モジュール) の中で使う軽量な構造である job レコード型を提供します。現在のところ、これを使っているのはcontrol.thread-poolだけですが、他にもいくつかのモジュールがjobレコードを使う予定です。

     A job record may be returned to an application by other control.* modules so that the application can keep track of the job.  It's not meant for general use, however.   An application isn't supposed to create a new job, or to modify its content; it can just query the job's properties. control.*モジュールは、アプリケーションがジョブを追跡できるように jobレコードを返すことができます。ただし、これは、アプリケーションが普通に使用するためのものではありません。アプリケーションが新しいジョブを作成したり、その内容を変更したりすることは想定されていません; できるのは、そのジョブの属性について問い合わせることだけです。

     In this section we only describe procedures an application needs to know.  The interface for control subsystems is still fluid and may be changed as more subsystems are developed. この節では、アプリケーションが知るべき手続きだけを説明します。制御サブシステムのためのインタフェースは未だ流動的であり、さらなるサブシステムの開発が進むにつれて、変更されるかもしれません。

     Different control flow subsystems may use job structure differently. This section only describes the common properties.  Check the individual control flow module to know how to handle returned job objects. 異なる制御フローサブシステムは、ジョブ構造の使い方が異なるかもしれません。この節では、共通する属性のみを説明します。返されたジョブオブジェクトの扱い方については、個々の制御フローモジュールを調べて下さい。

 -- Record type: job
     A record type denotes the job.  Applications should treat it as an opaque structure. ジョブを表すレコード型です。アプリケーションはこれを、不透明(opaque)な構造として扱うべきです。

 -- Function: job? obj
     Returns #t iff OBJ is a job record, #f otherwise. OBJがジョブレコードだったら#tを、そうでなければ#fを返します。

 -- Function: job-status job
     Returns the status of the job.  It may be either one of the followings. ジョブの状態を返します。ジョブの状態は以下のいずれかになります。

     #f
          Newborn or orphaned job.  Usually an application won't see a job in this status. 作成したてか、孤児のジョブです。通常、アプリケーションがジョブのこの状態に遭遇することはありません。

     acknowledged
          A job is recognized by a control flow library, but haven't yet been run. ジョブは制御フローライブラリによって認識されていますが、まだ実行されてはいません。

     running
          A job is being processed. ジョブは実行中です。

     done
          A job is finished.  An application can retrieve its result by job-result. ジョブは完了しています。アプリケーションはその処理の結果を、 job-resultを使って受け取ることができます。

     error
          A job is terminated by an error.  An application can retrieve the error causing condition by job-result. ジョブはエラーで終了しています。アプリケーションはエラーの原因となったコンディションを、job-resultを使って受け取ることができます。

     killed
          A job is killed by external force.  An application can retrieve the reason of kill (which is specific to a particular control flow subsystem) by job-result. ジョブは外部から殺されています。アプリケーションは殺された理由を、 job-resultを使って受け取ることができます。どのような理由でジョブが殺されるかは制御フローサブシステムによります。

 -- Function: job-result job
     If the job is in done status, it returns the result of the job. If the job is in error status, it returns the condition object that describes the error. If the job is in killed status, it returns an object describing the reason of kill.  The details of the object depends on a particular control flow library. Calling job-result on a job in any other status may return anything; you can't rely on the result. 与えられたジョブがdone状態だったら、そのジョブの処理結果を返します。与えられたジョブがerror状態だったら、そのエラーを説明するコンディションオブジェクトを返します。そのジョブがkilled状態だったら、殺された理由を説明するオブジェクトを返します。このオブジェクトの詳細は、実際の制御フローライブラリに依存することになります。これら以外の状態のジョブに対してjob-resultを読んだ場合、何が返るかはわかりません; その結果を当てにすることはできません。

 -- Function: job-wait job :optional timeout timeout-val
     Suspends the calling thread until the job becomes either done, error or killed status.  If the job is already in one of those status, it returns immediately. Returns job's status. 与えられたジョブがdone、errorもしくはkilled 状態になるまで、呼び出したスレッドの実行をサスペンドします。ジョブがすでにこれらの状態であった時は、ただちに制御を戻します。ジョブの状態が返ります。

     If TIMEOUT is given and not #f, it must be a valid timeout spec (a <time> object that represents an absolute time point, or a real number that represents a relative time in seconds.)  The meaning of TIMEOUT is the same as in mutex-unlock! (see Synchronization primitives). Once the timeout reaches, job-wait returns no matter how the job's status is, and returns the value specified to TIMEOUT-VAL, which defaults to #f. TIMEOUTが与えられ、それが#fではない場合は、タイムアウトのスペックとして有効なもの(時間の絶対値を表す <time>か、現時点からの相対的な秒数を表す実数)でなければなりません。TIMEOUTの意味は、mutex-unlock! (see Synchronization primitives)のそれと同じです。タイムアウトすると、そのジョブの状態が何であれ、 job-waitは引数TIMEOUT-VALとして指定された値を返します。デフォルト値は#fです。

     Depending on the control flow subsystem, jobs created by it may not be waitable; check out each subsystem's documentation for the details. そのジョブを作成する制御フローサブシステムによっては、待ち受けできないかもしれません。それぞれのサブシステムのドキュメントを調べて詳細を確認してください。

 -- Function: job-acknowledge-time job
 -- Function: job-start-time job
 -- Function: job-finish-time job
     If the control flow subsystem keeps track of timestamps, these procedure returns the time (in <time> objects) when the job is acknowledged, started and finished (either normally, or abnormally by an error or by being killed).  If the job hasn't reached to certain status, #f is returned instead. 制御フローサブシステムがジョブのタイムスタンプを記録する場合、これらの手続きは、そのジョブがサブシステムによって認識された時刻、開始された時刻、(正常に、あるいはエラーや殺されるなど異常に) 終了した時刻を(<time>オブジェクトとして)返します。ジョブがそうした状態に達していない場合は#fを返します。

     If the subsystem does not track timestamps, these procedures always returns #f. そのサブシステムがタイムスタンプを記録しない場合、これらの手続きは常に#fを返します。

control.thread-pool - Thread pools
==================================

 -- Module: control.thread-pool
     Provides thread pools.  Only available when Gauche is compiled with pthreads support. スレッドプールを提供します。Gaucheがpthreadサポート付きでコンパイルされている場合にのみ利用可能です。

 -- Class: <thread-pool>
     A class for thread pool objects.   It maintains a set of worker threads, and let them work on the jobs you ask to do asynchronously.

     Currently the size of pool (number of threads) is fixed and you have to specify it when creating a pool. In future we might add a feature to grow or shrink the pool.

     You can also set maximum backlog of the job queue.  You cannot put a job when the queue already reaches the max length (see add-job! below). スレッドプールオブジェクトのクラスです。ワーカースレッドのセットを保持し、投入されたジョブを非同期に実行します。

     現在の実装では、プールのサイズ (スレッド数) は固定で、プール作成時に指定しなければなりません。いずれスレッド数を動的に増減させる機能を追加する予定です。

     また、ジョブのキューの最大長を指定することもできます。ジョブのキューが一杯になると、空きができるまでは新たなジョブを投入することができなくなります (下記のadd-job!参照)。

 -- Condition type: <thread-pool-shut-down>
     A condition indicating that a thread pool is already shut down by terminate-all! and no longer accepting new jobs. Inherits <error>.  The following slot is provided. スレッドプールがterminate-all!によって停止され、新規のジョブを受け付けていないことを示すコンディションです。 <error>を継承します。次のスロットが提供されます。

      -- Instance Variable of <thread-pool-shut-down>: pool
          The thread pool object that caused the condition. 例外の原因となったスレッドプールオブジェクト

 -- Function: make-thread-pool size :key (max-backlog 0)
     Creates a new thread pool of size SIZE (the number of worker threads).  Optionally you can give a nonnegative integer to the maximum backlog; 0 means unlimited. 大きさ(ワーカースレッド数)SIZEのスレッドプールを作成して返します。省略可能引数MAX-BACKLOGによってジョブのバックログの最大値を指定することもできます。0を与えた場合(デフォルト)は無制限です。

 -- Function: thread-pool-results pool
     When you put a job to a thread pool, you can specify whether you need to check its result or not.  If you say you need a result, the terminated job is queued to a result queue, an <mt-queue> object, in the pool. This procedure returns the pool's result queue. See Queue, for the details of <mt-queue>. ジョブをスレッドプールに投入する際に、ジョブの結果を知る必要があるかどうかを指定することができます。結果を要求した場合は、終了したジョブレコードがプール中の結果キュー(<mt-queue>オブジェクト)にエンキューされます。この手続きは、プールの結果キューを返します。 <mt-queue>の詳細についてはQueueを参照してください。

 -- Function: thread-pool-shut-down? pool
     Returns #t if the thread pool is shut down and no longer accepting new jobs, or #f otherwise. スレッドプールが停止され、新規のジョブを受け付けていない場合に#tを、そうでなければ#fを返します。

 -- Function: add-job! pool thunk :optional (need-result #f) (timeout #f)
     Add a THUNK to be executed in the thread pool POOL. Returns a job record (see A common job descriptor for control modules). THUNKがスレッドプールPOOLのスレッドにより実行されるように設定します。 jobレコードを返します。 (A common job descriptor for control modules参照)。

     The returned job record is not waitable; if you need to track its result, you have to give a true value to NEED-RESULT argument.  Then when the job is terminated (either normally or abnormally) the job is queued to the result-queue of the pool, and you can check the queue.   If you don't pass a true value to NEED-RESULT, the job won't be queued to result-queue even it is terminated. 返されるjobレコードはwaitableにはなっていません。結果を知る必要がある場合は、省略可能引数NEED-RESULTに真の値を渡してください。そうするとジョブが終了した時点 (正常終了でも異常終了でも) で、 jobレコードがスレッドプールのresult-queueに入るので、そのキューから結果を受け取ることができます。 NEED-RESULTを省略したり偽値を渡した場合は、ジョブが終了しても jobレコードはresult-queueに入れられません。

     The returned job is timestamped.  You can examine acknowledged time, start time and finish time of the job (if the job hasn't been started and/or finished, the corresponding timestamp fields are #f.)  It's sometimes handy to find out how long the job was waiting in the queue and how long it took to run. 返されるjobレコードにはタイムスタンプが付加され、受付時間、実行開始時間、実行終了時間が記録されます。 (ジョブがまだ実行されていなかったり、終了されていない場合は、対応するタイムスタンプは#fになっています)。ジョブがどのくらいキューの中で待たされ、どのくらい実行にかかったかを知るのに便利でしょう。

     If the pool has positive max-backlog value, and it already has that many jobs to be waiting, then add-job! blocks until some jobs are start being executed. You can give a real number in seconds, or a <time> object as an absolute point of time, to the TIMEOUT argument to set the time limit of blocking.  If timeout is reached, add-job! returns #f without creating any job. Omitting TIMEOUT or giving #f to it sets no timeout. スレッドプールが非負のmax-backlog値を持ち、既にその数だけジョブが待ち行列に入っている場合は、 add-job!は待ち行列に空きができるまでブロックします。 TIMEOUT引数に、実数値の秒数、あるいは絶対時刻を指定する<time> オブジェクトを渡すことでタイムアウトを指定できます。タイムアウトに達した場合は、add-job!はジョブを作らずに#fを返します。 TIMEOUT引数を省略するか、#fを渡した場合はタイムアウトが設定されません。

     (Note: This behavior is different from 0.9.1, in which add-job! didn't take the timeout argument and always behaved as if zero timeout value was given.  To achieve the same behavior, you have to give 0 to the TIMEOUT argument explicitly.) (註: この動作は0.9.1から変更されました。0.9.1では、add-job!はタイムアウト引数を取らず、常にタイムアウトに0秒が指定されたかのように振る舞っていました。現在のバージョンで同じ動作をさせるには、TIMEOUT引数に0を明示的に渡します。)

     If the thread pool is shut down, this procedure raises <thread-pool-shut-down> condition. スレッドプールが停止していた場合、この手続きは <thread-pool-shut-down>コンディションを投げます。

 -- Function: wait-all pool :optional (timeout #f) (check-interval #e5e8)
     Wait for the job queue to be empty and all worker threads to finish.  It is done by polling the pool's status in every CHECK-INTERVAL nanoseconds. Returns #t if all jobs are finished.

     You can give a real number in seconds, or a <time> object as an absolute point of time, in TIMEOUT optional argument. When timeout is reached, wait-all returns #f. ジョブ待ち行列が空になり、すべての実行中のジョブも終了するまで待ちます。終了待ちはCHECK-INTERVALにナノ秒で指定される間隔でスレッドプールをポールすることで行われます。すべてのジョブが終了したら#tを返します。

     秒数を表す実数か、絶対時刻を表す<time>オブジェクトをTIMEOUT 引数に渡すことで、タイムアウトを指定できます。タイムアウトに達した場合は、 wait-allは#fを返します。

 -- Function: terminate-all! pool :key (force-timeout #f) (cancel-queued-jobs #f)
     Wait for all the queued jobs to be finished, then ask all threads to terminate.  After calling this procedure, the pool no longer accepts new jobs.  Calling add-job! on this module would raise a <thread-pool-shut-down> condition. This is intended to be called when shutting down the application.

     By default, this procedure first waits for all queued jobs to be handled, then tries to terminate threads gracefully.

     Giving a true value to the CANCEL-QUEUED-JOBS argument immediately cancels queued but not started jobs; the status of such jobs is set killed. It does not cancels already started jobs, though.

     If you want to cancel already started jobs, you can give a timeout value (either <time> object to specify absolute point of time, or a real number indicating relative time in seconds) to the FORCE-TIMEOUT argument. Once timeout is reached, it forcefully terminates the threads and the jobs handled at that time are also killed.

     Forcing termination of threads is an extreme measure; the terminated thread may not have a chance to clean up properly.  So it is usually better to give some time for the thread to finish the executing jobs. 投入されたジョブがすべて終了するのを待ち、すべてのスレッドを終了させます。ひとたびこの手続きを呼ぶと、スレッドプールPOOLは新規のジョブを受けつけません。この状態のスレッドプールに対してadd-job!を呼ぶと <thread-pool-shut-down>コンディションが投げられます。この手続きはアプリケーションのシャットダウン時などに呼ばれることを意図しています。

     デフォルトでは、この手続きはまずキューに既に投入されたジョブが全て処理されるのを待ち、それからスレッドを穏やかに終了させます。

     真の値をCANCEL-QUEUED-JOBS引数に与えると、キューに入っているがまだ開始されていないジョブは直ちにキャンセルされます。それらのジョブのステータスにはkilledがセットされます。ただし、既に開始されたジョブについてはキャンセルされません。

     既に開始されたジョブも中断したい場合は、タイムアウト値(秒数を表す実数か、絶対時刻を表す<time>オブジェクト)を FORCE-TIMEOUT引数に渡します。タイムアウトに達した時点で残っているスレッドは強制終了され、実行中のジョブもキャンセルされます。

     スレッドの強制終了は極端な処置です。終了されるスレッドは、適切なクリーンアップを行う機会も与えられないかもしれません。したがって通常は、スレッドが処理中のジョブを終わらせるための適切な時間的猶予を与えるのが良いでしょう。

crypt.bcrypt - Password hashing
===============================

 -- Module: crypt.bcrypt
     This module implements a password hashing algorithm using blowfish, and compatible to OpenBSD's bcrypt algorithm (version 2a, 2b). このモジュールは、blowfishを使ったパスワードハッシュアルゴリズムを実装します。 OpenBSDのbcryptアルゴリズム(version 2a, 2b)と互換です。

     Don't use version ``2a'' for new code. It's vulnerable. Use version ``2b''. version 2a は脆弱性が発見されているので、新規のコードでは使用しないでください。代わりに version 2b を使用して下さい。

     The typical usage of this module is simple enough. To get a new password hash value (e.g. for a new user), pass the password string to bcrypt-hashpw as the only argument: 典型的な使い方は非常にシンプルです。新しいパスワードハッシュ値を得たい場合 (例えば新しいユーザのために、など) は、パスワード文字列を唯一の引数としてbcrypt-hashpwを呼び出してください。

          (bcrypt-hashpw PASSWORD)
            => hashed-string

     The routine automatically adds a salt value.  The returned hash string can be stored in the user database.  To check if the given password matches the stored one, pass the hashed string as the second argument of bcrypt-hashpw to check the password. このルーチンは自動的にソルト値を付加します。戻り値の文字列はそのままユーザデータベースに格納できます。与えられたパスワードがハッシュ値に一致するかどうかを調べるには、ハッシュ値そのものを第二引数としてbcrypt-hashpwに渡します。

          (bcrypt-hashpw PASSWORD HASHED-STRING)
            => hashed-string

     If the given password is correct, the returned value should exactly matches HASH-STRING. パスワードが正しければ、戻り値はHASHED-STRINGと完全に一致するはずです。

 -- Function: bcrypt-hashpw password :optional setting
     Calculates a hash value of PASSWORD, using the salt value and parameters included in SETTING.  If SETTING is omitted, a suitable default settings and random salt value is chosen automatically.

     The returned hash value contains the salt value and parameters, and can be used as SETTING.  So, to check the password against existing hash value, just pass the hash value to SETTING; if the password is correct, the returned hash value should match the one you passed in.

     The bcrypt algorithm supports up to 72 octets for the password.

     To tweak parameters when you calculate a new hash value, use bcrypt-gensalt below to get the initial SETTING value. PASSWORDのハッシュ値を計算します。SETTINGはソルト値とパラメータを指定する文字列です。SETTINGが省略された場合は、適切なデフォルトのパラメータとランダムなソルト値が自動的に選択されます。

     戻り値のハッシュ値文字列にはソルト値とパラメータが含まれているので、それを再びSETTINGに渡すことができます。したがって、パスワードを既存のハッシュ値に一致するかチェックしたい場合は、ハッシュ値をSETTINGに渡し、戻ってきた文字列が渡したハッシュ値と一致するかを見れば良いことになります。

     bcryptアルゴリズムは最大72オクテットまでのパスワードを使えます。

     新しいハッシュ値を計算する際にパラメータを指定したい場合は、次に説明する bcrypt-gensaltを使うとSETTINGに使える文字列を得ることができます。

 -- Function: bcrypt-gensalt :key prefix count entropy-source
     Returns a string that contains given parameters and suitable to pass to the SETTING argument of bcrypt-hashpw.

     The PREFIX argument specifies the version/scheme of password hashing.  Currently $2a$ and $2b$ are supported, which means the blowfish algorithm compatible to bcrypt. But $2a$ is vulnerable. Use $2b$ for new code. If you omit PREFIX, use $2b$ for default value.

     The COUNT argument specifies the amount of iterations; the larger the value is, the more time is required to calculate the hash value.  Note that for the password hashing, taking more time is actually a good thing, for it works against the dictionary attack. For normal password checking you need to run the hash routine only once per login, so it doesn't matter if the calculation takes a fraction of second. The bcrypt algorithm iterates (expt 2 COUNT) times.

     The ENTROPY-SOURCE argument is a u8vector to feed a random bytes.  For bcrypt algorithm it must be at least 16 octet long. 与えられたパラメータを折り込んだ、 bcrypt-hashpwのSETTING引数に使える文字列を返します。

     PREFIX引数はハッシュ関数およびそのバージョンを指定する文字列です。現在のところ、bcrypt互換である$2a$と$2b$がサポートされています。ただし、$2a$には脆弱性が発見されていますので、新規のコードには$2b$を使用して下さい。 PERFIX引数を省略した場合は$2b$が用いられます。

     COUNT引数はハッシュの繰り返し回数に関係します。大きな値を指定すれば、ハッシュ値の計算により長い時間がかかります。パスワードハッシュにおいては、時間をかけた方が良いことに注意してください。一回のハッシュの時間が長くなれば辞書攻撃への防御になります。一方で、通常のパスワードチェックではログインの度にたかだか一回しはハッシュ関数を呼ばないので、それがたとえコンマ数秒かかったとしてもたいした負荷ではありません。 bcryptアルゴリズムでは、(expt 2 COUNT)回ハッシュが繰り返されます。

     ENTROPY-SOURCE引数はランダムなバイト列を格納したu8vectorです。 bcryptアルゴリズムでは少なくとも16バイトの長さが必要です。

data.cache - Cache
==================

 -- Module: data.cache
     A cache works similarly as a dictionary, associating keys to values, but its entries may disappear according to the policy of the cache algorithm.  This module defines a common protocol for cache datatypes, and also provides several typical cache implementations. キャッシュは、キーと値を結びつけるという点では辞書と似たように動作しますが、キャッシュアルゴリズムの方針によってエントリが消去されることがあります。このモジュールは、キャッシュについて共通のプロトコルを定義し、またいくつかの典型的なキャッシュの実装を提供します。

Examples
--------

例
-

Let's start from simple examples to get the idea. まず簡単な例によって、どんな具合かを示しましょう。

Suppose you want to read given files and you want to cache the frequently read ones.  The following code defines a cached version of file->string: 指定されたファイルを読み込むルーチンに、頻繁に読むファイルをキャッシュする機能をつけたいとします。次のコードはfile->stringにキャッシュ機能を持たせたものです。

     (use data.cache)
     (use file.util)

     (define file->string/cached
       (let1 file-cache (make-lru-cache 10 :comparator string-comparator)
         (^[path] (cache-through! file-cache path file->string))))

The procedure closes a variable file-cache, which is an LRU (least recently used) cache that associates string pathnames to the file contents. The actual logic is in cache-through!, which first consults the cache if it has an entry for the path.  If the cache has the entry, its value (the file content) is returned.  If not, it calls file->string with the PATH to fetch the file content, register it to the cache, and return it.  The capacity of cache is set to 10 (the first argument of make-lru-cache), so when the 11th file is read, the least recently used file will be purged from the cache. この手続きはfile-cache変数をクロージャの中に綴じ込んでいます。その値は文字列のパス名とファイルの中身を結びつけるLRU(least recently used)キャッシュです。キャッシュの動作はcache-through!で実現されています。この手続きは、まずPATHをキーとして持つエントリがfile-cacheにあるかどうか調べます。そのキーを持つエントリがキャッシュ中にあればその値(ファイルの中身)が返されます。キャッシュ中に無ければ、file->stringがPATHを引数として呼ばれ、それが返したファイルの中身がキャッシュに登録され、返されます。キャッシュの容量はmake-lru-cacheの第1引数で指定され、ここでは10になっています。つまり、11個目のファイルが読まれた時に、一番長く使われていない (least recently used)ファイルがキャッシュから消去されます。

The effect of cache isn't very visible in the above example.  You can insert some print stubs to see the cache is actually in action, as the following example. Try read various files using file->string/cached. 上の例そのままではキャッシュの効果が見え辛いです。次の例の通り、printスタブをいれて、いろいろなファイルを file->string/cachedで読んでみて下さい。いつキャッシュが実際にファイルの中身を取りにゆくかわかるでしょう。

     (define file->string/cached
       (let1 file-cache (make-lru-cache 10 :comparator string-comparator)
         (^[path]
           (print #"file->string/cached called on ~path")
           (cache-through! file-cache path
                           (^[path]
                             (print #"cache miss.  fetching ~path")
                             (file->string path))))))

Caveat: A cache itself isn't MT-safe.  If you are using it in multithreaded programs, you have to wrap it with an atom (see Synchronization primitives): 注意: キャッシュ自身はスレッドセーフではありません。マルチスレッドプログラムでキャッシュを使う場合は、キャッシュをatomでラップしてください。

     (use data.cache)
     (use file.util)
     (use gauche.threads)

     (define file->string/cached
       (let1 file-cache (atom (make-lru-cache 10 :comparator string-comparator))
         (^[path]
           (atomic file-cache (cut cache-through! <> path file->string)))))

Common properties of caches
---------------------------

キャッシュに共通の性質
-----------

A cache of any kind has a comparator and a storage. The comparator is used to compare keys; in the example above, we use string-comparator to compare string pathnames (see Basic comparators, for more about comparators). どんなキャッシュにも、比較器とストレージがあります。比較器はキーを比較するのに使われます。上の例ではパス名を比較するために string-comparatorを渡しています比較器について詳しくはBasic comparatorsを参照してください。

The storage is a dictionary that maps keys to internal structures of the cache.  By default, a hashtable is created automatically using the given comparator (or, if a comparator is omitted, using default-comparator). The comparator must have hash function. ストレージは、キーとキャッシュ内部の構造とをマッピングする辞書です。デフォルトでは与えられた比較器を使うハッシュテーブルが使われるので、比較器はハッシュ関数を持っていなければなりません。比較器が省略された場合はdefault-comparatorが使われます。

Alternatively, you can give a pre-filled dictionary (copied from another instance of the same kind of cache) to start cache with some data already in it.  Note that what the cache keeps in the dictionary totally depends on the cache algorithm, so you can't just pass a random dictionary; it has to be created by the same kind of cache. If you pass in the storage, the comparator is taken from it. あるいは、 (同じ種類のキャッシュからコピーされた)辞書をストレージとして渡すことで、既にエントリがある状態のキャッシュを作ることもできます。キャッシュが辞書に登録している構造はキャッシュアルゴリズムごとに異なるので、何でも辞書を渡せるわけではないことに注意してください。同じ種類のキャッシュによって作られた辞書しか渡せません。ストレージとなる辞書を渡した場合、比較器はその辞書から取られます。

Thus, the cache constructors uniformly take keyword arguments COMPARATOR and STORAGE; you can specify either one, or omit both to use the defaults. 従ってキャッシュのコンストラクタは共通してCOMPARATORとSTORAGEのキーワード引数を取ります。デフォルトの動作で良ければ、どちらかひとつ、あるいは両方とも省略することができます。

Predefined caches
-----------------

定義済みのキャッシュ
----------

For the STORAGE and COMPARATOR keyword arguments, see above. STORAGEとCOMPARATORキーワード引数については上の節を参照してください。

 -- Function: make-fifo-cache capacity :key storage comparator
     Creates and returns a FIFO (first-in, first-out) cache that can hold up to CAPACITY entries. If the number of entries exceeds CAPACITY, the oldest entry is removed. CAPACITY個までのエントリを保持できる、FIFO(先入れ先出し)キャッシュを作って返します。エントリ数がCAPACITYを越えそうになった場合、一番古いものから削除されます。

 -- Function: make-lru-cache capacity :key storage comparator
     Creates and returns an LRU (least recently used) cache that can hold up to CAPACITY entries. If the number of entries exceeds CAPACITY, the least recently used entry is removed. CAPACITY個までのエントリを保持できる、 LRU(least recently used)キャッシュを作って返します。エントリ数がCAPACITYを越えそうになった場合、一番長く使われなかったものから削除されます。

 -- Function: make-ttl-cache timeout :key storage comparator timestamper
     Creates and returns a TTL (time to live) cache with the timeout value TIMEOUT. Each entry is timestamped when it's inserted, and it is removed when the current time passes TIMEOUT unit from the timestamp. The actual entry removal is done when the cache is accessed. タイムアウト値TIMEOUTを持つTTL(生存時間)キャッシュを作って返します。各エントリには、挿入された時間が記録されます。TIMEOUTを経過したエントリは削除されます。実際の削除は、キャッシュがアクセスされた時に行われます。

     By default, the Unix system time (seconds from Epoch) is used as a timestamp, and TIMEOUT is in seconds.  It may not be fine-grained enough if you add multiple entries in shorter intervals than seconds.   You can customize it by giving a thunk to TIMESTAMPER; the thunk is called to obtain a timestamp, which can be any monotonically increasing real number (it doesn't need to be associated with physical time). If you give TIMESTAMPER, the unit of TIMEOUT value should be the same as whatever TIMESTAMPER returns. デフォルトではUnixシステム時間(Epochからの秒数)がタイムスタンプに使われます。 1秒より短い間隔でたくさんのエントリが追加される場合にはこれでは分解能が足りないかもしれません。 TIMESTAMPERにサンクを与えることで、タイムスタンプをカスタマイズすることができます。キャッシュは時刻が必要になる度にTIMESTAMPERを引数無しで呼び出します。 TIMESTAMPERは単調非減少な実数を返さねばなりません(物理的な時間と結びついている必要はありません)。 TIMESTAMPERを与えた場合、TIMEOUT引数の単位は TIMESTAMPERが返す値の単位と同じでなければなりません。

 -- Function: make-ttlr-cache timeout :key storage comparator timestamper
     A variation of TTL cache, but the entry's timestamp is updated (refreshed) whenever the entry is read.  Hence we call it TTL with refresh (TTLR).  But you can also think it as a variation of LRU cache with timeout. TTLキャッシュのバリエーションで、エントリは書き込まれた時だけでなく、読み出された時にもタイムスタンプが更新されます。手続きの名前TTLRは、リフレッシュ付きTTL(TTL with refresh)という意味です。ただ、これをタイムアウト付きLRUキャッシュと見ることもできます。

     The unit of timeout, and the role of TIMESTAMPER argument, are the same as make-ttl-cache. タイムアウトの単位およびTIMESTAMPER引数の役割については、 make-ttl-cacheと同じです。

Common operations of caches
---------------------------

キャッシュに共通の操作
-----------

The following APIs are for the users of a cache. 以下のAPIはキャッシュのユーザに向けたものです。

 -- Function: cache-lookup! cache key :optional default
     Look for an entry with KEY in CACHE, and returns its value if it exists.  If there's no entry, the procedure returns DEFAULT if it is provided, or throws an error otherwise.

     Some types of cache algorithms update CACHE by this operation, hence the bang is in the name. CACHEからKEYに結びつけられたエントリを探し、見つかれば返します。エントリが無い場合は、DEFAULTが与えられていればそれを返し、与えられていなければエラーを投げます。

     キャッシュアルゴリズムによってはこの操作でCACHEがアップデートされる場合があるため、名前にエクスクラメーションマークがついています。

 -- Function: cache-through! cache key value-fn
     Look for an entry with KEY in CACHE, and returns its value if it exists.  If there's no entry, a procedure VALUE-FN is called with KEY as the argument, and its return value is inserted into CACHE and also returned. CACHEからKEYに結びつけられたエントリを探し、見つかれば返します。見つからなかった場合、VALUE-FNがKEYを引数として呼び出され、その結果がCACHEに新たなエントリとして追加され、またcache-through!の戻り値として返されます。

 -- Generic function: cache-write! cache key value
     This inserts association of KEY and VALUE into CACHE. If there's already an entry with KEY, it is overwritten. Otherwise a new entry is created.

     The same effect can be achieved by calling cache-evict! then cache-through!, but cache algorithms may provide efficient way through this method. CACHEに、KEYとVALUEの関係を追加します。既にKEYに結びつけられたエントリがあった場合は上書きされ、そうでなければ新たなエントリが作られます。

     同じ効果は、cache-evict!を呼んでからcache-through!を呼ぶことでも達成できますが、アルゴリズムによってはcache-write!に対して効率のよい実装を提供しているかもしれません。

 -- Generic function: cache-evict! cache key
     Removes an entry with KEY from CACHE, if it exists. CACHEからKEYに結びついたエントリを(もしあれば)削除します。

 -- Generic function: cache-clear! cache
     Removes all entries from CACHE. CACHE内のエントリを全て取り除きます。

Implementing a cache algorithm
------------------------------

キャッシュアルゴリズムの実装
--------------

Each cache algorithm must define a class inheriting <cache>, and implement the following two essential methods. The higher-level API calls them. 新たなキャッシュアルゴリズムを提供するには、<cache>を継承したクラスを定義し、次の二つの必須メソッドを実装します。高レベルAPIはこれらの必須メソッドを呼び出します。

 -- Generic function: cache-check! cache key
     Looks for an entry with KEY in CACHE. If it exists, returns a pair of KEY and the associated value. Otherwise, returns #f.  It may update the cache, for example, the timestamp of the entry for being read. CACHEからKEYに結びついたエントリを探します。見つかれば、KEYとその値とのペアを、見つからなければ#fを返します。この時、必要ならばキャッシュを更新して構いません。例えば読み出されたエントリのタイムスタンプを更新するなどです。

 -- Generic function: cache-register! cache key value
     Add an entry with KEY and associated VALUE into CACHE. This is called after KEY is confirmed not being in CACHE. CACHEに、KEYと対応するVALUEを追加します。このメソッドは、CACHEにKEYに対応するエントリが無いことが確認された後で呼び出されます。

Additionally, the implementation should consider the following points. アルゴリズムの実装は、また以下の点を考慮しなければなりません。

  * The initialize method must call next-method first, which sets up the comparator and storage slots.  You should check if storage has pre-filled entries, and if so, set up other internal structures appropriately.

  * The default methods of cache-evict! and cache-clear! only takes care of the storage of the cache.  You should implement them if your auxiliary structure needs to be taken care of.

  * The default method of cache-write! is just cache-evict! followed by cache-register!.  You may provide alternative method if you can do it more efficiently, which is often the case.

There are several procedures that help implementing cache subclasses:

 -- Function: cache-comparator cache
 -- Function: cache-storage cache
     Returns the comparator and the storage of the cache, respectively.

Typical caches may be constructed with a storage (dictionary) and a queue, where the storage maps keys to (<n> . <value>), and queues holds (<key> . <n>), <n> being a number (timestamp, counter, etc.)  Here are some common operations work on this queue-and-dictionary scheme:

 -- Function: cache-populate-queue! queue storage
     You can call this in the initialize method to set up the queue.  This procedure walks storage to construct (<key> . <n>) pairs, sorts it in increasing order of <n>, and pushes them into the queue.

 -- Function: cache-compact-queue! queue storage
     The queue may contain multiple pairs with the same key.  Sometimes the queue gets to have too many duplicated entries (e.g. the same entry is read repeatedly).  This scans the queue and removes duplicated entries but the up-to-date one.  After this operation, the length of the queue and the number of entries in the storage should match.

 -- Function: cache-renumber-entries! queue storage
     This procedure renumbers <n>s in the queue and the storage starting from 0, without changing their order, and returns the maximum <n>.  The duplicated entries in the queue is removed as in cache-compact-queue!.

     When you're using monotonically increasing counter for <n> and you don't want <n> to get too big (i.e. bignums), you can call this procedure occasionally to keep <n>'s in reasonable range.

data.heap - Heap
================

 -- Module: data.heap
     A heap is a data container that allows efficient retrieval of the minimum or maximum entry.  Unlike a <tree-map> (see Treemaps), which always keeps all entries in order, a heap only cares the minimum or the maximum of the current set; the other entries are only partially ordered, and reordered when the minimu/maximum entry is removed.  Hence it is more efficient than a treemap if all you need is minimum/maximum value. Besides binary heaps can store entries in packed, memory-efficient way. ヒープは最小値また最大値を効率よく取り出せるデータコンテナです。 <tree-map>は全てのエントリの順序を常に保っていますが (Treemaps参照)、ヒープは最小値/最大値以外については部分的にしか順序を保持していません。最小値/最大値が取り除かれる時点で内部を再構成して、次の最小値/最大値を見つけます。したがって、最小値/最大値のみが必要な場合、treemapより効率が良いです。さらに、バイナリヒープでは値をメモリ効率の良い詰められた形で保持できます。

 -- Class: <binary-heap>
     An implementation of a binary heap.  Internally it uses min-max heap, so that you can find both minimum and maximum value in O(1). Pushing a new value and popping the minimum/maximum value are both O(log n).

     It also stores its values in a flat vector, a lot more compact than a general tree structure that needs a few pointers per node. By default it uses a sparse vector for the backing storage, allowing virtually unlimited capacity (see Sparse vectors). But you can use an ordinal vector or a uniform vector as a backing storage instead. バイナリヒープの実装です。内部的にmin-maxヒープを使っており、最大値と最小値のどちらにもO(1)でアクセスできます。新たな値をpushしたり、最大最小値をpopするのはO(log n)です。

     バイナリヒープはまた、値をフラットなベクタに格納します。一般的なツリー構造がノードあたりいくつかのポインタを必要とするのに比べずっとコンパクトです。デフォルトでは疎なベクタ (Sparse vectors) がバッキングストレージとして使われ、事実上上限なしでデータを格納できますが、通常のベクタやユニフォームベクタをバッキングストレージとして指定することもできます。

     A binary heap isn't MT-safe structure; you must put it in atom or use mutexes if multiple threads can access to it (see Synchronization primitives). バイナリヒープはスレッドセーフではありません。複数のスレッドでアクセスする可能性がある場合は、atomに入れるか、mutexを適切に使ってください(Synchronization primitives参照)。

 -- Function: make-binary-heap :key comparator storage key
     Creates and returns a new binary heap.

     The COMPARATOR keyword argument specifies how to compare the entries.  It must have comparison procedure or ordering predicate. The default is default-comparator. See Basic comparators, for the details of comparators.

     The STORAGE keyword argument gives alternative backing storage.  It must be either a vector, a uniform vector, or an instance of a sparse vector (see Sparse vectors). The default is an instance of <sparse-vector>. If you pass a vector or a uniform vector, it determines the maximum number of elements the heap can hold. The heap won't be extend the storage once it gets full.

     The KEY keyword argument must be a procedure; it is applied on each entry before comparison.  Using key procedure allows you to store auxiliary data other than the actual value to be compared. The following example shows the entries are compared by their car's: 新しいバイナリヒープを作って返します。

     COMPARATORキーワード引数は、エントリの比較方法を指定する比較器です。比較手続きを持っていなければなりません。省略時はdefault-comparatorが使われます。比較器について詳しくはBasic comparatorsを参照してください。

     STORAGEキーワード引数には、データの格納に使うデータ構造を渡します。引数はベクタ、ユニフォームベクタ、あるいは疎ベクタ(Sparse vectors参照)のインスタンスでなければなりません。省略時は<sparse-vector>のインスタンスが使われます。

     ベクタまたはユニフォームベクタを渡した場合、そのベクタの大きさがヒープが格納できる要素の最大数を決めます。それが一杯になった時に自動的に拡張されることはありません。

     KEYキーワード引数は手続きでなければならず、要素の比較の前に各要素に適用されます。この手続きを使って、実際に比較される値に付随するデータを格納しておくことができます。次の例では、データのcarを使って比較しています。

          (define *heap* (make-binary-heap :key car))
          (binary-heap-push! *heap* (cons 1 'a))
          (binary-heap-push! *heap* (cons 3 'b))
          (binary-heap-push! *heap* (cons 1 'c))

          (binary-heap-find-min *heap*) => (1 . c)
          (binary-heap-find-max *heap*) => (3 . b)

 -- Function: build-binary-heap storage :key comparator key num-entries
     Create a heap from the data in STORAGE, and returns it. (Sometimes this operation is called heapify.) This allows you to create a heap without allocating a new storage. The COMPARATOR and KEY arguments are the same as make-binary-heap.

     STORAGE must be either a vector, a uniform vector, or an instance of a sparse vector.  The storage is modified to satisfy the heap property, and will be used as the backing storage of the created heap.  Since the storage will be owned by the heap, you shouldn't modify the storage later.

     The storage supposed to have keys from index 0 below NUM-ENTRIES. If NUM-ENTRIES is omitted or #f, entire vector or uniform vector, or up to sparse-vector-num-entries on the sparse vector, is heapified. STORAGEに入っているデータを使ってヒープを作り返します。 (この操作はしばしばヒープ化(heapify)と呼ばれます。) データ格納場所を新たにアロケートせずにヒープを作ることが可能です。 COMPARATORおよびKEY引数はmake-binary-heapと同じです。

     STORAGEはベクタ、ユニフォームベクタ、疎ベクタのインスタンスでなければなりません。このデータはヒープの属性を満たすために変更され、さらには作られたヒープのデータ格納場所となります。ヒープの一部になるので、 STORAGEを後から変更してはなりません。

     STORAGEの要素のうち、先頭からNUM-ENTRIESまでの要素が有効であるとしてヒープ化されます。NUM-ENTRIESが省略されるか #fであれば、ベクタおよびユニフォームベクタはその全てが、疎ベクタはsparse-vector-num-entriesまでの要素がヒープ化されます。

 -- Function: binary-heap-copy heap
     Copy the heap.  The backing storage is also copied. ヒープをコピーして返します。データ格納場所も全てコピーされます。

 -- Function: binary-heap-clear! heap
     Empty the heap. ヒープを空にします。

 -- Function: binary-heap-num-entries heap
     Returns the current number of entries in the heap. ヒープ中の要素数を返します。

 -- Function: binary-heap-empty? heap
     Returns #t if the heap is empty, #f otherwise. ヒープが空なら#tを、そうでなければ#fを返します。

 -- Function: binary-heap-push! heap item
     Insert ITEM into the HEAP.  This is O(log n) operation. If the heap is already full, an error is raised. ITEMをHEAPに挿入します。O(log n)の操作です。ヒープが既に一杯であった場合はエラーが通知されます。

 -- Function: binary-heap-find-min heap :optional fallback
 -- Function: binary-heap-find-max heap :optional fallback
     Returns the minimum and maximum entry of the heap, respectively. The heap will be unmodified.  This is O(1) operation.

     If the heap is empty, FALLBACK is returned when it is provided, or an error is signaled. それぞれヒープ中の最小および最大の要素を返します。O(1)の操作です。ヒープ自体は変更されません。

     ヒープが空の場合、FALLBACKが与えられればそれが返され、そうでなければエラーが通知されます。

 -- Function: binary-heap-pop-min! heap
 -- Function: binary-heap-pop-max! heap
     Removes the minimum and maximum entry of the heap and returns it, respectively.  O(log n) operation. If the heap is empty, an error is signaled. それぞれヒープから最小および最大の要素を取り除き、取り除いた要素を返します。 O(log n)の操作です。ヒープが空ならエラーが通知されます。

The following procedures are not heap operations, but provided for the convenience. 以下の手続きは一般的なデータ構造としてのヒープの操作には含まれませんが、便利なので用意してあります。

 -- Function: binary-heap-swap-min! heap item
 -- Function: binary-heap-swap-max! heap item
     These are operationally equivalent to the followings, respectively: これらはそれぞれ以下のコードと操作的には等価です。

          (begin0 (binary-heap-pop-min! heap)
            (binary-heap-push! heap item))

          (begin0 (binary-heap-pop-max! heap)
            (binary-heap-push! heap item))

     However, those procedures are slightly efficient, using heap property maintaining procedure only once per function call. ただしこれらの手続きは、ヒープ特性を維持するための手続きを呼び出し毎に1回しか行わないので、やや効率的です。

 -- Function: binary-heap-find heap pred
     Returns an item in the heap that satisfies PRED. If there are more than one item that satisfy PRED, any one of them can be returned.  If no item satisfy PRED, #f is returned.  This is O(n) operation. ヒープの中で、述語PREDを満たす要素を返します。PREDを満たす要素が複数ある場合にどれが返るかは不定です。PREDを満たす要素が無ければ #fが返ります。O(n)の操作です。

 -- Function: binary-heap-remove! heap pred
     Remove all items in the heap that satisfy PRED.  This is O(n) operation. PREDを満たす要素を全てヒープから取り除きます。O(n)の操作です。

 -- Function: binary-heap-delete! heap item
     Delete all items in the heap that are equal to ITEM, in terms of the heap's comparator and key procedure.  This is O(n) operation.

     Note that the key procedure is applied to ITEM as well before comparison. ITEMに等しい要素を全てヒープから取り除きます。「等しい」の判定にはヒープの比較器およびキー手続きが使われます。O(n)の操作です。

     キー手続きは、比較の前にITEMにも適用されます。

data.ideque - Immutable deques
==============================

 -- Module: data.ideque
     This module provides a functional double-ended queue (deque, pronounced as ``deck'').

     Almost all procedures in this module are now a part of R7RS large. See R7RS immutable deques, for description of the following procedures:

          ideque               ideque-unfold        ideque-unfold-right
          ideque-tabulate      ideque?              ideque-empty?
          ideque-add-front     ideque-add-back
          ideque-remove-front  ideque-remove-back
          ideque-front         ideque-back
          ideque-reverse       ideque=              ideque-ref
          ideque-take          ideque-drop
          ideque-take-right    ideque-drop-right
          ideque-split-at      ideque-append        ideque-zip
          ideque-map           ideque-for-each      ideque-for-each-right
          ideque-fold          ideque-fold-right    ideque-append-map
          ideque-filter        ideque-remove
          ideque-find          ideque-find-right
          ideque-take-while    ideque-take-while-right
          ideque-drop-while    ideque-drop-while-right
          ideque-span          ideque-break
          ideque-any           ideque-every
          ideque->list         list->ideque
          ideque->generator    generator->ideque

 -- Function: make-ideque n :optional init
     Creates an ideque of length N with all the elements being INIT.  If INIT is omitted, #f is used.

     This is provided just for the symmetry with other container data structures; it's not in srfi-134, and the portable code can use ideque-tabulate.

data.imap - Immutable map
=========================

 -- Module: data.imap
     This module provides a immutable data structure with O(log n) access and update operations (here, update means to return a new structure with requested changes). The current implementation is based on the functional red-black tree. このモジュールは、O(log n)でアクセスと更新が可能な、変更不可のデータ構造を提供します(ここでの「更新」とは、要求された変更を取り込んだ新たな構造を作って返すことです)。現在の実装は関数的な赤黒木に基づいています。

Although lists and alists are useful for stack-like immutable operations, where you can add and remove items to the head of existing data without modifying them, they require O(n) access time and sometimes you need better one.  The <imap> object provides O(log n) access, in exchange of O(log n) insertion and deletion. リストや連想リストは、スタック風の変更不可なデータ構造として使えます。つまり既存のデータ構造自体に変更を加えることなく、その先頭に要素を追加したり、先頭から要素を取り除いたりできるということです。一方で、リストや連想リストは任意の要素にアクセスするにはO(n)の時間を必要としますが、もっと速いアクセスが必要な場合もあります。<imap>オブジェクトはO(log n)のアクセスを可能にします。そのかわり、要素の追加や削除にもO(log n)を必要とします。

 -- Class: <imap-meta>
     Metaclass of <imap>. <imap>のメタクラスです。

 -- Class: <imap>
     Immutable map class.  An instance of <imap-meta>.

     Inherits <ordered-dictionary>, conforms dictionary protocol except mutating operators (see Dictionary framework). As a sequence, you can access key-value pairs in increasing order of keys. 変更不可なマップのクラスです。<imap-meta>をメタクラスとします。

     <ordered-dictionary>を継承し、変更操作を除くディクショナリプロトコルを実装します(Dictionary framework参照)。シーケンスとしてアクセスした場合は、キーと値のペアをキーの昇順に取り出すことができます。

 -- Function: make-imap
 -- Function: make-imap comparator
 -- Function: make-imap key=? key<?
     Creates a new empty immutable map.  Without arguments, default-comparator is used to compare keys.  To give a specific comparator, use the second form; the COMPARATOR argument should have comparison procedure. For the details of comparators, see Basic comparators. The third form creates a key comparator from a equality predicate KEY=? and less-than predicate key<?, both must accept two keys.  This interface is consistent with tree-map (see Treemaps). 空の変更不可なマップを新たに作って返します。引数無しの場合は、キーの比較にはdefault-comparatorが使われます。キーの比較方法を指定したい場合は、比較手続きを持つ比較器COMPARATORを引数に渡してください。比較器についてはBasic comparatorsを参照。 3番目の呼び出し形式は、キーの等価性を調べる述語KEY=?と大小比較の述語KEY<?から比較器を作ります。どちらの述語もふたつの引数をとらなければなりません。このインタフェースは tree-mapとの一貫性のためにサポートされています (Treemaps参照)。

 -- Function: alist->imap alist
 -- Function: alist->imap alist comparator
 -- Function: alist->imap alist key=? key<?
     Creates a new empty immutable map, populates it with key-value association list ALIST, and returns it. This may be a bit more efficient than creating an empty map with make-imap and populates it with imap-put one by one.

     The COMPARATOR argument specifies how to compare the keys. It must have comparison procedure.  If omitted, default-comparator is used.  See Basic comparators, for the details.

     The third form creates a key comparator from a equality predicate KEY=? and less-than predicate key<=?, both must accept two keys.

          (define m (alist->imap '((a . 1) (b . 2))))

          (imap-get m 'a) => 1
          (imap-get m 'b) => 2

 -- Function: tree-map->imap tree-map
     Returns a new immutable map with the same content (and the same comparator) as TREE-MAP.

 -- Function: imap? obj
     Returns #t if OBJ is an immutable map, #f otherwise.

 -- Function: imap-empty? immap
     Returns #t if an immutable map IMMAP is empty, #f otherwise.

 -- Function: imap-exists? immap key
     Returns #t if KEY exists in an immutable map IMMAP.

 -- Function: imap-get immap key :optional default
     Returns the value associated with KEY in an immutable map IMMAP. If IMMAP doesn't have KEY, DEFAULT is returned when provided, otherwise an error is signalled.

 -- Function: imap-put immap key val
     Returns a new immutable map where association of KEY to VAL is added to (or replaced in) an immutable map IMMAP. This operation is O(log n).

          (define m1 (alist->imap '((a . 1) (b . 2))))

          (define m2 (imap-put m1 'a 3))

          (imap-get m2 'a)  => 3
          (imap-get m1 'a)  => 1  ; not affected

 -- Function: imap-delete immap key
     Returns a new immutable map where KEY is removed from IMMAP.   If IMMAP doesn't have KEY, returned map has the same content as IMMAP.

          (define m1 (alist->imap '((a . 1) (b . 2))))

          (define m2 (imap-delete m1 'a))

          (imap-get m2 'a #f)  => #f
          (imap-get m1 'a)     => 1  ; not affected

 -- Function: imap-min immap
 -- Function: imap-max immap
     Returns a pair of key and value with the minimum or maximum key in IMMAP, respectively.  If IMMAP is empty, #f is returned.

data.priority-map - Priority map
================================

 -- Module: data.priority-map
     Priority map is a dictionary that can map keys to values, while the entires are sorted by their values. (If the entires are sorted by keys, it's a treemap--see Treemaps).

     It is useful when you wanted a sorted sequence, with quick access by keys that are associated to each value.

     Note: If what you need is just a priority queue, you can use data.heap (see Heap).

 -- Class: <priority-map>
     Priority map class.  It has no public slots. Instances of priority maps must be created by make-priority-map procedure instead of make method on the class.

     Inherits <ordered-dictionary>, and implements dictionary protocol. Operations concerning associations of keys and values are done through dictionary generic functions (see Generic functions for dictionaries).

     When iterated, it iterates increasing order of values.

 -- Function: make-priority-map :key key-comparator value-comparator
     Creates and returns an empty priority map. It can take KEY-COMPARATOR, which must have a hash procedure and is used to hash keys, and VALUE-COMPARATOR, which must have ordering predicate and is used to order values. When omitted, default-comparator is assumed.

 -- Function: priority-map-min pmap
 -- Function: priority-map-max pmap
     Return a pair of a key and a value, where the value is smallest or largest in the priority map PMAP, respectively.

     If PMAP is empty, #f is returned.

     If PMAP has more than one value that are equal to each other (w.r.t. VALUE-COMPARATOR given to the constructor), either one of them is picked.

 -- Function: priority-map-pop-min! pmap
 -- Function: priority-map-pop-max! pmap
     Remove one entry with the smallest or largest value, respectively, and returns a pair of the key and the value of removed entry.

     If PMAP is empty, #F is returned.

     If PMAP has more than one value that are equal to each other (w.r.t. VALUE-COMPARATOR given to the constructor), either one of them is picked.

data.queue - Queue
==================

 -- Module: data.queue
     Provides a queue (FIFO).  You can create a simple queue, which is lightweight but not thread-safe, or an MTqueue, a thread-safe queue.  Basic queue operations work on both type of queues.  When an mtqueue is passed to the procedures listed in this section, each operation is done in atomic way, unless otherwise noted.

     There are also a set of procedures for mtqueues that can be used for thread synchronization; for example, you can let the consumer thread block if an mtqueue is empty, and/or the producer thread block if the number of items in the mtqueue reaches a specified limit. Using these procedures allows the program to use an mtqueue as a channel.

     The simple queue API is a superset of SLIB's queue implementation, which supports not only enqueue! (add item to the end of the sequence) and dequeue! (take item from the front of the sequence), but also queue-push! (add item to the front of the sequence), so that it can be used as a stack as well.

     If you also want to take item from the end of the sequence in O(1), you need a deque (double-ended queue). See Ring buffer, which works as an efficient (both speed and space) dequeue on top of vectors.  Or you can use immutable deques provided by data.ideque (see Immutable deques).

     See also scheme.list-queue (R7RS list queues), which defines a portable API for list-based queue. キュー(FIFO)機能を提供します。極めて軽量ですがスレッドセーフでないシンプルなキューと、スレッドセーフなmtqueueがあります。基本的なキュー操作手続きはどちらのキューに対しても使うことができます。本節で説明されている手続きをmtqueueに適用した場合、特に断りが無い限り、操作はアトミックに行われます。

     また、スレッド間同期に使えるmtqueue用の手続きも用意されています。例えばキューが空の時に読み出しスレッドをブロックさせたりキューの長さが指定値に達した場合に書き込みスレッドをブロックさせることができ、いわゆる「チャネル」としてキューを使うことができます。

     シンプルキューのAPIはSLIBのキュー実装の上位互換になっています。要素を並びの末尾に追加するenqueue!と、要素を並びの先頭から取り除く dequeue!だけでなく、要素を並びの先頭に追加するqueue-push!も提供されているので、スタックとしても使えます。

     要素を並びの末尾からO(1)で取り除くAPIも欲しい場合は、 deque (double-ended queue)が必要です。data.ring-bufferモジュールは、ベクタの上に実装された(空間的にも時間的にも)効率の良いdequeを提供しています (Ring buffer参照)。また、変更不可な両端キューdata.ideque もあります(Immutable deques参照)。

     また、scheme.list-queueはポータブルなリストベースのキューのAPIを提供しています (R7RS list queues)。

 -- Class: <queue>
     A class of simple queue. シンプルなキューのクラスです。

      -- Instance Variable of <queue>: length
          A read-only slot that returns the number of items in the queue. キュー中の要素の数を返す、読み取り専用のスロットです。

 -- Class: <mtqueue>
     A class of mtqueue.  Inherits <queue>. mtqueueのクラスです。<queue>を継承しています。

      -- Instance Variable of <mtqueue>: max-length
          The upper bound of the number of items in the queue. キュー中の要素数の上限を示します。

          If this slot is zero, the queue cannot hold any items, but works as a synchronization device. A writer will block until a reader appears to take the item; a reader will block until a writer appears to give the item. このスロットが0の場合、キューは要素を中に持つことはできませんが、同期デバイスとして動作します。書き込みスレッドは、その要素を受け取る読み出しスレッドが現れるまでブロックし、読み出しスレッドは、要素を渡してくれる書き込みスレッドが現れるまでブロックします。

 -- Function: make-queue
     Creates and returns an empty simple queue. 空のシンプルなキューを作って返します。

 -- Function: make-mtqueue :key max-length
     Creates and returns an empty mtqueue.  When an integer is given to the keyword argument MAX-LENGTH, it is used to initialize the max-length slot. 空のmtqueueを作って返します。整数がMAX-LENGTHに与えられた場合は、それがmax-lengthスロットの値となります。

 -- Function: queue? obj
     Returns #t if OBJ is a queue (either a simple queue or an mtqueue). OBJがキューであれば(シンプルなキューでもmtqueueでも)#tを返します。

 -- Function: mtqueue? obj
     Returns #t if OBJ is an mtqueue. OBJがmtqueueであれば#tを返します。

 -- Function: queue-empty? queue
     Returns #t if OBJ is an empty queue. OBJが空のキューであれば#tを返します。

 -- Function: queue-length queue
     Returns the number of the items in the queue. キューの中にある要素の数を返します。

 -- Function: mtqueue-max-length mtqueue
     Returns the maximum number of items the mtqueue can hold. If the queue doesn't have a limit, #f is returned. キューが保持できる要素の最大数を返します。限度がない場合は#fが返ります。

 -- Function: mtqueue-room mtqueue
     Returns the number of elements the mtqueue can accept at this moment before it hits its maximum length.   For example, if the queue already has the maximum number of elements, 0 is returned. If the queue doesn't have the limit, +inf.0 is returned. 保持できる最大容量に達するまであといくつ要素を受け入れることができるかを示す整数を返します。例えば、既にキューがいっぱいであれば0が返ります。キューに最大容量が設定されていなければ+inf.0が返ります。

     Note that even if this returns a non-zero finite value, subsequent enqueue! may throw an error because of the queue being full. It's because another thread may put an item to the queue between this procedure call and enqueue!.  To avoid this situation, use enqueue/wait! to insert item to mtqueue with finite max-length. この手続きが0以外有限値を返した場合でも、続くenqueue!の呼び出し時点でキューがいっぱいになっている可能性があることに注意してください。この手続きの呼び出しとenqueue!の呼び出しの間に、他のスレッドがキューに要素を入れるかもしれないからです。有限長のmtqueueに確実に要素を挿入したい場合はenqueue/wait!を使ってください。

 -- Function: mtqueue-num-waiting-readers mtqueue
     Returns the number of threads waiting on the mtqueue to read at this moment. The return value is always a nonnegative exact integer.

     Note that the value might change between this procedure's returning the value and your checking it, if some other thread inserts an element into the queue.  To use the value reliably, you need another mutex to restrict putting items in the queue. MTQUEUEからの読み出しで待っているスレッドの数を返します。返り値は常に非負の正確な整数です。

     この手続きが値を返してからその値を使うまでの間に、別のスレッドがキューに要素を挿入したら、待っているスレッドの数は変わってしまうことに注意してください。この手続きの返り値を安全に使うには、キューに値を挿入する部分を別に排他制御する必要があります。

          (define q (make-mtqueue))

          (thread-start! (make-thread (^[] (dequeue/wait! q))))

          (mtqueue-num-waiting-readers q) => 1

          (enqueue! q 'a)

          (mtqueue-num-waiting-readers q) => 0

 -- Function: copy-queue queue
     Returns a copy of the queue. キューqueueのコピーを返します。

 -- Function: enqueue! queue obj :optional more-objs ...
     Add OBJ to the end of QUEUE.  You may give more than one object, and each of them are enqueued in order. OBJをキューQUEUEの末尾に追加します。一つ以上のOBJを与えることができ、その場合はそれらが順にenqueueされます。

     If QUEUE is an mtqueue, all the objects are enqueued atomically; no other objects from other threads can be inserted between the objects given to a single enqueue! call. Besides, if the value of its max-length slot has a positive finite value, and adding OBJs makes the number of elements in QUEUE exceeds max-length, an error is signaled and QUEUE won't be modified. (If max-length is zero, this procedure always fail. Use enqueue/wait! below.) QUEUEがmtqueueの場合、渡されたオブジェクト全ての追加はアトミックに行われます。すなわち、途中に別スレッドが要素を挿入することはありません。さらに、max-lengthスロットが正の有限値を持っており、このenqueue!の実行によってキューの要素数が max-lengthを越えることになる場合は、QUEUEは変更されずエラーとなります。 (max-lengthがゼロの場合、この手続きは常にエラーとなります。下に説明するenqueue/wait!を使ってください。)

 -- Function: queue-push! queue obj :optional more-objs ...
     Add OBJ in front of QUEUE.  You may give more than one object, and each of them are pushed in order.

     Like enqueue!, when QUEUE is an mtqueue, all objects are added atomically, and the value of max-length slot is checked.  See enqueue! above for the details. OBJをキューQUEUEの先頭に追加します。一つ以上のOBJを与えることができ、その場合はそれらが順にpushされます。

     enqueue!と同様に、QUEUEがmtqueueの場合は全てのオブジェクトはアトミックに追加され、またmax-lengthの値もチェックされます。詳しくは上のenqueue!の説明を参照してください。

 -- Function: enqueue-unique! queue eq-proc obj :optional more-objs ...
 -- Function: queue-push-unique! queue eq-proc obj :optional more-objs ...
     Like enqueue! and queue-push!, respectively, except that these don't modify QUEUE if it already contains OBJ (elements are compared by two-argument procedure EQ-PROC).

     When QUEUE is an mtqueue, all objects are added atomically, and the value of max-length slot is checked.  See enqueue! above for the details. OBJが既にQUEUEの中に含まれている場合にはQUEUEを変更しないことを以外には、enqueue!およびqueue-push!と同じ動作をします。OBJが含まれているかどうかの検査は 2引数の関数EQ-PROCで行います。

     QUEUEがmtqueueの場合は全てのオブジェクトはアトミックに追加され、またmax-lengthの値もチェックされます。詳しくは上のenqueue!の説明を参照してください。

 -- Function: dequeue! queue :optional fallback
 -- Function: queue-pop! queue :optional fallback
     Take one object from the front of the queue QUEUE and returns it. Both function works the same, but queue-pop! may be used to emphasize it works with queue-push!.

     If QUEUE is empty, FALLBACK is returned if given, otherwise an error is signaled.

     If QUEUE is an mtqueue and its max-length is zero, the queue is always empty.  Use dequeue/wait! to use such a queue as an synchronization device. キューQUEUEの先頭からひとつ要素を取って返します。二つの手続きは全く同じ動作をします。queue-pop!はqueue-push!とペアで使われていることを強調したいときに使うと良いでしょう。

     キューが空の場合は、FALLBACKが与えられていればそれが返され、そうでなければエラーが報告されます。

     キューがmtqueueでそのmax-lengthがゼロの場合、キューは常に空であるとみなされます。ゼロ長のキューを同期デバイスとして使う場合はdequeue/wait!を使ってください。

 -- Function: dequeue-all! queue
     Returns the whole content of the queue by a list, with emptying QUEUE.   If QUEUE is already empty, returns an empty list. See also queue->list below. キューの全ての内容をリストにして返します。キューそのものは空になります。キューが既に空の場合は空リストが返されます。下のqueue->listも参照してください。

 -- Function: queue-front queue :optional fallback
 -- Function: queue-rear queue :optional fallback
     Peek the head or the tail of the queue and returns the object, respectively. The queue itself is not modified. If QUEUE is empty, FALLBACK is returned if it is given, otherwise an error is signaled. キューQUEUEの先頭もしくは末尾の要素を返します。キューそのものは変更されません。キューが空の場合、FALLBACKが与えられていればその値を返し、そうでなければエラーを報告します。

 -- Function: list->queue list :optional class :rest initargs
     Returns a new queue whose content is the elements in LIST, in the given order.

     By default the created queue is a simple queue, but you can create mtqueue or instances of other subclasses of <queue> by giving the class to the optional CLASS arguments. The optional INITARGS arguments are passed to the constructor of CLASS. 与えられたリストLISTの各要素をその順で持つようなキューを作成して返します。

     デフォルトではシンプルキューが作られますが、CLASSに<class>のサブクラスを渡すことで他のキュークラスのインスタンスを作ることができます。 INITARGSはCLASSのコンストラクタに渡されます。

 -- Function: queue->list queue
     Returns a list whose content is the items in the queue in order. Unlike dequeue-all!, the content of QUEUE remains intact.

     In Gauche, queue->list copies the content of the queue to a freshly allocated list, while dequeue-all! doesn't copy but directly returns the queue's internal list.   There are some Scheme systems that has queue->list but doesn't guarantee the content is copied, so if you're planning to share the code among these implementations, it's better not to rely on the fact that queue->list copies the content. キューQUEUEの内容をリストにして返します。 dequeue-all!と異なり、キューそのものの内容は変化しません。

     Gaucheではqueue->listは新しいリストをアロケートしてキューの内容をコピーします (dequeue-all!はコピーをせずにキューの内部のリストをそのまま返します)。組込みでqueue->listを持っているScheme 実装がいくつかありますが、その中にはqueue->listがキューの内容をコピーすることを保証していないものがあるので、それらの処理系と共有するコードではqueue->listがリストをコピーすることをあてにしない方が良いでしょう。

 -- Function: queue-internal-list queue
     Like queue->list, returns a list whose content is the items in the queue in order, but the returned list may share the internal storage of QUEUE.  The returned list can be modified by subsequent operations of QUEUE, and any modification on the list can make QUEUE inconsistent.

     Because of this danger, we don't allow <mtqueue> to be passed to this procedure; it would signal an error if you do so.

     If you just want to extract the accumulated result in QUEUE without copying, consider dequeue-all!, which is safe because it atomically resets the queue.  Use this procedure only when you absolutely need to access the contents of the queue without taking them out. queue->listと同じように、QUEUEの内容をリストとして返しますが、そのリストはQUEUEの内部構造と共有されているかもしれません。つまり、返されたリストは続くQUEUEへの操作によって変更される可能性があり、また返されたリストを変更するとQUEUEの一貫性は失われるでしょう。

     この危険性のため、<mtqueue>をこの手続きに渡すことは禁じられています。もしそうしたらエラーとなります。

     QUEUEに蓄積されたデータをコピーせずに取り出したいというだけなら、 dequeue-all!を使ってください。それは取り出すのとキューを空にする操作をアトミックに行うので安全です。この手続きは、キューの中身を取り出すこと無く内部にアクセスしたいという場合にだけ使って下さい。

 -- Function: find-in-queue pred queue
     Returns the first item in QUEUE that satisfies a predicate PRED.  The order of arguments follows find (see Other list procedures). キュー内の要素のうち述語PREDを満たす最初の要素を返します。引数の順序はfindに揃えました (Other list procedures参照)。

 -- Function: any-in-queue pred queue
     Like any in SRFI-1, apply PRED on each item in QUEUE until it evaluates true, and returns that true value (doesn't necessarily be #t).  If no items in the queue satisfies PRED, #f is returned. SRFI-1のanyのように、QUEUE中の各要素に順にPREDを適用し、それが真の値 (#tである必要はありません) に評価されたらその値を返します。PREDを満たす要素が無ければ#fが返ります。

 -- Function: every-in-queue pred queue
     Like every in SRFI-1, apply PRED on each item in QUEUE.  If PRED returns #f, stops iteration and returns #f immediately. Otherwise, returns the result of the application of PRED on the last item of the queue.  If the queue is empty, #t is returned. SRFI-1のeveryのように、QUEUE中の各要素に順にPREDを適用し、それが#fを返したらすぐ#fを返します。 PREDに対し#fを返す要素が無ければ、最後の要素にPREDを適用した結果が返ります。キューが空なら#fが返ります。

 -- Function: remove-from-queue! pred queue
     Removes all items in the queue that satisfies PRED. Returns #t if any item is removed.  Otherwise returns #f. The order of arguments follows remove in scheme.list (see R7RS lists). キューから、述語PREDを満たす要素を全て取り除きます。要素が削除された場合は#tが、そうでなければ#fが返されます。引数の順序はscheme.list のremoveに揃えました (R7RS lists参照)。

Note on portability: Scheme48 has delete-from-queue!, which takes object to remove rather than predicate, and also takes arguments in reversed order (i.e. queue comes first).   Avoid conflicting with that I intentionally left out delete-from-queue!; it's easy to write one in either Scheme48 compatible way or consistent to SRFI-1 argument order. 移植性に関する註：Scheme48には、述語ではなく削除するオブジェクトそのものを取る delete-from-queue!がありますが、引数の順序が逆(キューが先)になっています。まぎらわしい衝突を避けるため、敢えてdelete-from-queue!は提供しませんでした。remove-from-queue!を使えば、Scheme48互換の方法でも、あるいはSRFI-1と一貫性のある方法でもdelete-from-queue!を簡単に書けるでしょう。

 -- Function: enqueue/wait! mtqueue obj :optional timeout timeout-val
 -- Function: queue-push/wait! mtqueue obj :optional timeout timeout-val
 -- Function: dequeue/wait! mtqueue :optional timeout timeout-val
 -- Function: queue-pop/wait! mtqueue :optional timeout timeout-val
     These synchronizing variants work on an mtqueue and make the caller thread block when the mtqueue has reached its maximum length (for enqueue/wait! and queue-push/wait!), or the mtqueue is empty (for dequeue/wait! and queue-pop/wait!).   The blocked caller thread is unblocked either when the blocking condition is resolved, or the timeout condition is met.

     The optional TIMEOUT argument specifies the timeout condition. If it is #f, those procedures wait indefinitely. If it is a real number, they wait at least the given number of seconds.  If it is a <time> object (see Time), they wait until the absolute point of time the argument specifies.

     In case the call is blocked then timed out, the value of TIMEOUT-VAL is returned, which defaults to #f.

     When enqueue/wait! and queue-push/wait! succeeds without hitting timeout, they return #t. これらの手続きはMTQUEUEに対して使うことができ、スレッド間同期を実現できます。 enqueue/wait!とqueue-push/wait!は、キューの要素数がMAX-LENGTHを越える場合に、キューに空きができるまで、 dequeue/wait!とqueue-pop/wait!は、キューが空の場合に、キューに要素が追加されるまで、呼び出しスレッドをブロックします。

     TIMEOUT引数で、ブロックされたスレッドのタイムアウトを指定することができます。 #fは指定しなかった場合と同じで、キューの状態が変化するまで無期限に待ちます。実数が渡された場合はそれが秒数と解釈され、最低限その時間経過するまでは待ちます。渡されたのが<time>オブジェクト (Time参照)である場合は、そのオブジェクトが指定する絶対時刻を経過するまで待ちます。

     タイムアウトによりブロックが解かれた場合は、TIMEOUT-VALで指定した値が返されます。TIMEOUT-VALの省略時値は#fです。

     enqueue/wait!とqueue-push/wait!は、タイムアウトせずに操作が成功した場合は#tを返します。

data.random - Random data generators
====================================

 -- Module: data.random
     This module defines a set of generators and generator makers that yield random data of specific type and distribution. このモジュールは、特定のデータ型や、特定の値の分布を持つランダムなデータを生成するジェネレータ、およびそういったジェネレータを作り出すジェネレータ構築器を提供します。

A naming convention: Procedures that takes parameters and returns a generator is suffixed by $ (e.g. integer$). Procedures that are generators themselves are not (e.g. fixnums). Procedures that are combinators, that is, the ones that take one or more generators and returns a generator, generally ends with a preposition (e.g. list-of). 名前付けの規則：パラメータを受け取り、それにそったジェネレータを返す手続きにはサフィックス$がついています (例: integer$)。それ自体がジェネレータである手続きにはサフィックスがつきません (例: fixnums)。コンビネータ、つまり複数のジェネレータを取ってジェネレータを返す手続きの名前は、通常前置詞で終わります (例: list-of)。

Global state
------------

グローバルな状態
--------

All the generators in this module shares a global random state. The random seed is initialized by a fixed value when the module is loaded. You can get and set the random seed by the following procedure. このモジュールのジェネレータはすべて一つのグローバルな乱数状態を共有します。モジュールがロードされた時点で、固定のシードによりこの状態は初期化されます。次の手続きでグローバルな乱数状態のシードを読み出したり、新たな値に設定することができます。

 -- Function: random-data-seed
 -- Function: (setter random-data-seed) seed-value
     Calling random-data-seed (without arguments) returns the random seed value used to initialize the current random state.

     It can be used with generic setter, to reinitialize the random state with SEED-VALUE.

     Random seed value must be an exact integer.  Its lower 32bits are used. 引数無しでrandom-data-seedを呼ぶと、現在の乱数状態を初期化したシード値が返されます。

     ジェネリックなセッターと一緒に使えば、乱数状態をSEED-VALUEをシードとして再初期化することができます。

     ランダムシード値は正確な整数でなければなりません。その下位32ビットが使われます。

          ; reinitialize the random state with a new random seed.
          (set! (random-data-seed) 1)

          (random-data-seed) => 1

     Note: This procedure doesn't have parameter interface (alter the global value by giving the new value as an argument), since it doesn't work like a parameter (see Parameters). You can get the random seed value, but you can't get the current random state itself---if you restore the random seed value again, the internal state is reset, instead of restoring the state at the time you called random-data-seed. 註: この手続きはパラメータインタフェース (引数として値を与えるとそれを新たな値に設定し、以前の値を返す) にはなっていません。本質的に、パラメータとは相容れないからです (Parameters参照)。得られるのは現在の乱数状態の出発点となるシード値であって、現在の乱数状態そのものではありません。一旦別のシード値に切り替えて、その後元のシード値に戻した場合、乱数状態は切り替えた時点に戻るのではなく、あらためて初期化されます。

     If you want to use different random state temporarily, and ensure to restore original state afterwards, use with-random-data-seed below. 乱数状態を一時的に切り替えて、その後で切り替えた時点の状態を確実に回復したい場合は、次に示すwith-random-data-seedを使ってください。

 -- Function: with-random-data-seed seed thunk
     Saves the current global random state, initializes the random state with SEED, then executes THUNK.  If THUNK returns or the control exits out of THUNK, the state at the time with-random-data-seed was called is restored. 現在のグローバルな乱数状態を保存し、乱数状態をSEEDで初期化して THUNKを実行します。THUNKから帰ってくるか、制御がTHUNKを抜け出した場合、乱数状態はwith-random-data-seedが呼び出された時点の状態に戻されます。

Since the default random seed value is fixed, you can get deterministic output when you call the random data generators below without altering the random seed explicitly. デフォルトのランダムシードが固定なのは、何もしなければ再現可能な振る舞いが得られるからです。

Generators of primitive data types
----------------------------------

プリミティブデータ型のジェネレータ
-----------------

Those generators generate uniformly distributed data. 以下のジェネレータは特に断りが無い限り、一様分布するデータを生成します。

In the following examples, we use generator->list to show some concrete data from the generators.  It is provided in gauche.generator module.  See Generators, for more utilities work on generators. 例の中では、生成された値を具体的に示すために gauche.generatorモジュールのgenerator->listを使っています。ジェネレータを扱うユーティリティについては Generatorsを参照してください。

 -- Function: integers$ size :optional (start 0)
 -- Function: integers-between$ lower-bound upper-bound
     Create exact integer generators.  The first one, integers$, creates a generator that generates integers from start (inclusive) below start+size (exclusive) uniformly.  The second one, integers-between$, creates a generator that generates integers between LOWER-BOUND and UPPER-BOUND (both inclusive) uniformly. 正確な整数のジェネレータを作成します。 integer$が返すジェネレータは、 START 以上 START + SIZE 未満の整数を一様に発生させます。 integers-between$はが返すジェネレータは、LOWER-BOUND以上、 UPPER-BOUND以下の整数を一様に発生させます。

          ;; A dice roller
          ;; サイコロ
          (define dice (integers$ 6 1))

          ;; Roll the dice 10 times
          ;; サイコロを10回振ってみる
          (generator->list dice 10)
           => (6 6 2 4 2 5 5 1 2 2)

 -- Function: fixnums
 -- Function: int8s
 -- Function: uint8s
 -- Function: int16s
 -- Function: uint16s
 -- Function: int32s
 -- Function: uint32s
 -- Function: int64s
 -- Function: uint64s
     Uniform integer generators.  Generate integers in fixnum range, and 8/16/32/64bit signed and unsigned integers, respectively. 固定範囲の一様整数ジェネレータです。それぞれ、fixnumおよび8/16/32/64ビットの符号つき/符号無し整数を生成します。

          (generator->list int8s 10)
           => (20 -101 50 -99 -111 -28 -19 -61 39 110)

 -- Function: booleans
     Generates boolean values (#f and #t) in equal probability. 真偽値(#fと#t)を等確率で生成します。

          (generator->list booleans 10)
           => (#f #f #t #f #f #t #f #f #f #f)

 -- Function: chars$ :optional char-set
     Creates a generator that generates characters in CHAR-SET uniformly. The default CHAR-SET is #[A-Za-z0-9]. CHAR-SETにある文字を一様分布で生成するジェネレータを作ります。 CHAR-SETが省略された場合は#[A-Za-z0-9]が使われます。

          (define alphanumeric-chars (chars$))

          (generator->list alphanumeric-chars 10)
           => (#\f #\m #\3 #\S #\z #\m #\x #\S #\l #\y)

 -- Function: reals$ :optional size start
 -- Function: reals-between$ lower-bound upper-bound
     Create a generator that generates real numbers uniformly with given range. The first procedure, reals$, returns reals between start and start+size, inclusively.  The default of size is 1.0 and start is 0.0. The second procedure, reals-between$, returns reals between lower-bound and upper-bound, inclusively. 与えられた範囲の実数値を一様に生成するジェネレータを返します。 reals$の返すジェネレータは、 START 以上 START + SIZE 以下の実数値を生成します。 SIZEのデフォルト値は1.0、STARTのデフォルト値は0.0です。 reals-between$の返すジェネレータは、 LOWER-BOUND以上UPPER-BOUND以下の実数値を生成します。

          (define uniform-100 (reals$ 100))

          (generator->list uniform-100 10)
           => (81.67965004942268 81.84927577572596 53.02443813660833)

     Note that a generator from reals$ can generate the upper-bound value start+size, as opposed to integers$.  If you need to exclude the bound value, just discard the bound value; gfilter may come handy. reals$の返すジェネレータは、integer$と違って上限の値を生成し得ることに注意してください。限界値を除外したい場合は、 gfilter等を使ってその値を棄却します。

          (define generate-from-0-below-1
            (gfilter (^r (not (= r 1.0))) (reals$ 1.0 0.0)))

 -- Function: samples$ collection
     Creates a generator that returns randomly chosen item in COLLECTION at a time.

     Do not confuse this with samples-from below, which is to combine multiple generators for sampling. コレクションCOLLECTIONから毎回ランダムにひとつ要素を選んで返すジェネレータを作成します。

     下で説明するsamples-fromと混同しないようにしてください。samples-from は複数のジェネレータを組み合わせてサンプリングするものです。

          (define coin-toss (samples$ '(head tail)))

          (generator->list coin-toss 5)
           => (head tail tail head tail)

 -- Function: regular-string$ regexp
     Creates an infinite generator that generates random strings each of which matches the given REGEXP.  The REGEXP shouldn't include conditional patterns and lookahead/behind assertions.

     Note: It is hard to define how the distribution of the generated strings should look like.  For now, we build an NFA from regexp and put the same probability when there are multiple choices, but that may not be really useful for typical use cases (e.g. generate test data). Please assume the current implementation strategy a provisional one. 与えられたREGEXPにマッチするランダムな文字列を生成し続けるジェネレータを作って返します。REGEXPには条件付きパターン、lookahead/lookbehindアサーションを含めないでください。

     註: 生成される文字列の分布をどうすべきかというのは難しい問題です。現在の実装は単純に、内部で正規表現からNFAを生成し、複数の選択肢がある場合は等しい重みでランダムに選択していますが、それが目的(例えばテストデータの生成)にふさわしいかどうかはまだわかりません。現在の実装は暫定的なものと考えてください。

Nonuniform distributions
------------------------

非一様分布
-----

 -- Function: reals-normal$ :optional mean deviation
     Creates a generator that yields real numbers from normal distribution with MEAN and DEVIATION.  The default of MEAN is 0.0 and DEVIATION is 1.0. 期待値MEAN、標準偏差DEVIATIONの正規分布に従って実数値を生成するジェネレータを作ります。省略時はMEANが0.0、DEVIATIONが 1.0になります。

 -- Function: reals-exponential$ mean
     Creates a generator that yields real numbers from exponential distribution with MEAN. 期待値MEANの指数分布に従って実数値を生成するジェネレータを作ります。

 -- Function: integers-geometric$ p
     Creates a generator that yields integers from geometric distribution with success probability P (0 <= p <= 1).  The mean is 1/p and variance is (1-p)/p^2. 成功確率P (0 ≦ p ≦ 1) である幾何分布に従って非負整数値を生成するジェネレータを作ります。期待値は1/p、分散は(1-p)/p^2になります。

 -- Function: integers-poisson$ L
     Creates a generator that yields integers from poisson distribution with mean L, variance L. 期待値Lのポアソン分布に従う非負整数値を生成するジェネレータを作ります。分散もLになります。

Aggregate data generators
-------------------------

複合データ型のジェネレータ
-------------

 -- Function: samples-from generators
     Takes a finite sequence of generators (sequence in the sense of gauche.sequence), and returns a generator.  Every time the resulting generator is called, it picks one of the input generators in equal probability, then calls it to get a value. ジェネレータの有限シーケンス (ここではgauche.sequenceがシーケンスとして扱うもの) を取り、新たなジェネレータを返します。返されたジェネレータは、値を必要とする度に、入力となるジェネレータのどれかを等確率で選んで、その入力ジェネレータから値を取ります。

          (define g (samples-from (list uint8s (chars$ #[a-z]))))

          (generator->list g 10)
           => (207 107 #\m #\f 199 #\o #\b 57 #\j #\e)

     NB: To create a generator that samples from a fixed collection of items, use samples$ described above. 註: 固定した要素の集まりからサンプルするジェネレータを作るには、上の方で説明したsamples$を使ってください。

 -- Function: weighted-samples-from weight&gens
     The argument is a list of pairs of a nonnegative real number and a generator. The real number determines the weight, or the relative probability that the generator is chosen.  The sum of weight doesn't need to be 1.0. 引数は、非負の実数値とジェネレータのペアのリストです。実数値が「重み」、すなわちペアとなっているジェネレータが選ばれる相対確率を決定します。重みの総和が1.0である必要はありません。

     The following example chooses the uint8 generator four times frequently than the character generator. 次の例では、uint8ジェネレータは文字ジェネレータより4倍頻繁に使われます。

          (define g (weighted-samples-from
                     `((4.0 . ,uint8s)
                       (1.0 . ,(chars$)))))

          (generator->list g 10)
           => (195 97 #\j #\W #\5 72 49 143 19 164)

 -- Function: pairs-of car-gen cdr-gen
     Returns a generator that yields pairs, whose car is generated from CAR-GEN and whose cdr is generated from CDR-GEN. ペアを生成するジェネレータを作ります。各ペアのcarはジェネレータCAR-GEN、 cdrはジェネレータCDR-GENによって生成されます。

          (define g (pairs-of int8s booleans))

          (generator->list g 10)
           => ((113 . #t) (101 . #f) (12 . #t) (68 . #f) (-55 . #f))

 -- Function: tuples-of gen ...
     Returns a generator that yields lists, whose i-th element is generated from the i-th argument. リストを生成するジェネレータを作ります。各リストのi番目の要素はi番目の引数のジェネレータによって生成されます。

          (define g (tuples-of int8s booleans (char$)))

          (generator->list g 3)
           => ((-43 #f #\8) (53 #f #\1) (-114 #f #\i))

 -- Function: permutations-of seq
     Returns a generator that yields a random permutations of SEQ.

     The type of SEQ should be a sequence with a builder (see Sequence framework).  The type of generated objects will be the same as SEQ. シーケンスSEQの要素をランダムに並べ替えたシーケンスを生成するジェネレータを作ります。

     SEQの型は、ビルダーを持つシーケンスである必要があります (Sequence framework参照)。生成されるオブジェクトは SEQと同じ型になります。

          (generator->list (permutations-of '(1 2 3)) 3)
           => ((1 2 3) (2 3 1) (3 2 1))

          (generator->list (permutations-of "abc") 3)
           => ("cba" "cba" "cab")

 -- Function: combinations-of size seq
     Returns a generator that yields a sequence of SIZE elements randomly picked from SEQ.

     The type of SEQ should be a sequence with a builder (see Sequence framework).  The type of generated objects will be the same as SEQ. シーケンスSEQからランダムにSIZE個の要素を取り出して並べたシーケンスを生成するジェネレータを作ります。

     SEQの型は、ビルダーを持つシーケンスである必要があります (Sequence framework参照)。生成されるオブジェクトは SEQと同じ型になります。

          (generator->list (combinations-of 2 '(a b c)) 5)
           => ((a c) (a b) (a c) (b a) (a c))

          (generator->list (combinations-of 2 '#(a b c)) 5)
           => (#(a c) #(b c) #(c b) #(b a) #(b c))

The following procedures takes optional SIZER argument, which can be either a nonnegative integer or a generator of nonnegative integers. The value of the sizer determines the length of the result data. 以下の手続きは、省略可能なSIZER引数を取ります。 SIZER引数は非負整数か、非負整数を生成するジェネレータで、その値(もしくは生成された値)が、最終的に生成されるデータの長さを決定します。

Unlike most of Gauche procedures, SIZER argument comes before the last argument when it is not omitted. We couldn't resist the temptation to write something like (lists-of 3 booleans). Gaucheの他のほとんどの手続きと違って、SIZER引数は省略されない時は最後の引数よりも前に来ます。これは統一性を損ないますが、 (lists-of 3 booleans) のように書ける、という誘惑に勝てませんでした。

If SIZER is omitted, the default value is taken from the parameter default-sizer.  The default of default-sizer is (integers-poisson$ 4). SIZER引数が省略された場合、パラメータdefault-sizerの値が使われます。default-sizerのデフォルトは (integers-poisson$ 4)で作られるジェネレータです。

 -- Function: lists-of item-gen
 -- Function: lists-of sizer item-gen
 -- Function: vectors-of item-gen
 -- Function: vectors-of sizer item-gen
 -- Function: strings-of
 -- Function: strings-of item-gen
 -- Function: strings-of sizer item-gen
     Creates a generator that generates lists, vectors or strings of values from ITEM-GEN, respectively.  The size of each datum is determined by SIZER. それぞれ、リスト、ベクタ、文字列を生成するジェネレータを作ります。作られるデータの各要素はジェネレータITEM-GENから取られます。各データの長さはSIZERにより決定されます。

     You can also omit ITEM-GEN for strings-of.  In that case, a generator created by (chars$) is used. strings-ofの場合はITEM-GENも省略することができます。その場合は、(chars$)で作られるジェネレータが使われます。

          (generator->list (lists-of 3 uint8s) 4)
           => ((254 46 0) (77 158 46) (1 134 156) (74 5 110))

          ;; using the default sizer
          ;; デフォルトのsizerを使う
          (generator->list (lists-of uint8s) 4)
           => ((93 249) (131 97) (98 206 144 247 241) (126 156 31))

          ;; using a generator for the sizer
          ;; sizerにジェネレータを使う
          (generator->list (strings-of (integers$ 8) (chars$)) 5)
           => ("dTJYVhu" "F" "PXkC" "w" "")

 -- Function: sequences-of class item-gen
 -- Function: sequences-of class sizer item-gen
     Creates a generator that yields sequences of class CLASS, whose items are generated by ITEM-GEN.  The size of each sequence is determined by SIZER, or the value of default-sizer if omitted; the sizer can be a nonnegative integer, or a generator that yields nonnegative integers.

     The class CLASS must be a subclass of <sequence> and implement the builder interface. クラスCLASSのインスタンスであるシーケンスを生成するジェネレータを作ります。シーケンスの要素はITEM-GENにより生成されます。各シーケンスの長さはSIZER引数 (省略時はdefault-sizerの値) によって決められます。SIZERは非負整数か、非負整数を生成するジェネレータです。

     CLASSは<sequence>のサブクラスであり、ビルダーインタフェースを実装していなければなりません。

          (generator->list (sequences-of <u8vector> 4 uint8s) 3)
           => (#u8(95 203 243 46) #u8(187 199 153 152) #u8(39 114 39 25))

 -- Parameter: default-sizer
     The sizer used by lists-of, vectors-of and strings-of when SIZER argument is omitted.

     The value must be either an nonnegative integer, or a generator of nonnegative integers. lists-of、vectors-of、strings-ofで SIZER引数が省略された場合に使われるsizerです。

     値は、非負整数か、非負整数を生成するジェネレータでなければなりません。

data.ring-buffer - Ring buffer
==============================

 -- Module: data.ring-buffer
     A ring buffer is an array with two fill pointers; in a typical usage, a producer adds new data to one end while a consumer removes data from the other end; if fill pointer reaches at the end of the array, it wraps around to the beginning, hence the name. リングバッファは、両端を指す二つのポインタを持つ配列と考えられます。良くある使い方は、生産者が配列の一方の端にデータを追加してゆき、消費者がもう一方の端からデータを取り出してゆくというものです。もし端を示すポインタが配列の終端に達したら、それはもう一方の端につながっているように振る舞います。「リング」バッファと呼ばれるのはそのためです。

     The ring buffer of this module allows adding and removing elements from both ends, hence functionally it is a double-ended queue, or deque.  It also allows O(1) indexed access to the contents, and customized handling for the case when the buffer gets full. このモジュールの提供するリングバッファは、どちらの端にもデータを追加し、どちらの端からもデータを取り出すことができます。したがって機能的には両端キュー(double-ended queue, deque)の一種とも考えられます。また、O(1)で要素にアクセス可能で、さらにバッファが一杯になった時の振る舞いをカスタマイズできます。

     You can use an ordinary vector or a uniform vector as the backing storage of a ring buffer. リングバッファがデータを格納するバッキングストレージとして、通常のベクタかユニフォームベクタを使えます。

 -- Function: make-ring-buffer :optional initial-storage :key overflow-handler
     Creates a ring buffer.  By default, a fresh vector is allocated for the backing storage.  You can pass a vector or a uvector to INITIAL-STORAGE to be used instead.  The passed storage must be mutable, and will be modified by the ring buffer; the caller shouldn't modify it, nor make assumption about its content. リングバッファを作成します。デフォルトでは、データ格納のための領域として新たなベクタがアロケートされます。かわりに、呼び出し側でベクタかユニフォームベクタを用意してINITIAL-STORAGEに渡すこともできます。その場合、渡すベクタやユニフォームベクタは変更可能でなければなりません。以降、リングバッファがそのベクタを変更するので、呼び出し側でベクタを変更したりベクタの内容が保存されることを期待してはいけません。

     The OVERFLOW-HANDLER keyword argument specifies what to do when a new element is about to be added to the full buffer. It must be a procedure, or a symbol error or overwrite. OVERFLOW-HANDLERキーワード引数は、バッファがフルの状態で新たな要素が追加されようとした時の振る舞いを指定します。引数は手続きか、シンボルerrorかoverwriteのいずれかでなければなりません。

     If it is a procedure, it will be called with a ring buffer and a backing storage (vector or uvector) when it is filled.  The procedure must either (1) allocate and return a larger vector/uvector of the same type of the passed backing storage, (2) return a symbol error, or (3) return a symbol overwrite.  If it returns a vector/uvector, it will be used as the new backing storage.  The returned vector doesn't need to be initialized; the ring buffer routine takes care of copying the necessary data. If it returns error, an error (``buffer is full'') is thrown.  If it returns overwrite, the new element overwrites the existing element (as if one element from the other end is popped and discarded.) 引数が手続きの場合、リングバッファと(一杯になった)バッキングストレージが引数として渡されます。この手続きは以下の3つのアクションのうちひとつを実行しなければなりません。(1)渡されたバッキングストレージ(ベクタかユニフォームベクタ)と同じ型で、より大きなベクタまたはユニフォームベクタをアロケートして返す。(2)シンボルerrorを返す。(3)シンボルoverwriteを返す。手続きがベクタもしくはユニフォームベクタを返した場合は、それが新たなバッキングストレージとして使われます。返すベクタの内容を設定する必要はありません。リングバッファが適切に内容のコピーや必要な初期化を行います。手続きがerrorを返した場合は、 ``buffer is full''のエラーが投げられます。手続きがoverwriteを返した場合は、新たな要素で古い要素を上書きします(つまり、あたかも別の端から1要素がポップされて捨てられ、その後で新たな要素が追加されたかのように振る舞います)。

     Passing a symbol error or overwrite to OVERFLOW-HANDLER is a shorthand of passing a procedure that unconditionally returns error or overwrite, respectively. OVERFLOW-HANDLER引数にシンボルerrorかoverwrite を渡した場合は、あたかもそれらのシンボルを無条件に返すoverflow handlerが指定されたかのように振る舞います。

     The default behavior on overflow is to double the size of backing storage.  You can use make-overflow-doubler below to create the customized overflow handler easily. OVERFLOW-HANDLERが指定されない場合のデフォルトの動作は、元のバッキングストレージの倍の容量をアロケートして返すことです。下のmake-overflow-doublerを使うと、カスタマイズしたオーバフローハンドラを簡単に作ることができます。

 -- Function: make-overflow-doubler :key max-increase max-capacity
     Returns a procedure suitable to be passed to the OVERFLOW-HANDLER keyword argument of make-ring-buffer.

     The returned procedure takes a ring buffer and its backing storage, and behaves as follows. make-ring-bufferのOVERFLOW-HANDLERキーワード引数に渡せる手続きを作って返します。

     返される手続きは、リングバッファとバッキングストレージを引数に取り、以下のとおり振る舞います。

       * If the size of current backing storage is equal to or greater than MAX-CAPACITY, returns error. 現在のバッキングストレージの大きさがMAX-CAPACITY以上であれば、 errorを返す。

       * Otherwise, if the size of current backing storage is equal to or greater than MAX-INCREASE, allocates a vector/uvector of the same type of the current backing storage, with the size (+ max-increase size-of-current-storage). そうではなく、現在のバッキングストレージの大きさがMAX-INCREASE以上であれば、(+ max-increase 現在の大きさ)の大きさを持つベクタもしくはユニフォームベクタをアロケートして返す。

       * Otherwise, allocates a vector/uvector of the same type of the current backing storage with the size (* 2 size-of-current-storage). そうでない場合は、(* 2 現在の大きさ) の大きさを持つベクタもしくはユニフォームベクタをアロケートして返す。

     The default value of MAX-INCREASE and MAX-CAPACITY is +inf.0. MAX-INCREASEとMAX-CAPACITYのデフォルト値はどちらも +inf.0です。

 -- Function: ring-buffer-empty? rb
     Returns #t if the ring buffer RB is empty, #f if not. リングバッファRBが空なら#tを、そうでなければ#fを返します。

 -- Function: ring-buffer-full? rb
     Returns #t if the ring buffer RB is full, #f if not. リングバッファRBがフルなら#tを、そうでなければ#fを返します。

 -- Function: ring-buffer-num-entries rb
     Returns the number of current elements in the ring buffer RB. リングバッファRBが格納している要素数を返します。

 -- Function: ring-buffer-capacity rb
     Returns the size of the current backing storage of the ring buffer RB. リングバッファの現在のバッキングストレージの容量(格納可能な要素数)を返します。

 -- Function: ring-buffer-front rb
 -- Function: ring-buffer-back rb
     Returns the element in the front or back of the ring buffer RB, respectively. If the buffer is empty, an error is signaled. リングバッファRBの先頭あるいは末尾の要素をそれぞれ返します。バッファが空の場合はエラーが投げられます。

 -- Function: ring-buffer-add-front! rb elt
 -- Function: ring-buffer-add-back! rb elt
     Add an element to the front or back of the ring buffer RB, respectively.  If RB is full, the behavior is determined by the buffer's overflow handler, as described in make-ring-buffer. リングバッファRBの先頭もしくは末尾にそれぞれ要素を追加します。 RBがフルの場合の振る舞いは、バッファのオーバーフローハンドラによって決定されます。詳しくはmake-ring-bufferのエントリを参照してください。

 -- Function: ring-buffer-remove-front! rb
 -- Function: ring-buffer-remove-back! rb
     Remove an element from the front or back of the ring buffer RB, and returns the removed element, respectively. If the buffer is empty, an error is signaled. リングバッファRBの先頭もしくは末尾から要素をひとつ取り、取った要素を返します。バッファが空の場合はエラーが投げられます。

 -- Function: ring-buffer-ref rb index :optional fallback
     Returns INDEX-th element in the ring buffer RB. The elements are counted from the front; thus, if a new element is added to the front, the indexes of existing elements will shift.

     If the index out of bounds of the existing content, FALLBACK will be returned; if FALLBACK is not provided, an error is signaled. リングバッファRBのINDEX番目の要素を返します。要素は先頭から数えられます。したがって、新たな要素が先頭に付け加えられた場合、既存の要素のインデックスはひとつづつずれます。

     INDEXがRBの持つ要素の範囲外の場合、FALLBACKが与えられていればそれを返し、そうでなければエラーが投げられます。

 -- Function: ring-buffer-set! rb index value
     Sets INDEX-th element of the ring buffer RB to VALUE. The elements are counted from the front; thus, if a new element is added to the front, the indexes of existing elements will shift.

     An error is signaled if the index is out of bounds. リングバッファRBのINDEX番目の要素にVALUEをセットします。要素は先頭から数えられます。したがって、新たな要素が先頭に付け加えられた場合、既存の要素のインデックスはひとつづつずれます。

     INDEXがRBの持つ要素の範囲外の場合はエラーが投げられます。

data.skew-list - Skew binary random-access lists
================================================

 -- Module: data.skew-list
     This module implements skew binary random-access list (we call it skew-list for short).  It's an immutable data structure that has properties of both list and vector; constant time to take the first element (car) and append an element in front of existing one (cons), O(log n) to take the rest of the elements (cdr), and O(log n) for indexed access, wher n is the number of elements.

     A skew-list is always 'proper'; that is, it is either an empty skew-list (skew-list-null), or an object appended in front of a skew-list.

 -- Class: <skew-list>
     The class for skew-lists.

     It inherits <sequence> and follws the sequence protocol.

 -- Function: skew-list? obj
     Returns #t iff OBJ is a skew-list.

 -- Function: skew-list-empty? sl
     The argument must be a skew list.  Returns #t iff SL is an empty skew list.

 -- Variable: skew-list-null
     An empty skew list.

 -- Function: skew-list-cons obj sl
     Returns a new skew-list which has OBJ prepended to a skew-list SL.

 -- Function: skew-list-car sl
     Returns the first element of a skew-list SL.  An error is raised when SL is empty.

 -- Function: skew-list-cdr sl
     Returns a new skew-list that containts elements in SL but the firest one.  An error is raised when SL is empty.

 -- Function: skew-list-ref sl k :optional fallback
     Returns the K-th element of a skew-list SL.  If K points past the range of SL, FALLBACK is returned if it is given, or an error is signaled.

     Sicne a skew-list is also a sequence, you can use generic ref as well (see Sequence framework.

 -- Function: skew-list-set sl k obj
     Returns a new skew-list which is the same as SL except the K-th element is replaced with OBJ.  The argument SL remains intact.

     It is an error if K points beyond the last element of SL.

 -- Function: skew-list-length sl
     Returns an integer length of a skew-list SL.

     Sicne a skew-list is also a sequence, you can use generic size-of as well (see Sequence framework.

 -- Function: skew-list-length<=? sl n
     Returns #t iff the length of a skew-list SL is less than or equal to N.  It is more efficient than calculating the total length and compares with N.

 -- Function: list->skew-list lis
     Returns a new skew-list which contains elements in LIS, with the same order.  It is an error if LIS is not a proper list.

     Sicne a skew-list is also a sequence, you can use generic coerce-to as well (see Sequence framework.

 -- Function: list*->skew-list lis
     The argument LIS may be an improper list (but can't be circular). Returns two values: a new skew-list which contains elements in LIS except the last cdr of it, and the last cdr of LIS.

 -- Function: skew-list->list sl
     Returns a new list that contains all the elements in a skew-list SL, with the same order.

     Sicne a skew-list is also a sequence, you can use generic coerce-to as well (see Sequence framework.

 -- Function: skew-list->generator sl
     Returns a new generator that traverses a skew-list SL.

 -- Function: skew-list->lseq sl
     Converts a skew-list SL to a lazy sequence.

 -- Function: skew-list-take sl k
 -- Function: skew-list-drop sl k
     Returns a new skew-list of the first K elements and the elements except the first K elements, respectively.

 -- Function: skew-list-split-at sl k
     Returns two values, the result of (skew-list-take sl k) and (skew-list-drop sl k), but more efficiently.

 -- Function: skew-list-append sl sl2 ...
     Returns a skew-list which is a concatenation of all the given skew-lists.

 -- Function: skew-list-fold sl kons knil
     Like FOLD on a list.

     Sicne a skew-list is also a sequence, you can use generic fold as well (see Sequence framework.

 -- Function: skew-list-map sl proc
     Returns a skew list, each element of which is the result of applying PROC on the element of SL.

     NB: If you want ot map over multiple skew-lists, you can use generic map (see Sequence framework).  The skew-list-map employs optimization that's specific to one-argument case.

data.sparse - Sparse data containers
====================================

 -- Module: data.sparse
     This module provides a sparse vector and sparse matrix, a space efficient data container indexed by nonnegative integer(s), and a sparse table, a hash table using a sparse vector as a backing storage. このモジュールは、非負整数でインデックスされる空間効率の良いデータ構造である疎ベクタ (sparse vector)と疎行列 (sparse matrix)、および疎ベクタを格納領域に用いるハッシュテーブルである疎テーブル (sparse table) を提供します。

A sparse vector associates a nonnegative integer index to a value.  It has vector in its name since it is indexed by an integer, but it isn't like a flat array on contiguous memory; it's more like an associative array.  (Internally, the current implementation uses compact trie structure.) It is guaranteed that you can store a value with index at least up to 2^32-1; the actual maximum bits of indexes can be queried by sparse-vector-max-index-bits. (We have a plan to remove the maximum bits limitation in future). 疎ベクタは非負整数のインデックスと値を関連付けます。整数でインデックスされるので名前にベクタがついていますが、連続するメモリに置かれる配列ではなく、むしろ連想配列のようなものです。 (内部的には、現在の実装はコンパクトなトライを使っています)。少なくとも2^32-1までのインデックスが使えることは保証されています。実装が許す最大のインデックスのビット長は sparse-vector-max-index-bitsで得ることができます。 (将来的にはこの制限を無くす計画です)。

Unlike ordinary vectors, you don't need to specify the size of a sparse vector when you create one.  You can just set a value to any index in the supported range. 通常のベクタと違い、疎ベクタは作る時に大きさを指定する必要がありません。サポートされている範囲内ならどんなインデックスにでも単に値を格納できます。

     (define v (make-sparse-vector))

     (sparse-vector-set! v 0 'a)
     (sparse-vector-ref v 0) => a

     (sparse-vector-set! v 100000000 'b)
     (sparse-vector-ref v 100000000) => b

     ;; set! also work
     (set! (sparse-vector-ref v 100) 'c)
     (sparse-vector-ref v 100) => c

If you try to access an element that hasn't been set, an error is signaled by default.  You can set a default value for each vector, or give a fallback value to sparse-vector-ref, to suppress the error. 値がセットされていない要素にアクセスすると、デフォルトではエラーが通知されます。ベクタごとに既定値を設定したり、 sparse-vector-refの省略可能引数にフォールバック値を渡すことでエラーを回避できます。

     (sparse-vector-ref v 1)        => error
     (sparse-vector-ref v 1 'noval) => noval

     (let1 w (make-sparse-vector #f :default 'x)
       (sparse-vector-ref w 1))     => x

A sparse matrix is like a sparse vector, except it can be indexed by a pair of integers. 疎行列は、二つの整数でインデックスされるという点以外は疎なベクタと同じです。

A sparse table works just like a hash table, but it uses a sparse vector to store the values using hashed number of the keys. 疎テーブルはハッシュテーブルと同じように動作しますが、キーのハッシュ値をインデックスとして値を疎ベクタに格納しています。

The main reason of these sparse data containers are for memory efficiency.   If you want to store values in a vector but knows you'll use only some entries sparsely, obviously it is waste to allocate a large vector and to leave many entries unused. But it is worse than that; Gauche's GC doesn't like a large contiguous region of memory.  Using lots of large vectors adds GC overhead quickly.  It becomes especially visible when you store large number of entries (like >100,000) into hash tables, since Gauche's builtin hash tables use a flat vector as a backing storage.   You'll see the heap size grows quickly and GC runs more frequently and longer. On the other hand, sparse table works pretty stable with large number of entries. これらの疎なデータコンテナの主な目的は、メモリ効率です。ベクタに値を入れておきたいけれどごく一部のインデックスしか使わないことが分かっている、と言った場合に、巨大なベクタをアロケートしてその大部分を使わないでおくのは明らかに無駄でしょう。ただそれだけではありません。 Gaucheのガベージコレクタは、一続きの巨大なメモリ領域を確保するのとあまり相性が良くありません。大きなベクタを大量に使うとGCのオーバヘッドが急速に増えます。 Gaucheの組み込みハッシュテーブルはデータストアに通常のベクタを使っているのですが、大量のデータを詰め込むとその効果が目に見えてきます。ヒープサイズが急に増え、 GCはより頻繁に走り、しかも一回一回に要する時間は長くなるでしょう。一方で、疎テーブルは大量のデータに対してもかなり安定に動作します。

Sparse data containers does have overhead on access speed. They are a bit slower than the ordinary hash tables, and much slower than ordinary vectors.  We should note, however, as the number of entries grow, access time on ordinary hash tables grows quicker than sparse tables and eventually two become comparable. 疎なデータコンテナは、単純なデータコンテナに比べるとアクセスにオーバヘッドはあります。通常のハッシュテーブルより若干遅いですし、通常のベクタと比べるとかなり遅いです。けれども、テーブル内のデータ数が大きくなる領域では、通常のハッシュテーブルのアクセス時間の方が急速に悪化するため、いずれ二つのアクセス時間はそこそこ同じになります。

It depends on your application which you should use, and if you're not sure, you need to benchmark. As a rule of thumb, if you use more than several hashtables each of which contains more than a few tens of thousands of entries, sparse tables may work better. If you see GC Warnings telling ``repeated allocation of large blocks'', you should definitely consider sparse tables. どちらを使うべきかはアプリケーションに依存します。良く分からないのであれば、ベンチマークを取りましょう。簡単な基準としては、数万以上のエントリを持つハッシュテーブルを数個以上作るなら、疎テーブルの方が良くなるかもしれません。実行中に``repeated allocation of large blocks''というGCからの警告を目にしたなら、疎テーブルへの切り替えを考えてみましょう。

Sparse vectors
--------------

 -- Class: <sparse-vector-base>
     An abstract base class of sparse vectors. Inherits <dictionary> and <collection>. Note that sparse vectors are not <sequence>; even they can be indexable by integers, they don't have means of ordered access.

     Sparse vector may be a general vector that can contain any Scheme objects (like <vector>), or a specialized vector that can contain only certain types of numbers (like <s8vector> etc.).

     All of these sparse vectors can be accessed by the same API.

     Sparse vectors also implements the Collection API (see Collection framework) and the Dictionary API (see Dictionary framework). 疎なベクタの抽象ベースクラスです。<dictionary>と<collection>を継承しています。<sequence>は継承していないことに注意してください。疎なベクタは整数でインデクス可能ですが、インデクスの順番に要素にアクセスする手段を持っていません。

     疎なベクタは、<vector>と同様、任意のSchemeオブジェクトを格納可能であるものもあれば、<s8vector>等と同様に特定の範囲の数値のみ格納可能なものもあります。全ての疎なベクタは同一セットのAPIで利用可能です。

     疎なベクタはまた、コレクションAPIとディクショナリAPIを実装しています。これらについては Collection frameworkおよびDictionary frameworkを参照してください。

 -- Class: <sparse-vector>
 -- Class: <sparse-@vector>
     The actual sparse vector classes.  Inherits <sparse-vector-base>. An instance of <sparse-vector> can contain any Scheme objects.

     @ is either one of s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, or f64. The range of values an instance of those classes can hold is the same as the corresponding <@vector> class in gauche.uvector (see Uniform vectors).  That is, <sparse-u8vector> can have exact integer values between 0 and 255. 疎なベクタの具体クラスです。それぞれ<sparse-vector-base>を継承します。

     <sparse-vector>のインスタンスは任意のSchemeオブジェクトを格納できます。

     @は s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, f64のいずれかで、それぞれの疎なベクタの格納可能な値は、gauche.uvectorの対応する<@vector>に準じます(Uniform vectors参照)。つまり、<sparse-u8vector>の要素には0以上255以下の正確な整数を格納できます。

 -- Function: make-sparse-vector :optional type :key default
     Creates an empty sparse vector.  The TYPE argument can be #f (default), one of subclasses of <sparse-vector-base>, or a symbol of either one of s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, or f64.

     If TYPE is omitted or #f, a <sparse-vector> is created.  If it is a class, an instance of the class is created (It is an error to pass a class that is not a subclass of <sparse-vector-base>.) If it is a symbol, an instance of corresponding <sparse-@vector> is created. 空の疎なベクタを作成して返します。TYPE引数は#f(デフォルト)か、 <sparse-vector-base>のサブクラスのどれか、あるいはシンボルs8, u8, s16, u16, s32, u32, s64, u64, f16, f32, f64のいずれかを指定できます。

     TYPEが省略されるか#fの場合は<sparse-vector>のインスタンスが作られます。TYPEがクラスであればそのインスタンスが、またシンボルであれば、対応する<sparse-@vector>のインスタンスが作られます。

     You can specify the default value of the vector by DEFAULT keyword argument.   If given, the vector behaves as if it is filled with the default value (but the vector iterator only picks the values explicitly set).

     Note that you have to give the optional argument as well to specify the keyword argument. キーワード引数DEFAULTによって、作成するベクタの要素既定値を指定できます。この引数が与えられると、ベクタは全てあらかじめその値で埋められているかのように振る舞います (ただしイテレータは陽にセットされた値のみ取り出します)。

     キーワード引数を与える場合、それに先立って省略可能引数も与える必要があることに注意してください。

          (define v (make-sparse-vector 'u8 :default 128))

          (sparse-vector-ref v 0) => 128

 -- Function: sparse-vector-max-index-bits
     Returns maximum number of bits of allowed integer.  If this returns 32, the index up to (expt 2 32) is supported. It is guaranteed that this is at least 32. 実装が利用できる、疎なベクタのインデックスの最大のビット数を返します。例えばこれが32を返したなら、インデックスとして(expt 2 32)まで使えるということです。この値は最低でも32であることが保証されています。

In the following entries, the argument SV denotes an instance of sparse vector; an error is signaled if other object is passed. 以下のエントリにおいて、引数SVは疎なベクタのインスタンスです。他のオブジェクトが渡された場合はエラーが報告されます。

 -- Function: sparse-vector-copy sv
     Returns a copy of a sparse vector SV. 疎なベクタSVのコピーを返します。

 -- Function: sparse-vector-ref sv k :optional fallback
     Returns K-th element of a sparse vector SV, where K must an exact integer.

     If the sparse vector doesn't have a value for K, it behaves as follows:

       * If FALLBACK is given, it is returned.

       * Otherwise, if the vector has the default value, it is returned.

       * Otherwise, an error is signaled.

     疎なベクタSVのインデックスKにある要素を返します。 Kは正確な整数でなければなりません。

     Kに対応する要素がない場合は、次のように振る舞います。

       * FALLBACK引数が与えられていればそれを返します。

       * そうでなく、ベクタが既定値を持っていれば、それを返します。

       * そうでなければ、エラーが報告されます。

 -- Function: sparse-vector-set! sv k value
     Sets VALUE for K-th element of a sparse vector SV. K must be a nonnegative exact integer, and below the maximum allowed index.

     If SV is a numeric sparse vector, VALUE must also be within the allowed range, or an error is signaled. 疎なベクタSVのK番めの要素にVALUEを設定します。 Kは非負の正確な整数で、許される最大のインデックス以下でなければなりません。

 -- Function: sparse-vector-num-entries sv
     Returns the number of entries in SV. SVの持つ要素数を返します。

 -- Function: sparse-vector-exists? sv k
     Returns #t if SV has an entry for index K, #f otherwise. SVのK番目のエントリが値を持っていれば#tを、そうでなければ#fを返します。 #t

 -- Function: sparse-vector-delete! sv k
     Deletes the K-th entry of SV.  If SV had the entry , returns #t.  If SV didn't have the entry, returns #f. SVのK番目のエントリが値を持っていれば、それを消去して #tを返します。そうでなければ何もせずに#fを返します。

 -- Function: sparse-vector-clear! sv
     Empties a sparse vector. 疎なベクタを空にします。

 -- Function: sparse-vector-inc! sv k delta :optional (fallback 0)
     This is a shortcut of the following.  It is especially efficient for numeric sparse vectors.

          (sparse-vector-set! sv k (+ (sparse-vector-ref sv k fallback) delta))

     If the result of addition exceeds the allowed value range of SV, an error is signaled.  In future we'll allow an option to clamp the result value within the range. これは次のコードと同じ動作をしますが、数値を格納する疎ベクタでは特に効率よく動作します。

          (sparse-vector-set! sv k (+ (sparse-vector-ref sv k fallback) delta))

     もし加算の結果がSVに許される数値の範囲を越えた場合は、エラーが投げられます。将来はそういった場合に値をクランプするオプションも用意する予定です。

 -- Function: sparse-vector-update! sv k proc :optional fallback
 -- Function: sparse-vector-push! sv k val
 -- Function: sparse-vector-pop! sv k :optional fallback
     Convenience routines to fetch-and-update an entry of a sparse vector.  Works just like hash-table-update!, hash-table-push! and hash-table-pop!; (see Hashtables). 疎なベクタのエントリの値を取り出してアップデートするパターンを簡単に書くためのルーチンです。それぞれ、hash-table-update!、 hash-table-push!、hash-table-pop!と同じように動作します。(Hashtables参照)。

The following procedures traverses a sparse vector. Note that elements are not visited in the order of index; it's just like hash table traversers. 以下の手続きは疎なベクタの要素を横断します。要素は必ずしもインデックスの順に訪問されるわけではないことに注意してください。その点ではハッシュテーブルの横断と似ています。

At this moment, if you want to walk a sparse vector with increasing/decreasing index order, you have to get a list of keys by sparse-vector-keys, sort it, then use it to retrieve values. We may add an option in future to make-sparse-vector so that those walk operation will be more convenient. 今のところ、疎なベクタをインデックスの昇順/降順に処理したい場合は、 sparse-vector-keysで全てのキーを得て、それをソートしたもので順に値を取り出してゆくしかありません。将来は、make-sparse-vectorにオプションをつけてインデックスの順番による横断を簡単にするかもしれません。

 -- Function: sparse-vector-fold sv proc seed
     For each entry in SV, calls PROC as (proc K_N V_N SEED_N), where K_N is an index and V_N is a value for it, and SEED_N is the returned value of the previous call to PROC if N >= 1, and SEED if N = 0. Returns the value of the last call of PROC. SVの各エントリに対し、手続きPROCを (proc K_N V_N SEED_N)のように呼び出してゆきます。ここでSEED_NはN >= 1の時は直前のPROCの戻り値、 N = 0の時は引数SEEDです。最後のPROCの戻り値を返します。

 -- Function: sparse-vector-for-each sv proc
 -- Function: sparse-vector-map sv proc
     Calls proc with index and value, e.g. (proc k value), for each element of SV.

     The results of PROC are discarded by sparse-vector-for-each, and gathered to a list and returned by sparse-vector-map.

 -- Function: sparse-vector-keys sv
 -- Function: sparse-vector-values sv
     Returns a list of all keys and all values in SV, respectively. それぞれ、SV中の全てのキー、または全ての値をリストにして返します。

Sparse matrixes
---------------

A sparse matrix is like a sparse vector, except it can be indexed by two nonnegative integers. 疎行列は要素が2つの非負整数でインデックスされること以外は疎なベクタと同じです。

Note: This implementation of sparse matrixes aims at a reasonable space efficiency for sparse matrixes without knowing its structure beforehand (imagine, for example, a 2D map with some scattered landmarks). If what you want is a sparse matrix implementation for efficient numeric calculations, with certain particular structures, probably the access speed of this module isn't suitable. 註：この疎行列の実装は、事前に構造が分かっていない疎な行列をそれなりに空間効率良く扱うことを目的としています(例えば、2Dのマップにランドマークを記録してゆく、といったイメージです)。もし探しているものが、数値計算用に特定の構造を持つ疎行列の実装でしたら、このモジュールは速度的に十分ではないでしょう。

Currently, each index can have half of bits of sparse-vector-max-index-bits.  We'll remove this limitation in future. 現在の実装では、それぞれのインデックスの最大ビット数が sparse-vector-max-index-bitsの半分までという制限があります。将来はこの制限をなくす予定です。

 -- Class: <sparse-matrix-base>
     An abstract base class of sparse matrixes.  Inherits <collection>.

     Like sparse vectors, a sparse matrix can be of type that can store any Scheme objects, or that can store only certain types of numbers.

     All of these sparse matrix subtypes can be accessed by the same API.

 -- Class: <sparse-matrix>
 -- Class: <sparse-@matrix>
     The actual sparse matrix classes.  Inherits <sparse-matrix-base>. An instance of <sparse-matrix> can contain any Scheme objects.

     @ is either one of s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, or f64. The range of values an instance of those classes can hold is the same as the corresponding <@vector> class in gauche.uvector (see Uniform vectors).  That is, <sparse-u8matrix> can have exact integer values between 0 and 255.

 -- Function: make-sparse-matrix :optional type :key default
     Creates an empty sparse matrix.  The TYPE argument can be #f (default), one of subclasses of <sparse-matrix-base>, or a symbol of either one of s8, u8, s16, u16, s32, u32, s64, u64, f16, f32, or f64.

     If TYPE is omitted or #f, a <sparse-matrix> is created.  If it is a class, an instance of the class is created (It is an error to pass a class that is not a subclass of <sparse-matrix-base>.) If it is a symbol, an instance of corresponding <sparse-@matrix> is created.

     You can specify the default value of the matrix by DEFAULT keyword argument.   If given, the vector behaves as if it is filled with the default value (but the matrix iterator only picks the values explicitly set).

     Note that you have to give the optional argument as well to specify the keyword argument.

 -- Function: sparse-matrix-num-entries mat
     Returns the number of entries explicitly set in a sparse matrix MAT.

 -- Function: sparse-matrix-ref mat x y :optional fallback
     Returns an element indexed by (X, Y) in a sparse matrix MAT. If the indexed element isn't set, FALLBACK is returned if provided; otherwise, if the matrix has the default value, it is returned; otherwise, an error is raised.

 -- Function: sparse-matrix-set! mat x y value
     Set VALUE to the sparse matrix MAT at the location (X, Y).

 -- Function: sparse-matrix-exists? mat x y
     Returns #t iff the sparse matrix MAT has a value at (X, Y).

 -- Function: sparse-matrix-clear! mat
     Empties the sparse matrix MAT.

 -- Function: sparse-matrix-delete! mat x y
     Remove the value at (X, Y) from the sparse matrix MAT.

 -- Function: sparse-matrix-copy mat
     Returns a fresh copy of MAT.

 -- Function: sparse-matrix-update! mat x y proc :optional fallback
     Call PROC with the value at (X, Y) of the sparse matrix, and sets the result of PROC as the new value of the location.

     The optional FALLBACK argument works just like sparse-matrix-ref; if provided, it is passed to PROC in case the matrix doesn't have a value at (X, Y). If FALLBACK isn't provided and the matrix doesn't have a value at the location, the default value of the matrix is used if it has one. Otherwise, an error is signalled.

 -- Function: sparse-matrix-inc! mat x y delta :optional fallback

          (sparse-matrix-update! mat x y (cut + <> delta) fallback)

 -- Function: sparse-matrix-push! mat x y val

          (sparse-matrix-update! mat x y (cut cons val <>) '())

 -- Function: sparse-matrix-pop! mat x y

          (rlet1 r #f
            (sparse-matrix-update! mat x y (^p (set! r (car p)) (cdr p))))

 -- Function: sparse-matrix-fold mat proc seed
     Loop over values in the sparse matrix MAT.  The procedure PROC is called with four arguments, X, Y, VAL and SEED, for each index (X, Y) which has the value VAL.  The initial value of SEED is the one given to sparse-matrix-fold, and the result of PROC is passed as the next seed value.  The last result of PROC is returned from sparse-matrix-fold.

     The procedure PROC is only called on the entries that's actually has a value, and the order of which the procedure is called is undefined.

 -- Function: sparse-matrix-map mat proc

          (sparse-matrix-fold sv (^[x y v s] (cons (proc x y v) s)) '()))

 -- Function: sparse-matrix-for-each mat proc

          (sparse-matrix-fold sv (^[x y v _] (proc x y v)) #f))

 -- Function: sparse-matrix-keys mat

          (sparse-matrix-fold sv (^[x y _ s] (cons (list x y) s)) '())

 -- Function: sparse-matrix-values mat

          (sparse-matrix-fold sv (^[x y v s] (cons v s)) '())

Sparse tables
-------------

 -- Class: <sparse-table>
     A class for sparse table.  Inherits <dictionary> and <collection>.

     Operationally sparse tables are the same as hash tables, but the former consumes less memory in trade of slight slower access. (Roughly x1.5 to x2 access time when the table is small. As the table gets larger the difference becomes smaller.)

 -- Function: make-sparse-table comparator
     Creates and returns an empty sparse table. The COMPARATOR argument specifies how to compare and hash keys; it must be either a comparator (see Basic comparators), or one of the symbols eq?, eqv?, equal? and string=?, like hash tables (see Hashtables).   If it is a symbol, eq-comparator, eqv-comparator, equal-comparator or string-comparator are used, respectively.

 -- Function: sparse-table-comparator st
     Returns the comparator used in the sparse table ST.

 -- Function: sparse-table-copy st
     Returns a copy of a sparse table ST.

 -- Function: sparse-table-num-entries st
     Returns the number of entries in a sparse table ST.

 -- Function: sparse-table-ref st key :optional fallback
     Retrieves a value associated to the KEY in ST. If no entry with KEY exists, FALLBACK is returned when it is provided, or an error is signaled otherwise.

 -- Function: sparse-table-set! st key value
     Sets VALUE with KEY in ST.

 -- Function: sparse-table-exists? st key
     Returns #t if an entry with KEY exists in ST, #f otherwise.

 -- Function: sparse-table-delete! st key
     Deletes an entry with KEY in ST if it exists. Returns #t if an entry is actually deleted, or #f if there hasn't been an entry with KEY.

 -- Function: sparse-table-clear! st
     Empties ST.

 -- Function: sparse-table-update! st key proc :optional fallback
 -- Function: sparse-table-push! st key val
 -- Function: sparse-table-pop! st key :optional fallback

 -- Function: sparse-table-fold st proc seed
 -- Function: sparse-table-for-each st proc
 -- Function: sparse-table-map st proc

 -- Function: sparse-table-keys st
 -- Function: sparse-table-values st

data.trie - Trie
================

 -- Module: data.trie
     This module provides Trie, a dictionary-like data structure that maps keys to values, where a key is an arbitrary sequence. Internally it stores the data as a tree where each node corresponds to each element in the key sequence. Key lookup is O(n) where n is the length of the key, and not affected much by the number of total entries. Also it is easy to find a set of values whose keys share a common prefix. このモジュールはTrieを提供します。Trieはディレクトリに似たデータ構造で、キーを値に写像します。また、キーは任意のシーケンスです。内部的にはデータはツリーとして保持されます。このとき各ノードがキーシーケンスの各要素に対応します。キーの検索は O(n) で、n はキーの長さです。したがって、全体のエントリ数には余り影響を受けません。また、キーが共通の接頭辞をもつような値の集合を簡単にみつけられます。

     The following example may give you the idea. 以下のサンプルを見れば考え方が理解できると思います。

          (define t (make-trie))   ;; create a trie

          (trie-put! t "pho" 3)    ;; populate the trie
          (trie-put! t "phone" 5)
          (trie-put! t "phrase" 6)

          (trie-get t "phone")  => 5  ;; lookup

          (trie-common-prefix t "pho")       ;; common prefix search
            => (("phone" . 5) ("pho" . 3))
          (trie-common-prefix-keys t "ph")
            => ("phone" "pho" "phrase")

     Tries are frequently used with string keys, but you are not limited to do so; any sequence (see Sequence framework) can be a key.  If the types of keys differ, they are treated as different keys: Trieでは文字列キーを使うことが多いですが、それに限定される必要はありません。あらゆるシーケンス(see Sequence framework)をキーにすることができます。キーの型が違えば、別のキーとして扱われます。

          (trie-put! t '(#\p #\h #\o) 8)  ;; different key from "pho"

     Trie inherits <collection> and implements collection framework including the builder. So you can apply generic collection operations on a trie (see Collection framework). When iterated, each element of a trie appears as a pair of a key and a value. Trieは<collection>を継承しており、コレクションフレームワークをビルダも含めて実装しています。それゆえ、ジェネリックなコレクション操作をTrieに適用することが可能です(Collection framework参照)。反復するとTrieの各要素がキーと値の対として現れます。

 -- Class: <trie>
     A class for Trie.  No slots are intended for public. Use the following procedures to operate on tries. Trieクラス。パブリックなスロットはありません。trieを操作するには以下の手続きを使ってください。

     This class also implements the dictionary interface (see Generic functions for dictionaries). このクラスはまた、ディクショナリインタフェースを実装しています (Generic functions for dictionaries参照)。

 -- Function: make-trie :optional tab-make tab-get tab-put! tab-fold tab-empty?
     Creates and returns an empty trie.  The optional arguments are procedures to customize how the nodes of the internal tree are managed. 空のtrieを生成し返します。オプション引数は、内部木のノードをどのようにマージするかをカスタマイズする手続きです。

     Each node can have a table to store its child nodes, indexed by an element of the key sequence (e.g. if the trie uses strings as keys, a node's table is indexed by characters). それぞれのノードは子のノードを格納するテーブルを持つことができます。キーシーケンスの要素でインデックスできます。(たとえば、trieがキーとしえ文字列を使っているとすると、ノードのテーブルは文字でインデックスされています。)

     tab-make
          A procedure with no arguments.  When called, creates and returns an empty table for a node.

     tab-get TAB ELT
          Returns a child node indexed by ELT, or returns #f if the table doesn't have a child for ELT.

     tab-put! TAB ELT CHILD-NODE
          If CHILD-NODE isn't #f, stores a CHILD-NODE with index ELT. If CHILD-NODE is #f, removes the entry with index ELT. In both cases, this procedure should return the updated table.

     tab-fold TAB PROC SEED
          Calls PROC for every index and node in TAB, while passing a seed value, whose initial value is SEED. That is, PROC has a type of (index, node, seed) -> seed. Should return the last result of PROC.

     tab-empty? TAB
          Returns #t if TAB is empty, #f otherwise. You can omit or pass #f to this procedure; then we use tab-fold to check if TAB is empty, which can be expensive.

     tab-make
          引数なしの手続き。呼ばれるとノード用の空テーブルを生成し返します。

     tab-get TAB ELT
          ELTでインデックスされた子ノードを返すか、あるいはELTに対応する子がテーブルにない場合には #fを返します。

     tab-put! TAB ELT CHILD-NODE
          CHILD-NODEが#fでなければ、CHILD-NODEにELTというインデックスをつけて保存します。CHILD-NODEが#fなら ELTのインデックスをもつエントリを削除します。どちらの場合にもこの手続きは更新されたテーブルを返します。

     tab-fold TAB PROC SEED
          TAB内の各インデックスと要素ごとにPROCを呼びます。シード値が順に渡されていきます。シード値の初期値はSEEDです。すなわち、 PROCの型は(index, node, seed) -> seed のような型ということになります。返り値は最後のPROCの適用結果です。

     tab-empty? TAB
          TABが空なら#tを、そうでなければ#fを返す手続きです。この手続きは省略するか#fを渡すことができます。その場合は空かどうかをチェックするのにtab-fold手続きが使われますが、少々重くなるかもしれません。

     The default assumes eqv?-hashtables, i.e. the following procedures are used. デフォルトではeqv?-ハッシュ可能であることが仮定されます。すなわち、以下の手続きが使われます。

          tab-make: (lambda () (make-hash-table 'eqv?))

          tab-get:  (lambda (tab k) (hash-table-get tab k #f))

          tab-put!: (lambda (tab k v)
                      (if v
                        (hash-table-put! tab k v)
                        (hash-table-delete! tab k))
                      tab)

          tab-fold: hash-table-fold

          tab-empty?: (lambda (tab) (zero? (hash-table-num-entries tab)))

     The following example creates a trie using assoc list to manage children, while comparing string keys with case-insensitive way: 以下の例では子を管理するのに連想リストを用いるtrieを作成しています。文字列キーの比較は大文字小文字を無視する方法で行っています。

          (make-trie list
                     (cut assoc-ref <> <> #f char-ci=?)
                     (lambda (t k v)
                       (if v
                         (assoc-set! t k v char-ci=?)
                         (alist-delete! k t char-ci=?)))
                     (lambda (t f s) (fold f s t))
                     null?)

     It is important that tab-put! must return an updated table---by that, you can replace the table structure on the fly. For example, you may design a table which uses assoc list when the number of children are small, and then switches to a vector (indexed by character code) once the number of children grows over a certain threshold. tab-put!が更新されたテーブルを返すというのは重要で、これのおかげで、テーブル構造を実行中に置き換えることができます。たとえば、子の数が少い場合にはテーブルに連想リストを使い、いったん子の数がある閾値を越えたら、(文字コードでインデックスされた)ベクタを使うように設計することができます。

 -- Function: trie params kv ...
     Construct a trie with the initial contents KV ..., where each KV is a pair of a key and a value. PARAMS are a list of arguments which will be given to make-trie to create the trie. The following example creates a trie with two entries and the default table procedures. 初期の内容がKV ... であるようなtrieを構成します。ここで、 KVはキーと値の対です。PARAMSはtrieを生成するときに make-trieに渡される引数のリストです。以下の例は2つのエントリとデフォルトのテーブル手続をもつtrieを生成します。

          (trie '() '("foo" . a) '("bar" . b))

 -- Function: trie-with-keys params key ...
     A convenient version of trie when you only concern the keys.  Each value is the same as its key. The following example creates a trie with two entries and the default table procedures. キーにだけ関心がある場合には便利なtrie。各値はキーと同じ。以下の例では2つのエントリとデフォルトのテーブル手続をもつtrieを生成します。

          (trie-with-keys '() "foo" "bar")

 -- Function: trie? obj
     Returns #t if OBJ is a trie, or #f otherwise. OBJがtrieなら#tを返し、さもなければ#fを返します。

 -- Function: trie-num-entries trie
     Returns the number of entries in TRIE. TRIE中のエントリの数を返します。

 -- Function: trie-exists? trie key
     Returns #t if TRIE contains an entry with KEY, or returns #f otherwise. TRIEがKEYというキーのエントリを含む場合には#tを返し、さもなければ、#fを返します。

          (let1 t (trie '() '("foo" . ok))
            (list (trie-exists? t "foo")
                  (trie-exists? t "fo")
                  (trie-exists? t "bar")))
            => '(#t #f #f)

 -- Function: trie-partial-key? trie seq
     Returns #t if there's at least one key in TRIE that is not equal to SEQ but SEQ matches its prefix.   Note that SEQ may or may not a key of TRIE; see the example below. TRIEの中に少なくともひとつ、SEQと同じではないがSEQをプリフィクスとするようなキーがあれば#tを返します。 SEQと一致するキーが他にあるかないかは結果には影響を及ぼしません。下の例を見てください。

          (define t (trie '() '("foo" . ok) '("fo" . ok)))

          (trie-partial-key? t "f")    => #t
          (trie-partial-key? t "fo")   => #t
          (trie-partial-key? t "foo")  => #f
          (trie-partial-key? t "bar")  => #f

 -- Function: trie-get trie key :optional fallback
     Returns the value associated with KEY in TRIE, if such an entry exists.  When there's no entry for KEY, if FALLBACK is given, it is returned; otherwise, an error is signaled. TRIE中のKEYをもつエントリがあれば、それにむすびついている値を返します。そのようなエントリがない場合、FALLBACKが与えられていればそれを返し、さもなければ、エラーシグナルがあがります。

 -- Function: trie-put! trie key value
     Puts VALUE associated to KEY into TRIE. KEYに結びついたVALUEをTRIEに挿入します。

 -- Function: trie-update! trie key proc :optional fallback
     Works like the following code, except that the lookup of entry in TRIE is done only once. TRIE中のエントリの検索が一度きりしか起らないことをのぞけば以下のコードのように動きます。

          (let ((val (trie-get trie key fallback)))
            (trie-put! trie key (proc val)))

 -- Function: trie-delete! trie key
     Removes an entry associated with KEY from TRIE. If there's no such entry, this procedure does nothing. TRIEからKEYに関連するエントリを削除します。そのようなエントリがない場合にはこの手続きはなにもしません。

 -- Function: trie->list trie
     Makes each entry in TRIE to a pair (KEY . VALUE) and returns a list of pairs of all entries.  The order of entries are undefined. TRIEの各エントリを(KEY . VALUE)という対にしてすべてのエントリの対のリストを返します。エントリの順序は未定義です。

 -- Function: trie-keys trie
 -- Function: trie-values trie
     Returns a list of all keys and values in TRIE, respectively. The order of keys/values are undefined. それぞれ、TRIEのすべてのキーのリスト、すべての値のリストを返します。順序は未定義です。

 -- Function: trie->hash-table trie ht-type
     Creates a hash table with type HT-TYPE (see Hashtables, about hash table types), and populates it with every key and value pair in TRIE. HT-TYPEタイプのハッシュテーブル(ハッシュテーブルのタイプについてはHashtablesを参照)を作成し、TRIEのすべてのキーと値の対をセットします。

 -- Function: trie-longest-match trie seq :optional fallback
     Returns a pair of the key and its value, where the key is the longest prefix of SEQ.   If no such key is found, FALLBACK is returned if it is provided, or an error is thrown.

     Do not confuse this with trie-common-prefix-* procedures below; In this procedure, the key is the prefix of the given argument. In trie-common-prefix-* procedures, the given argument is the prefix of the keys. SEQのプレフィクスになっているキーのうちもっとも長いものを見つけて、そのキーと値のペアを返します。そういったキーが見つからなかった場合は、 FALLBACKが与えられればそれを返し、なければエラーが通知されます。

     この手続きと以下のtrie-common-prefix-*手続きを混同しないようにしてください。この手続きでは、キーが引数のプレフィクスです。 trie-common-prefix-*手続きでは、引数がキーのプレフィクスです。

          (let1 t (make-trie)
            (trie-put! t "a"  'a)
            (trie-put! t "ab" 'ab)

            (trie-longest-match t "abc")  => ("ab" . ab)
            (trie-longest-match t "acd")  => ("a"  . a)
            (trie-longest-match t "ab")   => ("ab" . ab)
            (trie-longest-match t "zy")   => error
            )

 -- Function: trie-common-prefix trie prefix
 -- Function: trie-common-prefix-keys trie prefix
 -- Function: trie-common-prefix-values trie prefix
     Gathers all entries whose keys begin with PREFIX; trie-common-prefix returns those entries in a list of pairs (key . value); trie-common-prefix-keys returns a list of keys; and trie-common-prefix-values returns a list of values.   The order of entries in a returned list is undefined. If TRIE contains no entry whose key has PREFIX, an empty list is returned. PREFIXではじまるキーをもつエントリをすべて集め、 trie-common-prefixはその各エントリを(key . value)の対にしたリストを返します。trie-common-prefix-keysは、キーのリストを trie-common-prefix-valuesは値のリストを返します。返されるリストのエントリの順序は未定義です。 TRIEに指定したPREFIXをもつキーのエントリがなければ、空リストが返されます。

     Note that prefix matching doesn't consider the type of sequence; if TRIE has entries for "foo" and (#\f #\o #\o), (trie-common-prefix trie "foo") will return both entries. 接頭辞照合ではシーケンスの型を考慮しないことに注意してください。 TRIEのなかに"foo"と(#\f #\o #\o)に対応するエントリがあれば、(trie-common-prefix trie "foo")はその両方を返します。

 -- Function: trie-common-prefix-fold trie prefix proc seed
     For each entry whose key begins with PREFIX, calls PROC with three arguments, the entry's key, its value, and the current seed value.  SEED is used for the first seed value, and the value PROC returns is used for the seed value of the next call of PROC. The last returned value from PROC is returned from trie-common-prefix-fold. The order of entries on which PROC is called is undefined. If TRIE contains no entry whose key has PREFIX, PROC is never called and SEED is returned. PREFIXではじまるキーをもつ各エントリに対して、PROCを3つの引数、エントリのキー、値、現在のシード値で呼びます。SEEDは最初のシード値として使われ、PROCが返す値は次のPROCの呼び出しのシード値として使われます。PROCが返した最後の値が trie-common-prefix-foldから返ります。 PROCが適用される順序は未定義です。TRIEがPREFIXを持つキーのエントリを含まない場合にはPROCが呼ばれることはなく、 SEEDが返ります。

 -- Function: trie-common-prefix-map trie prefix proc
 -- Function: trie-common-prefix-for-each trie prefix proc
     These are to TRIE-COMMON-PREFIX-FOLD as map and for-each are to fold; trie-common-prefix-map calls PROC with key and value for matching entries and gathers its result to a list; trie-common-prefix-for-each also applies PROC, but discards its results. mapやfor-eachをfoldを合せたのと同じように、 TRIE-COMMON-PREFIX-FOLDに合せたものです。 trie-common-prefix-mapはPROCをマッチするエントリのキーと値に適用し結果をリストにあつめます。 trie-common-prefix-for-eachも同じくPROCを適用しますが結果は捨てます。

 -- Function: trie-fold trie proc seed
 -- Function: trie-map trie proc
 -- Function: trie-for-each trie proc
     These procedures are like their common-prefix versions, but traverse entire TRIE instead. これらの手続きはcommon-prefix版とおなじような働きをしますが、 TRIE全体をトラバースします。

dbi - Database independent access layer
=======================================

 -- Module: dbi
     This module provides the unified interface to access various relational database systems (RDBMS).  The operations specific to individual database systems are packaged in database driver (DBD) modules, which is usually loaded implicitly by DBI layer. このモジュールはさまざまなリレーショナルデータベースシステム(RDBMS)にアクセスするための統一されたインタフェースを提供します。個々のデータベースシステムに特有の操作についてはデータベースドライバ(DBD)モジュールにパッケージされています。DBDのモジュールは通常暗黙裏にDBIの層からロードされます。

     The module is strongly influenced by Perl's DBI/DBD architecture. If you have used Perl DBI, it would be easy to use this module. このモジュールは Perl の DBI/DBD アーキテクチャに強く影響を受けています。Perl DBIを使った経験があるなら、このモジュールを使うのはたやすいでしょう。

It's better to look at the example.  This is a simple outline of accessing a database by dbi module: まず例を見るほうがよいでしょう。以下はdbiモジュールを使ったデータベースアクセス例の概要です。

     (use dbi)
     (use gauche.collection) ; to make 'map' work on the query result

     (guard (e ((<dbi-error> e)
                ;; handle error
                ))
       (let* ((conn   (dbi-connect "dbi:mysql:test;host=dbhost"))
              (query  (dbi-prepare conn
                        "SELECT id, name FROM users WHERE department = ?"))
              (result (dbi-execute query "R&D"))
              (getter (relation-accessor result)))
         (map (lambda (row)
                (list (getter row "id")
                      (getter row "name")))
              result)))

There's nothing specific to the underlying database system except the argument "dbi:mysql:test;host=dbhost" passed to dbi-connect, from which dbi module figures out that it is an access to mysql database, loads dbd.mysql module, and let it handle the mysql-specific stuff.  If you want to use whatever database system, you can just pass "dbi:WHATEVER:PARAMETER" to dbi-connect instead, and everything stays the same as far as you have dbd.whatever installed in your system. dbi-connectにわたす、"dbi:mysql:test;host=dbhost"引数以外は使用するデータベースシステムに依存する部分はありません。この引数により、dbiモジュールはこのアクセスがmysqlデータベースに対するものであると判断します。そして、mysql-特有の手続を扱うようにします。別のデータベースシステムwhateverを使いたいのであれば、単に "dbi:WHATEVER:PARAMETER"をdbi-connectに渡せばよく、dbd.whateverがシステムにインストールされていれば同じようにできます。

A query to the database can be created by dbi-prepare. You can issue the query by dbi-execute.  This two-phase approach allows you to create a prepared query, which is a kind of parameterized SQL statement.  In the above example the query takes one parameter, denoted as '?' in the SQL. The actual value is given in dbi-execute.  When you issue similar queries a lot, creating a prepared query and execute it with different parameters may give you performance gain. Also the parameter is automatically quoted. データベースに対するクエリはdbi-prepareを使って作成します。クエリの発行はdbi-executeで行います。このような2つのフェーズを使うことで、パラメータ化されたSQL文の一種であるプリペアドクエリを作ることができます。上の例ではクエリはSQL文の中で'?'で表現されている部分に、ひとつの引数をわりあてます。実引数の値は dbi-executeで設定されます。類似のクエリを大量に発行するような場合にはプリペアドクエリをひとつ生成し、それにさまざまなパラメータを渡して実行するとパフォーマンスがかせげます。このパラメータは自動的にクォートされます。

When the query is a SELECT statement, its result is returned as a collection that implements the relation protocol.  See Collection framework and Relation framework for the details. クエリがSELECT文の場合、その結果は関係プロトコルを実装するコレクションとして返されます。詳細はCollection frameworkおよび Relation frameworkを見てください。

The outermost guard is to catch errors.  The dbi related errors are supposed to inherit <dbi-error> condition. There are a few specific errors defined in dbi module. A specific dbd layer may define more specific errors. いちばん外側にあるguardはエラーを捕捉するためのものです。 dbiに関連したエラーは<dbi-error>コンディションを継承しているものと見なされます。いくつかの特有のエラーはdbiモジュールで定義されています。特定のdbd層はさらに固有のエラーを定義しています。

In the next section we describe user-level API, that is, the procedures you need to concern when you're using dbi. The following section is for the driver API, which you need to use to write a specific dbd driver to make it work with dbi framework. 次節ではユーザレベルのAPIについて説明します。すなわち、dbiを使う際に必要となる手続に関する説明です。そのあとのセクションではドライバ APIを説明をします。すなわち特定のdbdドライバをdbiフレームワークで使えるようにするために使うAPIの説明です。

DBI user API
------------

DBI Conditions
..............

DBIのコンディション
...........

There are several predefined conditions dbi API may throw. See Exceptions for the details of conditions. dbi API が投げる可能性のあるコンディションがいくつか定義されています。コンディションの詳細についてはExceptionsを見てください。

 -- Condition Type: <dbi-error>
     The base class of dbi-related conditions.  Inherits <error>. dbi-関連のコンディションのベースクラス。<error>を継承しています。

 -- Condition Type: <dbi-nonexistent-driver-error>
     This condition is thrown by dbi-connect when it cannot find the specified driver.  Inherits <dbi-error>. dbi-connectは指定されたドライバが見つからない場合にこのコンディションを投げます。<dbi-error>を継承しています。

      -- Instance Variable of <dbi-nonexistent-driver-error>: driver-name
          Holds the requested driver name as a string. 要求されたドライバの名前を文字列として保持している。

 -- Condition Type: <dbi-unsupported-error>
     This condition is thrown when the called method isn't supported by the underlying driver.  Inherits <dbi-error>. 呼び出されたメソッドが基盤となるドライバでサポートされていない場合、このコンディションが投げられます。<dbi-error>を継承しています。

 -- Condition Type: <dbi-parameter-error>
     This condition is thrown when the number of parameters given to the prepared query doesn't match the ones in the prepared statement. プリペアドクエリへ渡されたパラメータの数がプリペアドステートメントの中のものと一致しないとき、このコンディションが投げられます。

Besides these errors, if a driver relies on dbi to parse the prepared SQL statement, <sql-parse-error> may be thrown if an invalid SQL statement is passed to dbi-prepare. (see SQL parsing and construction). 上の3つのエラー以外に、dbiがプリペアドSQL文を構文解析するのにドライバを利用す場合、不正なSQL文がdbi-prepareに渡されると、 <sql-parse-error>が投げられます (SQL parsing and construction参照)。

Connecting to the database
..........................

データベースへの接続
..........

 -- Function: dbi-connect dsn :key username password
     Connect to a database using a data source specified by DSN (data source name).  DSN is a string with the following syntax: DSN(データソース名)で指定されたデータソースを使ってデータベースに接続します。DSNは以下の構文をもつ文字列です。

          dbi:DRIVER:OPTIONS

     DRIVER part names a specific driver.  You need to have the corresponding driver module, dbd.DRIVER, installed in your system.  For example, if DSN begins with "dbi:mysql:", dbi-connect tries to load dbd.mysql. DRIVERは特定のドライバ名です。対応するドライバモジュールがなければなりません。すなわち、dbd.DRIVERがシステムにインストールされていなければなりません。たとえば、DSNが"dbi:mysql:" ではじまるとすると、dbi-connectはdbd.mysqlをロードしようとします。

     Interpretation of the OPTIONS part is up to the driver. Usually it is in the form of key1=value1;key2=value2;..., but some driver may interpret it differently.  For example, mysql driver allows you to specify a database name at the beginning of OPTIONS.   You have to check out the document of each driver for the exact specification of OPTIONS. OPTIONS部分の解釈はドライバに依存します。通常この部分のフォーマットはkey1=value1;key2=value2;...のようになっていますが、ドライバによっては別の解釈になります。たとえば、mysqlドライバでは、 OPTIONSの最初の部分でデータベース名を指定することができます。 OPTIONSの正確な仕様については各ドライバのドキュメントをチェックしてください。

     The keyword arguments gives extra information required for connection.  The USERNAME and PASSWORD are commonly supported arguments.  The driver may recognize more keyword arguments. 接続のために必要な追加情報はキーワード引数であたえます。 USERNAMEおよびPASSWORDは共通でサポートされている引数です。ドライバは他にもキーワード引数を認識します。

     If a connection to the database is successfully established, a connection object (an instance of a subclass of <dbi-connection>) is returned.  Otherwise, an error is signaled. データベースへの接続が成功したら、コネクションオブジェクト (<dbi-connection>のサブクラスのインスタンス)が返ります。さもなければ、エラーがあがります。

 -- Class: <dbi-connection>
     The base class of a connection to a database system. Each driver defines a subclass of this to keep information about database-specific connections. データベースシステムへの接続のベースクラス。各ドライバはこのクラスのサブクラスを定義し、これにデータベース特有のコネクションに関する情報を持たせます。

 -- Method: dbi-open? (c <dbi-connection>)
     Queries whether a connection to the database is still open (active). データベースへの接続がオープン状態(アクティブ状態)にあるかどうかを確かめます。

 -- Method: dbi-close (c <dbi-connection>)
     Closes a connection to the database.  This causes releasing resources related to this connection.   Once closed, C cannot be used for any dbi operations (except passing to dbi-open?). Calling dbi-close on an already closed connection has no effect. データベースへの接続を閉じます。これによりこの接続に関連付けられたリソースが解放されます。いったん閉じたCに対してはどのようなdbi操作もできません。(dbi-open?だけは例外)。すでに閉じられたコネクションに対してdbi-closeを呼んでもなにも起りません。

     Although a driver usually closes a connection when <dbi-connection> object is garbage-collected, it is not a good idea to rely on that, since the timing of GC is unpredictable.  The user program must make sure that it calls dbi-close at a proper moment. ドライバは通常<dbi-connection>がガベージコレクションされたときにコネクションを閉じますが、このことを期待したコードを書くのはいただけません。GCのタイミングというのは予測不可能だからです。ユーザプログラムは適切なタイミングでdbi-closeを呼ぶようにすべきです。

 -- Function: dbi-list-drivers
     Returns a list of module names of known drivers. 解っているドライバのモジュール名のリストを返します。

 -- Class: <dbi-driver>
     The base class of a driver.  You usually don't need to see this as far as you're using the high-level dbi API. ドライバのベースクラス。高レベルのdbi APIを使うかぎり、これが必要になることはありません。

 -- Function: dbi-make-driver driver-name
     This is a low-level function called from dbi-connect method, and usually a user doesn't need to call it. dbi-connectから呼ばれる低レベル関数、通常この関数を呼ぶ必要はありません。

     Loads a driver module specified by DRIVER-NAME, and instantiate the driver class and returns it. DRIVER-NAMEで指定されたドライバモジュールをロードし、当該のドライバクラスのインスタンスを生成してそれを返します。

Preparing and issuing queries
.............................

クエリの準備と発行
.........

 -- Method: dbi-prepare conn sql :key pass-through ...
     From a string representation of SQL statement SQL, creates and returns a query object (an instance of <dbi-query> or its subclass) for the database connection conn SQL文の文字列表現SQLからデータベースコネクションconn用のクエリオブジェクト(<dbi-query>のインスタンスもしくはそのサブクラスのインスタンス)を生成してそれを返します。

     SQL may contain parameter slots, denoted by ?. SQLは?であらわされているパラメータスロットを持ちます。

          (dbi-prepare conn "insert into tab (col1, col2) values (?, ?)")

          (dbi-prepare conn "select * from tab where col1 = ?")

     They will be filled when you actually issue the query by dbi-execute. There are some advantages of using parameter slots: (1) The necessary quoting is done automatically. You don't need to concern about security holes caused by improper quoting, for example. (2) Some drivers support a feature to send the template SQL statement to the server at the preparation stage, and send only the parameter values at the execution stage.  It would be more efficient if you issue similar queries lots of time. これらのスロットはdbi-executeを使って実際にクエリを発行したときに埋められます。パラメータスロットを使うのは以下の利点があるからです。 (1) クォートが自動的にほどこされます。不適切なクォートによるセキュリティホールを気にする必要はありません。 (2) いくつかのドライバでは準備の段階でサーバへテンプレートSQL文を送る機能がサポートされていて、実行段階ではパラメータを送るだけで済みます。これは似たようなクエリを大量に一度に発行するときには効率のよいやりかたです。

     If the backend doesn't support prepared statements (SQL templates having ? parameters), the driver may use text.sql module to parse SQL.  It may raise <sql-parse-error> condition if the given SQL is not well formed. バックエンドでプリペアド文がサポートされていない場合(でSQLテンプレートが?パラメータを持つ場合)、ドライバはSQLを解析するのに text.sqlモジュールを使います。与えられたSQL文が正しい構文でなければ、<sql-parse-error>コンディションが発生します。

     You may pass a true value to the keyword argument PASS-THROUGH to suppress interpretation of SQL and pass SQL as-is to the back end database system.  It is useful if the back-end supports extension of SQL which text.sql doesn't understand. キーワード引数PASS-THROUGHに真の値を渡して、SQLの解釈を抑制し、 SQLをそのままバックエンドのデータベースシステムに渡すことができます。text.sqlで理解できないようなSQLの拡張をバックエンドがサポートしている場合に役立ちます。

     If the driver lets prepared statement handled in back-end, without using text.sql, the pass-through argument may be ignored. The driver may also take other keyword arguments.  Check out the documentation of individual drivers. ドライバがプリペアド文をtext.sql抜きでバックエンドに処理させた場合、pass-through引数は無視されます。ドライバは他のキーワード引数を取ることもあります。詳細はそれぞれのドライバのドキュメントを参照してください。

     Note: Case folding of SQL statement is implementation dependent.  Some DBMS may treat table names and column names in case insensitive way, while others do in case sensitive way.  To write a portable SQL statement, make them quoted identifiers, that is, always surround names by double quotes. 注意：SQL文のケース畳み込みは実装依存です。DBMSのなかにはテーブル名やカラム名は大文字小文字の区別をしないものもあり、一方で区別するものもあります。ポータブルなSQL文を書きたいのなら、識別子をクォートしましょう。すなわち常に名前をダブルクォートで囲むようにします。

 -- Class: <dbi-query>
     Holds information about prepared query, created by dbi-prepare. The following slots are defined. dbi-prepareによって作成されたプリペアドクエリに関する情報を保持します。以下のスロットが定義されています。

      -- Instance Variable of <dbi-query>: connection
          Contains the <dbi-connection> object. <dbi-connection>オブジェクトを含みます。

      -- Instance Variable of <dbi-query>: prepared
          If the driver prepares query by itself, this slot may contain a prepared statement.  It is up to each driver how to use this slot, so the client shouldn't rely on its value. ドライバがクエリを準備する場合、このスロットがプリペアド文を保持します。このスロットをどのように使うかはおのおののドライバによります。したがって、クライアントはこの値に依存してはいけません。

 -- Method: dbi-open? (q <dbi-query>)
     Returns #t iff the query can still be passed to dbi-execute. クエリがdbi-executeに渡せる状態になっているときにのみ、 #tを返します。

 -- Method: dbi-close (q <dbi-query>)
     Destroy the query and free resources associated to the query. After this operation, dbi-open? returns #f for Q, and the query can't be used in any other way.  Although the resource may be freed when Q is garbage-collected, it is strongly recommended that the application closes queries explicitly. クエリを破棄し、当該クエリに関連づけられたリソースを解放します。この操作を実行後は、dbi-open?はQに対して#fを返します。そして、当該クエリは他の用途にはつかえません。Qがガベージコレクションにより回収された場合、リソースは解放されますが、アプリケーションが明示的にクエリを閉じるようにすることを強く勧めます。

 -- Method: dbi-execute (q <dbi-query>) parameter ...
     Executes a query created by dbi-prepare.  You should pass the same number of PARAMETERs as the query expects. dbi-prepareによって作成さればクエリを実行します。当該クエリが期待するのと同じ数のパラメータを渡す必要があります。

     If the issued query is select statement, dbi-execute returns an object represents a relation. A relation encapsulates the values in rows and columns, as well as meta information like column names. See "Retrieving query results" below for how to access the result. 発行されたクエリがselect文の場合dbi-executeはリレーションを表わすオブジェクトを返します。リレーションは行とカラムの値をカプセル化したもので、カラム名のようなメタ情報も同様です。結果へアクセスの方法については後述の「クエリの結果を見る」を見てください。

     If the query is other types, such as create, insert or delete, the return value of the query closure is unspecified. クエリがSELECT以外のcreate、insert、deleteなどの場合、クエリクロージャー返り値は不定です。

 -- Method: dbi-do conn sql :optional options parameter-value ...
     This is a convenience procedure when you create a query and immediately execute it.   It is equivalent to the following expression, although the driver may overload this method to avoid creating intermediate query object to avoid the overhead. この手続はクエリを作成し、すぐに実行したいときに便利です。これは次の式と同じですが、この場合はドライバはオーバーヘッドを避けるため、中間のクエリを作らないようにこのメソッドをオーバーロードします。

          (dbi-execute (apply dbi-prepare conn sql options)
                       parameter-value ...)

 -- Method: dbi-escape-sql conn str
     Returns a string where special characters in STR are escaped. STR中の特殊文字をエスケープした文字列を返します。

     The official SQL standard only specify a single quote (') as such character.  However, it doesn't specify non-printable characters, and the database system may use other escaping characters.  So it is necessary to use this method rather than doing escaping by your own. SQLの公式標準ではこのような文字としてはシングルクォート(')についてだけ規定しています。しかし、印字可能文字ではない文字については規定がありません。また、データベースシステムによっては他のエスケープ文字を使うものもあります。それゆえ、自分でエスケープしようとせずに、このメソッドを使う必要があります。

          ;; assumes c is a valid DBI connection
          (dbi-escape-sql c "don't know")
            => "don''t know"

          ;; c を利用可能なDBIコネクションとする
          (dbi-escape-sql c "don't know")
            => "don''t know"

Retrieving query results
........................

クエリの結果を見る
.........

If the query is a select statement, it returns an object of both <collection> and <relation>. It is a collection of rows (that is, it implements <collection> API), so you can use map, for-each or other generic functions to access rows.  You can also use the relation API to retrieve column names and accessors from it.  See Relation framework, for the relation API, and Collection framework, for the collection API. クエリがselect文である場合、<collection>と <relation>の両方のオブジェクトが返ります。行のコレクション (すなわち、<collection> APIの実装)ですから、行にアクセスするにはmap、for-each、その他のジェネリック関数が使えます。また、カラム名やアクセサを取り出すにはリレーションAPIが使えます。リレーションAPIについてはRelation frameworkをコレクションAPIについてはCollection frameworkを見てください。

The actual class of the object returned from a query depends on the driver, but you may use the following method on it. クエリから戻ったオブジェクトの実際のクラスはドライバによりますが、以下のメソッドを使うことができます。

 -- Method: dbi-open? result
     Check whether the result of a query is still active. The result may become inactive when it is explicitly closed by dbi-close and/or the connection to the database is closed. クエリの結果がまだアクティブであるかどうかをチェックします。結果はdbi-closeによって明示的に閉じられるかデータベースへのコネクションが閉じられると非アクティブになります。

 -- Method: dbi-close result
     Close the result of the query.  This may cause releasing resources related to the result.   You can no longer use RESULT once it is closed, except passing it to dbi-open?. クエリの結果を閉じます。結果に関連付けられていたリソースが解放されます。 RESULTは、いったん閉じると使えなくなります。ただし、 dbi-open?にだけは渡せます。

     Although a driver usually releases resources when the result is garbage-collected, the application shouldn't rely on that and is recommended call dbi-close explicitly when it is done with the result. ドライバは通常、結果がガベージコレクタによって回収される時にリソースを解放しますが、アプリケーションはこれに依存してはいけません。結果を使いおわったら明示的にdbi-closeを呼ぶことをおすすめします。

Writing drivers for DBI
-----------------------

Writing a driver for a specific database system means implementing a module dbd.FOO, where FOO is the name of the driver. 特定のデータベースシステムのドライバを書くということは、 dbd.FOOモジュールを実装することです。ここでFOOはドライバの名前になります。

The module have to implement several classes and methods, as explained below. このモジュールは以下に説明するいくつかのクラスとメソッドを実装しなければなりません。

DBI classes to implement
........................

実装するDBIクラス
..........

You have to define the following classes. 以下のクラスを定義しなければなりません。

  * Subclass <dbi-driver>. The class name must be <FOO-driver>, where FOO is the name of the driver. Usually this class produces a singleton instance, and is only used to dispatch dbi-make-connection method below.

  * Subclass <dbi-connection>.  An instance of this class is created by dbi-make-connection.  It needs to keep the information about the actual connections.

  * Subclass <relation> and <collection> to represent query results suitable for the driver.  (In most cases, the order of the result of SELECT statement is significant, since it may be sorted by ORDER BY clause.  Thus it is more appropriate to inherit <sequence>, rather than <collection>).

  * Optionally, subclass <dbi-query> to keep driver-specific information of prepared queries.

  * <dbi-driver>のサブクラス。このクラスの名前は必ず <FOO-driver>でなければなりません。ここで、FOOはドライバの名前です。通常このクラスはシングルトンインスタンスを生成し、後述のdbi-make-connectionメソッドをディスパッチするためにのみ利用されます。

  * <dbi-connection>のサブクラス。このクラスのインスタンスは dbi-make-connectionによって生成されます。そのためには、実際のコネクションに関する情報を保持する必要があります。

  * ドライバにあったクエリ結果を表現するための<relation>および <collection>のサブクラス。(ほとんどの場合、SELECT文の結果は順序が重要です。それは、ORDER BY 節によってソートされる可能性があるからです。したがって、<sequence>を継承するほうが、<collection> を継承するよりも適切です。)

  * オプションとして、プリペアドクエリのドライバ特有の情報を保持するため <dbi-query>のサブクラスを実装します。

DBI methods to implement
........................

実装するDBIメソッド
...........

The driver need to implement the following methods. ドライバは以下のメソッドを実装しなければなりません。

 -- Method: dbi-make-connection (d <foo-driver>) (options <string>) (options-alist <list>) :key username password ...
     This method is called from dbi-connect, and responsible to connect to the database and to create a connection object. It must return a connection object, or raise an <dbi-error> if it cannot establish a connection. このメソッドはdbi-connectから呼ばれ、データベースへの接続を担い、コネクションオブジェクトを作成します。コネクションオブジェクトを返さなければなりません。コネクションが確立できない場合には、 <dbi-error>をあげなければなりません。

     OPTIONS is the option part of the data source name (DSN) given to dbi-connect.  OPTIONS-ALIST is an assoc list of the result of parsing OPTIONS.  Both are provided so that the driver may interpret OPTIONS string in nontrivial way. OPTIONSはdbi-connectに与えられるデータソースネーム(DSN)のオプションパートです。OPTIONS-ALISTはOPTIONSを解析した結果の連想リストです。両方ともに用意して、ドライバが自明ではない方法で OPTIONS文字列を解釈できるようにします。

     For example, given "dbi:foo:myaddressbook;host=dbhost;port=8998" as DSN, foo's dbi-make-connection will receive "myaddressbook;host=dbhost;port=8998" as OPTIONS, and (("myaddressbook" . #t) ("host" . "dbhost") ("port" . "8998")) as OPTIONS-ALIST. たとえば、DSNとして "dbi:foo:myaddressbook;host=dbhost;port=8998"が与えられたとすると、fooのdbi-make-connectionはOPTIONSとして "myaddressbook;host=dbhost;port=8998"を受け取り、 OPTIONS-ALISTとして (("myaddressbook" . #t) ("host" . "dbhost") ("port" . "8998")) を受け取ります。

     After OPTIONS-ALIST, whatever keyword arguments given to dbi-connect are passed.  DBI protocol currently specifies only USERNAME and PASSWORD. The driver may define other keyword arguments. It is recommended to name the driver-specific keyword arguments prefixed by the driver name, e.g. for dbd.foo, it may take a :foo-whatever keyword argument. OPTIONS-ALISTの後ろならどのようなキーワード引数でも dbi-connectに渡せます。DBIプロトコルは現在のところは USERNAMEおよびPASSWORDのみを指定します。ドライバはその他のキーワード引数を定義できます。ドライバ特有のキーワード引数にはドライバ名を接頭辞として付けることをお勧めします。たとえば、dbd.fooなら、:foo-whateverのようにです。

     It is up to the driver writer to define what options are available and the syntax of the options.  The basic idea is that the DSN identifies the source of the data; it's role is like URL in WWW. So, it may include the hostname and port number of the database, and/or the name of the database, etc.  However, it shouldn't include information related to authentication, such as username and password. That's why those are passed via keyword arguments. どのようなオプションを使えるようにするか、あるいはオプションの構文をどうするかはドライバを書く人しだいです。基本的な考え方は、DSN はデータのソースを識別するためのものであり、その役割りはWWWにおけるURLのようなものだということです。それゆえ、データベースのホスト名、ポート番号、それにデータベース名などが含まれることになるでしょう。しかし、ユーザ名やパスワードのような認証に関する情報を含めてはいけません。というわけで、その手の情報はキーワード引数で渡すのです。

 -- Method: dbi-prepare (c <foo-connection>) (sql <string>) :key pass-through ...
     This method should create and return a prepared query object, which is an instance of <dbi-query> or its subclass. The query specified by SQL is issued to the database system when the prepared query object is passed to dbi-execute. このメソッドは<dbi-query>あるいはそのサブクラスのインスタンスであるプリペアドクエリオブジェクトを生成し、それを返すものでなくてはなりません。SQLによるクエリがデータベースに発行されるのは、プリペアドクエリオブジェクトがdbi-executeに渡されたときです。

     The method must set C to the connection slot of the returned query object. このメソッドは返されるクエリオブジェクトのconnectionスロットに Cを設定しなけばなりません。

     SQL is an SQL statement.  It may contain placeholders represented by '?'.  The query closure should take the same number of arguments as of the placeholders.   It is up to the driver whether it parses SQL internally and construct a complete SQL statement when the query closure is called, or it passes SQL to the back-end server to prepare the statement and let the query closure just send parameters. SQLはSQL文です。これには'?'で表現されたプレイスホルダが含まれることがあります。クエリクロージャはこのプレイスホルダと同じ数の引数をとらなければなりません。内部的にSQLをどのようにパーズするか、クエリクロージャが呼ばれたとき完全なSQL文を構築するか、SQLをバックエンドのサーバに送って文を準備し、クエリクロージャはパラメータだけを送るようにするかなどはドライバに依存します。

     If the driver parses SQL statement internally, it should recognize a keyword argument pass-through.  If a true value is given, the driver must treat sql opaque and pass it as is when the query closure is called. ドライバがSQL文を内部的にわたす場合、キーワード引数pass-through を認識しなければいけません。もし、真の値が与えられたら、ドライバは sqlを不透明なものとして扱い、これをそのままクエリクロージャが呼ばれた際に渡さなければなりません。

     The driver may define other keyword arguments. It is recommended to name the driver-specific keyword arguments prefixed by the driver name, e.g. for dbd.foo, it may take a :foo-whatever keyword argument. ドライバがその他のキーワード引数を定義することもできます。その場合、ドライバ特有のキーワード引数にはドライバ名を接頭辞として付けることをお勧めします。たとえば、dbd.fooなら、 :foo-whateverのようにです。

 -- Method: dbi-execute-using-connection (c <foo-connection>) (q <dbi-query>) (params <list>)
     This method is called from dbi-execute. It must issue the query kept in Q.  If the query is parameterized, the actual parameters given to DBI-EXECUTE are passed to PARAMS argument. このメソッドはdbi-executeから呼ばれます。Qが保持するクエリを発行しなければなりません。クエリがパラメータ化されている場合、 DBI-EXECUTEに与えられた実際のパラメータはPARAMS引数に渡されます。

     If Q is a select-type query, this method must return an appropriate relation object. Qがselect-型のクエリの場合は、このメソッドは適切なリレーションオブジェクトを返さなければなりません。

 -- Method: dbi-escape-sql (c <foo-connection>) str
     If the default escape method isn't enough, the driver may overload this method to implement a specific escaping. For example, MySQL treats backslash characters specially as well as single quotes, so it has its dbi-escape-sql method. デフォルトのエスケープメソッドでは十分でないとき、ドライバは特別のエスケープを行うためにこのメソッドをオーバーロードすることができます。たとえば、MySQLではバックスラッシュ文字はシングルクォートと同様に特別あつかいしますので、dbi-escape-sqlメソッドを持っています。

 -- Method: dbi-open? (c <foo-connection>)
 -- Method: dbi-open? (q <foo-query>)
 -- Method: dbi-open? (r <foo-result>)
 -- Method: dbi-close (c <foo-connection>)
 -- Method: dbi-close (q <foo-query>)
 -- Method: dbi-close (r <foo-result>)
     Queries open/close status of a connection and a result, and closes a connection and a result.  The close methods should cause releasing resources used by connection/result.  The driver has to allow dbi-close to be called on a connection or a result which has already been closed. これらのメソッドでコネクションおよび結果の状態を調べ、コネクションおよび結果を閉じます。closeメソッドはコネクションや結果が利用しているリソースを解放しなければなりません。ドライバはdbi-closeがすでに閉じられたコネクションや結果に対しても適用できるようにしておかなければなりません。

 -- Method: dbi-do (c <foo-connection>) (sql <string>) :optional options parameter-value ...
     The default method uses dbi-prepare and dbi-execute to implement the function.  It just works, but the driver may overload this method in order to skip creating intermediate query object for efficiency. この機能を実装するのにデフォルトメソッドはdbi-prepareおよび dbi-executeを使っています。これだけでも動きますが、ドライバは効率のために中間のクエリオブジェクトの生成をスキップするためにこのメソッドをオーバーロードできます。

DBI utility functions
.....................

DBIのユーティリティ関数
.............

The following functions are low-level utilities which you may use to implement the above methods. 以下の関数は上述のメソッドを実装するための低レベルのユーティリティです。

 -- Function: dbi-parse-dsn data-source-name
     Parse the data source name (DSN) string given to dbi-connect, and returns tree values: (1) The driver name in a string. (2) 'options' part of DSN as a string.  (3) parsed options in an assoc list.  This may raise <dbi-error> if the given string doesn't conform DSN syntax. dbi-connectに与えられたデータソースネーム(DSN)文字列を解析し、以下の3つの値を返す。(1) ドライバ名(文字列) (2) DSNのオプション部分(文字列) (3) 解析済オプション(連想リスト)。与えられた文字列がDSN構文に準拠していない場合には<dbi-error>があがります。

     You don't need to use this to write a typical driver, for the parsing is done before dbi-make-connection is called. This method may be useful if you're writing a kind of meta-driver, such as a proxy. 典型的なドライバを書く場合には必要ありません。構文解析は dbi-make-connectionを呼ぶ前にすんでいるからです。このメソッドはプロキシのようなメタドライバという類のものを書くときに便利です。

 -- Function: dbi-prepare-sql connection sql
     Parses an SQL statement SQL which may contain placeholders, and returns a closure, which generates a complete SQL statement when called with actual values for the parameters.  If the back-end doesn't support prepared statements, you may use this function to prepare queries in the driver. プレイスホルダを含むSQL文 SQL をパーズし、実際の値をパラメータとして渡されたときに完全なSQLを生成するクロージャを作成します。バックエンドがプリペアド文をサポートしていない場合は、ドライバ中でクエリを準備するのにこの関数を使うことになります。

     CONNECTION is a DBI connection to the database.  It is required to escape values within SQL properly (see dbi-escape-sql above). CONNECTIONはデータベースへのDBIコネクションです。SQL中の値は適切にエスケープされている必要があります(上述のdbi-escape-sqlをみてください)。

          ;; assume c contains a valid dbi connection
          ((dbi-prepare-sql c "select * from table where id=?") "foo'bar")
           => "select * from table where id='foo''bar'"

          ;; c は正しいdbiコネクションを持っているとする
          ((dbi-prepare-sql c "select * from table where id=?") "foo'bar")
           => "select * from table where id='foo''bar'"

dbm - Generic DBM interface
===========================

 -- Module: dbm
     DBM-like libraries provides an easy way to store values to a file, indexed by keys.  You can think it as a persistent associative memory. DBM系のライブラリはキーでインデックスされた値をファイルに格納する簡単な方法を提供します。一種の永続的な連想記憶と言えるでしょう。

     This modules defines <dbm> abstract class, which has a common interface to use various DBM-type database packages. As far as you operate on the already opened database, importing dbm module is enough. このモジュールが定義する抽象クラス<dbm>は、DBM系ライブラリへの統一されたインタフェースを提供します。dbmモジュールだけをインポートすれば、既にオープンされたデータベースを操作することができます。

     To create or open a database, you need a concrete implementation of the database.  With the default build-time configuration, the following implementations are included in Gauche. Bindings to various other dbm-like libraries are available as extension packages. Each module defines its own low-level accessing functions as well as the common interface. Note that your system may not have one or more of those DBM libraries; Gauche defines only what the system provides. データベースをオープンしたり作成したりするには、dbmインタフェースを実装したモジュールが必要になります。デフォルトのビルド時コンフィグレーションでは、以下の実装がGaucheに含まれます。他の様々なdbmライブラリへのバインディングが拡張パッケージとして提供されています。それぞれのモジュールは、dbmインタフェース共通の手続きの他に、直接実装を操作できる低レベルの手続きも提供します。システムによっては以下のインタフェースの全てが実装されているわけではないことに注意してください。Gaucheではシステムが提供する実装のみを定義します。

     dbm.fsdbm
          file-system dbm (see File-system dbm). ファイルシステムdbm (File-system dbm参照).

     dbm.gdbm
          GDBM library (see GDBM interface). GDBMライブラリ (GDBM interface参照).

     dbm.ndbm
          NDBM library (see NDBM interface). NDBMライブラリ (NDBM interface参照).

     dbm.odbm
          DBM library  (see Original DBM interface). DBMライブラリ  (Original DBM interface参照).

The following code shows a typical usage of the database. 以下に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*)

The <dbm> abstract class implements collection and dictionary framework.  (See Collection framework and Dictionary framework, respectively). <DBM>抽象クラスは、コレクションフレームワークとディクショナリフレームワークを実装しています。 (それぞれCollection frameworkとDictionary framework参照。)

Opening and closing a dbm database
----------------------------------

 -- Class: <dbm>
     An abstract class for dbm-style database.    Inherits <dictionary> (see Dictionary framework). Defines the common database operations.   This class has the following instance slots. They must be set before the database is actually opened by dbm-open.

     The concrete class may add more slots for finer control on the database, such as locking. DBM系のデータベースのための抽象クラスです。 <dictionary>クラスを継承します (Dictionary framework参照)。データベースへの共通のオペレーションを定義します。以下のインスタンススロットを持ちます。これらのスロットの値は dbm-openによってデータベースがオープンされる前にセットされていなければなりません。

     具体クラスは、データベースの操作をより細かく行うための追加のスロット(例えばロックを行うかどうか)を持つかもしれません。

      -- Instance Variable of <dbm>: path
          Pathname of the dbm database.  Some dbm implementation may append suffixes to this. データベースファイルのパス名。dbmの実装によっては、このパスにサフィックスが追加されます。

      -- Instance Variable of <dbm>: rw-mode
          Specifies read/write mode.  Can be either one of the following keywords:

          :read
               The database will be opened in read-only mode.  The database file must exist when dbm-open is called.

          :write
               The database will be opened in Read-write mode. If the database file does not exist, dbm-open creates one.

          :create
               The database will be created and opened in Read-write mode. If the database file exists, dbm-open truncates it.

          読み書きのモードを指定します。以下の値のいずれかを取ります。

          :read
               データベースはdbm-openによって読みだし専用モードでオープンされます。オープンされる時点でデータベースは存在していなければなりません。

          :write
               データベースはdbm-openによって読み書き可能なモードでオープンされます。データベースが存在しなければ、dbm-openは新しいデータベースを作成します。

          :create
               dbm-openによって新しいデータベースが作成され、読み書き可能なモードでオープンされます。既にデータベースが存在していた場合、その内容はクリアされます。

      -- Instance Variable of <dbm>: file-mode
          Specifies the file permissions (as sys-chmod) to create the database.  The default value is #o664. データベースが作成されるときのファイルパーミッションを指定します。デフォルトは#o664です。

      -- Instance Variable of <dbm>: key-convert
      -- Instance Variable of <dbm>: value-convert
          By default, you can use only strings for both key and values.  With this option, however, you can specify how to convert other Scheme values to/from string to be stored in the database.   The possible values are the followings:

          #f
               The default value.  Keys (values) are not converted.  They must be a string.

          #t
               Keys (values) are converted to its string representation, using write, to store in the database, and converted back to Scheme values, using read, to retrieve from the database. The data must have an external representation that can be read back. (But it is not checked when the data is written; you'll get an error when you read the data).  The key comparison is done in the string level, so the external representation of the same key must match.

          a list of two procedures
               Both procedure must take a single argument.  The first procedure must receive a Scheme object and returns a string.  It is used to convert the keys (values) to store in the database.  The second procedure must receive a string and returns a Scheme object.  It is used to convert the stored data in the database to a Scheme object. The key comparison is done in the string level, so the external representation of the same key must match.

          デフォルトでは、dbmデータベースはキーにも値にも文字列しか使うことはできません。これらのスロットによって、それ以外のSchemeオブジェクトを取り扱う方法を指定することができます。以下の値のいずれかが可能です。

          #f
               デフォルトの値です。キーあるいは値は変換されません。それらは文字列でなければなりません。

          #t
               キーあるいは値はwriteを使って文字列に変換されデータベースに格納されます。そしてreadを使って文字列からSchemeオブジェクトへと変換されます。後でreadで読みこめるようなキーあるいは値のみを扱うことができます。 (但し、dbmライブラリは書き込み時にそれが後で読み込めるかどうかのチェックは行いません)。キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列表現を持つ必要があります。

          二つの手続きのリスト
               どちらの手続きも一つの引数を取ります。最初の手続きはSchemeオブジェクトを受け取り、文字列を返します。キーあるいは値をデータベースに格納する時に呼ばれます。二つ目の手続きは文字列を受け取りSchemeオブジェクトを返します。データベースからキーあるいは値を取り出す時に呼ばれます。キーの比較は文字列に変換された後で行われるので、同じ値となるキーは同じ文字列に変換される必要があります。

 -- Metaclass: <dbm-meta>
     A metaclass of <dbm> and its subclasses. <DBM>クラス及びそのサブクラスのメタクラスです。

 -- Method: dbm-open (dbm <dbm>)
     Opens a dbm database.  DBM must be an instance of one of the concrete classes that derived from the <dbm> class, and its slots must be set appropriately.   On success, it returns the DBM itself.  On failure, it signals an error. DBMデータベースをオープンします。DBMは、<dbm>クラスを継承した具体クラスのインスタンスでなければなりません。また、そのスロットには適切な値がセットされている必要があります。オープンに成功したらDBM自身が返されます。失敗した場合はエラーが報告されます。

 -- Method: dbm-open (dbm-class <dbm-meta>) options ...
     A convenient method that creates dbm instance and opens it. It is defined as follows. DBMインスタンスを作成してオープンするための便利なメソッドです。次のように定義されます。

          (define-method dbm-open ((class <class>) . initargs)
            (dbm-open (apply make class initargs)))

Database file is closed when it is garbage collected. However, to ensure the modification is properly synchronized, you should close the database explicitly. データベースファイルはガベージコレクトされる際にクローズされますが、変更を正しくデータベースに反映するには、明示的にクローズした方が良いでしょう。

 -- Method: dbm-close (dbm <dbm>)
     Closes a database DBM.  Once the database is closed, any operation to access the database content raises an error. データベースDBMをクローズします。データベースがクローズされると、それ以降のアクセスオペレーションはエラーとなります。

 -- Method: dbm-closed? (dbm <dbm>)
     Returns true if a database DBM is already closed, false otherwise. データベースDBMが既にクローズされていたら#tを返します。

 -- Function: dbm-type->class dbmtype
     Sometimes you don't know which type of dbm implementation you need to use in your application beforehand, but rather you need to determine the type according to the information given at run-time. This procedure fulfills the need.

     The DBMTYPE argument is a symbol that names the type of dbm implementation; for example, gdbm for dbm.gdbm, and fsdbm for dbm.fsdbm.   We assume that the dbm implementation of type FOO is provided as a module dbm.FOO, and its class is named as <FOO>.

     This procedure first checks if the required module has been loaded, and if not, it tries to load it.   If the module loads successfully, it returns the class object of the named dbm implementation.   If it can't load the module, or can't find the dbm class, this procedure returns #f.

          (use dbm)

          (dbm-type->class 'gdbm)
            => #<class <gdbm>>

          (dbm-type->class 'nosuchdbm)
            => #f

Accessing a dbm database
------------------------

Once a database is opened, you can use the following methods to access individual key/value pairs. データベースがオープンされたら、以下のアクセスメソッドが使えます。

 -- Method: dbm-put! (dbm <dbm>) key value
     Put a VALUE with KEY. 値VALUEをキーKEYと関連付けて保存します。

 -- Method: dbm-get (dbm <dbm>) key :optional default
     Get a value associated with KEY.  If no value exists for KEY and DEFAULT is specified, it is returned.  If no value exists for KEY and DEFAULT is not specified, an error is signaled. キーKEYに関連付けられた値を返します。もし値が存在しなければ、DEFAULTが与えられていればそれを返し、そうでなければエラーを報告します。

 -- Method: dbm-exists? (dbm <dbm>) key
     Return true if a value exists for KEY, false otherwise. キーKEYに関連付けられた値が存在すれば#tを返します。

 -- Method: dbm-delete! (dbm <dbm>) key
     Delete a value associated with KEY. キーKEYに関連付けられた値を消去します。値が存在しない場合は何もしません。

Iterating on a dbm database
---------------------------

To walk over the entire database, following methods are provided. 全データベースを渡り歩く処理のために、以下のメソッドが用意されています。

 -- Method: dbm-fold (dbm <dbm>) procedure knil
     The basic iterator. For each key/value pair, PROCEDURE is called as (PROCEDURE KEY VALUE R), where R is KNIL for the fist call of PROCEDURE, and the return value of the previous call for subsequent calls. Returns the result of the last call of PROCEDURE. If no data is in the database, KNIL is returned.

     The following method returns the sum of all the integer values. 基本的な繰り返し処理です。データベース内の各キー／値のペアに関して、手続き 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
     For each key/value pair in the database DBM, PROCEDURE is called.  Two arguments are passed to PROCEDURE---a key and a value.   The result of PROCEDURE is discarded. データベース内の各キー／値のペアに関して、手続きPROCEDUREを呼び出します。 PROCEDUREにはキーと値が渡されます。PROCEDUREの戻り値は捨てられます。

 -- Method: dbm-map (dbm <dbm>) procedure
     For each key/value pair in the database DBM, PROCEDURE is called.  Two arguments are passed to PROCEDURE---a key and a value.   The result of PROCEDURE is accumulated to a list which is returned as a result of dbm-map. データベース内の各キー／値のペアに関して、手続きPROCEDUREを呼び出します。 PROCEDUREにはキーと値が渡されます。PROCEDUREの戻り値はリストに集められてdbm-mapの戻り値となります。

Managing dbm database instance
------------------------------

Each dbm implementation has its own way to store the database.  Legacy dbm uses two files, whose names are generated by adding .dir and .pag to the value of PATH slot.  Fsdbm creates a directory under PATH.  If dbm database is backed up by some database server, PATH may be used only as a key to the database in the server. 各DBM実装は、データベースを格納するのに独自の方法を使います。レガシーなDBMは、PATHスロットの値にそれぞれ.dirと .pagを付けた名前の2つのファイルを使います。 fsdbmはPATHの下にディレクトリを作ります。 DBMデータベースが他のデータベースサーバによってバックアップされる場合は、PATHはそのサーバで単なるキーとして使われるでしょう。

The following methods hide such variations and provides a convenient way to manage a database itself.   You have to pass a class that implements a concrete dbm database to their first argument. 以下のメソッドは、そのようなバリエーションを隠し、データベースそれ自体を管理する簡易な方法を提供します。最初の引数に、具体的なDBMデータベースを実装しているクラスを渡す必要があります。

 -- Generic Function: dbm-db-exists? class name
     Returns #t if a database of class CLASS specified by NAME exists. NAMEで指定されたCLASSクラスのデータベースが存在する場合は#tを返します。

          ;; Returns #t if testdb.dir and testdb.pag exist
          (dbm-db-exists? <odbm> "testdb")

 -- Generic Function: dbm-db-remove class name
     Removes an entire database of class CLASS specified by NAME. NAMEで指定されるCLASSクラスのデータベース全体を削除します。

 -- Generic Function: dbm-db-copy class from to
     Copy a database of class CLASS specified by FROM to TO.  The integrity of FROM is guaranteed if the CLASS's dbm implementation supports locking (i.e. you won't get a corrupted database even if some other process is trying to write to FROM during copy).   If the destination database TO exists, its content is destroyed.  If this function is interrupted, whether TO is left in incomplete state or not depends on the dbm implementation.   The implementation usually tries its best to provide transactional behavior, that is, to recover original TO when the copy fails.  However, for the robust operations the caller have to check the state of TO if dbm-db-copy fails. FROMで指定されたCLASSクラスのデータベースを TOへコピーします。 CLASSのdbm実装がロックをサポートしている限り、FROMの一貫性は保たれます (つまり、コピー中に他のプロセスがFROMを変更しようとした場合であっても、TOが壊れたデータベースになることはありません)。  もしコピー先のTOが既に存在するデータベースであった場合、TOの元の内容は失われます。コピーが中断された場合にTOが不完全な状態のままになるかどうかは dbm実装に依存します。dbm実装の多くはトランザクショナルな振る舞い、すなわち、コピーが失敗した場合に元のTOを復元することを試みます。しかし確実な操作のためには、コピーが失敗した場合には呼び出し側でTOの状態を確認することが必要です。

          (dbm-db-copy <gdbm> "testdb.dbm" "backup.dbm")

 -- Generic Function: dbm-db-move class from to
     Moves or renames a database of class CLASS specified by FROM to TO.  Like dbm-db-copy, the database integrity is guaranteed as far as CLASS's dbm implementation supports locking.  If the destination database TO exists, its content is destroyed. FROMで指定されたCLASSクラスのデータベースを TOへ移動、あるいはリネームします。dbm-db-copyと同じく、 CLASSのdbm実装がロックをサポートしていればデータベースの一貫性は保証されます。移動先のTOが既に存在していた場合、その元の内容は失われます。

Dumping and restoring dbm database
----------------------------------

Most dbm implementations use some kind of binary format, and some of them are architecture dependent. That makes it difficult to pass around dbm databases between different machines. A safe way is to write out the content of a dbm database into some portable format on the source machine, and rebuild another dbm database from it on the destination machine.

The operation is so common that Gauche provides convenience scripts that does the job.  They are installed into the standard Gauche library directory, so it can be invoked by gosh <scriptname>.

To write out the content of a dbm database named by DBM-NAME, you can use dbm/dump script:

     $ gosh dbm/dump [-o OUTFILE][-t TYPE] DBM-NAME

The OUTFILE argument names the output file.  If omitted, the output is written out to stdout.  The TYPE argument specifies the implementation type of the dbm database; e.g. gdbm or fsdbm.  The program calls dbm-type->class (see Opening and closing a dbm database) on the TYPE argument to load the necessary dbm implementation.

The dumped format is simply a series of S-expressions, each of which is a dotted pair of string key and string value. Character encodings are assumed to be the same as gosh's native character encoding.

The dumped output may contain S-expressions other than dotted pair of strings to include meta information.  For now, programs that deals with dumped output should just ignore S-expressions other than dotted pairs.

To read back the dumped dbm format, you can use dbm/restore script:

     $ gosh dbm/restore [-i INFILE][-t TYPE] DBM-NAME

The INFILE argument names the dumped file to be read. If omitted, it reads from stdin.  The TYPE argument specifies the dbm type, as in dbm/dump script. The DBM-NAME argument names the dbm database; if the database already exists, its content is cleared, so be careful.

Writing a dbm implementation
----------------------------

When you write an extension module that behaves like a persistent hashtable, it is a good idea to adapt it to the dbm interface, so that the application can use the module in a generic way.

The minimum procedures to conform the dbm interface are as follow:

  * Define a metaclass <FOO-meta>.   It doesn't need to inherit anything except <class>.

  * Define a dbm class <FOO> that inherits <dbm> and whose metaclass is <FOO-meta>.

  * Define methods for dbm-open, dbm-close, dbm-put!, dbm-get, dbm-exists, dbm-delete!, dbm-fold, dbm-closed?, specialized for <FOO>. (The case of dbm-open for <FOO-meta> is handled automatically, so you don't need to define it unless you want something special). Also note that the specialized dbm-open must call next-method in it to set up dbm base class internals.

  * Define methods for dbm-db-exists? and dbm-db-remove on <FOO-meta>.

Besides above, you may define the following methods.

  * Methods for dbm-for-each and dbm-map. If you don't define them, a generic implementation by dbm-fold is used.  There may be an implementation specific way which is more efficient.

  * Methods for dbm-db-copy and dbm-db-move. If you don't define them, a fallback method opens the specified databases and copies elements one by one, and removes the original if the method is  dbm-db-move. Note that the fallback method is not only inefficient, but also it may not copy any implementation-specific meta information.  It is highly recommended for the dbm implementation to provide these methods as well.

It is generally recommended to name the implementation module as dbm.FOO, and the class of the implementation as <FOO>.  With this convention it is easier to write an application that dynamically loads and uses dbm implementation specified at runtime.

dbm.fsdbm - File-system dbm
===========================

 -- Module: dbm.fsdbm
     Implements fsdbm.  Extends dbm.

 -- Class: <fsdbm>
     Fsdbm is a dbm implementation that directly uses the filesystem.  Basically, it uses file names for keys, and file content for values.   Unlike other dbm implementations, this doesn't depend on external libraries---it is pure Scheme implementation---so it is always available, while other dbm implementations may not. fsdbmは、直接ファイルシステムを扱うDBM実装です。基本的には、ファイル名をキー、ファイルの内容を値として使います。他のDBM実装とは違い、これは他の特別なライブラリに依存しません (純粋にSchemeのみにより実装されています)。したがって、他のDBM実装が使えないときでも、いつでも使うことができます。

     Obviously, it is not suitable for the database that has lots of entries, or has entries deleted and added very frequently. The advantage is when the number of entries are relatively small, and the values are relatively large while keys are small. 明らかに、たくさんのエントリを持っていたり、エントリの追加や削除が頻繁に起こるようなデータベースには向いていません。エントリの数が相対的に小さく、キーが小さいのに値が大きいような場合に向いています。

     The database name given to <fsdbm> instance is used as a directory name that stores the data. <fsdbm>のインスタンスに与えられるデータベース名は、データを格納するディレクトリの名前として使われます。

     The data files are stored in subdirectories under PATH of fsdbm instance, hashed by the key.  Non-alphanumeric characters in the key is encoded like _3a for ':', for example. If a key is too long to be a file name, it is chopped to chunks, and each chunk but the last one is used as a directory name. Note that a long key name may still cause a problem, for example, some of old 'tar' command can't deal with pathnames (not each pathname components, but the entire pathname) longer than 256 characters. データのファイルは、fsdbmインスタンスのPATHのサブディレクトリに格納され、キーによりハッシュされます。キーに英数字でない文字がある場合はエンコードされます。例えば、':'は、_3aにエンコードされます。キーがファイル名としては長すぎる場合は、いくつかに分割され、その最後の文字列片以外はディレクトリ名として使われます。長いキー名は問題を引き起こすかも知れないことに注意して下さい。例えば、いくつかの古い'tar'コマンドは、256文字を越える長いパス名を扱えません(それぞれのパスコンポーネントではなく、パス名全体でです)。

Fsdbm implements all of the dbm protocol (see Generic DBM interface). It doesn't have any fsdbm-specific procedures. fsdbmは、全てのDBMプロトコルを実装しています (Generic DBM interface参照)。 fsdbm特有の手続きというものはありません。

dbm.gdbm - GDBM interface
=========================

 -- Module: dbm.gdbm
     Provides interface to the gdbm library.  Extends dbm.

 -- 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). <dbm> を継承します。GDBM ライブラリのための実装を提供します。このモジュールは、すでにあなたのシステムにすでに GDBM がある場合にのみインストールされます(バージョン 1.8.0 が推奨されますが、いくつかの制限があるだけで古い 1.7.x でも動作します)。

      -- Instance Variable of <gdbm>: sync

      -- Instance Variable of <gdbm>: nolock

      -- Instance Variable of <gdbm>: bsize

Besides the unified DBM interface (see Generic DBM interface), this module provides the following low-level functions that provides direct access to the gdbm API.  See gdbm manual for details of these APIs. 統合された DBM インターフェース (see Generic DBM interface) の他に、このモジュールでは GDBM API への直接のアクセスを提供する以下の低レベルな手続きを提供しています。これらの API の詳細については GDBM のマニュアルを見て下さい。

 -- 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

dbm.ndbm - NDBM interface
=========================

 -- Module: dbm.ndbm
     Provides interface to the 'new' dbm library, a.k.a. ndbm. Extends dbm.

 -- Class: <ndbm>
     Inherits <dbm>.  Provides an implementation for NDBM library. This module is only installed when your system already has NDBM. <dbm> を継承します。NDBM ライブラリのための実装を提供します。このモジュールはあなたのシステムにすでに NDBM がある場合にのみインストールされます。

Besides the unified DBM interface (see Generic DBM interface), this module provides the following low-level functions that provides direct access to the ndbm API.  See ndbm manual for details of these APIs. 統合された DBM インターフェース (see Generic DBM interface) の他に、このモジュールでは NDBM API への直接のアクセスを提供する以下の低レベルな手続きを提供しています。これらの API の詳細については NDBM のマニュアルを見て下さい。

 -- 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

dbm.odbm - Original DBM interface
=================================

 -- Module: dbm.odbm
     Provides interface to the legacy dbm library. Extends dbm.

 -- 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. <dbm> を継承しています。レガシーな DBM ライブラリのための実装を提供します。このモジュールは、あなたのシステムにすでに DBM がある場合にのみインストールされます。

     レガシー DBM の最大の制限は、データベースを一時に一つしか開けないことです。複数の <odbm> のインスタンスを作ることができますが、一時に一つしか開くことが出来ず、一つ以上開こうとするとエラーになります。

Besides the unified DBM interface (see Generic DBM interface), this module provides the following low-level functions that provides direct access to the dbm API.  See dbm manual for details of these APIs. 統合された DBM インターフェース (see Generic DBM interface) の他に、このモジュールでは DBM API への直接のアクセスを提供する以下の低レベルな手続きを提供しています。これらの API の詳細については DBM のマニュアルを見て下さい。

 -- 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

file.filter - Filtering file content
====================================

 -- Module: file.filter
     This module provides utilities for a common pattern in filter-type commands, that is, to take an input, to process the content, and to write the result.   The common occurring pattern is:

       * Input may be a specified file, or an input port (the current input port by default).

       * Output may be a specified file, or an output port (the current output port by default).

       * Output may be a temporary file, which will be renamed upon completion of the processing.

       * Output file may be removed when an error occurs in the processing.

     このモジュールは、フィルター型のコマンド、すなわち入力を読み込み、処理をして結果を書き出すような場合に共通するパターンに使えるユーティリティ手続きを提供します。共通するパターンとは：

       * 入力は指定されたファイルかポートで、デフォルトはカレント入力ポート。

       * 出力は指定されたファイルかポートで、デフォルトはカレント出力ポート。

       * 出力は一時ファイルに書き出すこともできて、その場合は処理が終了した時点で指定されたファイルにリネーム。

       * 処理途中でエラーが起こった場合に出力ファイルを削除

 -- Function: file-filter proc :key input output temporary-file keep-output? rename-hook
     Calls PROC with two arguments, an input port and an output port.   Returns the result(s) of PROC. The input port and output port are chosen depending on the keyword arguments. 二つの引数、入力ポートと出力ポートを引数としてPROCを呼び出し、その結果を返します。入力ポートと出力ポートはキーワード引数により決定されます。

     input
          The argument must be either an input port or a string that specifies a file name. If it's an input port, it is passed to PROC as is. If it's a string, the named file is opened for input and the resulting port is passed to PROC, and the port is closed when PROC returns. If this argument is omitted, the current input port is passed. この引数は入力ポートかファイル名を示す文字列でなければなりません。入力ポートの場合、それはそのままPROCに渡されます。文字列が渡された場合は、そのファイル名を持つファイルを入力用にオープンし、そのポートがPROCに渡され、またこのポートはPROCが戻った時に閉じられます。この引数が省略された場合は、現在の入力ポートが渡されます。

     output
          The argument must be either an output port or a string that specifies a file name. If it's an output port, it is passed to PROC as is. If it's a string, the named file is opened for output (unless TEMPORARY-FILE is given, in that case a temporary file is opened instead), and the resulting port is passed to PROC.  This port is closed when PROC returns. If this argument is omitted, the current output port is passed. この引数は出力ポートかファイル名を示す文字列でなければなりません。出力ポートの場合、それはそのままPROCに渡されます。文字列が渡された場合は、そのファイル名を持つファイルを出力用にオープンし、そのポートがPROCに渡されます (但し、TEMPORARY-FILE 引数が渡された時はそれに指定されるファイルが一時ファイルとしてオープンされます)。オープンされたポートはPROCが戻った時に閉じられます。この引数が省略された場合は、現在の出力ポートが渡されます。

     temporary-file
          The value must be a boolean or a string.  If a non-false value is given, and output is a file, then a fresh temporary file is created and opened for output and passed to PROC. When PROC returns normally, the file is renamed to the name given to OUTPUT keyword argument.

          If #t is given, a temporary file name is generated based on the name of the output file. If a string file name is given to this argument, the name is used for sys-mkstemp.

          If the given file name begins with characters except "/", "./" or "../", the directory of the file name given to OUTPUT argument is attached before it.

          The default value is #f (do not use a temporary file). 値は真偽値か文字列でなければなりません。#fでない値が渡され、かつ出力がファイルである場合、新たな一時ファイルが出力用に作成されPROCに渡されます。そしてPROCが正常に返って来た時点で、一時ファイルはOUTPUTに指定されたファイルへとリネームされます。

          この引数が#tの場合、一時ファイル名は出力ファイル名をもとに作られます。この引数が文字列の場合はそれがsys-mkstempに渡されます。

          もし一時ファイル名が"/"、"./"、"../"以外の文字で始まっていた場合は、OUTPUTに与えられたファイル名のディレクトリが一時ファイルの前に追加されます。

          デフォルトの値は#f (一時ファイルを使わない) です。

     keep-output?
          If a true value is given, the output is not deleted even when PROC signals an error. By default, the output (or the temporary file when TEMPORARY-FILE is given) will be deleted on error. 真の値が与えられた場合、PROCがエラーになった場合でも出力ファイルを削除しません。デフォルトでは、出力ファイル(もしくはTEMPORARY-FILEが与えられた場合はそのファイル)はエラーの場合には削除されます。

     leave-unchanged
          When a temporary file is used, and a true value is given to this argument, the existing output file is left intact when the generated output in the temporary file exactly matches the original content of the output file.  It is useful if touching output file may trigger some actions (e.g. by make) and you want to avoid invoking unnecessary actions.  The default value is #f (always replace the output). 一時ファイルを使う場合に、この引数に真の値が与えられると、出力ファイルが既に存在して一時ファイルに生成された内容と全く同じだった場合に、出力ファイルをそのままにします。これは、出力ファイルに触ることで何らかのアクションが起きるようになっている場合に(例: make)、不必要なアクションを起こさないために便利です。デフォルトの値は#f (常に出力ファイルを置き換える) です。

 -- Function: file-filter-fold proc seed :key reader input output temporary-file keep-output? rename-hook
     A convenience wrapper of file-filter. Call PROC for each item read from input by READER (read-line by default).  The argument PROC receives is the item, the seed value and the output port; PROC can emit the output, as well as returning some value that is passed along as the seed value.  Other keyword arguments are passed to file-filter.

     For example, the following code reads each line from file.txt and displays lines matching #/regexp/ with line numbers. file-filterの便利なラッパー手続きです。入力からREADERによって読まれるデータに対して次々にPROCを呼び出します。READERのデフォルトはread-lineです。 PROCの引数は、読まれたデータ、シード値、出力ポートです。 PROCは何かを出力することもできますし、値を返せばそれが次のシード値として受け渡されてゆきます。他のキーワード引数は file-filterにそのまま渡されます。

     例えば次のコードは、file.txtを1行づつ読み、#/regexp/にマッチする行を行番号つきで出力します。

          (file-filer-fold
            (^[line nc out]
              (when (#/regexp/ line) (format out "~3d: ~a\n" nc line))
              (+ nc 1))
            1 :input "file.txt")

 -- Function: file-filter-map proc :key reader input output temporary-file keep-output? rename-hook
 -- Function: file-filter-for-each proc :key reader input output temporary-file keep-output? rename-hook
     Utilities similar to file-filter-fold, like map and for-each to fold.

     The procedure PROC is called with two arguments, an item read from the input and an output port. The results of PROC are collected as a list and returned by file-filter-map, and discarded by file-filter-for-each.

     The meaning of keyword arguments are the same as file-filter-fold. file-filter-foldに似たユーティリティです。 foldに対するmap、for-eachに相当します。

     手続きPROCは二つの引数、入力から読まれたデータと出力ポートを受けとります。 PROCの結果は、file-filter-mapでは集められてリストとして戻り値となり、file-filter-for-eachでは捨てられます。

     キーワード引数の意味はfile-filter-foldと同じです。

file.util - Filesystem utilities
================================

 -- Module: file.util
     Provides convenient utility functions handling files and directories. Those functions are built on top of the primitive system procedures described in Filesystems. ファイルやディレクトリを扱う便利な手続き群を提供します。これらの手続きはFilesystemsで述べられたプリミティブなシステム手続きの上に構築されています。

     Many procedures in this module takes a keyword argument FOLLOW-LINK?, which specifies the behavior when the procedure sees a symbolic link. If true value is given to FOLLOW-LINK? (which is the default), the procedure operates on the file referenced by the link; if false is given, it operates on the link itself. このモジュール内の多くの手続きはFOLLOW-LINK?というキーワード引数を取ります。これは手続きがシンボリックリンクに出会ったときの動作を指定します。FOLLOW-LINK?が真であれば、手続きはリンクの指す先のファイルに作用します。これがデフォルトの振舞いです。 FOLLOW-LINK?に#fが渡された場合は手続きはリンクそのものに作用します。

Note on the naming convention: Some Scheme implementations "create" new directories and files, while the others "make" them. Some implementations "delete" them, while the others "remove" them. It seems that both conventions are equally popular. So Gauche provides both. 名前つけ規則に関する注記：ファイルやディレクトリを作成するのに"create"という語を使う処理系と"make"を使う処理系があります。ファイルやディレクトリを削除するのにも"remove"と "delete"の流派があります。どちらも同じくらい広く使われているようなので、 Gaucheでは両方の名前を提供することにしました。

Directory utilities
-------------------

 -- Function: current-directory :optional new-directory
     When called with no argument, this returns the pathname of the current working directory.  When called with a string argument NEW-DIRECTORY, this sets the current working directory of the process to it. If the process can't change directory to NEW-DIRECTORY, an error is signaled.

     This function is in ChezScheme, MzScheme and some other Scheme implementations.

     SRFI-170 defines current-directory without arguments, to return the current working directory. 引数無しで呼ばれた場合、カレントディレクトリを返します。文字列NEW-DIRECTORYが与えられた場合はプロセスのカレントディレクトリを NEW-DIRECTORYに変更します。変更が出来なかった場合はエラーとなります。

     この関数はChezSchemeやMzSchemeなどいくつかのScheme処理系に見られます。

     SRFI-170は引数を取らないcurrent-directoryを定義しています。現在のディレクトリを返すのは一緒です。

 -- Function: home-directory :optional user
     Returns the home directory of the given USER, which may be a string user name or an integer user id. If USER is omitted, the current user is assumed. If the given user cannot be found, or the home directory of the user cannot be determined, #f is returned. 名前または整数のユーザidで与えられたユーザUSERのホームディレクトリを返します。USERが省略された場合はカレントユーザが使われます。与えられたユーザが見付けられないか、ホームディレクトリを決定できなかった場合は #fが返されます。

     On Windows native platforms, this function is only supported to query the current user's directory. Windowsネイティブ環境では、この関数はカレントユーザに対してのみ動作します。

 -- Function: directory-list path :key children? add-path? filter filter-add-path?
     Returns a list of entries in the directory PATH. The result is sorted by dictionary order.

     By default, only the basename (the last component) of the entries returned.   If ADD-PATH? is given and true, PATH is appended to each entry.  If CHILDREN? is given and true, "." and ".." are excluded from the result.

     If FILTER is given, it must be a predicate that takes one argument. It is called on every element of the directory entry, and only the entries on which FILTER returns true are included in the result. The argument passed to FILTER is a basename of the directory entry by default, but when FILTER-ADD-PATH? is true, PATH is appended to the entry.

     If PATH is not a directory, an error is signaled. ディレクトリPATH中のエントリのリストを返します。リストは文字列順にソートされます。

     デフォルトではエントリのベースネーム(パスの最後のコンポーネント)のみが返されますが、キーワード引数ADD-PATH?に真の値が与えられた時は PATHが各エントリの前に追加されます。 CHILDREN?に真の値が与えられた時は、カレントディレクトリと親ディレクトリがリストから除かれます。

     FILTER引数は、もし与えられれば、一つの引数を取る手続きでなければなりません。ディレクトリ中の各エントリを引数としてその手続きが呼ばれ、真を返したエントリのみが結果に含まれます。 FILTERに与えられるエントリはデフォルトではベース名のみですが、引数FILTER-ADD-PATH?が真ならばPATHが前に追加された名前となります。

     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 :key children? add-path? filter follow-link?
     Like directory-list, but returns two values; the first one is a list of subdirectories, and the second one is a list of the rest. The keyword arguments CHILDREN?, add-path? and FILTER are the same as directory-list.

     Giving false value to FOLLOW-LINK? makes directory-list2 not follow the symbolic links; if the PATH contains a symlink to a directory, it will be included in the first list if FOLLOW-LINK? is omitted or true, while it will be in the second list if FOLLOW-LINK? is false. directory-listに似ていますが、ふたつの値を返します。最初の値は PATH内にあるサブディレクトリのリストで、次の値はそれ以外のエントリのリストです。キーワード引数CHILDREN?、add-path?、FILTERは directory-listと同じ意味をもちます。

     偽の値をFOLLOW-LINK?に与えると、PATH内のシンボリックリンクを辿りません；すなわち、PATH内にディレクトリへのシンボリックリンクがあった場合、デフォルト、もしくはFOLLOW-LINK?に真の値が与えられた場合はそれは最初のリスト(サブディレクトリ)に入りますが、FOLLOW-LINK? に偽の値が与えられた場合は後者のリスト(その他のエントリ)に入ります。

 -- Function: directory-fold path proc seed :key lister follow-link?
     A fundamental directory traverser. Conceptually it works as follows, in recursive way. ディレクトリ探索の最も基本的な手続きです。基本的な動作は以下に示すような再帰的なものです。

       * If PATH is not a directory, calls (PROC PATH SEED) and returns the result.

       * If PATH is a directory, calls (LISTER PATH SEED).  The procedure LISTER is expected to return two values: a list of pathnames, and the next seed value.   Then directory-fold is called on each returned pathname, passing the returned seed value to the SEED argument of the next call of directory-fold. Returns the result of the last seed value.

       * PATHがディレクトリでない場合は(PROC PATH SEED) を評価し、結果を返します。

       * PATHがディレクトリであった場合、まず (LISTER PATH SEED) を評価します。手続きLISTERは2つの値、パス名のリストと次のseedとなる値を返さなければなりません。続いて、directory-foldが各パス名に対して再帰的に呼ばれます。各呼び出しの結果が次の再帰呼び出しのSEEDの値に使われます。

     The default procedure of LISTER is just a call to directory-list, as follows. デフォルトのLISTERはdirectory-listを次のように呼び出すものです。

          (lambda (path seed)
            (values (directory-list path :add-path? #t :children? #t)
                    seed))

     Note that LISTER shouldn't return the given path itself (".") nor the parent directory (".."), or the recursion wouldn't terminate.  Also note LISTER is expected to return a path accessible from the current directory, i.e. if PATH is "/usr/lib/foo" and it contains "libfoo.a" and "libfoo.so", LISTER should return '("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so"). LISTERはPATH自身への参照 (".") やその親ディレクトリへの参照を返してはなりません。また、LISTERの戻り値は現在のディレクトリからアクセス可能なパス名でなければなりません。例えばPATHが"/usr/lib/foo"であり、そのディレクトリが"libfoo.a"と"libfoo.so"を含んでいた場合、 LISTERは'("/usr/lib/foo/libfoo.a" "/usr/lib/foo/libfoo.so") のようなリストを返す必要があります。

     The keyword argument FOLLOW-LINK? is used to determine whether LISTER should be called on a symbolic link pointing to a directory. When FOLLOW-LINK? is true (default), LISTER is called with the symbolic link if it points to a directory. When FOLLOW-LINK? is false, PROC is not called. キーワード引数FOLLOW-LINK?はディレクトリを指しているシンボリックリンクに対して LISTERを呼ぶかどうかを決定します。FOLLOW-LINK?が真(デフォルト値)である場合はそのようなシンボリックリンクに対してもLISTERが呼ばれます。一方、FOLLOW-LINK?が偽であればシンボリックリンクに対してはPROCが呼ばれます。

     The following example returns a list of pathnames of the emacs backup files (whose name ends with "~") under the given path. 次の例は、与えられたpath以下からemacsのバックアップファイル ("~"で終る名を持つファイル) のリストを返します。

          (use srfi-13) ;; for string-suffix?
          (directory-fold path
                          (lambda (entry result)
                            (if (string-suffix? "~" entry)
                                (cons entry result)
                                result))
                          '())

     The following example lists all the files and directories under the given pathname.   Note the use of LISTER argument to include the directory path itself in the result. 次の例は与えられたpath以下全てのファイルとディレクトリ名をリストにして返します。LISTER引数を使ってディレクトリ名そのものを結果に含めていることに注目して下さい。

          (directory-fold path cons '()
            :lister (lambda (path seed)
                      (values (directory-list path :add-path? #t :children? #t)
                              (cons path seed))))

 -- Function: make-directory* name :optional perm
 -- Function: create-directory* name :optional perm
     Creates a directory NAME.  If the intermediate path to the directory doesn't exist, they are also created (like mkdir -p command on Unix).   If the directory NAME already exist, these procedure does nothing. PERM specifies the integer flag for permission bits of the directory. ディレクトリNAMEを作成します。NAMEに至るパスが存在しない場合は必要なディレクトリが作成されます (Unixのmkdir -pコマンドと同様です)。ディレクトリNAMEが既に存在していた場合は何もしません。 PERMは作成されるディレクトリのパーミッションビットを指定します。

 -- Function: remove-directory* name
 -- Function: delete-directory* name
     Deletes directory NAME and its content recursively (like rm -r command on Unix).   Symbolic links are not followed. ディレクトリNAMEとその内容を再帰的に消去します (Unixのrm -rコマンドと同様です)。シンボリックリンクは辿られません。

 -- Function: copy-directory* src dst :key if-exists backup-suffix safe keep-timestamp keep-mode follow-link?
     If SRC is a regular file, copies its content to DST, just like copy-file does.  If SRC is a directory, recursively descends it and copy the file tree to DST.  Basically it mimics the behavior of cp -r command.

     If there's any symbolic links under SRC, the link itself is copied instead of the file pointed to by it, unless a true value is given to the FOLLOW-LINK? keyword argument, i.e. the default value of FOLLOW-LINK? is #f. (Note that this is opposite to the copy-file, in which FOLLOW-LINK? is true by default.) SRCが通常のファイルであれば、copy-fileと同じようにその内容をDSTにコピーします。しかしSRCがディレクトリの場合は、再帰的にディレクトリを辿り、その全てをDSTへとコピーします。 cp -rコマンドに相当するものだと考えて良いでしょう。

     SRCがディレクトリの場合、デフォルトではその下にあるシンボリックリンクは辿られず、リンクそのものがコピーされます。リンク先の内容をもコピーしたい場合はFOLLOW-LINK?キーワード引数に真の値を与えてください。つまり、FOLLOW-LINK?キーワード引数のデフォルト値は#fです。 (このデフォルト値はcopy-fileと逆であることに注意してください。 copy-fileではFOLLOW-LINK?はデフォルトで真であり、リンクそのものをコピーしたい場合に明示的に#fを与える必要があります。)

     The meanings of the other keyword arguments are the same as copy-file.  See the entry of copy-file for the details. 他のキーワード引数の意味はcopy-fileと同じです。詳細はcopy-fileを参照してください。

 -- Function: create-directory-tree dir spec
     Creates a directory tree under DIR according to SPEC. This procedure is useful to set up certain directory hierarchy at once.

     The SPEC argument is an S-expression with the following structure:

          <spec> : <name>                             ; empty file
                 | (<name> <option> ...)              ; empty file
                 | (<name> <option> ... <string>)     ; file with content
                 | (<name> <option> ... <procedure>)  ; file with generated content
                 | (<name> <option> ... (<spec> ...)) ; directory

          <name> : string or symbol

          <option> ... : keyword-value alternating list

     SPECで指定されるディレクトリツリーをDIRの下に作成します。特定のディレクトリ構造を一気にセットアップする際に便利です。

     SPEC引数は次に示される構造をもつS式です。

          <spec> : <name>                             ; 空のファイル
                 | (<name> <option> ...)              ; 空のファイル
                 | (<name> <option> ... <string>)     ; 固定内容のファイル
                 | (<name> <option> ... <procedure>)  ; 内容を生成するファイル
                 | (<name> <option> ... (<spec> ...)) ; ディレクトリ

          <name> : 文字列かシンボル

          <option> ... : キーワードと値の交代リスト

     With the first and second form of SPEC, an empty file is created with the given name. With the third form of SPEC, the string becomes the content of the file.

     With the fourth form of SPEC, the procedure is called with the pathname as an argument, and output to the current output port within the procedure is written to the created file. The pathname is relative to the DIR argument. At the time the procedure is called, its parent directory is already created.

     The last form of SPEC creates a named directory, then creates its children recursively according to the specs. SPECの最初と2番目の形式では、名前NAMEを持つ空のファイルが作られます。 3番目の形式では与えられた文字列がファイルの内容となります。

     4番目の形式では、手続きがファイルのパス名を引数として呼び出され、その手続きがcurrent output portに出力した内容がファイルの内容となります。引数に渡されるパス名はDIR引数からの相対パスです。手続きが呼ばれる時、その親ディレクトリは既につくられています。

     最後の形式は、名前NAMEを持つディレクトリを作成し、その子供として再帰的に指定されたSPECによるファイル/ディレクトリを作成します。

     With OPTIONs you can control attributes of created files/directories. Currently the following options are recognized.

     :mode MODE
          Takes integer as permission mode bits.

     :owner UID
     :group GID
          Takes integer uid/gid of the owner/group of the file/directory. Calling process may need special privilege to change the owner and/or group.

     :symlink PATH
          This is only valid for file spec, and it causes create-directory-tree to create a named symbolic link whose content is PATH.

     OPTIONによって、作られるファイル/ディレクトリの属性を細かく指定できます。今のところ、次のオプションが認識されます。

     :mode MODE
          整数MODEでパーミッションのモードビットを指定します。

     :owner UID
     :group GID
          整数UID/GIDで作成されるエントリのオーナー/グループを指定します。作成されるエントリのオーナー/グループを変更するには、呼び出すプロセスに特権が必要かもしれません。

     :symlink PATH
          ファイルを作成するSPECでのみ有効なオプションで、 PATHを指すシンボリックリンクを作成します。

 -- Function: check-directory-tree dir spec
     Checks if a directory hierarchy according to SPEC exists under DIR.  Returns #t if it exists, or #f otherwise.

     The format of SPEC is the same as create-directory-tree described above.

     If SPEC contains options, the attributes of existing files/directories are also checked if they match the given options. SPECで記述されるディレクトリ階層がDIRの下に存在するかどうかを調べ、存在すれば#t、そうでなければ#fを返します。

     SPECの形式は上で説明したcreate-directory-treeと同じです。

     SPECがオプションを含んでいる場合、該当するファイル/ディレクトリの属性もそのオプションに合致するかどうかチェックされます。

Pathname utilities
------------------

 -- Function: build-path base-path component ...
     Appends pathname components COMPONENT to the BASE-PATH. COMPONENT can be a symbol up or same; in Unix, they are synonym to ".." and ".". This API is taken from MzScheme. パス名のコンポーネントCOMPONENTをBASE-PATHに追加します。 COMPONENTはシンボルupまたはsameであっても構いません; Unixではそれらは".."または"."と等価です。このAPIはMzSchemeから採られました。

 -- Function: absolute-path? path
 -- Function: relative-path? path
     Returns #t if PATH is absolute or relative, respectively. PATHがそれぞれ絶対パスまたは相対パスならば#tを返します。

 -- Function: expand-path path
     Expands tilda-notation of PATH if it contains one. Otherwise, PATH is returned.  This function does not check if PATH exists and/or readable. PATHがチルダ表記を含んでいたらそれを展開したものを返します。そうでなければPATHそのものを返します。この手続きはPATHが存在しアクセス可能であるかどうかはチェックしません。

 -- Function: resolve-path path
     Expands PATH like expand-path, then resolve symbolic links for every components of the path.  If PATH does not exist, or contains dangling link, or contains unreadable directory, an error is signaled. PATHをexpand-pathと同様に展開し、続いてPATHの各コンポーネントに対してそれがシンボリックリンクであればリンク先のものに置き換えてゆきます。PATHが存在しないパスを指していたり、シンボリックリンクの先が存在しなかったり、読み出せないディレクトリがあった場合はエラーとなります。

 -- Function: simplify-path path
     Remove 'up' ("..") components and 'same' (".") components from PATH as much as possible. This function does not access the filesystem. PATHから、親ディレクトリへの参照("..")と自分自身への参照(".")を出来る限り取り除きます。この手続きはファイルシステムへはアクセスしません。

 -- Function: decompose-path path
     Returns three values; the directory part of PATH, the basename without extension of PATH, and the extension of PATH.    If the pathname doesn't have an extension, the third value is #f.  If the pathname ends with a directory separator, the second and third values are #f. (Note: This treatment of the trailing directory separator differs from sys-dirname/sys-basename; those follow popular shell's convention, which ignores trailing slashes.) パス名PATHのディレクトリ部、拡張子を除いたファイル名、そして拡張子の3つの値を返します。パス名が拡張子を持たない場合、最後の値は#fになります。パス名がディレクトリセパレータで終わっている場合は2番目と3番目の値が#fになります。 (後置されたディレクトリセパレータに関するこの取扱いは、 sys-dirname/sys-basenameと異なることに注意して下さい。 sys-dirname等は後置されたディレクトリセパレータを無視するというシェル等の慣習に従っています。)

          (decompose-path "/foo/bar/baz.scm")
            => "/foo/bar", "baz", "scm"
          (decompose-path "/foo/bar/baz")
            => "/foo/bar", "baz", #f

          (decompose-path "baz.scm")
            => ".", "baz", "scm"
          (decompose-path "/baz.scm")
            => "/", "baz", "scm"

          ;; Boundary cases
          (decompose-path "/foo/bar/baz.")
            => "/foo/bar", "baz", ""
          (decompose-path "/foo/bar/.baz")
            => "/foo/bar", ".baz", #f
          (decompose-path "/foo/bar.baz/")
            => "/foo/bar.baz", #f, #f

 -- Function: path-extension path
 -- Function: path-sans-extension path
     Returns an extension of PATH, and  a pathname of PATH without extension, respectively. If PATH doesn't have an extension, #f and PATH is returned respectively. それぞれ、PATHの拡張子と、PATHから拡張子を除いたものを返します。 PATHが拡張子を持っていない場合はそれぞれ#fとPATHが返されます。

          (path-extension "/foo/bar.c")       => "c"
          (path-sans-extension "/foo/bar.c")  => "/foo/bar"

          (path-extension "/foo/bar")         => #f
          (path-sans-extension "/foo/bar")    => "/foo/bar"

 -- Function: path-swap-extension path newext
     Returns a pathname in which the extension of PATH is replaced by NEWEXT.  If PATH doesn't have an extension, "." and NEWEXT is appended to PATH.

     If NEWEXT is #f, it returns PATH without extension. PATHの拡張子がNEWEXTに置換されたものが返されます。pathが拡張子を持たない場合は、PATHに "." とNEWEXTが追加されます。

     NEWEXTが#fの場合は、PATHの拡張子が除かれたものが返されます。

          (path-swap-extension "/foo/bar.c" "o")  => "/foo/bar.o"
          (path-swap-extension "/foo/bar.c" "")   => "/foo/bar."
          (path-swap-extension "/foo/bar.c" #f)   => "/foo/bar"

          (path-swap-extension "/foo/bar" "o")  => "/foo/bar.o"
          (path-swap-extension "/foo/bar" "")   => "/foo/bar."
          (path-swap-extension "/foo/bar" #f)   => "/foo/bar"

 -- Function: find-file-in-paths name :key paths pred extensions
     Looks for a file that has name NAME in the given list of pathnames PATHS and that satisfies a predicate PRED.  If found, the absolute pathname of the file is returned.  Otherwise, #f is returned.

     If NAME is an absolute path, only the existence of NAME and whether it satisfies PRED are checked.

     The default value of PATHS is taken from the environment variable PATH, and the default value of PRED is file-is-executable? (see File attribute utilities).  That is, find-file-in-paths searches the named executable file in the command search paths by default. 名前NAMEを持ち、述語PREDを満たすファイルをパス名のリストPATHS から探します。見つかった場合はファイルの絶対パス名を、見つからなかった場合は #fを返します。

     NAMEが絶対パス名で与えられた場合はそれが存在するかどうかと PREDを満たすかどうかのみがチェックされます。

     PATHSのデフォルト値は環境変数PATHから取られます。また、 PREDのデフォルト値はfile-is-executable? (File attribute utilities参照)です。すなわち、デフォルトではこの手続きはコマンドサーチパスから実行可能ファイルを探すのに使えます。

          (find-file-in-paths "ls")
            => "/bin/ls"

          ;; example of searching user preference file of my application
          ;; アプリケーション"myapp"のユーザプレファレンスファイルを探す例
          (find-file-in-paths "userpref"
            :paths `(,(expand-path "~/.myapp")
                     "/usr/local/share/myapp"
                     "/usr/share/myapp")
            :pred  file-is-readable?)

     The EXTENSIONS keyword argument may list alternative extensions added to NAME.  For example, the following example searches not only notepad, but also notepad.exe and notepad.com, in the PATH.  If an alternate name is found, the returned pathname contains the extension. EXTENSIONSキーワード引数には、NAMEに追加して探すべき拡張子のリストを指定できます。例えば次の例では、notepadに加え notepad.exeとnotepad.comがPATHから探されます。拡張子つきの名前が見つかった場合、返されるパスは拡張子を含んだものとなります。

          (find-file-in-paths "notepad" :extensions '("exe" "com"))

     For each path, the name and the alternative names are checked in order. That is, if there are /bin/b.com and /usr/bin/b.exe and PATHS is ("/bin" "/usr/bin"), you'll get /bin/b.com when you search b with extensions ("exe" "com"). 各パスについて、NAMEおよび拡張子つきの名前が順にチェックされます。すなわち、/bin/b.comと/usr/bin/b.exeがあって PATHSが("/bin" "/usr/bin")である場合、 EXTENSIONSに("exe" "com")を与えてbを探すと、 /bin/b.comが返ります。

 -- Function: null-device
     Returns a name of the null device. On unix platforms (including cygwin) it returns "/dev/null", and on Windows native platforms (including mingw) it returns "NUL". nullデバイス名を返します。cygwinを含むunixプラットフォームでは "/dev/null"、mingwを含むWindowsネイティブプラットフォームでは "NUL"が返されます。

 -- Function: console-device
     Returns a name of the console device. On unix platforms (including cygwin) it returns "/dev/tty", and on Windows native platforms (including mingw) it returns "CON".

     This function does not guarantee the device is actually available to the calling process. コンソールデバイス名を返します。cygwinを含むunixプラットフォームでは "/dev/tty"、mingwを含むWindowsネイティブプラットフォームでは "CON"が返されます。

     そのデバイスが実際に現在のプロセスから利用可能であるかどうかはチェックされません。

File attribute utilities
------------------------

 -- Function: file-type path :key follow-link?
 -- Function: file-perm path :key follow-link?
 -- Function: file-mode path :key follow-link?
 -- Function: file-ino path :key follow-link?
 -- Function: file-dev path :key follow-link?
 -- Function: file-rdev path :key follow-link?
 -- Function: file-nlink path :key follow-link?
 -- Function: file-uid path :key follow-link?
 -- Function: file-gid path :key follow-link?
 -- Function: file-size path :key follow-link?
 -- Function: file-atime path :key follow-link?
 -- Function: file-mtime path :key follow-link?
 -- Function: file-ctime path :key follow-link?
     These functions return the attribute of file/directory specified by PATH.  The attribute name corresponds to the slot name of <sys-stat> class (see File stats). If the named path doesn't exist, #f is returned.

     If PATH is a symbolic link, these functions queries the attributes of the file pointed by the link, unless an optional argument FOLLOW-LINK? is given and false.

     MzScheme and Chicken have file-size.  Chicken also has file-modification-time, which is file-mtime. これらの手続きはPATHで示されるファイルやディレクトリのアトリビュートを返します。アトリビュート名は<sys-stat>のスロット名に対応しています。 File statsを参照して下さい。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
     Returns #t if PATH exists and readable/writable/executable by the current effective user, respectively. This API is taken from STk. PATHが存在して、現在の実効ユーザがそれぞれ読み取り/書き込み/実行可能なら#tを返します。このAPIはSTkから取られました。

 -- Function: file-is-symlink? path
     Returns #t if PATH exists and a symbolic link. See also file-is-regular? and file-is-directory? in File stats. PATHが存在して、それがシンボリックリンクなら#tを返します。 (参照：File statsのfile-is-regular?, file-is-directory?).

 -- Function: file-eq? path1 path2
 -- Function: file-eqv? path1 path2
 -- Function: file-equal? path1 path2
     Compares two files specified by PATH1 and PATH2. file-eq? and file-eqv? checks if PATH1 and PATH2 refers to the identical file, that is, whether they are on the same device and have the identical inode number.  The only difference is when the last component of PATH1 and/or PATH2 is a symbolic link, file-eq? doesn't resolve the link (so compares the links themselves) while FILE-EQV? resolves the link and compares the files referred by the link(s). PATH1とPATH2で示されるファイルを比較します。 file-eq?とfile-eqv?はPATH1とPATH2が全く同一のファイルを参照しているかどうか、すなわち、同じデバイス上にあり同じ inode番号を持つかどうかをチェックします。二つの手続きの違いは、 path1やPATH2の最後のコンポーネントがシンボリックリンクであった場合に、FILE-EQ?はリンクそのものの比較をするが file-eqv?はリンクを辿った先のファイルの比較をする、という点です。

     file-equal? compares PATH1 and PATH2 considering their content, that is, when two are not the identical file in the sense of file-eqv?, file-equal? compares their content and returns #t if all the bytes match. file-equal?はPATH1とPATH2をその内容まで考慮して比較します。すなわち、二つのファイルがfile-eqv?の意味で同一でなかった場合、 file-equal?はファイルの内容を比較し、全てが一致した場合に#tを返します。

     The behavior of file-equal? is undefined when PATH1 and PATH2 are both directories. Later, it may be extended to scan the directory contents. PATH1とPATH2ともにディレクトリが与えられた場合の 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
     Compares file modification time stamps.  There are a bunch of methods defined, so each argument can be either one of the followings.

       * String pathname.   The mtime of the specified path is used.

       * <sys-stat> object (see File stats). The mtime is taken from the stat structure.

       * <time> object.  The time is used as the mtime.

       * Number.  It is considered as the number of seconds since Unix Epoch, and used as mtime.

     二つのファイルの変更時間を比較します。それぞれの引数に対して、次のような型のオブジェクトが渡せるようなメソッドが定義されています。

       * 文字列のパス名。そのパス名で示されるファイルから変更時間が取られます。

       * <sys-stat>オブジェクト (see File stats)。 stat構造体から変更時間が取られます。

       * <time>オブジェクト。その示す時間が変更時間と考えられます。

       * 数値。変更時間をUnix Epochからの秒数で表したものと見なされます。

          ;; compare "foo.c" is newer than "foo.o"
          ;; "foo.c" より "foo.o" が新しいかどうか調べる
          (file-mtime>? "foo.c" "foo.o")

          ;; see if "foo.log" is updated within last 24 hours
          ;; "foo.log"が過去24時間以内に更新されたかどうかを調べる
          (file-mtime>? "foo.c" (- (sys-time) 86400))

 -- Generic Function: file-ctime=? f1 f2
 -- Generic Function: file-atime=? f1 f2
     Same as file-mtime=?, except these checks file's change time and access time, respectively. All the variants of <, <=, >, >= are also defined. file-mtime=?と同じですが、ファイルの属性変更時間とアクセス時間に関して比較します。 <, <=, >, >=を使う関数も同様に定義されています。

File operations
---------------

 -- Function: touch-file path :key (time #f) (type #f) (create #t)
 -- Function: touch-files paths :key (time #f) (type #f) (create #t)
     Updates timestamp of PATH, or each path in the list PATHS, to the current time.  If the specified path doesn't exist, a new file with size zero is created, unless the keyword argument CREATE is #f.

     If the keyword argument TIME is given and not #f, it must be a nonnegative real number.  It is used as the timestamp value instead of the current time.

     The keyword argument TYPE can be #f (default), a symbol atime or mtime.  If it is a symbol, only the access time or modification time is updated.

     Note: touch-files processes one file at a time, so the timestamp of each file may not be exactly the same.

     These procedures are built on top of the system call sys-utime (see File stats). PATHもしくはリストPATHS中の各パスのタイムスタンプを現在の時刻に更新します。指定されたパスが存在しなかった場合、キーワード引数CREATEが#fでなければ、その名前で大きさゼロのファイルが作成されます。

     キーワード引数TIMEが与えられて#fでない場合、それは非負の実数でなければなりません。現在の時刻のかわりにその値がタイムスタンプとして使われます。

     キーワード引数TYPEは#f(デフォルト)か、シンボルatimeもしくは mtimeです。シンボルの場合は、それぞれアクセス時刻か変更時刻のみが更新されます。

     註：touch-filesはファイルをひとつづつ処理するので、各ファイルのタイムスタンプが完全に同一にはならない可能性があります。

     これらの手続きはシステムコールsys-utimeを使って作られています (File stats参照)。

 -- Function: copy-file src dst :key if-exists backup-suffix safe keep-timestamp keep-mode follow-link?
     Copies file from SRC to DST.  The source file SRC must exist. The behavior when the destination DST exists varies by the keyword argument IF-EXISTS;

     :error
          (Default) Signals an error when DST exists.

     :supersede
          Replaces DST to the copy of SRC.

     :backup
          Keeps DST by renaming it.

     :append
          Append the SRC's content to the end of DST.

     #f
          Doesn't copy and returns #f when DST exists.

     ファイルSRCをDSTへコピーします。コピー元ファイルSRCは存在していなければなりません。コピー先ファイルDSTが存在していた場合のふるまいはキーワード引数IF-EXISTSによって以下のように指定されます。

     :error
          (デフォルト) DSTが存在していたらエラーを通知する。

     :supersede
          DSTをSRCのコピーで置き換える。

     :backup
          DSTの名前を変えてキープする。

     :append
          DSTの末尾にSRCの内容を追加する。

     #f
          DSTが存在していたらコピーをせず#fを返す。

     Copy-file returns #t after completion. copy-fileはコピーが完了したら#tを返します。

     If SRC is a symbolic link, copy-file follows the symlink and copies the actual content by default.  An error is raised if SRC is a dangling symlink.

     Giving #f to the keyword argument FOLLOW-LINK? makes copy-file to copy the link itself. It is possible that SRC is a dangling symlink in this case. SRCがシンボリックリンクであった場合、copy-fileはデフォルトでリンクを辿ります。つまり、ファイルの実体がコピーされます。 SRCが存在しないパスを指すシンボリックリンクであった場合はエラーが通知されます。

     キーワード引数FOLLOW-LINK?に#fを与えることで、 copy-linkにシンボリックリンクそのものをコピーさせることもできます。この場合、SRCが存在しないパスを指すシンボリックリンクであっても構いません。

     If IF-EXISTS is :backup, the keyword argument BACKUP-SUFFIX specifies the suffix attached to the DST to be renamed. The default value is ".orig". IF-EXISTSが:backupである場合、 DSTがリネームされる名前は DSTにキーワード引数BACKUP-SUFFIXで指定されるサフィックスを付けたものとなります。デフォルト値は".orig"です。

     By default, copy-file starts copying to DST directly. However, if the keyword argument SAFE is a true value, it copies the file to a temporary file in the same directory of DST, then renames it to DST when copy is completed. (When SAFE is true and IF-EXISTS is :append, we first copy the content of DST to a temporary file if DST exists, appends the content of SRC, then renames the result to DST). If copy is interrupted for some reason, the filesystem is "rolled back" properly.

     デフォルトではcopy-fileは直接DSTにコピーを行いますが、キーワード引数SAFEに真の値が与えられた場合は、DSTと同じディレクトリ内の一時ファイルにまずコピーし、それが完了した時点でDSTへとリネームします。 (SAFEが真でかつIF-EXISTSが:appendであった場合は、 DSTがあればまずその内容を一時ファイルにコピーし、そこにSRCの内容を追加し、最後にそれをDSTへリネームします。) コピーが何らかの理由で中断された場合、ファイルシステムはコピー前の状態へと「ロールバック」されます。

     If the keyword argument KEEP-TIMESTAMP is true, copy-file sets the destination's timestamp to the same as the source's timestamp after copying. キーワード引数KEEP-TIMESTAMPに真の値が与えられた場合は、 copy-fileはコピー後にコピー先のファイルのタイムスタンプをコピー元のタイムスタンプに合わせます。

     If the keyword argument KEEP-MODE is true, the destination file's permission bits are set to the same as the source file's.  If it is false (default), the destination file's permission remains the same if the destination already exists and the SAFE argument is false, otherwise it becomes #o666 masked by umask settings. キーワード引数KEEP-MODEに真の値が与えられた場合は、コピー先のファイルのパーミッションビットはコピー元のそれに合わせられます。 KEEP-MODEが偽の場合(デフォルト)は、コピー先が既に存在して SAFE引数が偽の場合にコピー先のもとのパーミッションが保持され、そうでなければ#o666がumaskセッティングによってマスクされた値となります。

 -- Function: move-file src dst :key if-exists backup-suffix
     Moves file SRC to DST.   The source SRC must exist. The behavior when DST exists varies by the keyword argument IF-EXISTS, as follows.

     :error
          (Default) Signals an error when DST exists.

     :supersede
          Replaces DST by src.

     :backup
          Keeps DST by renaming it.

     #f
          Doesn't move and returns #f when DST exists.

     ファイルSRCをDSTへ移動します。移動元ファイルSRCは存在していなければなりません。移動先ファイルDSTが存在した場合のふるまいはキーワード引数IF-EXISTSによって以下のように指定されます。

     :error
          (デフォルト) DSTが存在していたらエラーを通知する。

     :supersede
          DSTをsrcで置き換える。

     :backup
          DSTの名前を変えてキープする。

     #f
          DSTが存在していたら移動をせず#fを返す。

     Move-file returns #t after completion. move-fileは移動が完了したら#tを返します。

     If IF-EXISTS is :backup, the keyword argument BACKUP-SUFFIX specifies the suffix attached to the DST to be renamed. The default value is ".orig". IF-EXISTSが:backupである場合、DSTがリネームされる名前はDSTにキーワード引数BACKUP-SUFFIXで指定されるサフィックスを付けたものとなります。デフォルト値は".orig"です。

     The file SRC and DST can be on the different filesystem. In such a case, move-file first copies SRC to the temporary file on the same directory as DST, then renames it to DST, then removes SRC. ファイルSRCとDSTは別のファイルシステム上にあっても構いません。その場合、move-fileはまずSRCをDSTと同じディレクトリの一時ファイルにコピーし、それをDSTにリネームし、それから SRCを消去します。

 -- Function: remove-file filename
 -- Function: delete-file filename
     [R7RS file] Removes the named file.  An error is signalled if FILENAME does not exist, is a directory, or cannot be deleted with other reasons such as permissions. R7RS defines delete-file.

     Compare with sys-unlink (see Directory manipulation), which doesn't raise an error when the named file doesn't exist. 指定された名前のファイルを消去します。ファイルが存在しなかったり、ディレクトリであったり、パーミッションがなく消去できなかった場合等にはエラーが報告されます。 delete-fileはR7RSで定義されています。

     sys-unlinkと似ていますが、sys-unlinkはファイルが無かった場合にエラーをあげず#fを返すことに注意。(Directory manipulation参照。)

 -- Function: remove-files paths
 -- Function: delete-files paths
     Removes each path in a list PATHS.  If the path is a file, it is unlinked.  If it is a directory, its contents are recursively removed by remove-directory*. If the path doesn't exist, it is simply ignored.

     delete-files is just an alias of remove-files. リストPATHS中の各パスを削除します。パスがファイルの場合は unlinkし、ディレクトリの場合はremove-directory*を使って再帰的にその内容を消去します。存在しないパスは単に無視されます。

     delete-filesはremove-filesの別名です。

 -- Function: file->string filename options ...
 -- Function: file->list reader filename options ...
 -- Function: file->string-list filename options ...
 -- Function: file->sexp-list filename options ...
     Convenience procedures to read from a file FILENAME. They first open the named file, then call port->string, port->list, port->string-list and port->sexp-list on the opened file, respectively.  (see Input utility functions). The file is closed if all the content is read or an error is signaled during reading. ファイル FILENAME から読み込むための便利手続き。これらの手続きは、まず、指定された名前のファイルをオープンし、そのオープンしたファイルに対してそれぞれ port->string、 port->list、port->string-list および port->sexp-list を呼びます(Input utility functions参照)。すべての内容が読み込まれるかまたは読み込み中にエラーシグナルがあがれば、ファイルはクローズされます。

     Those procedures take the same keyword arguments as call-with-input-file. When the named file doesn't exist, the behavior depends on :IF-DOES-NOT-EXIST keyword argument---an error is signaled if it is :error, and #f is returned if the argument is #f. これらの手続きはcall-with-input-fileと同じキーワード引数を取ります。ファイルが見つからなかった場合の振舞いはキーワード引数:if-does-not-existによって指定できます。それが:errorならエラーが報告され、 #fなら#fが返されます。

 -- Function: string->file filename string options ...
 -- Function: list->file writer filename lis options ...
 -- Function: string-list->file filename lis options ...
 -- Function: sexp-list->file filenme lis options ...
     Opposite of file->string etc.  They are convenient to quickly write out things into a file.

     NB: The name string->file etc. might suggest they would take the object to be written as the first argument.  We decided to put FILENAME first, since in the situations where these procedures are used, it is more likely that one want to write literal data, which would be bigger than the filename itself.

     The options part is passed to call-with-output-file as is. For example, the following code appends the text when foo.txt already exists: file->string等の逆を行う手続きです。手軽にファイルに何かを書き出したい時に便利です。

     註: string->file等の名前からして、書き出されるオブジェクトを第一引数にする方が慣習にあっているかもしれません。けれども、実際にこれらの手続きが使われる場面では、書き出されるオブジェクトとしてリテラルデータが来る場合も多く、だとするとより短いファイル名を先にした方が読み書きしやすいだろうと考え、FILENAMEを先に持ってきてあります。

     OPTIONS ...部分はそのままcall-with-output-fileに渡されます。次の例はfoo.txtが存在していればそれにデータを書き足します。

          (string->file "foo.txt" "New text to append\n"
                        :if-exists :append)

     The list->file takes WRITER argument, which is a procedure that receives two arguments, an element from the list LIS, and an output port.  It should write out the element to the port in a suitable way.  The string-list->file and sexp-list->file are specialized versions of list->file, where string-list->file uses (^[s p] (display s p) (newline p)) as WRITER, and sexp-list->file uses (^[s p] (write s p) (newline p)) as WRITER. list->fileが取るWRITER引数は、リストLISからのひとつの要素と出力ポートの二つの引数を取る手続きで、適切な形式で要素をポートに書き出します。 string-list->fileとsexp-list->fileは list->fileの特化したバージョンで、 string-list->fileはwriterとして(^[s p] (display s p) (newline p))を、 sexp-list->fileはwriterとして(^[s p] (write s p) (newline p))を使います。

Temporary files and directories
-------------------------------

 -- Parameter: temporary-directory
     A parameter that keeps the name of the directory that can be used to create a temporary files.   The default value is the one returned from sys-tmpdir (see Pathnames). The difference of sys-tmpdir is that, since this is a parameter, it can be overridden by application during execution. Libraries are recommended to use this instead of sys-tmpdir for greater flexibility. 一時ファイルを作るのに適したディレクトリ名を保持しているパラメータです。デフォルトの値はsys-tmpdirの戻り値です (Pathnames参照)。 sys-tmpdirとの違いは、これはパラメータなのでアプリケーションが実行時に変更できることです。ライブラリは柔軟性を高めるためにできるだけsys-tmpdirよりはこちらを利用するのが良いでしょう。

 -- Function: call-with-temporary-file proc :key directory prefix
     Creates a temporary file with a unique name and opens it for output, then calls PROC with the output port and the temporary file's name. The temporary file is removed after either PROC returns or raises an uncaught error. Returns the value(s) PROC returns.

     The temporary file is created in the directory DIRECTORY, with the name PREFIX followed by several random alphanumeric characters. When omitted, the value of (temporary-directory) is used for DIRECTORY, and "gtemp" for PREFIX.

     The name passed to PROC consists of DIRECTORY and the file's name.  So whether the name is absolute or relative pathname depends on the value of DIRECTORY.

          (call-with-temporary-file (^[_ name] name)
           => Something like "/tmp/gtemp4dSpMh"

     You can keep the output file by renaming it in PROC.  But if doing so, make sure to specify DIRECTORY so that the temporary file is created in the same directory as the final output; rename may not work across filesystems.

     Internally, it calls sys-mkstemp to create a unique file. See Directory manipulation, for the details. 一意な名前を持つ一時ファイルを作成し、出力用にオープンして、その出力ポートと名前を引数としてPROCを呼びます。一時ファイルは、PROCから戻った場合でも、PROCがエラーを投げた場合でも、消去されます。 PROCの返す値(複数可)がcall-with-temporary-fileの戻り値となります。

     一時ファイルはディレクトリDIRECTORY以下に作られ、その名前はPREFIXの後にいくつかの英数字を付け加えたものになります。省略された場合、(temporary-directory)の値がDIRECTORYに、 "gtemp"がPREFIXに使われます。

     PROCに渡される名前はDIRECTORYとファイル名をつなげたパス名です。絶対パスになるか相対パスになるかはDIRECTORYの値によります。

          (call-with-temporary-file (^[_ name] name)
           => 例えば "/tmp/gtemp4dSpMh"

     出力したファイルを取っておきたい場合は、PROCの中でリネームしてください。その場合、最終的なファイルと同じディレクトリに一時ファイルを作るように、 DIRECTORY引数を指定するのを忘れないように。ファイルシステムをまたぐリネームはうまくいかない場合があります。

     内部的に、この手続きはsys-mkstempを呼んで一意なファイルを作っています。 sys-mkstempについてはDirectory manipulation参照。

 -- Function: call-with-temporary-directory proc :key directory prefix
     Creates a temporary directory with unique name, then calls PROC with the name. The temporary directory and its contents are removed after either PROC returns or raises an uncaught error. Returns the value(s) PROC returns.

     The temporary directory is created in the directory DIRECTORY, with the name PREFIX followed by several random alphanumeric characters. When omitted, the value of (temporary-directory) is used for DIRECTORY, and "gtemp" for PREFIX.

     The name passed to PROC consists of DIRECTORY and the directory name.  So whether the name is absolute or relative pathname depends on the value of DIRECTORY.

     Internally, it calls sys-mkdtemp to create a unique file. See Directory manipulation, for the details. 一意な名前を持つ一時ディレクトリを作成し、その名前を引数としてPROCを呼びます。一時ディレクトリは、PROCから戻った場合でも、PROCがエラーを投げた場合でも、消去されます。 PROCの返す値(複数可)がcall-with-temporary-directoryの戻り値となります。

     一時ディレクトリはディレクトリDIRECTORY以下に作られ、その名前はPREFIXの後にいくつかの英数字を付け加えたものになります。省略された場合、(temporary-directory)の値がDIRECTORYに、 "gtemp"がPREFIXに使われます。

     PROCに渡される名前はDIRECTORYとファイル名をつなげたパス名です。絶対パスになるか相対パスになるかはDIRECTORYの値によります。

     内部的に、この手続きはsys-mkdtempを呼んで一意なディレクトリを作っています。 sys-mkstempについてはDirectory manipulation参照。

Lock files
----------

Exclusivity of creating files or directories is often used for inter-process locking.   The following procedure provides a packaged interface for it. ファイルやディレクトリを作成する排他性は、しばしばプロセス間のロックに使われます。以下の手続きはパッケージ化されたインタフェースを提供します。

 -- Function: with-lock-file lock-name thunk :key type retry-interval
     retry-limit secondary-lock-name retry2-interval
     retry2-limit perms abandon-timeout
     Exclusively creates a file or a directory (lock file) with LOCK-NAME, then executes THUNK. After THUNK returns, or an error is thrown in it, the lock file is removed.  When THUNK returns normally, its return values become the return values of with-lock-file. LOCK-NAMEという名前を持つファイルもしくはディレクトリ (ここではロックファイルと呼びます) を排他的に作成し、 THUNKを実行します。THUNKから戻ってくるか、エラーが投げられたら、ロックファイルは削除されます。THUNKが正常に戻ってきた場合、その戻り値がwith-lock-fileの戻り値となります。

     If the lock file already exists, with-lock-file waits and retries getting the lock until timeout reaches.  It can be configured by the keyword arguments. ロックファイルが既に存在していた場合、with-lock-fileはタイムアウトになるまで少し待ってリトライすることを続けます。細かい動作はキーワード引数で指定できます。

     There's a chance that with-lock-file leaves the lock file when it gets a serious error situation and doesn't have the opportunity to clean up.  You can allow with-lock-file to steal the lock if its timestamp is too old; say, if you know that the applications usually locks just for seconds, and you find the lock file is 10 minutes old, then it's likely that the previous process was terminated abruptly and couldn't clean it up. You can also configure this behavior by the keyword arguments. with-lock-file実行中に深刻なエラーによって、ロックファイルを消せずにプロセスが終了してしまう可能性があります。そのため、 with-lock-fileは、ロックファイルのタイムスタンプが非常に古い場合にはロックを盗むことを許しています。例えば、通常アプリケーションはたかだか数秒しかロックしないはずなのに、10分前のタイムスタンプを持つロックファイルを見つけたとしたら、以前のプロセスがクリーンアップをせずに落ちてしまったことは十分考えられるでしょう。この振る舞いも、キーワード引数で制御することができます。

     Internally, two lock files are used to implement this stealing behavior safely.  The creation and removal of the primary lock file (named by LOCK-NAME argument) are guarded by the secondary lock file (named by SECONDARY-LOCK-FILE argument, defaulted by .2 suffix attached to LOCK-NAME). The secondary lock prevents more than one process steals the same primary lock file simultaneously. 内部的には、安全な「盗ロック」を実現するために、二つのロックファイルが使われています。主ロックファイル(LOCK-NAMEで指定される名前を持つもの)の作成と削除の操作がそれぞれ、副ロックファイル(SECONDARY-LOCK-FILEで指定される名前を持つもの。指定が省略された場合はLOCK-NAMEにサフィックス.2をつけたもの) によって保護されます。副ロックは、二つ以上のプロセスが主ロックファイルを同時に盗もうとした場合を保護します。

     The secondary lock is acquired for a very short period so there's much less chance to be left behind by abnormal terminations. If it happens, however, we just give up; we don't steal the secondary lock. 副ロックファイルによるロックはほぼ常に極めて短い期間に限定されるため、事故により副ロックファイルが残されてしまう可能性は主ロックファイルに比べ非常に小さいです。それでももし副ロックファイルが残されてしまった場合は、with-lock-fileは単に諦めます。副ロックファイルまで盗むことはしません。

     If with-lock-file couldn't get a lock before timeout, a <lock-file-failure> condition is thrown. with-lock-fileがタイムアウトまでにロックを獲得できなけば、 <lock-file-failure>コンディションが投げられます。

     Here's a list of keyword arguments. 以下のキーワード引数が認識されます。

     type

          It can be either one of the symbols file or directory. シンボルfileかdirectoryのどちらか。

          If it is file, we use a lock file, relying on the O_EXCL exclusive creation flag of open(2). This is the default value. It works for most platforms; however, some NFS implementation may not implement the exclusive semantics properly. fileを指定した場合、open(2)のO_EXCLフラグを使う排他的ファイル作成を利用したロックファイルを使います。これがデフォルトの動作です。ほとんどのプラッフォームで動作しますが、NFSの実装の一部に、排他的ファイル作成のセマンティクスが正しく実装されていない場合があります。

          If it is directory, we use a lock directory, relying on the atomicity of mkdir(2).  It should work for any platforms, but it may be slower than file. directoryを指定した場合は、mkdir(2)の排他性を利用したロックディレクトリを使います。これはどんなプラットフォームでも動作するはずですが、fileを指定した場合より遅いかもしれません。

     retry-interval
     retry-limit

          Accepts a nonnegative real number that specifies either the interval to attempt to acquire the primary lock, or the maximum time we should keep retrying, respectively, in seconds. The default value is 1 second interval and 10 second limit. To prevent retrying, give 0 to RETRY-LIMIT. 時間を秒で指定する非負の実数を取ります。前者は主ロック獲得を再試行する時間間隔、後者は再試行を繰り返す総時間を指定します。デフォルトはそれぞれ、1秒と10秒です。再試行をしないようにするには、 RETRY-LIMITに0を渡してください。

     secondary-lock-name

          The name of the secondary lock file (or directory).  If omitted, LOCK-NAME with a suffix .2 attached is used. Note: The secondary lock name must be agreed on all programs that locks the same (primary) lock file.  I recommend to leave this to the default unless there's a good reason to do otherwise. 副ロックファイル(もしくはディレクトリ)の名前を指定します。省略された場合は、LOCK-NAMEにサフィックス.2をつけたものが使われます。副ロックファイルの名前は、同じ(主)ロックファイルを使うプログラム全てで一致していなければなりません。特に変える必要が無ければデフォルトのままにするのが良いでしょう。

     retry2-interval
     retry2-limit

          Like RETRY-INTERVAL and RETRY-LIMIT, but these specify interval and timeout for the secondary lock file.  The possibility of secondary lock file collision is usually pretty low, so you would hardly need to tweak these.  The default values are 1 second interval and 10 second limit. RETRY-INTERVALとRETRY-LIMITに似ていますが、こちらは副ロックファイルの再試行間隔と最長再試行時間を指定します。副ロックが衝突する確率は通常極めて低いので、これらのパラメータを調整する必要は滅多に無いでしょう。デフォルトの値はそれぞれ 1秒と10秒です。

     perms

          Specify the permission bitmask of the lock file or directory, in a nonnegative exact integer.  The default is #o644 for a lock file and #o755 for a lock directory.

          Note that to control who can acquire/release/steal the lock, what matters is the permission of the directory in which the lock file/directory, not the permission of the lock file/directory itself. ロックファイルもしくはディレクトリのパーミッションを、非負正確整数のビットマスクで指定します。デフォルトは、ロックファイルに対して#o644、ロックディレクトリに対しては#o755です。

          ロックを獲得/解放したり盗んだりするには、ロックファイル自身のパーミッションではなく、ロックファイルが置かれるディレクトリのパーミッションが関係することに注意してください。

     abandon-timeout

          Specifies the period in seconds in a nonnegative real number. If the primary lock file is older than that, with-lock-file steals the lock. To prevent stealing, give #f to this argument. The default value is 600 seconds. 時間の長さ(秒)を非負の実数で指定します。 with-lock-fileがロックファイルを見つけて、そのタイムスタンプが現在の時刻マイナスこの時間よりも古いものだった場合、ロックを盗みます。ロックを盗むことを禁止したければこの引数に#fを渡してください。デフォルトは600秒です。

 -- Condition type: <lock-file-failure>
     A condition indicating that with-lock-file couldn't obtain the lock.  Inherits <error>. with-lock-fileがロックを獲得できなかった場合に投げられるコンディションです。<error>を継承します。

      -- Instance Variable of <lock-file-failure>: lock-file-name
          The primary lock file name. 獲得しようとした主ロックファイルの名前です。

Gauche also provides OS-supported file locking feature, fcntl lock, via gauche.fcntl module. Whether you want to use fcntl lock or with-lock-file will depend on your application. Gaucheは、OSによりサポートされるfcntlロックの機能も、 gauche.fcntlモジュールによって提供しています。 fcntlロックを使うべきかwith-lock-fileを使うべきかは、アプリケーションによります。

These are the advantages of the fcntl lock: fcntlロックの利点は次の通りです。

  * The lock is removed when the process dies without explicitly unlocking it. プロセスが死んだ時に、ロックは自動的に解除される

  * You can directly lock the file you're touching. 作業するファイルそのものをロックできる。

  * You can lock a part of a file. ファイルの一部だけをロックできる。

  * You can have shared (read) and exclusive (write) locks. 共有(読み出し)ロックと排他(書き込み)ロックが使える。

In common situations, probably the most handy property is the first one; you don't need to worry about leaving lock behind unexpected process termination. 多くの場合、最も便利なのは最初の性質でしょう。プロセスが予想外に落ちてしまった場合でも、ロックが残されてしまうことを心配しないで済みます。

However, there are a couple of shortcomings in fcntl locks. けれども、fcntlロックには欠点もあります。

  * It is not guaranteed to work across different platforms, and/or NFS-mounted filesystems. 異なるプラットフォームや、NFSマウントされたファイルシステム間で確実に動作する保証がない。

  * The lock is per-process, per-file, and non-recursive. If you have a lock in a file, then calls a library that also locks the file, the lock always succeeds.  Worse, if the library unlocks the file, the lock is completely removed, while the caller doesn't know about it.  It also means that, in order to prevent multiple threads in a process from accessing the same file, you have to use mutex along the fcntl lock. ロックはプロセス単位、ファイル単位でかつ非再帰的である。例えば、既にプロセスがロックしているファイルに対して、呼び出したライブラリ内でまたロックを獲得しようとすると、それは常に成功する。さらに悪いことに、そのライブラリがロックを解放した時点で、元からロックがかかっていたかどうかに関わらず、プロセス全体がロックを手放してしまう。このことはまた、複数のスレッド間で排他的にファイルにアクセスしたい場合は、fcntlロックと一緒にmutexも使う必要があるということでもある。

Especially because of the second point, it is very difficult to use fcntl lock unless you have total control over and knowledge of the entire application. It is ok to use the fcntl lock by the application code to lock the application-specific file. Library developers have difficulty, however, to make sure any potential user of the library won't try to lock the same file as the library tries to lock (usually it's impossible). 二番目の欠点のせいで、アプリケーション全体を知っていてコードを好きにできる場合でなければ、 fcntlロックを安全に使うことが非常に難しくなっています。アプリケーションコードが、そのアプリケーションで使うためだけのファイルをロックするのに fcntlロックを使うのは何も問題ありません。しかしライブラリ開発者は、ライブラリ内でfcntlロックを使うなら、そのライブラリのユーザや他のライブラリが将来に渡って同じファイルを決してロックしないということを保証しなければなりません(通常、そんなことは不可能です)。

math.const - Mathematic constants
=================================

 -- 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
     Bound to pi, pi/2, pi/4, pi/180, 1/pi and 180/pi, respectively. それぞれ、π、π/2、π/4、π/180、1/π、180/πです。

 -- Constant: e
     Napier's constant.

math.mt-random - Mersenne Twister Random number generator
=========================================================

 -- 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 https://dl.acm.org/citation.cfm?id=272995, for details about the algorithm. Makoto MatsumotoとTakuji Nishimuraにより開発された、 ``Mersenne Twister''アルゴリズムに基づく、仮想的な乱数発生器(RNG)を提供します。高速で、2^19937-1という極めて長大な周期を持ちます。アルゴリズムの詳細については、https://dl.acm.org/citation.cfm?id=272995を参照して下さい。

     For typical use cases of random number generators, we recommend to use srfi-27 which is implemented on top of this module and provides portable API. You should use this module directly only when you need functions that aren't available through srfi-27. 乱数発生器の通常の用途には、srfi-27を使うことをお勧めします。 srfi-27はこのモジュールの上に実装されていますが、ポータブルなAPIを提供しています。 srfi-27にない機能が必要な時のみこのモジュールを直接使うようにしてください。

 -- 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. Mersenne Twister RNGの状態をカプセル化するクラスです。このクラスのそれぞれのインスタンスは独自の状態を持ち、個別のシードで初期化されていれば、それぞれがランダムビットの独立したソースになり得ます。

     ランダムシードの値は初期化引数:seedにより初期化時に与えるか、以下で説明するmt-random-set-seed!を使います。

          (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 (MTRNG) MT. SEED can be an arbitrary positive exact integer, or arbitrary length of u32vector (see Homogeneous vectors). If it is a u32vector, up to 624 elements are used for initialization. メルセンヌツイスターRNG MTにランダムシードの値SEEDをセットします。 SEEDは任意の正の正確整数か、任意長のu32vector (Homogeneous vectors参照)が使えます。 u32vectorの場合は、初期化のために624個までの要素が使われます。

     Internally, MTRNG keeps its state in array of 32-bit integers.  When a fixnum is given, its lower 32bit is used to generate a linear congruential series to fill the state space.  If you do so, there is an algorithm that only samples a couple of result from MTRNG to calculate the original seed value, hence can predict entire sequence.  If you want the random sequence harder to predict, prepare your own u32vector seed filled with high-entroby bits.

     Note that Mersenne Twister is never intended for cryptograhpy, you shouldn't use it for security-sensitive purposes. MTRNGは32ビット整数配列を内部状態として持っています。fixnumがSEEDとして与えられた場合、その下位32bitを初期値とする線形合同法で得られる数列で内部状態が初期化されます。そういた場合、MTRNGの二つの出力だけからシード値を逆算するアルゴリズムがあり、全ての乱数列の値が予測できてしまいます。もし乱数列をもっと予測しづらくしたいなら、u32vectorをエントロピーの高いビットで満たしてそれをシードとして使ってください。

     メルセンヌツイスターは暗号学的に安全であることを意図して作られてはいません。セキュリティが重要な用途には使わないでください。

     NB: Up to 0.9.9, when SEED is a bignum, we roll our own way to fold it in 32bit integer and then called Mersenne-Twister's initialization function.  It loses the entropy, so we changed it and now all the bits in the bignum is used for the seed. 註: 0.9.9までは、SEEDにbignumが渡された場合、そこから独自のアルゴリズムで 32bitの値を生成してメルセンヌツイスタの初期化関数を呼んでいました。しかしそれだとエントロピーを捨てることになるので、現在は全てのビットがシード値に使われるように変更されています。

 -- 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. Mersenne Twister RNG MTを取り出して再インストールします。状態は、625要素のu32vectorで表現されます。状態はどこにでも保存することができ、仮想的なランダムシーケンスの生成を続行するために、<mersenne-twister>のインスタンスとしてリストアできます。

 -- 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. 0.0と1.0の間のランダムな実数を返します。 1.0は範囲に含まれません。 mt-random-realは、0.0も範囲に含みませんが、 mt-random-real0は含みます。 0.0を含まないのは、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. 0からRANGE-1までの正の正確整数をランダムに返します。 RANGEはいかなる正の正確整数でも構いません。

 -- 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. 与えられたユニフォームベクタをランダムな数値で埋めます。 mt-random-fill-u32vector!では、要素は0と2^32-1の間の正の正確整数で埋められます。 mt-random-fill-f32vector!とmt-random-fill-f64vector! では、0.0と1.0(含まれない)の間の不正確実数で埋められます。

math.prime - Prime numbers
==========================

 -- Module: math.prime
     This module provides utilities related to prime numbers. このモジュールは、素数を扱うユーティリティ関数を提供します。

Sequence of prime numbers
-------------------------

素数のシーケンス
--------

 -- Variable: *primes*
     An infinite lazy sequence of primes. 素数の無限遅延シーケンスです。

          ;; show 10 prime numbers from 100-th one.
          (take (drop *primes* 100) 10)
           => (547 557 563 569 571 577 587 593 599 601)

 -- Function: reset-primes
     Once you take a very large prime out of *primes*, all primes before that has been calculated remains in memory, since the head of sequence is held in *primes*.  Sometimes you know you need no more prime numbers and you wish those calculated ones to be garbage-collected.  Calling reset-primes rebinds *primes* to unrealized lazy sequence, allowing the previously realized primes to be GCed. *primes*から大きな素数を取り出すと、それ以前の素数も全てメモリに残り続けます。*primes*変数がシーケンスの頭を抱えているからです。もう素数を必要としないことがわかっている場合、それらのメモリがガベージコレクトされることが望ましいかもしれません。reset-primes手続きは *primes*をまだ現実化されていない遅延シーケンスに再束縛し、次のGCで計算済みの素数シーケンスが回収されるようにします。

 -- Function: primes
     Returns a fresh lazy sequence of primes.  It is useful when you need certain primes in a short period of time---if you don't keep a reference to the head of the returned sequence, it will be garbage collected after you've done with the primes. (Note that calculation of a prime number needs the sequence of primes from the beginning, so even if your code only keep a reference in the middle of the sequence, the entire sequence will be kept in the thunk within the lazy sequence---you have to release all references in order to make the sequence GCed.)

     On the other hand, each sequence returned by primes are realized individually, duplicating calculation.

     The rule of thumb is---if you use primes repeatedly throughout the program, just use *primes* and you'll save calculation. If you need primes one-shot, call primes and abandon it and you'll save space. 新たな素数の遅延シーケンスを返します。その時だけ素数を使いたい、という時に便利です。返されたシーケンスへの参照が無くなれば、シーケンスはガベージコレクトされます。 (ある素数の計算には素数のシーケンスが最初から必要なので、たとえシーケンスの頭ではなく途中への参照だけを持っていたとしても、遅延シーケンスの中のサンクにはシーケンスの頭への参照が保持されています。シーケンスがGCされるためには、いかなる部分への参照も残さないようにしなければなりません)。

     primesが返す各シーケンスは独立しているので、素数の計算もそれぞれで (重複して)行われることになります。

     単純なルールとして、プログラム中で何度も素数を使う必要があるのなら変数*primes*を利用するのが良いでしょう。各素数の計算は一度しか行われず、余分な計算を省くことができます。しかしその場だけ素数が欲しいなら、 primesを呼んで、仕事が済んだらシーケンスを捨ててしまえば、不要なシーケンスがメモリに残りつづけることを心配しなくても済みます。

Testing primality
-----------------

素数かどうかを調べる
----------

 -- Function: small-prime? n
     For relatively small positive integers (below *small-prime-bound*, to be specific), this procedure determines if the input is prime or not, quickly and deterministically. If N is on or above the bound, this procedure returns #f.

     This can be used to quickly filter out known primes; it never returns #t on composite numbers (while it may return #f on large prime numbers). Miller-Rabin test below can tell if the input is composite for sure, but it may return #t on some composite numbers. 比較的小さな正整数 (*small-prime-bound*以下の正整数) に対して、それが素数であるかどうかを判定し、素数なら#tを返します。 Nがそれ以上である場合は常に#fを返します。

     この手続きは確実に素数であるとわかるものを素早く判別する時に便利です。 #tが返れば確実に素数であるとわかるからです (入力が大きな素数の時に #fを返すことはありえますが)。これに対し、下に述べるMiller-Rabin法では、合成数は確実に判別できますが、素数であるかどうかは確実には言えません。

 -- Variable: *small-prime-bound*
     For all positive integers below this value (slightly above 3.4e14 in the current implementation), small-prime? can determines whether it is a prime or not. これより小さな数に対しては、SMALL-PRIME?は決定的に素数かどうかを判別します。現在の実装ではこの数は3.4e14よりちょっと大きな数です。

 -- Function: miller-rabin-prime? n :key num-tests random-integer
     Check if an exact integer N is a prime number, using probabilistic Miller-Rabin algorithm (N must be greater than 1). If this procedure returns #f, N is a composite number.  If this procedure returns #t, N is likely a prime, but there's a small probability that it is a false positive. 2以上の正確な整数Nが素数かどうかを、確率的なMiller-Rabin法を使って判定します。この手続きが#fを返したなら、Nは確実に合成数です。この手続きが#tを返した場合、Nはおそらく素数ですが、疑陽性である確率もわずかにあります。

     Note that if N is smaller than a certain number (*small-prime-bound*), the algorithm is deterministic; if it returns #t, N is certainly a prime. ただし、nがある数(*small-prime-bound*) より小さければ、アルゴリズムは決定的で、#tが返るNは確実に素数です。

     If N is greater than or equal to *small-prime-bound*, we use a probabilistic test.  We choosing random base integer to perform Miller-Rabin test up to 7 times by default. You can change the number of tests by the keyword argument NUM-TESTS.  The error probability (to return #t for a composite number) is at most (expt 4 (- num-tests)). Nが*small-prime-bound*以上の場合は確率的テストを用います。デフォルトでは7回、ランダムにベース整数値を選んで Miller-Rabinテストを適用します。試行回数はNUM-TESTSキーワード引数で変更可能です。合成数に対して誤って#tを返してしまう確率はたかだか(expt 4 (- num-tests))です。

     For a probabilistic test, miller-rabin-prime? uses its own fixed random seed by default.  We chose fixed seed so that the behavior can be reproducible.  To change the random sequence, you can provide your own random integer generator to the RANDOM-INTEGER keyword argument.   It must be a procedure that takes a positive integer K and returns a random integer from 0 to K-1, including. 確率的テストでは、MILLER-RABIN-PRIME?はデフォルトでこの手続き固有の、固定したランダムシードを使います。固定値なのは再現性を確保するためです。異なる乱数系列を使いたければ、ランダムな整数生成手続きを RANDOM-INTEGERキーワード引数に与えてください。手続きは正整数Kを取り、0からK-1までのランダムな整数値を返すものでなければなりません。

 -- Function: bpsw-prime? n
     Check if an exact integer N is a prime number, using Baillie-PSW primality test (http://www.trnicely.net/misc/bpsw.html).   It is deterministic, and returns the definitive answer below 2^64 (around 1.8e19). For larger integers this can return #t on a composite number, although such number hasn't been found yet.  This never returns #f on a prime number.

     This is slower than Miller-Rabin but fast enough for casual use, so it is handy when you want a definitive answer below the above range. Nが素数かどうかをBaillie-PSW法を用いて判定します (http://www.trnicely.net/misc/bpsw.html)。このアルゴリズムは2^64 (約1.8e19) 以下の入力に対しては決定的であり、正しい答えを返します。入力がそれ以上の場合、合成数に対して#tが返る可能性があります (具体的な数はまだ見つかっていませんが)。素数に対して#fが返ることは決してありません。

     Miller-Rabin法より遅いですがカジュアルに使う分には十分に速いので、上記の入力範囲で確実な答えを得たい場合は便利でしょう。

Factorization
-------------

素因数分解
-----

 -- Function: naive-factorize n :optional divisor-limit
     Factorize a positive exact integer N by trying to divide it with all primes up to (sqrt n).  Returns a list of prime factors (each of which is equal to or greater than 2), smaller ones first. 正整数Nを、(sqrt n)までの素数で順に割ってみることで素因数分解します。戻り値は小さい順に並べられた素因数(2以上の整数)のリストです。

          (naive-factorize 142857)
            => (3 3 3 11 13 37)

     Note that (naive-factorize 1) is (). (naive-factorize 1)は()を返します。

     Although this is pretty naive method, this works well as far as any of N's factors are up to the order of around 1e7. For example, the following example runs in about 0.4sec on 2.4GHz Core2 machine. (The first time will take about 1.3sec to realize lazy prime sequences.) この方法は極めてナイーブなものですが、目安としてどの素因数も1e7程度以下であればそれなりに使えます。例えば次の例は2.4GHz Core2マシンで0.4秒で答えが返ります (ただし、初回の実行は遅延素数シーケンスの実現化があるので1.3秒ほどかかりますが)。

          (naive-factorize 3644357367494986671013))
            => (10670053 10670053 32010157)

     Of course, if N includes any factors above that order, the performance becomes abysmal.   So it is better to use this procedure below 1e14 or so. もちろんNがより大きなオーダーの素因数を含んでいると、性能は急激に悪化します。安全に使うにはNを1e14程度のオーダーに止めておくのが良いでしょう。

     Alternatively, you can give DIVISOR-LIMIT argument that specifies the upper bound of the prime number to be tried.  If it is given, naive-factorize leaves a factor F as is if it can't be divided by any primes less than or equal to DIVISOR-LIMIT. So, the last element of the returned list may be composite number. This is handy to exclude trivial factors before applying more sophisticated factorizing algorithms. オプショナル引数DIVISOR-LIMITを与えると、試行する素数の上限を指定できます。この引数がある場合、naive-factorizeは因数Fが DIVISOR-LIMIT以下の素数で割りきれなければ、そこで諦めてFを結果に含めます。この場合、結果の最後の要素は合成数であるかもしれないわけです。これは、より高度な素因数分解アルゴリズムを適用する前にありきたりの素因数を除外するのに便利です。

          (naive-factorize 825877877739 1000)
            => (3 43 6402154091)

          ;; whereas
          (naive-factorize 825877877739)
            => (3 43 4591 1394501)

     The procedure also memoizes the results on smaller N to make things faster. この手続きは高速化のために小さなNに対する結果はメモ化しています。

 -- Function: mc-factorize n
     Factorize a positive exact integer N using the algorithm described in R. P. Brent, An improved Monte Carlo factorization algorithm, BIT 20 (1980), 176-184. http://maths-people.anu.edu.au/~brent/pub/pub051.html. 正整数Nをモンテカルロ素因数分解法 (R. P. Brent, An improved Monte Carlo factorization algorithm, BIT 20 (1980), 176-184. http://maths-people.anu.edu.au/~brent/pub/pub051.html)により素因数分解します。

     This one is capable to handle much larger range than naive-factorize, somewhere around 1e20 or so.

     Since this method is probabilistic, the execution time may vary on the same N.  But it will always return the definitive results as far as every prime factor of N is smaller than 2^64.

     At this moment, if N contains a prime factor greater than 2^64, this routine would keep trying factorizing it forever. Practical applications should have some means to interrupt the function and give it up after some time bounds. This will be addressed once we have deterministic primality test. この手続きはnaive-factorizeよりも大きな数に使えます (目安としては1e20程度まで)。

     アルゴリズムは確率的なので、同じNに対しても実行時間はばらつきますが、 Nの素因数が全て2^64より小さければ、かならず確定的な答えを返します。

     今のところ、Nが2^64以上の素因数を含んでいる場合、この手続きは永遠にそれを分割しようとしてループしてしまいます。現実的なアプリケーションは何らかの方法で一定の時間でルーチンを中断して諦めるメカニズムが必要でしょう。全ての入力に大して確定的な素数判定が実装されれば、この欠陥も修正されます。

Miscellaneous
-------------

その他の関数
------

 -- Function: jacobi a n
     Calculates Jacobi symbol (A/N) (http://en.wikipedia.org/wiki/Jacobi_symbol). Jacobi symbol (A/N) を計算します (http://en.wikipedia.org/wiki/Jacobi_symbol)。

 -- Function: totient n
     Euler's totient function of nonnegative integer N.

     The current implementation relies on mc-factorize above, so it may take very long if N contains large prime factors. オイラーのトーシェント関数です。Nは非負整数です。

     現在の実装は上のmc-factorizeを使っており、 Nが大きな素因数を持っている場合は非常に長い時間がかかります。

os.windows - Windows support
============================

 -- Module: os.windows
     This module is only available on Windows-native Gauche, and provides Windows-specific procedures. You can check gauche.os.windows feature with cond-expand macro (see Feature conditional) to conditionalize windows-specific code.

          (cond-expand
            [gauche.os.windows
             (use os.windows)
             ... Windows-specific code ...]
            [else
             ... Unix code ...])

     Currently there aren't enough procedures provided here, but eventually we want to support simple scripting on Windows.

     Unless otherwise noted, when Windows API returns an error value, a <system-error> condition is thrown.

Windows dialogs
---------------

Currenly we only have MessageBox API.

 -- Function: sys-message-box window message :optional caption flags
     Calls Windows MessageBox API.   The WINDOW argument should be a handle for a window, or #f; at the moment we don't provide any API that retrieves window handles, so you should always pass #f here.  The MESSAGE argument takes a string for the content of the message box.  Optional CAPTION argument takes a string to be used in the window title.

     The FLAGS argument is an integer; it should be logior of values from one or more of the following groups.  See the Windows reference manual for the details.

     Buttons
          MB_ABORTRETRYIGNORE, MB_CANCELTRYCONTINUE, MB_HELP, MB_OK (default), MB_OKCANCEL, MB_RETRYCANCEL, MB_YESNO, MB_YESNOCANCEL

     Icon
          Default is no icon.  Possible values: MB_ICONEXCLAMATION, MB_ICONWARNING, MB_ICONINFORMATION, MB_ICONASTERISK, MB_ICONQUESTION, MB_ICONSTOP, MB_ICONERROR, MB_ICONHAND

     Default button
          MB_DEFBUTTON1 (default), MB_DEFBUTTON2, MB_DEFBUTTON3, MB_DEFBUTTON4

     Modality
          MB_APPLMODAL (default), MB_SYSTEMMODAL, MB_TASKMODAL

     Other options
          MB_DEFAULT_DESKTOP_ONLY, MB_RIGHT, MB_RTLREADING, MB_SETFOREGROUND, MB_TOPMOST, MB_SERVICE_NOTIFICATION

     Return value is one of the following integer constants, indicating which button is pressed: IDABORT, IDCANCEL, IDCONTINUE, IDIGNORE, IDNO, IDOK, IDRETRY, IDTRYAGAIN, or IDYES

Windows console API
-------------------

Most of these procedures corresponds to Windows Console API one-to-one. See the Windows reference for the detail description of what each API does.

Attaching and detaching
.......................

 -- Function: sys-alloc-console
 -- Function: sys-free-console
     [Windows] Calls AllocConsole and FreeConsole, respectively.

 -- Function: sys-generate-console-ctrl-event event pgid
     [Windows]

 -- Constant: CTRL_C_EVENT
 -- Constant: CTRL_BREAK_EVENT
     [Windows]

Console codepage
................

 -- Function: sys-get-console-cp
 -- Function: sys-get-console-output-cp
 -- Function: sys-set-console-cp codepage
 -- Function: sys-set-console-output-cp codepage
     [Windows]

 -- Function: sys-get-console-cursor-info handle
 -- Function: sys-set-console-cursor-info handle size visible
     [Windows]

 -- Function: sys-set-console-cursor-position handle x y
     [Windows]

Console mode
............

 -- Function: sys-get-console-mode handle
 -- Function: sys-set-console-mode handle mode
     [Windows]

 -- Constant: ENABLE_LINE_INPUT
 -- Constant: ENABLE_ECHO_INPUT
 -- Constant: ENABLE_PROCESSED_INPUT
 -- Constant: ENABLE_WINDOW_INPUT
 -- Constant: ENABLE_MOUSE_INPUT
 -- Constant: ENABLE_PROCESSED_OUTPUT
 -- Constant: ENABLE_WRAP_AT_EOL_OUTPUT
     [Windows]

Screen buffer
.............

 -- Function: sys-create-console-screen-buffer desired-access share-mode inheritable
     [Windows]

 -- Constant: GENERIC_READ
 -- Constant: GENERIC_WRITE
     [Windows]

 -- Constant: FILE_SHARE_READ
 -- Constant: FILE_SHARE_WRITE
     [Windows]

 -- Function: sys-set-console-active-screen-buffer handle
     [Windows]

 -- Function: sys-scroll-console-screen-buffer handle scroll-rectangle clip-rectangle x y fill
     [Windows]

 -- Class: <win:console-screen-buffer-info>
     [Windows]

      -- Instance Variable of <win:console-screen-buffer-info>: size.x
      -- Instance Variable of <win:console-screen-buffer-info>: size.y

      -- Instance Variable of <win:console-screen-buffer-info>: cursor-position.x
      -- Instance Variable of <win:console-screen-buffer-info>: cursor-position.y

      -- Instance Variable of <win:console-screen-buffer-info>: attributes

      -- Instance Variable of <win:console-screen-buffer-info>: window.left
      -- Instance Variable of <win:console-screen-buffer-info>: window.top
      -- Instance Variable of <win:console-screen-buffer-info>: window.right
      -- Instance Variable of <win:console-screen-buffer-info>: window.bottom

      -- Instance Variable of <win:console-screen-buffer-info>: maximum-window-size.x
      -- Instance Variable of <win:console-screen-buffer-info>: maximum-window-size.y

 -- Constant: FOREGROUND_BLUE
 -- Constant: FOREGROUND_GREEN
 -- Constant: FOREGROUND_RED
 -- Constant: FOREGROUND_INTENSITY
 -- Constant: BACKGROUND_BLUE
 -- Constant: BACKGROUND_GREEN
 -- Constant: BACKGROUND_RED
 -- Constant: BACKGROUND_INTENSITY
     [Windows]

 -- Function: sys-get-console-screen-buffer-info handle
     [Windows]

 -- Function: sys-get-largest-console-window-size handle
     [Windows]

 -- Function: sys-set-screen-buffer-size handle x y
     [Windows]

Console input/output
....................

 -- Class: <win:input-record>
     [Windows]

      -- Instance Variable of <win:input-record>: event-type

      -- Instance Variable of <win:input-record>: key.down
      -- Instance Variable of <win:input-record>: key.repeat-count
      -- Instance Variable of <win:input-record>: key.virtual-key-code
      -- Instance Variable of <win:input-record>: key.virtual-scan-code
      -- Instance Variable of <win:input-record>: key.unicode-char
      -- Instance Variable of <win:input-record>: key.ascii-char
      -- Instance Variable of <win:input-record>: key.control-key-state

      -- Instance Variable of <win:input-record>: mouse.x
      -- Instance Variable of <win:input-record>: mouse.y
      -- Instance Variable of <win:input-record>: mouse.button-state
      -- Instance Variable of <win:input-record>: mouse.control-key-state
      -- Instance Variable of <win:input-record>: mouse.event-flags

      -- Instance Variable of <win:input-record>: window-buffer-size.x
      -- Instance Variable of <win:input-record>: window-buffer-size.y

      -- Instance Variable of <win:input-record>: menu.command-id

      -- Instance Variable of <win:input-record>: focus.set-focus

 -- Function: sys-get-number-of-console-input-events handle
     [Windows]

 -- Function: sys-get-number-of-console-mouse-buttons
     [Windows]

 -- Function: sys-peek-console-input handle
 -- Function: sys-read-console-input handle
     [Windows]

 -- Function: sys-read-console handle buf
     [Windows]

 -- Function: sys-read-console-output handle buf w h x y region
     [Windows]

 -- Function: sys-read-console-output-attribute handle buf x y
     [Windows]

 -- Function: sys-read-console-output-character handle len x y
     [Windows]

 -- Function: sys-set-console-text-attribute handle attr
     [Windows]

 -- Function: sys-set-console-window-info handle absolute window
     [Windows]

 -- Function: sys-write-console handle string
     [Windows]

 -- Function: sys-write-console-output-character handle string x y
     [Windows]

 -- Function: sys-fill-console-output-character handle char len x y
     [Windows]

 -- Function: sys-fill-console-output-attribute handle attr len x y
     [Windows]

 -- Function: sys-flush-console-input-buffer handle
     [Windows]

 -- Function: sys-get-console-title
     [Windows]

 -- Function: sys-set-console-title string
     [Windows]

Standard handles
................

 -- Function: sys-get-std-handle which
 -- Function: sys-set-std-handle which handle
     [Windows]

 -- Constant: STD_INPUT_HANDLE
 -- Constant: STD_OUTPUT_HANDLE
 -- Constant: STD_ERROR_HANDLE
     [Windows]

parser.peg - PEG parser combinators
===================================

 -- Module: parser.peg
     This module implements a parser combinator library to build parsers based on Parsing Expression Grammar, or PEG. このモジュールは、Parsing Expression Grammar (PEG)に基づいたパーザを組み立てるコンビネータライブラリを実装しています。

     PEG is a formal grammar to define a language, like regular expressions or context-free grammars. An interesting characteristic of PEG is that it can be directly mapped to a recursive decent parser, which is exactly what this library does---each production rule is a Scheme expression that takes parsers and returns a combined parser.  One advantage of this approach is that you can freely mix ordinary Scheme code within the parser, that is, there's no special ``parser description language'' distinct from the base Scheme language, nor you need to run separate tools like parser generators to obtain a runnable parser code. PEGは、正規表現や文脈自由文法と同様の形式言語です。 PEGが興味深いのは、文法記述がそのまま再帰下降パーザに移し替えられるところで、このライブラリはまさにそれをやっています。各生成規則は、パーザを受け取って結合されたパーザを返すScheme式です。このアプローチの利点は、Schemeコードと文法記述を混ぜて書けることです。特別な「パーザー記述言語」を別に学ぶ必要も、パーザジェネレータのような別ツールを使ってソースコードを生成する必要もありません。

     Although PEG can directly parse the character string, the parser combinators are not tied to it.  In fact, most of the combinators work transparently for any sequence of tokens, where the exact meanings of tokens depend on the application; you can have separate lexer that generates token sequence that PEG parser can parse, for example. PEGは文字列を直接パーズすることもできますが、パーザコンビネータは文字列のパーズ限定ではありません。実際、多くのコンビネータは「トークン」の列 (具体的なトークンの意味はアプリケーションが決められます) に対して透過的に動作します。例えば字句解析器を別に作ってトークンの列を生成し、それをPEGでパーズする、ということもできます。

     This library is specifically written to get a good performance on Gauche.  The parser created by parser.peg is no slower than the parser written manually from scratch. However, you have to watch out some traps; see PEG performance tips, for the details. このライブラリは、Gaucheで性能が出るように書かれています。 parser.pegで作られたパーザは、手書きのパーザと遜色ない性能を持ちます。但し、いくつか気をつけるべき点はあります。それについては PEG performance tipsを参照してください。

Walkthrough
-----------

In this section we cover the basic concepts and tools of parser.peg. The code of examples is in examples/pegintro.scm if you have the source tree of Gauche. 本節では、parser.pegの基本的なコンセプトと道具を説明します。例に使ったコードは、Gaucheのソースツリーのexamples/pegintro.scmにあります。

In parser.peg, a parser is merely a Scheme procedure that takes a list of tokens as an argument and returns a result (well, in fact, it returns three values, but we'll go into the details later.) parser.pegでは、パーザとは単なるSchemeの手続きです。それはトークンのリストを引数に取り、結果を返します (実際は3つの値を返します。それについては後で詳しく述べます)。

Typically you don't need to write parser procedures directly. Instead, you can use procedures that generates parsers.   A parser can be as simple as the following, which accepts a character #\a. パーザ手続きを直接書く必要は滅多にありません。代わりに、パーザを生成する手続きがたくさん用意されているのでそれを使います。例えば、文字#\aを受理するパーザはこう書けます。

     ($. #\a)   ; => a parser

Here, accept means the parser checks if the head of input has a character #\a, and if it is, it succeeds, and if not, it fails. ここで受理するとは、パーザが入力の先頭をチェックして、それが文字#\aならば成功し、そうでなければ失敗するという意味です。

A parser can be invoked by a parser driver.  For example, you can use peg-parse-string to invoke the above parser on a string: パーザはパーザドライバによって呼び出せます。例えば peg-parse-stringを使って、上のパーザで文字列をパーズしてみましょう。

     gosh> (peg-parse-string ($. #\a) "abc")
     #\a

The parsing succeeds, and returns the matched value---#\a in this case. If the parser can't accept the input, the driver throws an error <parse-error>. パーズは成功し、マッチした値 (#\a) が返りました。パーザが期待する入力でなかった場合には、ドライバは<parse-error>を投げます。

     gosh> (peg-parse-string ($char #\a) "xyz")
     *** PARSE-ERROR: expecting #\a at 0, but got #\x

A parser can also be constructed by combining simpler parsers, using parser combinators.   For example, $seq takes zero or more parsers and apply them sequentially, returning the last result. 単純なパーザをパーザコンビネータで組み合わせて、より複雑なパーザを作ることができます。例えば、$seqはいくつかのパーザを受け取り、「それらを順に適用して最後の結果を返すパーザ」を作って返します。

     gosh> (peg-parse-string ($seq ($. #\a) ($. #\b) ($. #\c)) "abc")
     #\c

The combinator $many takes a parser and returns a new parser that accepts zero or more occurrence of the string the original parser accepts. コンビネータ$manyはパーザを取ると、それのゼロ回以上の繰り返しを受理するパーザを作って返します。

     gosh> (peg-parse-string ($many ($. #\a)) "aaaaabc")
     (#\a #\a #\a #\a #\a)
     gosh> (peg-parse-string ($many ($. #\a)) "xxxxxyz")
     ()

A parser is just an ordinary Scheme procedure, so it can be bound to a variable, then can be used to construct more complex parsers. パーザは通常のSchemeの手続きなので、変数に束縛し、それをより複雑なパーザを作るのに使えます。

     (define digits    ($many1 ($. #[\d])))
     (define ws        ($many_ ($. #[\s])))
     (define separator ($seq ws ($. #\,) ws))

I leave explanation of $many1 and $many_ for the later section, but you may be able to guess what those parsers do; digits accepts a sequence of one or more digits, and ws accepts sequence of zero or more whitespaces.   The separator parser accepts a comma, optionally surrounded by whitespaces. $many1と$many_の説明は後回しにしますが、何となくこれらのパーザの動作は推測できるのではないでしょうか。 digitsは1個以上の数字の並びを、 wsは0個以上の空白文字の並びを受理するパーザです。 separatorパーザは0個以上の空白で囲まれたコンマを受容します。

The digits parser returns a list of accepted characters: digitsは受理した文字のリストを返します。

     gosh> (peg-parse-string digits "12345")
     (#\1 #\2 #\3 #\4 #\5)

Can we create a parser that returns an integer as a parsed result?    Yes, we can use the $let macro. パーズの結果として整数値を返すようにできるでしょうか。 $letマクロを使えばできます。

     (define integer
       ($let ([ds digits])
         ($return (x->integer (list->string ds)))))

The $let works somewhat like and-let*; it takes a form of ($let ([VAR PARSER] ...) EXPR ...), applying the PARSERs in order, binding the result of each parser to VAR.  If any of the PARSER fails, the entire parser created by $let macro fails.  When all the PARSER succeeds, each result is  bound to VAR and EXPR ... are evaluated.  The last EXPR must yield a parser. $letはand-let*のように動作します。 ($let ([VAR PARSER] ...) EXPR)という形式を取り、 PARSERを順に入力に適用してゆきます。 PARSERのどれかひとつでも失敗したら全体が失敗します。全てのPARSERが成功したら、それぞれの結果がVARに束縛された環境下で EXPR ...が評価されます。最後のEXPRはパーザを返さねばなりません。

The $return procedure creates a parser that doesn't consume input, always succeeds and returns the given value.  The name is taken from Haskell's monads.  Note that is is just an ordinary procedure and not like a control-transfer syntax like traditional language's return.  You may think it just as type conversion procedure from a Scheme object to a parser. $return手続きは、入力を消費せず、常に成功し、引数をパーズ結果とするパーザを作ります。この名前はHaskellのモナドからきました。他の多くの言語にあるreturnのように制御の流れを変えるのではなく、単なる手続きであることに注意してください。任意のSchemeオブジェクトをパーザに変える変換手続きと考えても良いでしょう。

     gosh> (peg-parse-string integer "12345")
     12345

Now you can combine those parsers to build more complex one, such as a comma-separated list of integers: これらのパーザを組み合わせて、さらに複雑なパーザを作ることができます。例えばコンマで区切られた整数のリストです：

     (define integers1 ($seq integer
                             ($many ($seq separator integer))))

     gosh> (peg-parse-string integers1 "123, 456, 789")
     (456 789)

Oops, where's 123?  Well, remember that $seq discards the results but the last one. We can use $let again to keep all the results. あれ、最初の123がどっかいっちゃいました。そうそう、 $seqは最後のパーザの値以外は捨てるのでした。 $letを使って結果を集めることができます。

     (define integers2 ($let ([n  integer]
                              [ns ($many ($seq separator integer))])
                          ($return (cons n ns))))

     gosh> (peg-parse-string integers2 "123, 456, 789")
     (123 456 789)

(Unlike let where the order of its init expressions are not defined, $let guarantees the parsers are applied sequentially. The reason it is not called $let* is the scope; we also have $let*, which we'll explain shortly.) (letではinit式の評価順序は決まっていませんが、 $letはパーザを書かれた順に適用することを保証しています。これを$let*と呼んでいないのはスコープのためです。すぐ後で$let*も紹介します。)

Another way to gather the results of parsers is a combinator $lift. It is used as ($lift proc parser ...), where PROC is an ordinary procedure which receives the result of PARSER ... as arguments.  The return value of PROC becomes the result of the entire parser.  Unlike $let, PROC doesn't need to return a parser. パーザの結果を集めるもうひとつの方法は$liftコンビネータです。 ($lift proc parser ...) のように使います。ここで PROCは普通の手続きで、PARSER ...の結果を引数として受け取り、 PROCの返した結果が全体のパーザの結果になります。 $letと違って、PROCはパーザを返す必要はありません。

     (define integers3 ($lift cons
                              integer
                              ($many ($seq separator integer))))

The parsers so far doen't handle the case when the list contains no integers.   Using $or combinator, which represents a choice, we can modify it to handle zero-element case. これまでのパーザは入力に整数が全く含まれていない場合を考慮していませんでした。選択を表す$orコンビネータを使って、整数が無いケースをサポートできます。

     (define integers4 ($or ($let ([n  integer]
                                   [ns ($many ($seq separator integer))])
                              ($return (cons n ns)))
                            ($return '())))

By the way, ``list of stuff separated by something'' is a very common pattern, so we can extract the pattern to name it: ところで、「何かで区切られた何かのリスト」というのは頻繁に出てくるので、次のようにパターンを取り出しておくことができます：

     (define (sep-by stuff separator)
       ($or ($let ([n  stuff]
                   [ns ($many ($seq separator stuff))])
              ($return (cons n ns)))
            ($return '())))

Then the list of integers can be written this simple: すると整数のリストのパーザはこんなに簡単になります:

     (define integers5 (sep-by integer separator))

In fact, parser.peg provides $sep-by to do the above, but we've just shown the definition to demonstrate the power of the combinatorial approach; you can use ordinary procedural abstraction to factor out common patterns. 実はparser.pegには上と同じことができる$sep-byというのが既に用意されているんですが、コンビネータを使う方法の強みを示すためにあえて実装してみました。共通のパターンに通常の手続きを使った抽象化を使えるのが利点です。

There's one catch in the $or form. It tries the next alternative only when the parser fails without consuming the input.  Once the input is consumed, $or commits to that choice.   For example, the following fails even if the input seems to match the second alternative: $orについてはひとつ注意があります。ある選択肢が失敗した時、それが入力を消費していない場合に限り、次の選択肢が試されるということです。入力が少しでも消費されたら、$orはその選択肢にコミットし、その先で失敗しても他の選択肢を試しません。下の例では、 2番目の$seqが入力にマッチするにもかかわらず、パーズは失敗します。

     (define paren  ($. #\())
     (define thesis ($. #\)))

     (peg-parse-string ($or ($seq paren ($."ab") thesis)
                            ($seq paren ($."cd") thesis))
                       "(cd)")
      => *** PARSE-ERROR: expecting ab at 1, but got #\c

It's because when $or tries the first branch, it reads the initial open paren from the input, so $or commits to the first branch. When the branch fails, $or doesn't bother to try the second branch. (In other words, $or does not backtrack.) $orの最初の選択肢で、先頭の開き括弧はマッチに成功して入力が消費されます。その後でマッチが失敗するわけですが、既に入力が消費されているので、 $orは他の選択肢を考慮することなく全体を失敗させます。 (言い換えれば、$orはバックトラックを行いません。)

You may factor out the common prefix: 一つの手は、共通部分を括り出すことです。

     ($seq paren
           ($or ($."ab") ($."cd"))
           thesis)

But it may complicates the syntax, and it is not always trivial to factor out like above.  The better way is to use the $try combinator: ($try P) runs a parser P, and if it fails, $try rolls back the input as if it didn't consume input at all.  Using with $or, you can do arbitrary lookahead and backtrack. ただ、これは文法を複雑化させることがありますし、いつでも簡単にできるとは限りません。よりうまい方法は$tryコンビネータを使うことです。 ($try P)はパーザPを走らせ、それが失敗したら入力を元の時点まで巻き戻します。$orと一緒につかえば、いくらでも先読みとバックトラックができます。

     ($or ($try ($seq paren ($."ab") thesis))
          ($seq paren ($."cd") thesis))

Now, let's get back to the integer list example and make it more interesting. Suppose the list of integers are surrounded by parentheses, brackets or curly-braces.  Opening one and closing one must correspond. さて整数のリストの例をもうちょっとおもしろくしてみましょう。リストは小括弧、中括弧、大括弧のどれかで囲まれていて、開き括弧と閉じ括弧は対応していなければならない、とします。

     (define begin-list
       ($seq0 ($. #[\(\[\{]) ws))

     (define (end-list opener)
       ($seq ws (case opener
                 [(#\() ($. #\))]
                 [(#\[) ($. #\])]
                 [(#\{) ($. #\})])))

     (define int-list
       ($let* ([opener begin-list]                ;*1
               [ints ($sep-by integer separator)] ;*2
               [ (end-list opener) ])             ;*3
         ($return ints)))

The opening bracket is parsed by the parser begin-list. The $seq0 combinator is similar to seq, but returns the result of the first parser instead of the last one (it's begin0 to begin). 開き括弧はbegin-listパーザが受理します。$seq0は $seqとほぼ同じですが、最初のパーザの結果を返します。 (beginに対するbegin0と同じです。)

The closing bracket must match the opening one, so end-list is a procedure that takes the opening bracket and returns a suitable parser to accept the corresponding closing bracket. 閉じ括弧は開き括弧と対応しないとならないので、end-listは開き括弧を取って適切な閉じ括弧のパーザを返す手続きになっています。

The int-list first parses the opening bracket by begin-list and bind the result to OPENER (*1). Then goes to parse comma-separated integers (*2) and bind the result list to INTS. Finally, it parses the matching closing bracket (*3).  Note that the it omits the variable, since we don't need the result of closing bracket parser. int-listはまず開き括弧をbegin-listでパーズし、その結果を OPENERに束縛します(*1)。次にコンマ区切りの整数をパーズし、結果のリストを INTSに束縛します(*2)。最後に開き括弧に対応する閉じ括弧をパーズします(*3)。最後のパーザは値を使わないので、変数を省略しています。

Since we need to use the value of OPENER in the following bindings, we use $let* here, instead of $let.  The difference is the scope of the parser expressions in the binding.  Note that, however, $let is a lot more easier to optimize, so you want to use $let whenever possible. OPENERの値を続く束縛フォームの中で使う必要があるので、ここでは$letではなく$let*を使いました。この差はletとlet*の差と同じで、スコープの違いです。ただ、$letの方が処理系にはうんと最適化しやすいので、可能な限り$letを使う方が良いでしょう。

Let's see it works. 走らせてみます。

     gosh> (peg-parse-string int-list "[123, 456, 789]")
     (123 456 789)
     gosh> (peg-parse-string int-list "{123, 456, 789}")
     (123 456 789)
     gosh> (peg-parse-string int-list "(123, 456, 789}")
     *** PARSE-ERROR: expecting #\) at 14, but got #\}

The last example shows it rejects unmatched brackets. 最後の例は括弧の対応が取れていないと失敗する例です。

What if we want a nested list?  In BNF, we could write something like this: ネストしたリストをパーズするにはどうすればいいでしょう? BNFならこう書けるでしょう。

     list : begin-list (elem (separator elem)* )? end-list
     elem : integer | list

The straight translation would be he following. これをそのまま移し替えると次のようになります。

     ;; First try
     (define nested-list
       ($let* ([opener begin-list]
               [ints ($sep-by elem separator)]
               [ (end-list opener) ])
         ($return ints)))
     (define elem  ($or integer nested-list))

Let's load it... Oops. ロードしてみましょう。おっと

     *** ERROR: unbound variable: elem
     Stack Trace:
     _______________________________________
       0  elem
             [unknown location]
       1  (eval expr env)
             at "../lib/gauche/interactive.scm":267

We need the parser elem to construct nested-list, but we need the parser nested-list to construct elem. In lazy languages like Haskell this doesn't matter, but we Schemers are eager! nested-listの値を計算するのにelemの値を使いますが、 elemの値を計算するのにnested-listの値が必要です。 Haskellのような怠惰な言語ならこれでも構わないんですが、 Schemerは熱心なんです!

The solution is to delay the parser construction until it is actually used.  The $lazy form does the job: 解決策は、パーザの計算を必要になるまで遅らせることです。 $lazyフォームが必要な遅延を行います。

     (define nested-list
       ($lazy
         ($let* ([opener begin-list]
                 [ints ($sep-by elem separator)]
                 [ (end-list opener) ])
           ($return ints))))
     (define elem  ($or integer nested-list))

     gosh> (peg-parse-string nested-list "(123, [456, {}, 789], 987)")
     (123 (456 () 789) 987)

Ok, we're almost done.  Our code can parse nested list of integers, checking bracket matches.  But if you give an erroneous input, the message is cryptic and not helpful: さあ、ほとんど完成です。括弧の対応をチェックしながら、ネストした整数のリストをパーズできるようになりました。ただ、間違いのある入力を与えた時に出されるエラーメッセージがわかりにくいですね。

     gosh> (peg-parse-string nested-list "(123, [456, {}, 789), 987)")
     *** PARSE-ERROR: expecting one of (#[0-9] #\]) at 19
     Stack Trace:
     _______________________________________
       0  (eval expr env)
             at "../lib/gauche/interactive.scm":267

We could check the reason of failure in the parser, and call $fail with more reasonable error message.  Let's replace end-list above with end-list2 below: パーザの中で失敗の理由を調べて、意味のあるエラーメッセージで$failを呼び出すことができます。上のend-listを下のend-list2に置き換えてみて下さい。

     (define (end-list2 opener)
       (define expected
         (assv-ref '((#\( . #\)) (#\[ . #\]) (#\{ . #\})) opener))
       ($seq ws
             ($let ([closer ($. #[\)\]\}])])
               (if (eqv? closer expected)
                 ($return closer)
                 ($fail (format "Mismatched closing bracket. '~c' expected, \
                                 but got '~c'"
                                expected closer))))))

You also have to change nested-list and elem to use end-list2: nested-listとelemについてもend-list2を使うように変更します:

     (define nested-list2
       ($lazy
         ($let* ([opener begin-list]
                 [ints ($sep-by elem2 separator)]
                 [ (end-list2 opener) ])
           ($return ints))))

     (define elem2  ($or integer nested-list2))

(You could redefine end-list, but if you do so, don't forget to re-evaluate the definitions of nested-list and elem. It's because the combinators are caculated taking the value of other combinators when it's defined, unlike typical procedural approach where you redefine one procedure and other procedures will refer to the updated version after that.) (end-listを再定義しても良いのですが、その場合は nested-listとelemの定義を再評価することを忘れないでください。コンビネータは、定義時に他のコンビネータの値を使って計算されます。通常の手続き定義のアプローチでは、一つの手続きの定義を差し替えたら他の手続きは新しい定義を使うようになりますが、それと異なるので要注意です。)

And now you see this error: これで、エラーメッセージはこんなふうになります。

     gosh> (peg-parse-string nested-list2 "(123, [456, {}, 789), 987)")
     *** PARSE-ERROR: Mismatched closing bracket. ']' expected, but got ')' at 20
     Stack Trace:
     _______________________________________
       0  (eval expr env)
             at "../lib/gauche/interactive.scm":267

For further examples, you can take a look at some libraries in the Gauche source tree that use parser.peg: 更なる例は、Gaucheソースツリーの中でparser.pegを使っているライブラリに見ることができます:

  * lib/rfc/json.scm

  * lib/text/edn.scm

  * lib/www/css.scm

Parser drivers
--------------

 -- Function: peg-run-parser parser list
     Apply PARSER on the input LIST.   If PARSER accepts it, returns two values--the result of PARSER, and the rest of the input.  If PARSER fails, raise <parse-error>. パーザPARSERを入力LISTに適用します。入力が受理されたら、 PARSERの結果と、残りの入力の二つの値を返します。 PARSERが失敗したら、<parse-error>が投げられます。

     The result of PARSE is a value yielded by PARSER passed to rope-finalize, so any unfinalized rope is finalized before being returned.  See PEG ropes, for the details. PARSEの結果はrope-finalizeを通されるので、結果中のファイナライズされていないロープは全てファイナライズされて返されます。ロープについてはPEG ropesを参照してください。

     Typically, you don't want to have entire input as a list beforehand, so you pass a lazy sequence as LIST (see Lazy sequences). If the input is a string or a port, convenience procedures are defined. 多くの場合、入力をあらかじめ全部リストで持っておきたくはないと思います。その場合、遅延シーケンスをLISTに渡せば良いでしょう (Lazy sequences)。なお、入力が文字列やポートの場合はユーティリティ手続きが定義されています。

     Input doesn't need to be a character list.  You may, for example, have a separate lexer that generates a (lazy) list of tokens, and let PARSER parse them. 入力が文字のリストである必要はありません。例えば、別の字句解析器を使ってトークンの(遅延)リストにしてから、 PARSERでそれをパーズすることもできます。

 -- Function: peg-parse-string parser string :optional cont
 -- Function: peg-parse-port parser iport :optional cont
     Convenience wrappers of peg-run-parser that takes input from STRING or IPORT. peg-run-parserで文字列STRINGや入力ポートIPORTからの入力をパーズするユーティリティ手続きです。

     Without CONT argument or it is #f, it returns the parsed result and discards the rest of the input.  (Hint: To make sure there's no garbage following, use $eos parser.) CONT引数が省略されるか#fであれば、この手続きはパーザが受理したところ以降の入力は捨てて、パーザの結果だけ返します。 (ヒント: 余分なゴミが後に続いてないことを保証するには$eosパーザが使えます)。

     If you want to keep parsing after PARSER accepts its input, pass CONT a procedure; it must take two arguments, the result of PARSER and a lazy sequence of the rest of the input.  What CONT returns will be the result of these procedures. PARSERが入力を受理した後、さらにパーズを続けたければ、CONTに手続きを渡します。その手続きはPARSERの結果と、残りの入力の遅延シーケンスの二つの引数を取ります。CONTが返すものが全体の返り値となります。

     It is an error to pass other values ot CONT. CONTにそれ以外の値を渡すのはエラーです。

 -- Function: peg-parser->generator parser list
     This is useful when you need to apply PARSER repeatedly over the input LIST.    Returns a generator that generates the parsed result one match at a time.

     The same input can be accepted by by (peg-run-parser ($many parser) list), but this one won't return until all input is consumed.

 -- Condition type: <parse-error>
     An condition type raised by the parser driver when the given parser failed ultimately.  Inherits <error>. (Note that each parser won't throw this; one parser's failure doesn't necessarily mean the entire parser fails. It's the driver that recognizes the ultimate failure and raise this condition.)

     The following slots are available:

      -- Instance Variable of <parse-error>: message
          This slot is inherited from <error>.  Contains string error message.

      -- Instance Variable of <parse-error>: position
          The position the failure occurs, counted by the number of tokens from the beginning of the input.

      -- Instance Variable of <parse-error>: type
          The type of failure.  It's either one of the follownig symbols:

          fail-expect
               The parser expects one of the objects in OBJECTS slot, but got a different one (stored in TOKEN).

          fail-unexpect
               The parser isn't expecting any of the objects in OBJECTS slot, but got the one in TOKEN.

          fail-compound
               The parser failed multiple options.  The OBJECTS slot contains a list of of (type . msg) where TYPE is one of the <parse-error> types, and MSG is the message associated with it.

          fail-message
               Other miscellaneous failure.  The OBJECTS slot contains a mmessage.

      -- Instance Variable of <parse-error>: objects
          Value of this slot depends on the value of TYPE slot.

      -- Instance Variable of <parse-error>: token
          The token at the head of input when failure occur.  If input already reached at the end, this slot is set to #<eof>.

What is a PEG parser, really?
-----------------------------

A PEG parser is a Scheme procedure that takes a list of items as an input, and returns three values:

  * Failure type.  If the parser successfully accepts the input, this value is #f.  If the parser fails to accept the input, this value is either one of the symbols fail-expect, fail-unexpect, fail-compound and fail-message.  It corresponds to the type slot of <parse-error>, and determines the meaning of the second return value.

  * Value.  If the parser successfully accepts the input, this value is the parser's ``result'', sometimes called a semantic value.  If the parser fails to accept the input, this value contains the hint of the failure.  It corresponds to the objects slot of <parse-error>; see the documentation of <parse-error> for the details (see PEG parser drivers).

  * The rest of the input list.

Typically you don't need to write a parser as a procedure; instead, you can use one of the parser builders and combinators described in the following sections.

We do provide a few utilities to write a parser from scratch, in case you need to do so.

 -- Function: return-result value rest
     Call this at the tail position of the parser when it succeeds, with VALUE for the semantic value and REST for the rest of input.  This is the same as (values #f value rest), but clearer to show the intention.

 -- Function: return-failure/expect objs rest
 -- Function: return-failure/unexpect objs rest
 -- Function: return-failure/message msg rest
 -- Function: return-failure/compound fails rest
     Call one of these at the tail position of the parser when it fails. The first argument will be in objects slot of <parse-error>.

       * If you're expecting some types of objects (OBJS) but got anything else, call return-failure/expect.  It generates fail-expect type failure.

       * If you're not expecting some types of objects (OBJS) but got one, call return-failure/unexpect.  It generates fail-unexpect type failure

       * If you're failing because of all of multiple choices fail, you can gather those failures into an assoc list ((fail-type . objs) ...), and call return-failure/compound.  It generates fail-compound type failure.

       * Finally, your failure can't be categorized to one of the above, you can call return-failure/message, with the message describing the reason of the failure.

 -- Function: return-failure type objs rest
     This should only be used to pass down the failure form other parser. See the example in parse-success? entry below.

 -- Function: parse-success? r
     Check the first return value of a parser to see if it is a success. A typical usage is to check another parser's result and take actions accordingly:

          (receive (r v s) (parser input)
            (if (parse-success? r)
               (... do things after PARSER succeeds ...
                 (return-result ...))
               (return-failure r v s)))

Primitive parser builders
-------------------------

Procedures and macros that create parsers.

 -- Function: $return val
     Returns a parser that always succeeds, without consuming input, and yields VAL as the result of parser.

     Frequently used in $let and $let*'s body, but can be used anywhere a parser is expected.

 -- Function: $fail msg-string
     Returns a parser that always fails, without consuming input, and uses MSG-STRING as the failure message.

     Frequently used to produce user-friendly error messages.

 -- Function: $satisfy pred expect :optional result
     This corresponds to ``semantic predicate'' in PEG; a parser that can apply an arbitrary predicate on input.

     Returns a parser that works as follows:

       * If the head of input stream satisfies PRED, call (RESULT head (PRED head)) and yield its return value as the result of successful parsing. If RESULT is omitted, it yields the head of input.

       * Otherwise, the parsing fails with EXPECT as the expected input.

 -- Function: $. obj
     Creates a parser that matches a Scheme object OBJ, which may be a character, a string, or a char-set. If OBJ is a char-set, the parser matches any character in the set.

     The resulting parser is atomic, that is, it doesn't consume input when it fails.

 -- Function: $char c
 -- Function: $char-ci c
     Returns a parser that accepts a single character, C. $char-ci ignores case. On success, the parser yields the input character. The resulting parser is atomic, that is, it doesn't consume input when it fails.

 -- Function: $string str
 -- Function: $string-ci str
     Returns a parser that accepts an input that matches a string STR.  $string-ci ignores case. On success, the parser yields the matched string.

     The parsing of string is atomic: When the parser fails, it doesn't consume the input.  That is, ($string "ab") is not the same as ($let ([a ($char #\a)] [b ($char #\b)]) ($return (string a b))).

 -- Function: $one-of cset
     Returns a parser that accepts any character in the character set CSET. On success, the parser yields the accepted character.

 -- Function: $none-of cset
     Returns a parser that accepts any character not in the character set CSET. On success, the parser yields the accepted character.

 -- Function: $any
     Returns a parser that matches any one item, and yields the matched input item on success. It fails only when the input already reached at the end.

 -- Function: $eos
     Stands for ``end of stream''.  Returns a parser that matches the end of input.  It never consumes input.

 -- Macro: $match1 pattern result
 -- Macro: $match1 pattern
 -- Macro: $match1 pattern (=> fail) result
 -- Macro: $match1* pattern result
 -- Macro: $match1* pattern
 -- Macro: $match1* pattern (=> fail) result
     The pattern matcher macro match-let1 lifted to the parser. See Pattern matching, for the details of supported PATTERN.

     The macro $match1 returns a parser that takes one item from the input stream, and see if it matches PATTERN. If it matches, evaluate RESULT within an environment where pattern variables are bound to matched content, and the parser yields the value of RESULT.  If the input doesn't match PATTERN, or the input is empty, the parser fails without consuming input.

     In the third form => must be a literal identifier and FAIL must be an identifier.  The identifier FAIL is bound to a procedure that takes one string argument in RESULT.  You can call FAIL at the tail position of RESULT to make the match fail, with the passed argument as the message.  If FAIL is called, no input will be consumed.

     (NB: The match macro in util.match has a similar feature, but it binds FAIL to a continuation that abandons the current match clause and go to try the next pattern.  In $match1, FAIL is simply a procedure, so you have to call it at the tail position to make it work.)

     The macro $match1* is similar to $match1, except the entire input is matched PATTERN.   It is useful to look into several items in input, instead of just one. Note that if you give a pattern that consumes arbitrary length of input (e.g. ($match1* (a ...)), it will consume entire input.

     These macros especially come handy when you have a token stream generated by a separate lexer---each token can have some structure (instead of just a character) and you can take advantage of match.

Ropes
-----

Often you want to construct a string out of the results of other parsers. It can be costly to construct strings eagerly, for a string may be just an intermediate one to be a part of a larger string.  We provide a lightweight lazily string construction mechanism, called ropes.

A rope is either a character, a string or a pair of ropes.  It allows O(1) concatenation.  A rope becomes a string when finalized. The parser drivers such as peg-run-parser automatically finalizes ropes in the parser result.

 -- Function: $->rope parser ...
     The parsers must yield either a character, a string, a rope, or #f or ().  This procedure returns a parser that matches PARSER ..., then gather the result into a rope.  #f and () in the results are ignored.

 -- Function: $->string parser ...
     This is a common idiom of ($lift rope->string ($->rope parser ...)).

 -- Function: $->symbol parser ...
     Like $->string, but yields a symbol rather than a string.

 -- Function: rope->string rope
     Converts a rope to a string.

 -- Function: rope-finalize obj
     Converts any ropes in in OBJ into strings.

Choice, backtrack and assertion combinators
-------------------------------------------

 -- Function: $or p1 p2 ...
     Returns a choice parser.  Tries the given parser in order on input. If one succeeds, immediately yields its result. If one fails, and does not consume input, then tries the next one. If one fails with consuming input, immediately fails.

     If P1 P2 ... don't share the same prefix to match, you can let it fail as soon as one parser fails with consuming input.   If more than one parsers do match the same prefix, you want to wrap them with $try except the last one.

 -- Function: $try p
     Returns a parser that accepts the same input the parser P accepts, but when P fails the returned parser doesn't consume input.  Used with $or, you can explicitly implement a backtrack behavior.

 -- Function: $optional p :optional fallback
     Returns a parser that tries P on the input. If it succeeds, yielding its result.  If it fails, it still succeeds, yielding FALLBACK as the result.

     This is atomic; if P fails, it doesn't consume input.

 -- Function: $assert p
     Returns a parser that accepts the same input as P and returns its result on success, but never consumes the input. It can be used as a lookahead assertion.

 -- Function: $not p
     Returns a parser that succeeds when P fails, and that fails when P succeeds.  When P succeeds, it yields an ``unexpected'' error.  It never consumes input in either way. It can be used as a negative lookahead assertion.

 -- Function: $expect p msg-string
     Returns a parser that calls a parser P, and if it succeeds yields its result.  If P fails, fails with an error message that says expecting MSG-STRING. Useful to produce user-friendly error messages.

Sequencing combinators
----------------------

 -- Function: $seq p1 p2 ...
 -- Function: $seq0 p1 p2 ...
     Matches P1, P2, ... sequentially.  When all the parser succeeds, $seq returns the last result, while $SEQ0 returns the first result. Fails immediately when one of the parsers fails.

 -- Function: $between p1 p2 p3
     Matches P1, P2 and P3 sequentially, and returns the result of P2.

 -- Function: $bind p f
     The basic block of parser combinators; P argument is a parser, and F is a procedure that takes a Scheme value and returns a parser.

     Returns a parser that first applies P on the input, and if it succeeds, calls F with the result of P, and applies the returned parser on the subsequent input.

     This combinator, along with $return and $fail, composes a MonadFail interface as in Haskell.  Theoretically any combinators can be built on top of these three.  In practice, however, it is not always easy to build things directly on top of $bind, and more high-level forms such as $let, $let* and $lift are frequently used.

 -- Macro: $let (binding ...) body ...
 -- Macro: $let* (binding ...) body ...
     Monadic binding form.  Each BINDING can be one of the following forms:

     (var parser)
          Run the PARSER, and if it succeeds, bind its result to a variable VAR.  If it fails, the entire $let or $let* immdiately fails.

     (parser)
          The variable is omitted.  The PARSER is run, and if it succeeds, its result is discarded and the next binding or body is evaluated. If it fails, the entire $let or $let* immdiately fails.

     parser
          Same as above.  This form can only be used if PARSER is just a vairable reference.

     Once all the parsers in BINDING ... succeeds, BODY ... are evaluated in the environment where VAR in bindings are bound to the parser results.  The last expression of BODY must return a parser.

     Unlike let, the parsers in BINDING ... are always applied to the input sequentially.  The difference of $let and $let* is the scope.  With $let*, the variables bound in earlier BINDING can be used to consturct the PARSER later.

     This means $let can evaluate all the parsers beforehand, while $let* may need to construct parsers at the time of processing input.  Creating a parser involves closure allocations, so you want to use $let whenever possible.

     Note: $let* is similar to Haskell's do construct.  We chose the name $let and $let*, for it is easier to see it's a binding form, and also Scheme already uses do for loop construct.

 -- Function: $lift f p ...
 -- Function: $lift* f p ...
     Lifts a procedure F onto the parsers' world.

     In a pseudo type declaration, lift's type can be understood as follows:

          lift :: (a b ... -> z) (Parser a) (Parser b) ... -> (Parser z)

     That is, lift creates a parser such that it first applies parsers on the input, and if all of them succeeds, it calls F with the parsers' results as arguments, and the return value of F becomes the whole parser's result.

     In other words, the following equivalence holds:

          ($lift f p0 p1 ...)
           == ($let ([r0a p0] [r1 p1] ...) ($return (f r0 r1 ...)))

     It is sometimes simpler to use $lift instead of $let. For example, the following code creates a parser that matches input with P0 P1 ... sequentially, then yields the list of the parser results:

          ($lift list p0 p1 ...)

     Note that after all the parsers succeeds, the whole parser is destined to succeed---the procedure F can't make the parser fail.  If you need to fail after all the parsers succeeds, use $let or $let.

 -- Function: $fold-parsers proc seed ps
     PS is a list of parsers.  Apply those parsers sequentially on the input, passing around the seed value.  That is, if we let v0, V1 ... VN be the result of each parsers in PS, it returns (proc vn (... (proc v2 (proc v1 seed))...)).

     If any of the parser in PS fails, $fold-parsers fails at that point.

     Conceptually, it can be written as follows:

          (define ($fold-parsers proc seed ps)
            (if (null? ps)
              ($return seed)
              ($let ([v (car ps)])
                ($fold-parsers proc (proc v seed) (cdr ps)))))

     But we use more efficient implementation.

 -- Function: $fold-parsers-right proc seed ps
     Similar to $fold-parsers, but the folding by PROC right to left.  That is, if we let v0, V1 ... VN be the result of each parsers in PS, it returns (proc v1 (proc v2 (... (proc vn seed)...))).

     If any of the parser in PS fails, $fold-parsers-right fails at that point.

Repetition combinators
----------------------

 -- Function: $many p :optional min max
 -- Function: $many_ p :optional min max
     Without optional arguments, returns a parser that accepts zero or more repetition of P. On success, $many yields a list of mached results, while $MANY_ doesn't keep the results (and faster).

     Optinoal MIN and MAX must be nonnegative integers and limit the number of occurrences of P. The numbers are inclusive. For example, ($many ($. #\a) 3) accepts three or more #\a's, and ($many ($. #\a) 2 4) accepts aa, aaa and aaaa.

     Note that $many may fail if the input partially matches p.

          (peg-parse-string ($many ($seq ($. #\a) ($. #\b))) "ababcd")
            => (#\b #\b)

          (peg-parse-string ($many ($seq ($. #\a) ($. #\b))) "ababac")
            => *** PARSE-ERROR: expecting #\b at 5, but got #\c

     If you want to stop $many at the first two occurrences in the latter case, use $try:

          (peg-parse-string ($many ($try ($seq ($. #\a) ($. #\b)))) "ababac")
            => (#\b #\b)

 -- Function: $many1 p :optional max
 -- Function: $many1_ p :optional max
     Returns a parser that accepts one or more occurences of P. On success, $many1 yields a list of results of P, while $MANY_ discards the results of P and faster. If MAX is given, it specifies the maximum number of matches.

     Same as ($many p 1 max) and ($many_ p 1 max). Provided as a common pattern.

 -- Function: $repeat p n
 -- Function: $repeat_ p n
     Returns a parser that accepts exaclty N occurences of P. On success, $repeat yields a list of results of P, while $REPEAT_ discards the results of P and faster.

     Same as ($many p n n) and ($many_ p n n). Provided as a common pattern.

 -- Function: $many-till p pe :optional min max
 -- Function: $many-till_ p pe :optional min max
     Returns a parser that accepts repetition of P, until it sees input that accepts PE. On success, $many-till yields a list of results of P, while $MANY-TILL_ discards the results of P and faster.

          (define comment ($seq ($.";") ($many-till ($any) ($."\n"))))

 -- Function: $sep-by p psep :optional min max
 -- Function: $end-by p psep :optional min max
 -- Function: $sep-end-by p psep :optional min max
     These combinators match repetition of P separated by PSEP, such as comma-separated values. Returns the list of results of P. Optional MIN and MAX are integers that limits the number of repetitions.

     These three differ only on treatment of the last separator; $sep-by accepts strictly infix syntax, that is, the input must not end with the separator; while $end-by accepts strictly suffix syntax, that is, the input must end with the separator; $sep-end-by makes the last separator optional.

 -- Function: $chain-left p op
 -- Function: $chain-right p op
     Returns a parser that parsers left-assosiative and right-associative operators, respectively.

     The term of expression is parsed by a parser P, and the operator is parsed by OP.

Miscellaneous combinators
-------------------------

 -- Macro: $parameterize ((param expr) ...) parser ...
     Returns a parser that runs PARSER ..., while altering the parameter values of PARAM ... with the reuslt of EXPR ..., like parameterize. The PARSER ... are run as if in $seq, so only the value of them is returned on success.

     You can't use ordinary parameterize, since such parameterization takes effect on parser construction time, and not when the parser parsing the input.

 -- Function: $debug name p
     Parses the same input as P, but reports when it is parsing the input, and the result, just like debug-print.

     You can't use debug-print directly, for it will take effect on the parser construction time, not when the input is parsed.

 -- Macro: $lazy p
     Returns a parser that works the same as P, but delays evaluation of P until needed.  It is useful when you define mutually recursive parsers.

Performance
-----------

rfc.822 - RFC822 message parsing
================================

 -- 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 RFC5322. 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''. 電子メールを交換する際に使用されるテキストのフォーマットである、``インターネット・メッセージ・フォーマット''をパーズ/生成する手続きを定義しています。最新の仕様は、RFC5322にあります。このフォーマットは最初 RFC 822 で定義されたため、未だに``RFC822形式''と呼ばれています。それがこのモジュール名の由来です。以下では、このフォーマットを``RFC822形式''と呼びます。

Parsing message headers
-----------------------

メッセージヘッダのパーズ
------------

 -- Function: rfc822-read-headers iport :key strict? reader
     Reads RFC822 format message from an input port IPORT, until it reaches the end of the message header. The header fields are broken into a list of the following format: 入力ポート IPORT から、メッセージ・ヘッダの終わりに達するまで、 RFC822 形式のメッセージを読み込みます。ヘッダ・フィールドは以下のフォーマットのリストに展開、分離されます。

          ((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 unfolded. The order of fields are preserved. NAME ... はフィールド名で、BODY ... は対応するフィールドのボディ、ともに文字列です。フィールド名は小文字に変換されます。フィールドのボディは、行折り返しが取り除かれる以外は変更されません。フィールドの順番は保存されます。

     By default, the parser works permissively.  If EOF is encountered during parsing header, it is taken as the end of the message. And if a line that doesn't consist neither continuing (folded) line nor start a new header field, it is simply ignored. You can change this behavior by giving true value to the keyword argument STRICT?; then the parser raises an error for such a malformed header.

     The keyword argument READER takes a procedure that reads a line from IPORT.  Its default is read-line, which should be enough for most cases. デフォルトでは、パーザの動作は寛容です。ヘッダをパーズ中に EOF に出会うとそれをメッセージの終端とみなします。継続(折り返し)行でもなく、新しいヘッダフィールドの始端でもない行は無視します。このふるまいはキーワード引数 STRICT? に真の値を渡すことで変更することができます。真を渡すと、このような不正な形式のヘッダに対してエラーを発生させるようになります。

     キーワード引数 READER は IPORT から一行読み込む手続きをとります。デフォルトは read-line です。ほとんどの場合これで十分のはずです。

 -- Function: rfc822-header->list iport :key strict? reader
     This is an old name of rfc822-read-headers.  This is kept for the backward compatibility.  The new code should use rfc822-read-headers instead. これはrfc822-read-headersの古い名前です。互換性のために残してありますが、新しいコードは rfc822-read-headersを使って下さい。

 -- Function: rfc822-header-ref header-list field-name :optional default
     An utility procedure to get a specific field from the parsed header list, which is returned by rfc822-read-headers.

     FIELD-NAME specifies the field name in a lowercase string. If the field with given name is in HEADER-LIST, the procedure returns its value in a string.  Otherwise, if DEFAULT is given, it is returned, and if not, #f is returned.

     This procedure can actually be used not only for the result of rfc822-read-headers, but for retrieving a value keyed by strings in a list-of-list structure: ((name value option ...) ...). For example, the return value of parse-cookie-string can be passed to rfc-822-header-ref (see HTTP cookie handling, for parse-cookie-string). rfc822-read-headers が返すパーズ済みのヘッダリストから特定のフィールドを得るためのユーティリティ手続きです。

     FIELD-NAME は小文字の文字列でフィールド名を指定します。与えられた名前をもつフィールドが HEADER-LIST 中にあれば、その値を文字列で返します。そうでない場合、もし DEFAULT が与えられていればそれが返り、与えられていなければ #f が返されます。

     この手続きはrfc822-read-headersの結果だけでなく、文字列をキーにしたリストのリスト ((name value option ...) ...) という構造からvalue部分を取り出すのに使えます。例えばparse-cookie-stringの結果をrfc-822-header-refに渡せます。 (parse-cookie-stringについてはsee HTTP cookie handling参照。)

          (rfc822-header-ref
            '(("from" "foo@example.com") ("to" "bar@example.com"))
            "from")
           => "foo@example.com"

          ;; If no entry matches, #f is returned by default
          (rfc822-header-ref
            '(("from" "foo@example.com") ("to" "bar@example.com"))
            "reply-to")
           => #f

          ;; You can give the default value for no-match case
          (rfc822-header-ref
            '(("from" "foo@example.com") ("to" "bar@example.com"))
            "reply-to" 'none)
           => none

          ;; By giving the default value, you can distinguish
          ;; the no-match case and there's actually an entry with value #f.
          (rfc822-header-ref
            '(("from" "foo@example.com") ("reply-to" #f))
            "reply-to" 'none)
           => #f

Basic field parsers
-------------------

基本的なフィールドパーザ
------------

Several procedures are provided to parse "structured" header fields of RFC2822 messages.  These procedures deal with the body of a header field, i.e. if the header field is "To: Wandering Schemer <schemer@example.com>", they parse "Wandering Schemer <schemer@example.com>".

Most of procedures take an input port.  Usually you first parse the entire header fields by rfc822-read-headers, obtain the body of the header by rfc822-header-ref, then open an input string port for the body and use those procedures to parse them.

The reason for this complexity is because you need different tokenization schemes depending on the type of the field. Rfc2822 also allows comments to appear between tokens for most cases, so a simple-minded regexp won't do the job, since rfc2822 comment can be nested and can't be represented by regular grammar. So, this layer of procedures are designed flexible enough to handle various syntaxes.  For the standard header types, high-level parsers are also provided; see "specific field parsers" below. RFC2822メッセージの「構造化」されたヘッダフィールドをパーズするために、いくつかの手続きが提供されています。これらの手続きはヘッダフィールドの本体部を処理します。たとえば、ヘッダフィールドが、 "To: Wandering Schemer <schemer@example.com>" であれば、これらの手続きは "Wandering Schemer <schemer@example.com>" をパーズします。

ほとんどの手続きは入力ポートを引数にとります。通常は最初に、ヘッダフィールド全部を rfc822-read-headers でパーズし、ヘッダの本体を rfc822-header-ref で取得してから、その本体用に入力文字列ポートをオープンして、それをこれらの手続きを用いてパーズします。

このように複雑になっているのは、フィールドのタイプによって別々のトークン化スキームが必要になるからです。RFC2822 では多くの場合トークン間にコメントがあらわれことを許しているので、初心な正規表現ではうまくいきません。RFC2822 のコメントはネスト可能で、正規表現では表現しきれないからです。そういうわけで、このレイヤの手続きは、いろいろな構文に対応できるよう十分な柔軟性があるように設計されています。標準的なタイプのヘッダについては高水準のパーザも提供されています。後述の「特定フィールド用パーザ」を参照してください。

 -- Function: rfc822-next-token iport :optional tokenizer-specs
     A basic tokenizer.  First it skips whitespaces and/or comments (CFWS) from IPORT, if any.  Then reads one token according to TOKENIZER-SPECS.  If IPORT reaches EOF before any token is read, EOF is returned.

     TOKENIZER-SPECS is a list of tokenizer spec, which is either a char-set or a cons of a char-set and a procedure.

     After skipping CFWS, the procedure peeks a character at the head of IPORT, and checks it against the char-sets in TOKENIZER-SPECS one by one. If a char-set that contains the character belongs to is found, then a token is retrieved as follows: If the tokenizer spec is just a char-set, a sequence of characters that belong to the char-set consists a token. If it is a cons, the procedure is called with IPORT to read a token.

     If the head character doesn't match any char-sets, the character is taken from IPORT and returned.

     The default TOKENIZER-SPECS is as follows: 基本的なトークナイザです。まず、もしあれば、白空白および/またはコメント (CFWS) を IPORT から読み飛ばします。それから、 TOKENIZER-SPECS にしたがってトークンをひとつ読み込みます。トークンを読み込む前に、IPORT が EOF に到達したら、EOF が返されます。

     TOKENIZER-SPECS はトークナイザ仕様のリストです。トークナイザ仕様は、文字集合または文字集合と手続きのペアのどちらかです。

     CFWS を読み飛ばしたあと、この手続きは IPORT の先頭の一文字を見て、TOKENIZER-SPECS のひとつひとつに対してチェックします。その文字が含まれている文字集合がみつかれば、トークンを次のようにして引き出します。トークナイザ仕様が文字集合だけの場合、その文字集合に属している文字の並びがトークンを構成します。トークナイザ仕様が文字集合と手続きのペアだったら、その手続きを IPORT とともに呼びだし、トークンを読み込みます。

     もし、先頭の文字がどの文字集合ともマッチしなければ、その文字が IPORT から取り出され、それが返されます。

     デフォルトの TOKENIZER-SPECS は以下のようになっています。

          (list (cons #["] rfc822-quoted-string)
                (cons *rfc822-atext-chars* rfc822-dot-atom))

     Where rfc822-quoted-string and rfc822-dot-atom are tokenizer procedures described below, and *rfc822-atext-chars* is bound to a char-set of atext specified in rfc2822. This means rfc822-next-token retrieves a token either quoted-string or dot-atom specified in rfc2822 by default.

     Using TOKENIZER-SPECS, you can customize how the header field is parsed.  For example, if you want to retrieve a token that is either (1) a word constructed by alphabetic characters, or (2) a quoted string, then you can call rfc822-next-token by this: ここで rfc822-quoted-string および rfc822-dot-atom は後述するトークナイザ手続きで、*rfc822-atext-chars* は RFC2822 で規定された atext の文字集合に束縛されています。つまり、rfc822-next-token はデフォルトでは RFC2822 で規定された quoted-string あるいは dot-atom のトークンを引き出します。

     TOKENIZER-SPECS をつかって、ヘッダフィールドのパーズ方法をカスタマイズすることができます。たとえば、(1) 英字で構成された単語、または (2) クウォート文字列、のトークンを取り出したいときには、 rfc822-next-token をこんなふうに呼べます。

          (rfc822-next-token iport
             `(#[[:alpha:]] (#["] . ,rfc822-quoted-string)))

 -- Function: rfc822-field->tokens field :optional tokenizer-specs
     A convenience procedure.  Creates an input string port for a field body FIELD, and calls rfc822-next-token repeatedly on it until it consumes all input, then returns a list of tokens.   TOKENIZER-SPECS is passed to rfc822-next-token. これは便利関数です。フィールド本体 FIELD に対応する入力文字列ポートを生成し、それに対して、rfc822-next-token を全入力を消費するまで、繰り返しよび、トークンのリストを返します。TOKENIZER-SPECS は、 rfc822-next-token に渡されます。

 -- Function: rfc822-skip-cfws iport
     A utility procedure that consumes any comments and/or whitespace characters from IPORT, and returns the head character that is neither a whitespace nor a comment.  The returned character remains in IPORT. IPORT から、すべてのコメントおよび/または白空白文字を消費し、白空白でもコメントでもない、先頭の文字を返します。返された文字は、 IPORTに残ります。

 -- Constant: *rfc822-atext-chars*
     Bound to a char-set that is a valid constituent of atom. atom を構成する有効な文字集合に束縛されています。

 -- Constant: *rfc822-standard-tokenizers*
     Bound to the default TOKENIZER-SPECS. デフォルトの TOKENIZER-SPECS に束縛されています。

 -- Function: rfc822-atom iport
 -- Function: rfc822-dot-atom iport
 -- Function: rfc822-quoted-string iport
     Tokenizers for atom, dot-atom and quoted-string, respectively.  The double-quotes and escaping backslashes within quoted-string are removed by rfc822-quoted-string. それぞれ、atom、dot-atom および quoted-string に対応するトークナイザです。quoted-string 中の二重引用符およびエスケープのためのバックスラッシュは rfc822-quoted-string によって取り除かれます。

Specific field parsers
----------------------

特定フィールド用パーザ
-----------

 -- Function: rfc822-parse-date string
     Takes RFC-822 type date string, and returns eight values: RFC822 形式の日付文字列を取り、8つの値を返します。

          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. Month is an integer between 1 and 12, inclusive. If the string is not parsable, all the elements are #f. timezone は UT(グリニッジ標準時)からの分単位のオフセットです。 day-of-week は日曜日から数えた曜日で、情報が不足している場合は #f です。 monthは1から12までの整数です。文字列がパーズ不可能ならば、全ての要素が #f になります。

 -- Function: rfc822-date->date string
     Parses RFC822 type date format and returns SRFI-19 <date> object (see SRFI-19 Date).  If STRING can't be parsed, returns #f instead.

     To construct rfc822 date string from SRFI-19 date, you can use date->rfc822-date below. RFC822形式の日付フォーマットをパーズし、SRFI-19 の <date> オブジェクト (SRFI-19 Date 参照) を返します。STRING がパーズできないときはかわりに #f を返します。

     SRFI-19の日付からRFC822形式の日付文字列を作成するには、後で述べるdate->rfc822-dateが使えます。

Message constructors
--------------------

メッセージの構築
--------

 -- Function: rfc822-write-headers headers :key output continue check
     This is a sort of inverse function of rfc822-read-headers. It receives a list of header data, in which each header data consists of (<name> <body>), and writes them out in RFC822 header field format to the output port specified by the OUTPUT keyword argument.  The default output is the current output port.

     By default, the procedure assumes HEADERS contains all the header fields, and adds an empty line in the end of output to indicate the end of the header.  You can pass a true value to the CONTINUE keyword argument to prevent this, enabling more headers can be added later.

     I said ``a sort of'' above.  That's because this function doesn't (and can't) do the exact inverse. Specifically, the caller is responsible for line folding and make sure each header line doesn't exceed the ``hard limit'' defined by RFC2822 (998 octets).  This procedure cannot do the line folding on behalf of the caller, because the places where line folding is possible depend on the semantics of each header field.

     It is also the caller's responsibility to make sure header field bodies don't have any characters except non-NUL US-ASCII characters.  If you want to include characters outside of that range, you should convert them in the way allowed by the protocol, e.g. MIME.  The rfc.mime module (see MIME message handling) provides a convenience procedure mime-encode-text for such purpose. Again, this procedure cannot do the encoding automatically, since the way the field should be encoded depends on header fields.

     What this procedure can do is to check and report such violations. By default, it runs several checks and signals an error if it finds any violations of RFC2822.  You can control this checking behavior by the CHECK keyword argument.  It can take one of the following values:

     :error
          Default.  Signals an error if a violation is found.

     #f, :ignore
          Doesn't perform any check.  Trust the caller.

     PROCEDURE
          When rfc822-write-headers finds a violation, the procedure is called with three arguments; the header field name, the header field body, and the type of violation explained below. The procedure may correct the problem and return two values, the corrected header field name and body.  The returned values are checked again.  If the procedure returns the header field name and body unchanged, an error is signaled in the same way as :error is specified.

     The third argument passed to the procedure given to the CHECK argument is one of the following symbols.  New symbols may be added in future versions for more checks.

     incomplete-string
          Incomplete string is passed.

     bad-character
          Header field contains characters outside of US-ASCII or NUL.

     line-too-long
          Line length exceeds 998 octet limit.

     stray-crlf
          The string contains CR and/or LF character that doesn't consist of proper line folding.

 -- Function: date->rfc822-date date
     Takes SRFI-19 <date> object (see SRFI-19 Date) and returns a string of its rfc822 date representation. This is a reverse operation of rfc822-date->date. SRFI-19の<date>オブジェクト(SRFI-19 Date参照) を取り、そのrfc822日付形式表現の文字列を返します。 rfc822-date->dateの逆関数です。

rfc.base64 - Base64 encoding/decoding
=====================================

 -- Module: rfc.base64
     This module defines a few functions to encode/decode Base64 format, defined in RFC 2045 (https://www.ietf.org/rfc/rfc2045.txt), section 6.3 and RFC 4648 (https://www.ietf.org/rfc/rfc4648.txt). このモジュールでは、RFC 2045 (https://www.ietf.org/rfc/rfc2045.txt) の6.3節およびRFC 4648 (https://www.ietf.org/rfc/rfc4648.txt) で定義されている Base64 フォーマットへエンコード/デコードするいくつかの手続きを定義しています。

 -- Function: base64-encode :key line-width url-safe
     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.

     Newline characters can be inserted to keep the maximum line width to the value given to the LINE-WIDTH keyword argument.  The default value of LINE-WIDTH is 76, as specified in RFC2045.  You can give #f or zero to LINE-WIDTH to suppress line splitting. 現在の入力ポートからバイト・ストリームを読み込み、それを Base64 フォーマットにエンコードし、現在の出力ポートに文字ストリームとして書き出します。現在の入力ポートから EOF を読み込むと変換を終了します。

     一行あたりの文字数がLINE-WIDTHに与えられた文字数を越えないように、改行文字が適切に出力に挿入されます。LINE-WIDTHのデフォルト値は RFC2045に従い76となっています。LINE-WIDTHに#fまたは0 を与えることで改行を抑制することができます。

     If a true value is given to URL-SAFE, the input bytes will be encoded with an alternative encoding table, which substitutes + instead of - and / instead of _. The result will contain filename and url safe characters only.  Default value of URL-SAFE is false. URL-SAFEに真の値を与えると、標準の Base64 と異なったエンコーディングテーブルを使って入力をエンコードします。このエンコーディングでは、+の代わりに -が、/の代わりに_が使われます。このエンコーディングはファイル名やURLの一部として使うのに適しています。URL-SAFEのデフォルト値は偽です。

 -- Function: base64-encode-string string :key line-width url-safe
     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. STRING の内容を Base64 でエンコードされたフォーマットに変換します。入力となる文字列は、完全文字列でも不完全文字列でも良いです。常にバイト・シーケンスとして扱われます。

 -- Function: base64-decode :key url-safe
     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. 現在の入力ポートから文字ストリームを読み込み、それを Base64 フォーマットとしてデコードし、現在の出力ポートにバイトストリームとして書き出します。変換は EOF か、終端文字 (=) を読み込むと終了します。 Base64 でエンコードされた文字として適当でない文字は沈黙のまま無視されます。

 -- Function: base64-decode-string string :key url-safe
     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. Base64 でエンコードされた文字列 STRING をデコードして文字列を返します。変換は STRING の終わりか、終端文字 (=) で終了します。 Base64 でエンコードされた文字として適当でない文字は沈黙のまま無視されます。

rfc.cookie - HTTP cookie handling
=================================

 -- Module: rfc.cookie
     Defines a set of functions to parse and construct a ``cookie'' information defined in RFC 6265. RFC 6265で定義されている「クッキー」情報をパースしたり構築したりするための手続きを定義しています。

 -- 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 environment variable HTTP_COOKIE.

     If the cookie version is known, via ``Cookie2'' request header, the integer version must be passed to VERSION.  Otherwise, parse-cookie-string figures out the version from STRING.

     The result has the following format. リクエスト・ヘッダの Cookie の値のクッキー文字列 STRING をパースします。通常、CGI プログラムでは、同じ情報は環境変数 HTTP_COOKIE を通して利用できます。

     リクエスト・ヘッダ Cookie2 を通してクッキーのバージョンが分かる場合は、VERSION へ整数のバージョンとして渡されなければなりません。そうでなければ、parse-cookie-string は STRING からバージョンを取り出します。

     結果は以下のフォーマットを持ちます。

          ((<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. <NAME> は属性名で、<VALUE> は対応する値です。属性が値を持たない場合、<VALUE> は #f になります。 (属性が NULL 値を持つ場合は、"" となることに注意。) 属性がパスやドメイン、ポート番号のオプションを持つ場合は、キーワード-値のペアの形式で与えられます。

     Note: To retrieve the value of a specific cookie conveniently, you can use rfc822-header-ref (see RFC822 message parsing). 註: 特定のクッキーの値を簡単に取り出すには rfc822-header-refが使えます (RFC822 message parsing参照)。

 -- 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. 与えられたクッキーの仕様のリストから、Set-cookie2 か Set-cookie ヘッダに適切なクッキー文字列を作ります。

     オプションの VERSION 引数は、クッキー・プロトコルのバージョンを指定するものです。0 は古い Netscape スタイルのフォーマットで、1 は RFC2965 スタイルのフォーマットです。省略された場合、1 が指定されたものとされます。

     クッキーの仕様は以下のフォーマットを持ちます。

          (<name> <value> [:comment <comment>] [:comment-url <url>]
                          [:discard <bool>] [:domain <domain>]
                          [:max-age <age>] [:path <path>]
                          [:port <port-list>] [:secure <bool>] [:http-only <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.

     <name>
          文字列。クッキーの名前。

     <value>
          クッキーの値。文字列か、値が必要なければ #f 。

     <comment> <url> <domain> <path> <port-list>
          文字列。

     <bool>
          真偽値。

     <age> <version>
          整数。

     <date>
          整数(エポックからの秒数)か、Netscape のクッキー仕様に従うフォーマットされた日付文字列。

     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 RFC6265 for further details.

     Some examples: 属性値は適切にクォートされます。指定された属性が VERSION に不適切な場合は無視されます。古いスタイルと新しいスタイルの両方のクッキー文字列を作るために同じ仕様を渡すことができます。

     戻り値はそれぞれのクッキー文字列のリストです。(Set-cookie を使う) 古いスタイルのプロトコルでは、それぞれを独立したヘッダとして送らなければなりません。(Set-cookie2 ヘッダを使う)新しいプロトコルでは、それらをカンマで繋ぎ、一度に送ることができます。詳細は RFC6265 を見て下さい。

     いくつかの例を示します。

          (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")

rfc.ftp - FTP client
====================

 -- Module: rfc.ftp
     This module provides a set of convenient functions to access ftp servers. このモジュールはFTPサーバーにアクセスするための便利関数群を提供します。

 -- Class: <ftp-connection>
     An object to keep FTP connection to a server.  It has the following public slots. ひとつのサーバーへのFTPコネクションを保持するオブジェクト。以下の公開スロットがあります。

      -- Instance Variable of <ftp-connection>: transfer-type
          FTP transfer type.  Must be one of the following symbols: ascii, binary (default), and image. FTPの転送タイプ。以下のシンボルのどれかひとつでなければなりません。 ascii、binary (デフォルト)、およびimage。

      -- Instance Variable of <ftp-connection>: passive
          True if the client uses passive connection.c パッシブコネクションを使うとき真。

      -- Instance Variable of <ftp-connection>: log-drain
          This slot must hold a <log-drain> instance (see User-level logging) or #f.  If it has a <log-drain> instance, ftp communication logs are put to it. このスロットは<log-drain>のインスタンス(User-level logging参照) を保持しているかあるいは#fでなければなりません。<log-drain> のインスタンスを保持している場合、FTP通信のログがそこに記録されます。

 -- Condition Type: <ftp-error>
     This type of exception is thrown when the ftp server returns an error code. Inherits <error>.  The message field contains the server reply, including the status code. このタイプの例外はFTPサーバーがエラーコードを返したときに投げられます。 <error>を継承しています。メッセージフィールドにはステータスコードを含むサーバーからの返答が含まれます。

 -- Function: call-with-ftp-connection host proc :key passive port username password account log-drain
     A high-level convenience routine to open an ftp connection to an ftp server and calls the given procedure. 高水準の便利関数で、ひとつのFTPサーバーへのFTPコネクションをオープンし、与えられた手続きを呼びます。

     The server is specified by HOST.  Optionally, you can add user name and/or port number by the form USER@SERVERNAME:PORT. If present, user and port portion in HOST supersedes the keyword arguments. 接続するサーバーはHOSTで指定します。オプションでユーザー名、ポート番号をUSER@SERVERNAME:PORTという形式で指定できます。もしあれば、HOSTの部分をキーワード引数にすることもできます。

     If ftp connection to HOST is established successfully, PROC is called with one argument, which is an instance of <ftp-connection>.  When PROC returns, the connection is closed and the return value(s) of PROC is/are returned from call-with-ftp-connection. When an exception is thrown, the ftp connection is closed before the exception escapes from call-with-ftp-connection. HOSTへのFTPコネクション確立が成功したら、PROCが引数を1つとって呼ばれます。この引数は<ftp-connection>のインスタンスです。 PROCから返ったときにこのコネクションはクローズされ、PROCの返り値がcall-with-ftp-connectionから返されます。例外がなげられたら、その例外がcall-with-ftp-connectionから外へでる前にFTPコネクションはクローズされます。

     When a true value is given to the keyword argument PASSIVE, created ftp connection will use passive mode to send/receive data.  The default is the active mode. キーワード引数PASSIVEに真値を与えると、FTPコネクションはパッシブモードになります。デフォルトではアクティブモードです。

     The keyword argument PORT, USERNAME, and PASSWORD specify the port number, username, and password, respectively. When omitted, the port number defaults to 21, USERNAME to "anonymous", and PASSWORD to "anonymous@". Note that the port number and/or username are ignored when those information is given in the HOST argument. キーワード引数PORT、USERNAMEおよびPASSWORDはそれぞれ、ポート番号、ユーザー名、パスワードを指定するのに使います。省略された場合のデフォルトは、ポート番号が21,USERNAMEが "anonymous"、PASSWORDが"anonymous@"にセットされます。ポート番号とユーザー名はHOST引数で指定されたものが優先されます。

     If the keyword argument ACCOUNT is given, its value is passed to ftp ACCT command when requested by the server at login time.  The default value is a null string "". キーワード引数ACCOUNTが与えられた場合には、その値が、ログイン時にサーバーからの要求でFTPのACCTコマンドに渡されます。デフォルトでは空文字列""です。

     The keyword argument LOG-DRAIN is set to the created ftp connection's log-drain slot. キーワード引数LOG-DRAINが生成したFTPコネクションの log-drainスロットに設定されます。

 -- Function: ftp-transfer-type conn
     Returns the transfer type of the ftp connection conn. Can be used with setter, e.g. (set! (ftp-transfer-type conn) 'ascii). 指定したFTPコネクションconnの転送タイプを返します。セッターを適用することもできます。たとえば、(set! (ftp-transfer-type conn) 'ascii) とします。

 -- Function: ftp-passive? conn
     Returns true iff ftp connection uses passive data retrieval. 指定したFTPコネクションがパッシブモードである場合でその場合に限り真を返します。

 -- Function: ftp-login host :key passive port username password account log-drain
     Connects to the ftp server specified by HOST, authenticate the user, and returns a newly created <ftp-connection> instance. This procedure is called implicitly when you use call-with-ftp-connection.  The semantics of the HOST argument and the keyword arguments are the same as call-with-ftp-connection. HOSTで指定されたFTPサーバーに接続し、ユーザー認証をすませ、新しく生成した<ftp-connection>のインスタンスを返します。この手続きはcall-with-ftp-connectionを使ったときに暗黙の内に呼ばれます。 HOST引数およびキーワード引数のセマンティクスは call-with-ftp-connectionと同じです。

 -- Function: ftp-quit conn
     Sends ftp QUIT command to the connection CONN and shutdown the connection. This procedure is called implicitly when you use call-with-ftp-connection. FTPのQUITコマンドをコネクションCONNに送り、コネクションをシャットダウンします。この手続きはcall-with-ftp-connectionを使ったときに暗黙の内に呼ばれます。

     Once a connection is shut down, you cannot communicate through this connection. いったんシャットダウンしたコネクションをつかっての通信はできません。

 -- Function: ftp-chdir conn dirname
     Changes the remote directory to DIRNAME. リモートディレクトリをDIRNAMEに変更します。

 -- Function: ftp-remove conn path
     Removes the remote file named by PATH. PATHで指定したリモートファイルを削除します。

 -- Function: ftp-help conn :optional option ...
     Sends ftp HELP commands.  OPTIONs must be strings, and will be passed to the HELP command arguments. FTPコマンドHELPを送ります。OPTIONは文字列でなければなりません。これはHELPコマンドの引数にわたされます。

 -- Function: ftp-mkdir conn dirname
     Creates a directory DIRNAME.  Returns the created directory name. ディレクトリDIRNAMEを作成します。作成されたディレクトリ名が返ります。

 -- Function: ftp-current-directory conn
     Returns the current remote directory. 現在のリモートディレクトリを返します。

 -- Function: ftp-site conn arg
     Sends ftp SITE command with the argument ARG. The SITE command's semantics depends on the server. Returns the server reply. FTPコマンドSITEを引数ARGとともに送ります。SITEコマンドのセマンティクスはサーバーに依存します。返り値はサーバーのリプライです。

 -- Function: ftp-rmdir conn dirname
     Removes remote directory specified by DIRNAME. Returns the server reply. DIRNAMEで指定したリモートディレクトリを削除します。返り値はサーバーのリプライです。

 -- Function: ftp-stat conn :optional pathname
     Sends ftp STAT command to the server. RFC959 defines several different semantics of this command. See RFC959 for the details. Returns the server reply. FTPコマンドSTATをサーバーに送信します。 RFC959ではこのコマンドのセマンティクスをいくつか定義しています。詳細は RFC959を見てください。返り値はサーバーのリプライです。

 -- Function: ftp-system conn
     Queries the server's operating system by ftp SYST command. Returns the server reply without status code. FTPコマンドSYSTをつかってサーバーのオペレーティングシステムを問合せます。返り値はステータスコードを含まないサーバーのリプライです。

          (call-with-ftp-connection "localhost" ftp-system)
            => "UNIX Type: L8"

 -- Function: ftp-size conn path
     Queries the size of the remote file specified by PATH. Returns the integer value.

     Note: The size may differ whether the connection is in ascii mode or binary mode; furthermore, some ftp server may returns the value only if the connection is in binary mode.  Make sure you have desired transfer type in the connection. PATHで指定したリモートファイルのサイズを問合せます。整数値が返ります。

     註：コネクションがasciiモードかbinaryモードかによって、返されるサイズは異なるかもしれません。ftpサーバによっては、binaryモードでしか sizeリクエストに答えないものもあります。この関数を呼ぶ際には、コネクションに望みのtransfer typeがセットされているようにしてください。

 -- Function: ftp-mdtm conn path
     Queries the modification time of the remote file specified by PATH. This function returns the server's reply as is, including the status code.  Use ftp-mtime below to obtain a parsed result. PATHで指定したリモートファイルの更新時刻を問合せます。この関数はサーバーからのリプライをステータスコードも含めそのまま返します。解析済みの結果が欲しいときは後述のftp-mtimeを使ってください。

 -- Function: ftp-mtime conn path :optional local-time?
     Queries the modification time of the remote file specified by PATH, and returns the result in a <date> object (see Time data types and procedures). If a true value is given to local-time?, the returned date is in local time.  Otherwise, the returned date is in UTC. PATHで指定したリモートファイルの更新日時を問合せます。結果は <date>オブジェクト(Time data types and procedures参照)で返ります。local-time?が真値に設定されている場合、日付はローカル時刻で返ります。そうでない場合は日付はUTCです。

 -- Function: ftp-noop conn
     Sends ftp NOOP command and returns the server's reply. FTPコマンドNOOPを送り、サーバーからのリプライを返します。

 -- Function: ftp-list conn :optional path
     Returns the information about the files within the remote file or directory specified by PATH, or the current remote directory, much like ls(1) format.  Returns a list of strings, where each string is for each line of the server's reply.  The exact format depends on the server. PATHで指定されたリモートディレクトリあるいはリモートファイル内のファイルに関する情報を返します。PATH指定がない場合は現在のリモートディレクトリで、結果のフォーマットはls(1)のフォーマットと非常によく似ています。文字列のリストが返り、それぞれの文字列はサーバーのリプライの行に対応します。正確なフォーマットについてはサーバーに依存します。

 -- Function: ftp-name-list conn :optional path
 -- Function: ftp-ls conn :optional path
     Return the list of names in the specified PATH, or the current remote directory, without any other information.  ftp-ls is just an alias of ftp-name-list for the convenience. PATHで指定したパスもしくは現在のリモートディレクトリにあるファイル名リストを返します。ただし、他の情報は含みません。ftp-lsは ftp-name-listの別名です。便利なので定義してあります。

     Note that the server may return an error if there's no files in the remote directory. リモートディレクトリにファイルが含まれていないときにはサーバーはエラーを返すことがあることに注意してください。

 -- Function: ftp-get conn path :key sink flusher
     Retrieves a remote file PATH.  The retrieved data is sent to an output port given to SINK.  Once all the data is retrieved, a procedure given to FLUSHER is called with the port SINK as an argument, and its return value(s) is/are returned from ftp-get. リモートファイルPATHを検索します。検索データはSINKで与えられた出力ポートに送られます。すべてのデータが検索されたあと、 FLUSHERで与えられた手続きをポートSINKを引数として呼びます。返り値はftp-getから返されたものです。

     The default values of SINK and FLUSHER are a newly created string port and get-output-string, respectively. That is, ftp-get returns the retrieved data as a string by default. You don't want this behavior if the retrieved file is huge. SINKおよびFLUSHERのデフォルト値はそれぞれ、新しく作成された文字列ポートとget-output-stringです。すなわち、ftp-get はデフォルトでは検索データを文字列として返します。巨大なファイルの場合このデフォルトの挙動ではありがたくありません。

 -- Function: ftp-put conn from-file :optional to-file
     Sends the local file specified by FROM-FILE to the remote server as the name specified by TO-FILE.  If TO-FILE is omitted, the basename of FROM-FILE is used. Returns the server response. FROM-FILEで指定したローカルファイルをTO-FILEで指定した名前でリモートサーバーに送信します。TO-FILEが省略された場合にはベース名としてFROM-FILEが使われます。返り値はサーバーのレスポンスです。

 -- Function: ftp-put-unique conn from-file
     Sends the local file specified by FROM-FILE to the remote server.  The remote side filename is guaranteed to be unique.  Returns two values---the final server response, and the remote file name.  The second value can be #f if the remote host doesn't support RFC1123 (which must be rare). FROM-FILEで指定したローカルファイルをリモートサーバーへ送信します。リモート側のファイル名重複しないことを保証します。返り値は2つで、最終的なリモートサーバーからのレスポンスとリモートファイル名です。2つめの値は、リモートサーバーがRFC1123をサポートしていない(ほとんどない) 場合に#fになります。

 -- Function: ftp-rename conn from-name to-name
     Renames the remote file specified by FROM-NAME to the name TO-NAME.  Returns the final response of the server. FROM-NAMEで指定したリモートファイル名をTO-NAMEに変更する。返り値は最終的なサーバーのレスポンスです。

rfc.hmac - HMAC keyed-hashing
=============================

 -- Module: rfc.hmac
     This module implements HMAC algorithm, Keyed-hashing for message authentication, defined in RFC 2104.

     For simple batched keyed hashing, you can use high-level API hmac-digest and hmac-digest-string. Or you can create <hmac> object and update its state as the data coming in. このモジュールは、RFC 2104で定義されている、メッセージ認証のための鍵付きハッシングのHMACアルゴリズムを実装しています。

     シンプルなバッチ処理での鍵付きハッシングでは、高レベルなAPIである hmac-digestとhmac-digest-stringが使えます。あるいは、<hmac>オブジェクトを作成して、入力となるデータでその状態を更新することもできます。

 -- Class: <hmac>
     Keeps state information of HMAC algorithm. Key and the hashing algorithm should be given at the construction time, using :key and :hasher keyword-arguments respectively. You can pass any class object that implements message digest interface (see Message digester framework), such as <md5> (see MD5 message digest) or <sha256> (see SHA message digest).

     Example: HMACアルゴリズムの状態情報を保持します。鍵とハッシングアルゴリズムは、キーワード引数:keyと:hasherをそれぞれ使って、生成時に与えます。 <md5> (MD5 message digest参照)や <sha256> (SHA message digest参照)などのようなダイジェストインタフェース(Message digester framework参照)を実装するいかなるクラスオブジェクトを渡すこともできます。

     例:

          (make <hmac> :key (make-byte-string 16 #x0b) :hasher <md5>)

 -- Method: hmac-update! (hmac <hmac>) data
     Updates the internal state of HMAC by DATA, which must be represented by a (possibly incomplete) string. (不完全かもしれない)文字列で表現されるDATAにより、 HMACの内部状態を更新します。

 -- Method: hmac-final! (hmac <hmac>)
     Finalizes the internal state of HMAC and returns the hashed string in incomplete string. You can use digest-hexify (see Message digester framework) to obtain "hexified" result. Once finalized, you can't call hmac-update! or hmac-final! on HMAC. HMACの内部状態を終了させ、不完全文字列でハッシュされた文字列を返します。 ``hexified''(16進化)された結果を得るために、digest-hexify (Message digester framework参照)を使うことができます。一旦終了されると、HMACに対してはhmac-update!や hmac-final!を呼ぶことはできません。

 -- Method: hmac-digest :key key hasher
     Creates an <hmac> object and hash the data stream from the current input port, then returns the hashed result in an incomplete string. <hmac>オブジェクトを作り、現在の入力ポートからのデータストリームをハッシュし、不完全文字列でそのハッシュされた結果を返します。

 -- Method: hmac-digest-string string :key key hasher
     Creates an <hmac> object and hash the data in STRING, then returns the hashed result in an incomplete string. <hmac>オブジェクトを作り、STRINGにあるデータをハッシュし、不完全文字列でそのハッシュされた結果を返します。

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" このモジュールは、RFC2616 "Hypertext Transfer Protocol -- HTTP/1.1" で定義されているHTTP/1.1に対する簡単なクライアントAPIを提供します。 (https://www.ietf.org/rfc/rfc2616.txt).

     Current API implements only a part of the protocol. 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. 現在のAPIは、プロトコルの一部のみ実装されています。 HTTP/1.0のサーバーとはうまく通信できません。また、HTTP/1.1の先進的機能、例えば永続的接続などはサポートしていません。これらの機能は、将来のバージョンで追加されるでしょう。

 -- Condition Type: <http-error>
     This type of condition is raised when the server terminates connection prematurely or server's response has invalid header fields.  Inherits <error>. サーバから接続が切られた場合や、サーバの返したHTTPレスポンスのフォーマットが正しくない場合に投げられるコンディションです。<error>を継承します。

 -- Function: http-get server request-uri :key sink flusher redirect-handler secure ...
 -- Function: http-head server request-uri :key redirect-handler secure ...
 -- Function: http-post server request-uri body :key sink flusher redirect-handler secure ...
 -- Function: http-put server request-uri body :key sink flusher redirect-handler secure ...
 -- Function: http-delete server request-uri :key sink flusher redirect-handler secure ...
     Send http GET, HEAD, POST, PUT and DELETE requests to the http SERVER, respectively, and returns the server's reply.

     By default, if the server returns 300, 301, 302, 303, 305 and 307 status, these procedures attempts to fetch the redirected URL by the "location" reply message header if it is allowed by RFC2616. This behavior can be turned off or customized by the REDIRECT-HANDLER keyword argument; see the "keyword arguments" heading below for the details. SERVERに、それぞれHTTPのGET、HEAD、POST、PUT、DELETEリクエストを送り、サーバの応答を返します。

     デフォルトでは、サーバがステータスコード 300, 301, 302, 303, 305 の応答を返し、 RFC2616による自動リダイレクトが許されている場合は、これらの手続きは自動的に応答のメッセージヘッダの "location" で返されるURIに対してリクエストを再送します。この動作はREDIRECT-HANDLERキーワード引数でカスタマイズしたり抑制したりできます。下の"キーワード引数"を参照してください。

     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. You can use IP address, too; for IPv6, you have to surround the address in brackets.

     Additionally, you can specify "unix:/path" where /path is the absolute path to the unix domain socket; this allows to connect to httpd listening on unix domain sockets. 必須の引数: SERVER引数では、文字列でHTTPサーバ名を指定します。サーバ名は、オプションでコロンに続いてポート番号を付加できます。 IPアドレスも使えます。IPv6アドレスは角括弧で囲んでください。

     また、"unix:/path"という形式でUnixドメインソケットに接続することもできます。 /path部分にはソケットへの絶対パスを指定します。 Examples: "w3c.org", "mycompany.com:8080", "192.168.0.1:8000", "[::1]:8000"

     The REQUEST-URI argument can be a string or a list. If it is a string, it's request-uri specified in RFC2616; usually, this is the path part of http url. The string is passed to the server as is, so the caller must properly convert character encodings and perform necessary url encodings.

     If REQUEST-URI is a list, it must be in the following form: REQUEST-URI引数は文字列かリストです。文字列の場合、RFC2616で規定されているリクエストURIと解釈されます。通常これはHTTP URLのパス部分です。文字列はそのままサーバに渡されるので、呼び出し側で必要な文字コード変換やurlエンコーディングを行う必要があります。

     REQUEST-URIがリストの場合は、次の形式でなければなりません。

          (PATH (NAME VALUE) ...)

     Here, PATH is a string specifying up to the path component of the request-uri. From provided alist of NAMEs and VALUEs, http procedures compose a query string in application/x-www-form-urlencoded format as defined in HTML4, and append it to PATH. For example, the following two requests have the same effect. Note that url escaping is automatically handled in the second call. ここでPATHはリクエストURIのパスコンポーネントまでを指定する文字列です。与えられたNAMEとVALUEのalistから、 httpリクエスト手続きはHTML4で定められた application/x-www-form-urlencoded形式のクエリ文字列を構成し、PATHにアペンドします。例えば次のふたつのリクエストは同じ効果を持ちます。二番目の呼び出しではurlエスケープが自動的に行われることに注目してください。

          (http-get "example.com" "/search?q=foo%20bar&n=20")

          (http-get "example.com" '("/search" (q "foo bar") (n 20)))

     If REQUEST-ENCODING keyword argument is also given, NAMEs and VALUEs are converted into the specified character encoding before url escaping. If it is omitted, gauche's internal character encoding is used. REQUEST-ENCODINGキーワード引数が与えられた場合、 NAMEとVALUEはまずその文字エンコーディングに変換されたのちに urlエスケープされます。そうでない場合はgaucheの内部エンコーディングがそのまま使われます。

     Some procedures take the third argument, BODY, to specify the body of the request message. It can be a string, which will be copied verbatim to the request body, or a list, which will be encoded in multipart/form-data message.

     If BODY is a list, it is a list of parameter specs.  Each parameter spec is either a list of name and value, e.g. ("submit" "OK") or a name followed by keyword-value list, e.g. ("upload" :file "logo.png" :content-type "image/png").

     The first form is for the convenience.  It is also compatible to the query parameter list in REQUEST-URI, so that you can use the same format for GET and POST request.  Each value is put in a MIME part with text/plain media type, with the character encoding specified by request-encoding keyword argument described below.

     The second form allows further control over each MIME part's attributes. The following keywords are treated specially.

     :value
          Specifies the value of the parameter.  The convenience form, (NAME VAL), is just an abbreviation of (NAME :value VAL).

     :file
          Specifies the pathname of the file, whose content is inserted as the value of the parameter.  Useful to upload a file. This option has precedence over :value. MIME type of the part is set to application/octet-stream unless specified otherwise.

     :content-type
          Overrides the MIME type of the part.  A charset parameter is added to the content-type if not given in this argument.

     :content-transfer-encoding
          Specifies the value of content-transfer-encoding; currently the following values are supported: 7bit, binary, quoted-printable and base64. If omitted, binary is used.

     Other keywords are used as the header of the MIME part. いくつかの手続きは、リクエストメッセージのボディを指定するBODYを第3引数として取ります。BODYは文字列かリストで、文字列の場合はそのまま送られ、リストの場合はmultipart/form-data形式にエンコードされて送られます。

     BODYがリストの場合、それはパラメータ指定のリストです。各パラメータ指定は、("submit" "OK")のような名前と値のリスト、もしくは("upload" :file "logo.png" :content-type "image/png") のように名前の後にキーワード-値リストを付加したものです。

     最初の形式は使うのが簡単で、またREQUEST-URIのクエリパラメータリストと同じ形式なのでGETとPOSTでルーチンを共有したい場合にも便利でしょう。この形式では、各値はMIMEパートにtext/plainとして置かれます。文字コードは下に述べるrequest-encodingキーワード引数により変換されます。

     二番目の形式では、MIMEパートの属性についてより細かな指定を行うことができます。以下のキーワードが特別に扱われます。

     :value
          パラメータの値を指定します。簡潔な(NAME VAL)形式は (NAME :value VAL)の省略形です。

     :file
          指定された名前のファイルの中身をパラメータの値として挿入します。ファイルのアップロードに便利です。このオプションは:valueより優先されます。MIMEタイプは、指定が無ければ application/octet-streamとなります。

     :content-type
          MIMEタイプをオーバライドします。与えられた値にcharsetパラメータがついていない場合は自動的に付加されます。

     :content-transfer-encoding
          content-transfer-encodingを 7bit、binary、quoted-printable、base64のいずれかで指定します。指定が無ければbinaryが使われます。

     残りのキーワードはMIMEパートのヘッダにそのまま使われます。

     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"). 戻り値: 全ての手続きは3つの値を返します。

     1つ目は、RFC2616で定義されているステータスコードの文字列値(例えば、成功時の 200、"Not found"の404など)です。

     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. 2つ目は、パーズされたヘッダのリストで、リストの要素は(HEADER-NAME VALUE ...)です。HEADER-NAMEはヘッダの文字列名(例えば、 "content-type"や"location"など)で、VALUEは対応する値の文字列値です。ヘッダ名は小文字に変換されます。値は、RFC2822で定義されている無指定行区切 (ソフト・ライン・ブレイク)が除かれる以外はそのままです。サーバが同じ名前のヘッダを1つ以上返した場合は、 1つのリストに統合されます。それ以外では、2つ目の戻り値におけるヘッダのリストの順番は、サーバの応答での順番と同じです。

     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. 3つ目の戻り値は、サーバの応答におけるメッセージボディです。デフォルトでは、文字列で表現されたメッセージボディそのものです。サーバの応答がボディを持たない場合、3つ目の戻り値は#fです。キーワード引数によって、メッセージボディがどのように扱われるかを制御できます。例えば、中間的な文字列を作らずに、返されたメッセージボディを直接ファイルに格納することが出来ます。詳細は以下で説明しています。

     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. キーワード引数: デフォルトで、これらの手続きはリクエストメッセージに"Host"ヘッダ・フィールドを追加するだけです。他のヘッダ・フィールドを追加するためにキーワード引数を与えることができます。

          (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. 以下のキーワード引数は手続きによって解釈され、リクエストヘッダには現れません。

     request-encoding
          When a list is given to the REQUEST-URI or BODY arguments, the characters in names and values of the parameters are first converted to the character encoding specified by this keyword argument, then encoded into application/x-www-form-urlencoded or multipart/form-data MIME formats. If this argument is omitted, Gauche's internal character encoding is used.

          For multipart/form-data, you can override character encodings for individual parameters by giving content-type header. See the description of BODY arguments above.

          If you give a string to REQUEST-URI or BODY, it is used without encoding conversion.  It is caller's responsibility to ensure desired character encodings are used. REQUEST-URIやBODYがリストで与えられた場合、パラメータの名前や値はまずこの引数で指定される文字エンコーディングへと変換され、その後、application/x-www-form-urlencodedや multipart/form-data MIME形式にしたがったエンコーディングが行われます。この引数が省略された場合はGaucheの内部文字エンコーディングが使われます。

          multipart/form-dataについては、パラメータにcontent-typeヘッダを与えることでパラメータごとに文字エンコーディングの設定をオーバライドできます。詳しくは上のBODY引数の説明を参照してください。

          REQUEST-URIやBODYに文字列を与えた場合は、文字エンコーディング変換は行われません。呼び出し側で望みの文字コードにあらかじめ変換しておいてください。

     proxy
          Specify http proxy server in a string of a form hostname or hostname:port.  If omitted, the value of the parameter http-proxy is used. httpプロキシサーバを、hostnameまたはhostname:port形式の文字列で指定します。省略された場合、パラメータhttp-proxyの値が使われます。

     redirect-handler
          Specifies how the redirection is handled when the server responds with 3xx status code. You can pass #f, #t or a procedure.  The default is #t.

          If #f is given, no redirect attempt will be made; the 3xx status code and response is just returned from http-* procedures as they are.

          If a procedure is given, it is called when the response status code is 3xx.  The procedure takes four arguments, the request method (in symbol, e.g. GET), the response status code (in string, e.g. "302"), the parsed response headers and the response body (a string if there's a body, or #f if the response doesn't have a body).

          The procedure can return a pair or #f. If it is a pair, it should be (method . url), where METHOD is a symbol (e.g. GET) and URL is a string representing url. If a pair is returned, the http-* procedures tries to send the request with the given method (it allows a redirection of POST request to be GET, for example).  If it is #f, no further attempt of redirection is made.

          If REDIRECT-HANDLER is #t, which is the default, then it works as if the value of the parameter http-default-redirect-handler is passed to REDIRECT-HANDLER. The parameter contains a procedure with reasonable default behavior. See the http-default-redirect-handler entry below for the details.

          A loop in redirection is detected automatically and <http-error> is thrown. サーバが3xxステータスコードを返した場合のリダイレクトの処理を指定します。 #f, #tもしくは手続きを渡すことができます。省略時は#tとなります。

          #fが渡された場合は、リダイレクトは処理されません。3xxステータスコードを持つレスポンスもそのままhttp-*から返されます。

          手続きが渡された場合は、サーバが3xxステータスコードを返すとその手続きが4つの引数で呼ばれます。最初の引数はリクエストメソッド(シンボル、例:GET)、次がレスポンスステータスコード(文字列、例:"302")、次がパーズされたレスポンスヘッダ、そして最後がレスポンスボディです(レスポンスボディがあれば文字列、なければ#f)。

          この手続きは、ペアか#fを返さねばなりません。ペアの場合、それは (method . url)という形で、METHODがシンボルによるリクエストメソッド、 URLが文字列で次にリクエストすべきURLを表します。ペアが返されれば、http-*手続きはそのURLへ、指定されたメソッドでリクエストを再送します。(メソッドを返すことで、例えばPOSTリクエストのリダイレクトをGETリクエストに置き換えることが可能です)。手続きが#fを返した場合、リダイレクトは行われません。

          REDIRECT-HANDLERが#t(デフォルト値)の場合、パラメータhttp-default-redirect-handlerの値が REDIRECT-HANDLERに渡されたかのように振る舞います。このパラメータの初期値は、標準的なリダイレクトの振る舞いをする手続きになっています。下のhttp-default-redirect-handlerの項目を参照してください。

          リダイレクトのループは自動的に検出され、<http-error>が投げられます。

     no-redirect
          This is an obsoleted keyword argument kept only for the backward compatibility.  If a true value is given, it has the same effect as specifying #f to REDIRECT-HANDLER. これは互換性のためだけに残されている、古い引数です。真の値を与えると、 REDIRECT-HANDLERに#fを渡したのと同じ効果を持ちます。

     secure
          If a true value is given, the secure connection is used.  The value specifies the secure transport agent to establish https connection. It can be #t or a symbol tls or stunnel. If #f is given (default), non-secure plain http is used. See the ``Secure connection'' section below. 真の値が与えられた場合、セキュアな接続が使われます。値によってhttps接続につかうトランスポートエージェントを指定できます。有効な値は#tもしくはシンボルのtlsかstunnelです。 #fが与えられた場合(デフォルト)はセキュアでない通常のhttpが使われます。詳しくは下の「セキュアな接続」の項を参照してください。

     auth-user, auth-password
          If given, the authorization header using Basic Authentication (RFC2617) is added to the request. In future, we might add support for other authentication scheme. これらのキーワード引数が与えられた場合、Basic認証用のAuthorizationヘッダがリクエストに付加されます。将来はBasic認証以外の認証方式もサポートするかもしれません。

     sink, flusher
          You can customize how the reply 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. これらのキーワード引数によりリプライメッセージ・ボディがどのように扱われるかをカスタマイズできます。SINKには出力ポートを、FLUSHERには2引数を取る手続きを渡さなければなりません。

          手続きがメッセージ・ボディを受信し始めると、SINKへ受け取ったデータ片をフィードします。手続きがメッセージ・ボディを受信し終わると、 FLUSHERに与えられた手続きが、SINKと(手続きからの2つ目の戻り値と同じフォーマットの)メッセージ・ヘッダ・フィールドのリストとともに呼び出されます。FLUSHERの戻り値が、手続きからの3つ目の戻り値となります。

          したがって、SINKのデフォルト値は、新しく開かれた文字列ポートで、 FLUSHERのデフォルト値は(lambda (sink headers) (get-output-string sink)) とも言えます。

          以下のサンプルは、(とても大きい可能性のある)文字列バッファを作らずに、メッセージ・ボディを直接ファイルに保存します。

               (call-with-output-file "page.html"
                 (lambda (out)
                   (http-get "www.schemers.org" "/"
                      :sink out :flusher (lambda _ #t))))

The module also provides some utility procedures.

 -- Parameter: http-user-agent :optional value
     The value of this parameter is used as a default value to pass to the user-agent header. The default value is something like gauche.http/*, where * is Gauche's version. An application is encouraged to set this parameter appropriately. user-agentヘッダに渡される値のデフォルト値を指定するパラメータです。デフォルトの値はgauche.http/* (*部分はGaucheのバージョン) になっています。各アプリケーションは適切な値を設定するようにしてください。

 -- Parameter: http-proxy :optional value
     This value is used as the default http proxy name by http-get etc. The default value is #f (no proxy). このパラメータの値がhttp-get等のhttpプロキシのデフォルトの値として使われます。デフォルトの値は#f (プロキシを使用しない) です。

 -- Parameter: http-default-redirect-handler :optional value
     Specifies the behavior of redirection if no redirect-handler keyword argument is given to the http-* procedures. If you change this value, it must be a procedure that follows the protocol of redirect-handler; see the description of http-* procedures above. http-*手続きにredirect-handlerキーワード引数が与えられなかった場合のデフォルトの動作を指定します。この値を変える場合、それは redirect-handler引数のプロトコルに従う手続きでなければなりません。上のhttp-*手続きの項目を参照してください。

     The default behavior is as follows: デフォルトの動作は以下の通りです。

     300, 301, 305, 307
          Redirect to the url given to the location header only if the original request method is GET or HEAD. 元のリクエストがGETかHEADの場合に限り、同じリクエストを使って locationヘッダに与えられたURLにリダイレクトします。

     302
          Redirect to the url given to the location header.  If the original request method is HEAD, it is used again. Otherwise, GET method is used.

          Strictly speaking, this is a violation of RFC2616.  However, as the note in RFC2616 says, many user agent do this, so we follow the flock. (We may change this in future.) locationヘッダに与えられたURLにリダイレクトします。元がHEADリクエストならHEADを、それ以外ならGETリクエストを使います。

          厳密に言えばこれはRFC2616違反ですが、RFC2616の注記にもあるように、多くのユーザエージェントがこの振る舞いをするので、それに合わせてあります。 (将来は変えるかもしれません。)

     303
          Redirect to the url given to the location header.  If the original request method is HEAD, it is used again. Otherwise, GET method is used. locationヘッダに与えられたURLにリダイレクトします。元がHEADリクエストならHEADを、それ以外ならGETリクエストを使います。

     other than above
          No redirection is made. リダイレクトしません。

     The following code is an example of intercepting the default behavior in a specific request: 次のコードは、デフォルトの振る舞いを特定のリクエストでインターセプトする例です。

          (http-get server uri
            :redirect-handler
            (^[method status headers body]
              (if (and (equal? status "302")
                       (not (member method '(GET HEAD))))
                  #f
                  ((http-default-request-handler) method status headers body))))

 -- Function: http-compose-query path params :optional encoding
     A helper procedure to create a request-uri from a list of query parameters.  ENCODING specifies the character encodings to be used. クエリパラメータのリストからリクエストURIを生成する補助関数です。 ENCODING引数はクエリパラメータの文字エンコーディングを指定します。

          (http-compose-query "/search" '((q "$foo") (n 20)))
           => "/search?q=%24foo&n=20"

          (http-compose-query "" '((x "a b") (x 2)))
           => "?x=a%20b&x=2"

     If PATH is #f, only the query parameter part is returned (compare the following example and the last example): PATHが#fの場合は、クエリパラメータの部分だけが返されます (次の例と直前の例を比べてみてください)。

          (http-compose-query #f '((x "a b") (x 2)))
           => "x=a%20b&x=2"

 -- Function: http-compose-form-data params port :optional encoding
     A helper procedure to create multipart/form-data from a list of parameters.  The format of PARAMS argument is the same as the list format of BODY argument of http request procedures.  The result is written to an output port PORT, and the boundary string used to compose MIME message is returned.  Alternatively you can pass #f to the PORT to get the result in a string. In that case, two values are returned, the MIME message string and the boundary string. multibyte/form-data形式にエンコードされたデータをパラメータのリストから組み立てるための補助手続きです。 PARAMSの形式はhttpリクエスト手続きのBODY部にリストを渡す場合の形式と同様です。結果は出力ポートPORTに書き出され、 MIMEメッセージを構築するのに必要なboundary stringが返されます。 PORTに#fを渡した場合は、 boundary stringとデータをエンコードした文字列の二つの値が返されます。

     ENCODING specifies the character encodings to be used. When omitted, Gauche's native encoding is used. ENCODINGは文字エンコーディングを指定します。省略時はGaucheのネイティブエンコーディングが使われます。

          (define p (open-output-string))

          (http-compose-form-data '((name "Preludes and Fugues")
                                    (composer "Shostakovich, Dmitri")
                                    (opus "87"))
                                   p)
            => "boundary-fh87o52rp6zkubp2uhdmo"

          (get-output-string p)
            =>
            "\r\n--boundary-fh87o52rp6zkubp2uhdmo\r\nContent-type: te
             xt/plain; charset=utf-8\r\nContent-transfer-encoding: bi
             nary\r\ncontent-disposition: form-data; name=title\r\n\r\n
             Preludes and Fugues\r\n--boundary-fh87o52rp6zkubp2uhdmo...
          ;; (result is truncated)
          ;; (以下省略)

 -- Function: http-status-code->description code
     Returns a brief description of http status code code, which may be an integer or a string (e.g. "404"). If code isn't one of known code, #f is returned. HTTPステータスコードcodeの簡単な説明を返します。 codeは整数か、整数を表す文字列です(例: "404")。 codeが知られているものでなかった場合は#fが返されます。

          (http-status-code->description 404)
            => "Not Found"

Secure connection
-----------------

セキュアな接続
-------

When you pass a true value to secure keyword argument, the request-making APIs such as http-get use a secure connection.  That is, it connects with https instead of http.  The actual value for the keyword argument can be one of the followings: http-get等httpリクエスト発行APIのsecureキーワード引数に、真の値を渡した場合、セキュアなコネクションが使われます。すなわち、httpではなくhttpsで接続されるということです。実際にsecureキーワード引数に渡せる値は以下の通りです。

#t
tls
     The rfc.tls module is used for the secure connection. See Transport layer security, for the details---you might need to set CA certificate bundle path. rfc.tlsモジュールを使ってセキュアな接続を行います。詳しくはTransport layer securityを参照してください。 CA証明書のパスを設定する必要があるかもしれません。

stunnel
     The external process stunnel is spawned and used for the secure connection. stunnelプロセスをサブプロセスとして起動してそれを通じてセキュアな接続を作ります。

#f
     Secure connection is not used. セキュアな接続を行いません。

If specified secure connection subsystem isn't available in the running Gauche, an error is signaled. Use the following procedure to check if you can use secure connections: 指定されたセキュア接続を行うサブシステムが実行中のGaucheでは使えない場合は、エラーが報告されます。サブシステムが使えるかどうかをチェックしたい場合は次の手続きを使ってください。

 -- Function: http-secure-connection-available? :optional type
     The TYPE argument may be tls or stunnel. If omitted, tls is assumed. Returns #t if running Gauche can use secure connection of the given type, #f otherwise. TYPE引数はtlsかstunnelでなければなりません。省略時はtlsとみなされます。指定のセキュア接続を行うサブシステムが実行中のGaucheで使える場合は#tが、使えない場合は#fが返されます。

rfc.icmp - ICMP packets
=======================

 -- Module: rfc.icmp
     This module provides some basic utilities to construct and parse ICMP packets. このモジュールではICMPパケットの構築および解析用の基本的ユーティリティを提供しています。

For the functions below, BUFFER should be a writable u8vector of the enough size. 以下の関数のBUFFERは十分なサイズの書き込み可能なu8vectorでなければなりません。

Parsing functions takes OFFSET as well as BUFFER, which specifies the beginning of the ICMP packet.  Using the offset you can carry the whole IP packet in BUFFER, without creating a new buffer to extract ICMP portion. 解析用の関数はBUFFERのほかにOFFSETを引数としてとります。これはICMPパケットの開始位置を示すものです。このオフセットを用いて、ICMP 部分を取り出して新しいバッファを作るということなしに、IPパケット全体を BUFFER内に格納できます。

 -- Function: icmp4-fill-echo! buffer ident sequence data
     Fills BUFFER with the ICMPv4 Echo Request packet. DATA must be a u8vector.  The checksum field is left to be zero, which can be filled by icmp4-fill-checksum!. BUFFERにICMPv4のエコーリクエストパケットを詰め込みます。 DATAはu8vectorでなければなりません。チェックサムフィールドはゼロのままです。チェックサムはicmp4-fill-checksum!を使って埋め込みます。

 -- Function: icmp4-fill-checksum! buffer size
     Calculates the ICMPv4 checksum of the packet in the BUFFER, of SIZE length (the size of the packet, not the buffer), and fills the checksum field of the packet. BUFFER中のSIZE(バッファではなくパケットの長さ)分のパケットのICMPv4チェックサムを計算し、そのパケットのチェックサムフィールドをうめます。

 -- Function: icmp6-fill-echo! buffer ident sequence data
     Fills BUFFER with the ICMPv6 Echo Request packet. DATA must be a u8vector.  The checksum field is left to be zero, which is to be filled by the kernel (so you don't need to fill by yourself). BUFFERにICMPv6のエコーリクエストパケットを詰め込みます。 DATAはu8vectorでなければなりません。チェックサムフィールドはゼロのままで、ここはカーネルが埋めることになっています。したがって、ユーザーが自分で埋める必要はありません。

 -- Function: icmp-packet-type buffer offset
 -- Function: icmp-packet-code buffer offset
 -- Function: icmp-packet-ident buffer offset
 -- Function: icmp-packet-sequence buffer offset
     Extracts type, code, ident and sequence fields of ICMP packet. These functions are common to both ICMPv4/v6. それぞれICMPパケットのタイプ、コード、識別子、シーケンスフィールドを抜き出します。これらの関数はICMPv4/v6で共通です。

 -- Function: icmp4-describe-packet buffer offset
 -- Function: icmp6-describe-packet buffer offset
     Prints out a simple text description of the given ICMPv4 and v6 packet, respectively. それぞれ与えられたICMPv4およびICMPv6パケットの簡単な説明を印字します。

 -- Function: icmp4-message-type->string type
 -- Function: icmp4-unreach-code->string code
 -- Function: icmp4-redirect-code->string code
 -- Function: icmp4-router-code->string code
 -- Function: icmp4-exceeded-code->string code
 -- Function: icmp4-parameter-code->string code
 -- Function: icmp4-security-code->string code
 -- Function: icmp6-message-type->string type
 -- Function: icmp6-unreach-code->string code
 -- Function: icmp6-exceeded-code->string code
 -- Function: icmp6-parameter-code->string code
     Returns a text description of ICMPv4 and ICMPv6 types and codes. ICMPv4およびICMPv6のタイプとコードの説明テキストを返します。

rfc.ip - IP packets
===================

 -- Module: rfc.ip
     This module provides some basic utilities to parse raw IP packets. このモジュールは生のIPパケットを解析する基本的なユーティリティを提供します。

The PACKET argument in the following functions must be any type of uniform vector (see Uniform vectors), containing a raw IP packet including its IP header. Those functions work for both IPv4 and IPv6 packets; however, reading from a raw IPv6 socket returns a packet without IPv6 header, so you usually don't need to use these functions. 次からの関数におけるPACKET引数はユニフォームベクタ (Uniform vectors参照)型でなければなりません。これにはIPヘッダを含む生のIPパケットが入ります。以下の関数はIPv4およびIPv6パケットの両方で動きます。しかしながら、生のIPv6ソケットから読むときは、IPv6ヘッダを含まないパケットが返ります。とうわけで、通常これらの関数が必要になることはないでしょう。

The OFFSET argument specifies the beginning of the IP packet in PACKET.  If PACKET contains only one IP packet you can pass 0.  It is not an optional argument, since these routines may be used in speed-sensitive inner loop.

 -- Function: ip-version packet offset
     Returns the IP version number (either 4 or 6) of the given IP packet. 与えられたIPパケットのIPバージョン番号(4または6)が返ります。

 -- Function: ip-header-length packet offset
     Returns the size of IP header of the given packet in octets, including any IP header options. 与えられたパケットのIPヘッダ(IPヘッダオプションもすべて含む)のオクテットで数えたサイズを返します。

 -- Function: ip-protocol packet offset
     Returns the IP protocol number of the given packet. 与えられたパケットのIPプロトコル番号を返します。

 -- Function: ip-source-address packet offset
 -- Function: ip-destination-address packet offset
     Returns the source and destination address in the given packet in an integer, respectively. 与えられたパケットの送信元アドレスと送信先アドレスをそれぞれ整数で返します。

rfc.json - JSON parsing and construction
========================================

 -- Module: rfc.json
     Procedures to parse JSON (RFC7159) data to S-expressions, and convert S-expressions to JSON representation, are provided. RFC7159で規定される、JSON形式をパーズしてS式に直す手続きと、 S式をJSON形式に変換する手続きが提供されます。

 -- Condition type: <json-parse-error>
     The parser parse-json and parse-json-string raise this condition when they encounter invalid JSON syntax.  It inherits <error>, and adds the following slot. パーズ手続きparse-jsonとparse-json-stringは、無効なJSON構文に出会った時にこのコンディションを投げます。 <error>を継承し、次のスロットを追加で持ちます。

      -- Instance Variable of <json-parse-error>: position
          The input position, counted in characters, where the error occurred. エラーが起きた入力位置(文字数)。

 -- Parameter: json-nesting-depth-limit
     [SRFI-180] Its value must be a real number, specifying the maximum nesting depth of JSON text that can be parsed by parse-json.  If the input exceeds the value, an <json-parse-error> is thrown. The default value is +inf.0. このパラメータの値は実数でなければなりません。 parse-jsonがパーズするJSONテキストに許される最大のネストの深さを指定します。入力のネスト深さがこのパラメータの値を越えた場合、<json-parse-error>が投げられます。デフォルトは+inf.0です。

 -- Function: parse-json :optional input-port
     Reads and parses the JSON representation from INPUT-PORT (default is the current input port), and returns the result in an S-expression. May raise a <json-parse-error> condition when parse error occurs, or the nesting level exceeds the value of json-nesting-depth-limit. JSON表記をINPUT-PORT (省略された場合はcurrent-input-port)から読み込みパーズして、結果をS式で返します。パーズエラーが起きたり、ネストレベルがjson-nesting-depth-limitの値を超過した場合は<json-parse-error>コンディションを投げます。

     The following table shows how JSON datatypes are mapped to Scheme objects. 下のテーブルに、JSONのデータ型がどのようにSchemeにマップされるかを示します。

     true, false, null
          Symbols true, false and null. (Customizable by json-special-handler)

     Arrays
          Scheme vectors.  (Customizable by json-array-handler)

     Objects
          Scheme assoc-lists, in which keys are strings, and values are Scheme objects.  (Customizable by json-object-handler)

     Numbers
          Scheme inexact real numbers.

     Strings
          Scheme strings.

     true, false, null
          シンボルtrue, false and null。 (json-special-handlerで変更可能)

     配列
          Schemeのベクタ。 (json-array-handlerで変更可能)

     オブジェクト
          Schemeの連想リスト。キーは文字列で、値はSchemeオブジェクト。 (json-object-handlerで変更可能)

     数値
          Schemeの不正確な実数。

     文字列
          Schemeの文字列。

     Since the parser used internally in parse-json prefetches characters, some characters after the parsed JSON expression may already been read from PORT when parse-json returns. That is, you cannot call parse-json repeatedly on PORT to read subsequent JSON expressions.  Use parse-json* if you need to read multiple JSON expressions. parse-json内で使っているパーザは文字の先読みを行う可能性があるので、 parse-jsonが戻って来た時点で、パーズされたJSON式以降のいくつかの文字が PORTから既に読まれてしまっている可能性があります。すなわち、複数のJSON式を読み出すのに、PORTに対してparse-json を繰り返し呼び出すのはうまくいきません。複数のJSON式をパーズしたい場合は parse-json*を使ってください。

 -- Function: parse-json* :optional input-port
     Read JSON repeatedly from INPUT-PORT until it reaches EOF, and returns parsed results as a list. INPUT-PORTから、EOFに達するまでJSON式を繰り返し読み取り、パーズ結果をリストにして返します。

 -- Function: parse-json-string str
     Parses the JSON string and returns the result in an S-expression. May raise a <json-parse-error> condition when parse error occurs.

     See parse-json above for the mappings from JSON datatypes to Scheme types. 文字列STRをJSONとしてパーズし、結果をS式で返します。パーズエラーが起きた場合は<json-parse-error>コンディションを投げます。

     JSONのデータ型とSchemeの型とのマッピングについては上のparse-json を参照してください。

 -- Parameter: json-array-handler
 -- Parameter: json-object-handler
 -- Parameter: json-special-handler
     The value of these parameters must be a procedure that takes one argument: for json-array-handler, it is a list of elements of a JSON array, for json-object-handler, it is a list of conses of key and value of a JSON object, and for json-special-handler, it is one of the symbols false, true or null.

     Whenever parse-json reads a JSON array, a JSON object, or one of those special values, it calls corresponding parameter to get a Scheme object.

     The default value of these parameters are list->vector, identity, and identity, respectively.

     The following example maps JSON objects to hash tables. これらのパラメータの値は、引数をひとつ取る手続きでなければなりません。 json-array-handlerの値の手続きに渡される引数は、 JSON配列の要素のリストです。 json-object-handlerでは JSONオブジェクトのキーと値をconsしたもののリスト、 json-special-handlerではシンボルfalse, true, nullのいずれかです。

     parse-jsonはJSON配列やオブジェクト、false、true、nullに出会う度に、このパラメータの値の手続きを起動して、JSONに対応するSchemeオブジェクトを得ます。

     これらのパラメータのデフォルト値はそれぞれlist->object、 identity、identityです。

     次の例では、JSONオブジェクトをハッシュテーブルに変換しています。

          (parameterize ([json-object-handler (cut alist->hash-table <> 'string=?)])
            (parse-json-string "{\"a\":1, \"b\":2}"))
           => #<hash-table ...>

 -- Condition type: <json-construct-error>
     The converters construct-json and construct-json-string raise this condition when they cannot convert given Scheme object to JSON. It inherits <error>, and adds the following slot. construct-jsonとconstruct-json-stringは、 JSONに変換できないSchemeオブジェクトを見つけるとこのコンディションを投げます。 <error>を継承し、次のスロットを追加で持ちます。

      -- Instance Variable of <json-construct-error>: object
          The Scheme object that cannot convert to JSON representation. JSON表現に変換できなかったSchemeオブジェクト。

 -- Function: construct-json obj :optional output-port
 -- Function: construct-json-string obj
     Creates JSON representation of Scheme object OBJ. construct-json writes out the result to OUTPUT-PORT, whose default is the current output port.  construct-json-string returns the result in a string.

     If OBJ contains a Scheme object that cannot be mapped to JSON representation, a <json-construct-error> condition is raised.

     Scheme objects are mapped to JSON as follows: SchemeオブジェクトOBJのJSON表現を作ります。 construct-jsonは結果をOUTPUT-PORTに書き出します。デフォルトは current-output-portです。construct-json-stringは結果を文字列で返します。

     OBJがJSONにマップできないオブジェクトを含んでいた場合は <json-construct-error>コンディションが投げられます。

     Schemeオブジェクトは以下のようにJSONへと変換されます。

     symbol false, #f
          false

     symbol true, #t
          true

     symbol null
          null

     list, instance of <dictionary>
          JSON object (list must be an assoc list of key and value).

     string
          string

     real number
          number

     instance of <sequence> (except strings and lists)
          JSON array

     シンボルfalse, #f
          false

     シンボルtrue, #t
          true

     シンボルnull
          null

     リスト、 <dictionary>のインスタンス
          JSONオブジェクト (リストはキーと値の連想リストでなければならない)

     文字列
          文字列

     実数
          数値

     <sequence>のインスタンス (文字列とリストを除く)
          JSON配列

rfc.md5 - MD5 message digest
============================

 -- Module: rfc.md5
     This module implements MD5 message digest algorithm, defined in RFC 1321 (https://www.ietf.org/rfc/rfc1321.txt). The module extends util.digest (see Message digester framework). このモジュールは、RFC 1321 (https://www.ietf.org/rfc/rfc1321.txt) で定義されている、MD5メッセージダイジェストアルゴリズムを実装しています。このモジュールは、util.digest (Message digester framework参照) を拡張しています。

 -- Class: <md5>
     The instance of this class keeps internal state of MD5 digest algorithm.

     This class implements util.digest framework interface, digest-update!, digest-final!, digest, and digest-string. See Message digester framework, for detailed explanation of these methods. このクラスのインスタンスは、MD5ダイジェストアルゴリズムの内部状態を保持しています。

     このクラスは、util.digestフレームワークのインターフェースである、 digest-update!、digest-final!、digest、 digest-stringを実装しています。これらのメソッドの詳細な説明は、Message digester framework を参照して下さい。

Besides the digester framework, this module provides to short-cut procedures. ダイジェスタフレームワークに加えて、このモジュールはショートカット手続きを提供します。

 -- Function: md5-digest
     Reads data from the current input port until EOF, and returns its digest in an incomplete string. 現在の入力ポートからEOFまで読み込み、そのダイジェストを不完全文字列で返します。

 -- Function: md5-digest-string string
     Digest the data in STRING, and returns the result in an incomplete string. STRINGにあるデータをダイジェストし、その結果を不完全文字列で返します。

rfc.mime - MIME message handling
================================

 -- Module: rfc.mime
     This module provides utility procedures to handle Multipurpose Internet Mail Extensions (MIME) messages, defined in RFC2045 thorough RFC2049. Provided APIs include procedures to parse or compose MIME-specific header fields, and parse or compose MIME-encoded message bodies. RFC2045からRFC2049で定義されている、多目的インターネットメール拡張(Multipurpose Internet Mail Extensions; MIME) メッセージを扱う便利な手続きです。MIME特有のヘッダフィールドやメッセージボディをパーズしたり作成したりするAPIが提供されます。

     This module mainly focuses on providing low-level building-block procedures, on top of which application-specific modules are to be built. For example, rfc.http uses this module to compose multipart/form-data message for the body of POST requests (see HTTP). このモジュールは主としてビルディングブロックとなる低レベルの手続きにフォーカスしており、アプリケーション特有のモジュールがこの上に構築されることを意図しています。例えばrfc.httpはPOSTリクエストのボディをmultipart/form-dataとして構築する際にこのモジュールを利用します(HTTP参照)。

     This module is supposed to be used with rfc.822 module (see RFC822 message parsing). このモジュールは、rfc.822モジュールと一緒に使うことを想定しています(RFC822 message parsing参照)。

Utilities for header fields
---------------------------

A few utility procedures to parse and generate MIME-specific header fields. MIME特有のヘッダフィールドをパーズしたり生成したりする便利な手続き。

 -- Function: mime-parse-version field
     If FIELD is a valid header field for MIME-Version, returns its major and minor versions in a list.  Otherwise, returns #f. It is allowed to pass #f to FIELD, so that you can directly pass the result of rfc822-header-ref to it. Given parsed header list by rfc822-read-headers, you can get mime version (currently, it should be (1 0)) by the following code. FIELDがそのMIMEバージョンのヘッダフィールドとして有効であれば、そのメジャーバージョン番号とマイナーバージョン番号をリストにして返します。そうでなければ、#fを返します。 FIELDには#fを渡せるので、rfc822-header-refの戻り値を直接渡すこともできます。rfc822-read-headersにより返されるパーズ済みヘッダのリストを渡すことで、以下のように MIMEのバージョンを得ることができます。(現在は、(1 0)です。)

          (mime-parse-version (rfc822-header-ref headers "mime-version"))

     Note: simple regexp such as #/\d+\.\d+/ doesn't do this job, for FIELD may contain comments between tokens. 注意: FIELDはトークンの間にコメントを含むかもしれないので、 #/\d+\.\d+/のような単純な正規表現では不十分です。

 -- Function: mime-parse-content-type field
     Parses the "content-type" header field, and returns a list such as: ``content-type''ヘッダフィールドをパーズし、次のようなリストを返します。

          (type subtype (attribute . value) ...)

     where type and subtype are MIME media type and subtype in a string, respectively ここで、typeとsubtypeはそれぞれ、MIMEメディアタイプとサブタイプを文字列で表したものになります。

          (mime-parse-content-type "text/html; charset=iso-2022-jp")
           => ("text" "html" ("charset" . "iso-2022-jp"))

     If FIELD is not a valid content-type field, #f is returned. FIELDが有効なcontent-typeフィールドでない場合は、 #fが返ります。

 -- Function: mime-parse-content-disposition field
     Parses Content-disposition header field as specified in RFC2183. RFC2183に定められたContent-Dispositionヘッダフィールドをパーズします。 (mime-parse-content-disposition "attachment; filename=genome.jpeg;\ modification-date=\"Wed, 12 Feb 1997 16:29:51 -0500\";") => ("attachment" ("filename" . "genome.jpeg") ("modification-date" . "Wed, 12 Feb 1997 16:29:51 -0500"))

 -- Function: mime-parse-parameters :optional iport
 -- Function: mime-compose-parameters params :optional oport :key start-column
     These are low-level utility procedures to parse and compose parameter part of header fields (as appeared in RFC2045 Section 5.1 etc).

     Mime-parse-parameters reads the parameter part of the header body from an input port IPORT, and returns an assoc list of the parameter names and values. Conversely, mime-compose-parameters takes an assoc list of names and values, compose parameter part and emit it to OPORT.   When omitted, the current input port and the current output port are used for IPORT and OPORT, respectively.  You can pass #f to OPORT and mime-compose-parameters returns the result in a string instead of emitting it to a port. これらは、(RFC2045の5.1節にあるような)ヘッダフィールドの値のparameter 部分をパーズしたり作成したりするための低レベルのユーティリティ手続きです。

     mime-parse-parametersはヘッダフィールドの値のパラメータ部分を入力ポートIPORTから読んでパーズし、パラメータの名前と値の連想リストを返します。 mime-compose-parametersはその逆で、連想リストをとり、パラメータ部分を構成してOPORTへと書き出します。 IPORT、OPORTはそれぞれ省略された場合、 current-input-portとcurrent-output-portをデフォルトとします。また、OPORTに#fを渡すと mime-compose-parametersは結果をポートに書き出すかわりに文字列として返します。

          (call-with-input-string
             "; name=foo; filename=\"foo/bar/baz\""
             mime-parse-parameters)
           => (("name" . "foo") ("filename" . "foo/bar/baz"))

          (mime-compose-parameters
           '(("name" . "foo") ("filename" . "foo/bar/baz"))
           #f)
           => "; name=foo; filename=\"foo/bar/baz\""

     Mime-compose-parameters tries to insert folding line breaks between parameters to avoid the header line becomes too long. You can pass the beginning column position of the parameter part via START-COLUMN argument. MIME-COMPOSE-PARAMETERSはヘッダ行が長くなりすぎる場合にパラメータ間に折り返し改行を入れようとします。パラメータ部分が始まるカラム数はSTART-COLUMNで与えることができます。

     We plan to make these procedures handle RFC2231's parameter value extension transparently in future. 将来は、これらの手続きにRFC2231のパラメータ値拡張を透過的に処理させる予定です。

 -- Function: mime-decode-word word
     Decodes RFC2047-encoded word.  If WORD isn't an encoded word, it is returned as is.

     Note that this procedure decodes only if the entire WORD is an ``encoded word'' defined in RFC2047.  If you are dealing with a field that may contain multiple encoded word and/or unencoded parts, use mime-decode-text below. RFC2047でエンコードされたWORDをデコードします。 WORDがRFC2047でエンコードされたものでない場合は、そのまま返されます。

     この手続きはWORD全体がRFC2047の規定する``encoded-word''である場合にのみデコードを行うことに注意してください。複数のエンコードされた部分やエンコードされていない部分が混ざっているフィールドを扱う場合は、下に示すmime-decode-textを使います。

          (mime-decode-word "=?iso-8859-1?q?this=20is=20some=20text?=")
           => "this is some text"

 -- Function: mime-decode-text text
     Returns a string in which all encoded words contained within TEXT are decoded. This procedure can deal with a header field body that may contain mixture of non-encoded and encoded parts, and/or multiple encoded parts.  One of such header field is the Subject field of email.

          (mime-decode-text "This is =?US-ASCII?q?some=20text?=")
           => "This is some text"

     TEXT中に含まれるすべてのencoded wordをデコードした文字列を返します。この手続きは、エンコードされていない部分とエンコードされている部分が混ざっていたり、複数のエンコードされている部分を持つヘッダフィールドボディを処理することができます。そのようなフィールドの例はemailのSubjectフィールドです。

          (mime-decode-text "Yamada Taro (=?utf-8?B?5bGx55SwIOWkqumDjg==?=)")
           => "Yamada Taro (山田 太郎)"

     Care should be taken if you apply this procedure to a ``structured'' header field body (see RFC2822 section 2.2.2). The proper way of parsing a structured header field body is to tokenize it first, then to decode each word using mime-decode-word. since the decoded text may contain characters that affects the tokenization. (However, if you can just show the header field in human readable way for informational purposes, you may just use mime-decode-text on entire header field for the convenience). この手続きを「構造化された」ヘッダフィールドボディ (RFC2822 2.2.2節参照) に適用する際には注意が必要です。構造化されたヘッダフィールドボディをパーズする正式な方法は、最初にトークンに分割して、それから各wordを mime-decode-wordを使ってデコードするというものです。なぜならデコード後のテキスト中に、パージングに影響を与える文字が含まれているかもしれないからです。 (ただし、単に参考情報を人間にわかりやすいように表示するだけの目的の場合は、簡便のためにヘッダフィールド全体をこの手続きで一度にデコードしてしまっても良いでしょう)。

 -- Function: mime-encode-word word :key charset transfer-encoding
     Encodes WORD in the RFC2047 format.  The keyword argument CHARSET specifies the character encoding scheme in string or symbol. whose default is utf-8.  If CHARSET differs from Gauche's internal encoding and WORD is a complete string, the procedure converts the character encoding to CHARSET, then performs transfer encoding. WORDをRFC2047フォーマットにエンコードします。キーワード引数 CHARSETは文字列かシンボルで文字エンコーディングスキームを指定します。デフォルトはutf-8です。CHARSETの指定がGaucheの内部文字エンコーディングと異なっており、WORDが完全な文字列である場合は、まずWORDがCHARSETのエンコーディングへと変換され、その上でトランスファーエンコーディングがかけられます。

          (mime-encode-word "this is some text")
           => "=?utf-8?B?dGhpcyBpcyBzb21lIHRleHQ=?="

     The keyword argument TRANSFER-ENCODING specifies how the octets are encoded to transfer-safe characters.  You can give a symbol b, B or base64 for Base64, and Q, q, quoted-printable for Quoted-printable transfer encodings.  An error is raised if you pass values other than those.  The default is Base64 encoding. キーワード引数TRANSFER-ENCODINGは各オクテットを伝達上安全な文字列へどエンコードする方法を指定します。サポートされている値は、 Base64を指定するシンボルb、B、base64、およびQuoted printableを指定する Q、q、quoted-printableです。これ以外の値を渡した場合はエラーが通知されます。デフォルトはBase64です。

     This procedure does not consider the length of the resulting encoded word, which RFC2047 recommends to be less than 75 octets. Use mime-encode-text below to conform the line length limit. この手続きは結果のencoded wordの長さを気にしませんが、 RFC2047によればencoded wordは75オクテットまでに収めることが要請されています。この要請に対応するには下に示す mime-encode-textを使って下さい。

     (Note: In most Gauche procedures, a keyword argument encoding is used to specify character encodings.  In this context we have two encodings, however, and to avoid the confusion we chose to use the terms ``charset'' and ``transfer-encoding'' that appear in RFC documents.) (註：ほとんどのGaucheの手続きでは、キーワード引数encodingにより文字エンコーディングを指定します。しかしこの手続きの文脈では 2つの「エンコーディング」が存在しているので、混乱を避けるために RFC文書で使われている``charset''および``transfer-encoding''の用語を使うこととしました。)

 -- Function: mime-encode-text text :key charset transfer-encoding line-width start-column force
     Encode TEXT in RFC2047 format if necessary, and considering line folding if the result gets too long.

     The keyword arguments CHARSET and TRANSFER-ENCODING are the same as mime-encode-word. TEXTを、必要ならばRFC2047フォーマットに従いエンコードします。また、結果が長すぎる場合の行の折り返しも考慮します。

     キーワード引数CHARSETとTRANSFER-ENCODINGの意味は mime-encode-wordと同じです。

     If the TEXT only consists of printable ASCII characters, no encoding is done, and only line folding is considered. However, if a true value is given to the FORCE argument, even ASCII-only TEXT is encoded. もしWORDが印字可能なASCII文字のみで構成されていた場合はエンコーディングは行われず、行の折り返しのみが処理されます。但し、FORCE引数に真の値が与えられた場合はASCIIのみのTEXTもエンコードされます。

     The LINE-WIDTH specifies the maximum line width of the result. Its default is 76. If the encoded word gets too long, it is splitted to multiple encoded words and CR LF SPC sequence (``folding white space'' defined in RFC2822) are inserted inbetween. You can suppress this behavior by passing #f or 0 to LINE-WIDTH. Since encoded word needs some overhead characters, it doesn't make much sense to specify small value to line-width.  Current implementation rejects line-width smaller than 30. LINE-WIDTHは結果に現れる行の最大値を指定します。デフォルトは76です。 encoded wordがこれを越える場合は、複数のencoded wordへと結果は分割され、間にCR LF SPCシーケンス(RFC2822で定義される``folding white space'')が挿入されます。 LINE-WIDTHに#fか0を渡すことで行の折り返しを抑制することができます。 encoded wordには文字数でいくらかのオーバヘッドがあるため、あまり小さいline-widthには意味がありません。現在の実装では 30以下の値は拒否されます。

     The START-COLUMN keyword argument can be used to shorten the first of folded lines to make room for header field name.  For example, if you want to encode the body of a Subject header field, you can pass the value of (string-length "Subject: ") so that the encoded result can directly concatenated after the header field name.  The default value is 0. START-COLUMNキーワード引数は、ヘッダフィールド名を入れるためにエンコード結果の最初の行だけを短くするのに使えます。例えばSubjectヘッダフィールドのボディをエンコードする際に、 (string-length "Subject: ")の値を渡してやれば、結果を直接"Subject: "の後に連結することができるわけです。デフォルトの値は0です。

     This procedure is not designed to encode parts of structured header fields, which have further restrictions such as which parts can be encoded and where the folding white spaces can be inserted. The robust way is to encode some parts first, then construct a structured header fields, considering line folding. この手続きはstructured header fieldをエンコードするようには設計されていません。structured header fieldには、どの部分がエンコード可能でどの部分にfolding white spaceが挿入可能かについてさらなる制約があるためです。安全な方法は、まず必要な部分をエンコードし、それから折り返しを考慮しつつstructured header fieldを組み立てることです。

Streaming parser
----------------

The streaming parser is designed so that you can decide how to do with the message body before the entire message is read. メッセージ全体が読み込まれる前にメッセージボディをどのように扱うかをコントロールできるように、ストリームパーザが用意されています。

 -- Function: mime-parse-message port headers handler
     The fundamental streaming parser.  PORT is an input port from where the message is read.  HEADERS is a list of headers parsed by rfc822-read-headers; that is, this procedure is supposed to be called after the header part of the message is parsed from PORT: 基本的なストリームパーザです。PORTは、メッセージを読み込む入力ポートです。HEADERSはrfc822-read-headersによりパーズされたヘッダのリストです。つまり、この手続きは、 PORTから読み込まれたメッセージのヘッダ部分がパーズされた後に使われることを想定しています。

          (let* ((headers (rfc822-read-headers port)))
            (if (mime-parse-version (rfc822-header-ref headers "mime-version"))
               ;; parse MIME message
               (mime-parse-message port headers handler)
               ;; retrieve a non-MIME body
               ...))

     Mime-parse-message analyzes HEADERS, and calls HANDLER on each message body with two arguments: mime-parse-messageはHEADERSを解析し、メッセージボディのそれぞれについて、2引数をもって HANDLERを呼び出します。

          (handler PART-INFO XPORT)

     PART-INFO is a <mime-part> structure described below that encapsulates the information of this part of the message. PART-INFOは、以下で説明するような、メッセージのこのパートの情報をカプセル化した<mime-part>ストラクチャです。

     XPORT is an input port, initially points to the beginning of the body of message.  The handler can read from the port as if it is reading from the original PORT.  However, XPORT recognizes MIME boundary internally, and returns EOF when it reaches the end of the part. (Do not read from the original PORT directly, or it will mess up the internal state of VPORT). XPORTは入力ポートで、最初はメッセージボディの先頭を指しています。ハンドラはこのポートからメッセージボディを読み込むことが出来ます。 XPORTはMIMEバウンダリを認識し、パートの最後に到達したら EOFを返します。 (元のPORTから直接読み込まないようにして下さい。そうしてしまうと、VPORTの内部状態がおかしくなります)。

     HANDLER can read the part into the memory, or save it to the disk, or even discard the part. Whatever it does, it has to read from VPORT until it returns EOF.

     The return value of HANDLER will be set in the content slot of PART-INFO. HANDLERは、パートをメモリに読み込んだり、ディスクに保存したり、あるいはそのパートを無視したりできます。ただ、何をするにせよ、 VPORTがEOFを返すまでデータを読まなければなりません。

     HANDLERの戻り値は、PART-INFOのcontentスロットにセットされます。

     If the message has nested multipart messages, HANDLER is called for each "leaf" part, in depth-first order.  HANDLER can know its nesting level by examining PART-INFO structure. メッセージが、ネストしたマルチパートメッセージを含んでいる場合は、 HANDLERは深さ優先でそれぞれの``葉''のパートに対して呼ばれます。 HANDLERは、PART-INFOストラクチャを調べることで、そのネストのレベルを知ることができます。

     The message doesn't need to be a multipart type; if it is a MIME message type, HANDLER is called on the body of enclosed message.  If it is other media types such as text or application, HANDLER is called on the (only) message body. メッセージはマルチパートである必要はありません。メッセージが MIME messageタイプである場合は、HANDLERは囲まれたメッセージのボディに対して呼ばれます。メッセージが、textやapplication などの他のメディアタイプの場合は、HANDLERは単にメッセージボディに対して呼ばれます。

 -- Class: <mime-part>
     A structure that encloses metainformation about a MIME part. It is constructed when the header of the part is read, and passed to the handler that reads the body of the part.

     It has the following slots: MIMEパートのメタ情報を含むストラクチャです。これは、そのパートのヘッダが読み込まれた時点で構築され、そのパートのボディを読み込むハンドラに渡されます。

     以下のスロットを持ちます。

      -- Instance Variable of <mime-part>: type
          MIME media type string.  If content-type header is omitted to the part, an appropriate default value is set. MIMEメディアタイプの文字列。そのパートのcontent-typeヘッダが省略された場合は、適切なデフォルト値がセットされます。

      -- Instance Variable of <mime-part>: subtype
          MIME media subtype string.  If content-type header is omitted to the part, an appropriate default value is set. MIMEメディアのサブタイプの文字列。そのパートのcontent-type ヘッダが省略された場合は、適切なデフォルト値がセットされます。

      -- Instance Variable of <mime-part>: parameters
          Associative list of parameters given to content-type header field. content-typeヘッダフィールドに渡されるパラメータの連想リスト。

      -- Instance Variable of <mime-part>: transfer-encoding
          The value of content-transfer-encoding header field. If the header field is omitted, an appropriate default value is set. content-transfer-encodingヘッダフィールドの値。このヘッダフィールドが省略された場合は、適切なデフォルト値がセットされます。

      -- Instance Variable of <mime-part>: headers
          The list of header fields, as parsed by rfc822-read-headers. rfc822-read-headersによりパーズされた、ヘッダフィールドのリスト。

      -- Instance Variable of <mime-part>: parent
          If this is a part of multipart message or encapsulated message, points to the enclosing part's <mime-part> structure. Otherwise #f. それがマルチパートメッセージあるいはカプセル化されたメッセージのパートである場合は、それを含んでいるパートの<mime-part> ストラクチャを指します。そうでなければ#fを返します。

      -- Instance Variable of <mime-part>: index
          Sequence number of this part within the same parent. 同じ親を持つパートの中でのそのパートのシーケンス番号。

      -- Instance Variable of <mime-part>: content
          If this part is multipart/* or message/* media type, this slot contains a list of parts within it. Otherwise, the return value of HANDLER is stored. そのパートのメディアタイプがmultipart/*あるいはmessage/*である場合は、このスロットにはそれに含まれるパートのリストが入っています。そうでなければ、HANDLERの戻り値が格納されています。

      -- Instance Variable of <mime-part>: source
          This slot is only used when composing a MIME message. The caller can set this slot a name of the file to be inserted into this part, instead of setting the entire content of the file to the content slot.   See mime-compose-message below for the more details. このスロットはMIMEメッセージを作成する時のみ使われます。呼び出し元は、このスロットにファイル名をセットすることで、 MIMEメッセージのこのパートにファイルの内容を挿入することができます。詳しくは下のmime-compose-messageの項を参照してください。

 -- Function: mime-retrieve-body part-info xport outp
     A procedure to retrieve message body.  It is intended to to be a building block of HANDLER to be passed to mime-parse-message.

     PART-INFO is a <mime-part> object. XPORT is an input port passed to the handler, from which the MIME part can be read. メッセージボディを取得するための手続きです。 mime-parse-messageへ渡される、HANDLERのビルディングブロックとなることを意図しています。

     PART-INFOは、<mime-part>のオブジェクトです。 XPORTはハンドラに渡された入力ポートで、そこからMIMEパートが読みこまれるものです。

     This procedure read from XPORT until it returns EOF.  It also looks at the transfer-encoding of PART-INFO, and decodes the body accordingly; that is, base64 encoding and quoted-printable encoding is handled.  The result is written out to an output port OUTP.

     This procedure does not handle charset conversion. The caller must use CES conversion port as OUTP (see Character code conversion) if desired. この手続きは、XPORTからEOFに達するまで読み込み、 PART-INFOのtransfer-encodingも見て、ボディを適切にデコードします。つまり、base64やquoted-printable のエンコーディングは適切に処理されます。結果が出力ポートOUTPへと出力されます。

     この手続きは文字集合の変換は扱いません。必要であれば、呼び出し側がOUTPとしてCES変換ポートを使う必要があります(Character code conversion参照)。

A couple of convenience procedures are defined for typical cases on top of mime-retrieve-body. 典型的なケースのために、いくつかの便利な手続きがmime-retrieve-body の上に定義されています。

 -- Function: mime-body->string part-info xport
 -- Function: mime-body->file part-info xport filename
     Reads in the body of mime message, decoding transfer encoding, and returns it as a string or writes it to a file, respectively. MIMEメッセージのボディを読み込み、転送(transfer)エンコーディングをデコードし、それぞれ文字列として返すか、ファイルへ書き出します。

The simplest form of MIME message parser would be like this: MIMEメッセージパーザの最もシンプルな使い方は次のようになります。

     (let ((headers (rfc822-read-headers port)))
       (mime-parse-message port headers
                           (cut mime-body->string <> <>)))

This reads all the message on memory (i.e. the "leaf" <mime-part> objects' content field would hold the part's body as a string), and returns the top <mime-part> object.  Content transfer encoding is recognized and handled, but character set conversion isn't done.

You may want to feed the message body to a file directly, or even want to skip some body according to mime media types and/or other header information.  Then you can put the logic in the handler closure.  That's the reason that this module provides building blocks, instead of all-in-one procedure. これは、メッセージの全てをメモリに読み込み、一番上層の<mime-part>オブジェクトを返します。 (``葉''である<mime-part>オブジェクトのcontentフィールドは、そのパートのボディを文字列として保持しています。) 内容の転送エンコーディング(content transfer encoding)は認識され処理されますが、文字集合の変換は行われません。

メッセージボディを直接ファイルに書き出したり、MIMEメディアタイプや他のヘッダ情報に基づいていくつかのボディをスキップしたいかもしれません。その場合は、ロジックをハンドラのクロージャに入れることができます。それが、このモジュールが、オールインワンの手続きではなく、ビルディングブロックを提供している理由です。

Message composer
----------------

 -- Function: mime-compose-message parts :optional port :key boundary
 -- Function: mime-compose-message-string parts :key boundary
     Composes a MIME multipart message.  Mime-compose-message emits the result to an output port PORT, whose default is the current output port.  Mime-compose-message-string makes the result into a string.   You can give a boundary string via BOUNDARY argument; when omitted, a fresh boundary string is automatically generated by mime-make-boundary below.

     Mime-compose-message returns the boundary string. Mime-compose-message-string returns two values, the result string and the boundary string.

     The content of the message is provided by the PARTS argument, which can be a list of instances of <mime-part> (see above) or lists that describe parts.  The list form is supported for the caller's convenience, and internally it is converted to a list of <mime-part>s.

     The syntax of each part element in PARTS are defined as follow.

          <part>           : <mime-part> | <mime-part-desc>

          <mime-part>      : an instance of the class <mime-part>

          <mime-part-desc> : (<content-type> (<header> ...) <body>)
          <content-type>   : (<type> <subtype> <header-param> ...)
          <header-param>   : (<key> . <value>) ...
          <header>         : (<header-name> <encoded-header-value>)
                           | (<header-name> (<header-value> <header-param> ...))
          <body>           : a string
                           | (file <filename>)
                           | (subparts <part> ...)

     Note: In the first form of <header>, <encoded-header-value> must already be encoded using RFC2047 or RFC2231 if the original value contains non-ascii characters. In the second form, we plan to do RFC2231 encoding on behalf of the caller; but the current version does not implement it.  The caller should not pass encoded words in this form, since it may result double-encoding when we implement the auto encoding feature; for the time being, the second form restricts ASCII-only values.

     If <body> is a string, it is used as the part's content. If <body> is (file FILENAME), the content is read from the named file.   If <body> is (subparts PART ...), the part becomes nested MIME part.

     It is the caller's responsibility to give the proper content. For example, if <body> is in the third form, the part must have multipart content type.

     The caller needs to provide proper content-transfer-encoding header, depending on the application.  If none is given, the content is inserted into the message as is, which may be appropriate for some applications, but if you want to use the result in email message you certainly want to encode binary part with base64, for example.

 -- Function: mime-make-boundary
     Returns a unique string that can be used as a boundary of a MIME multipart message. MIMEマルチパートメッセージのboundaryとして使えるユニークな文字列を返します。

rfc.quoted-printable - Quoted-printable encoding/decoding
=========================================================

 -- Module: rfc.quoted-printable
     This module defines a few functions to encode/decode Quoted-printable format, defined in RFC 2045 (https://www.ietf.org/rfc/rfc2045.txt), section 6.7. このモジュールでは、RFC 2045 (https://www.ietf.org/rfc/rfc2045.txt) のセクション6.7で定義されている、Quoted-printableフォーマットにエンコード/からデコードするためのいくつかの関数を定義しています。

 -- Function: quoted-printable-encode :key line-width binary
     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. 現在の入力ポートからバイトストリームを読み込み、それをQuoted-printable フォーマットにエンコードし、現在の出力ポートへ結果の文字ストリームを書き出します。この変換は、現在の入力ポートからEOFを読み出すと終了します。 The keyword argument LINE-WIDTH specifies the maximum line width of the generated output in characters.  If the encoded output creates a long line, the procedure inserts a ``soft line break'' so that the each line is equal to or shorter than this number. Soft line breaks are removed when quoted-printable text is decoded. The default line width is 76.  (The minimum meaningful number of line-width is 4).  You can suppress soft line breaks by giving #f or 0 to LINE-WIDTH. キーワード引数LINE-WIDTHは、出力に現れる行の最大長を指定します。エンコードされた行の長さがこの値を越えそうな場合は、「ソフトラインブレーク」が適宜挿入され、各行の長さがこの値を越えないように調整されます。ソフトラインブレークはquoted-printableフォーマットのデコード時に取り除かれます。 LINE-WIDTHのデフォルト値は76です。(最小の意味のある値は4です。) LINE-WIDTHに#fまたは0を渡せば、ソフトラインブレークは挿入されません。 By default, quoted-printable-encode generates CR-LF sequence for each line break in the input (``hard line break''). When a true value is given to the keyword argument BINARY, however, octets #x0a and #x0d in the input are encoded as =0A and =0D, respectively.  See RFC2045 section 6.7 for the details. デフォルトでは、quoted-printable-encodeは入力中の改行に対して CR-LFシーケンスを出力します(「ハードラインブレーク」)。しかし、BINARYキーワード引数に真の値が与えられた場合、入力中のオクテット#x0aおよび#x0dはそれぞれ =0A、=0Dのようにエンコードされます。詳しくはRFC2045の6.7節を参照してください。

 -- Function: quoted-printable-encode-string string :key line-width binary
     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.

     The keyword arguments are the same as quoted-printable-encode. STRINGの内容をQuoted-printableエンコードされたフォーマットに変換します。入力の文字列は、完全文字列でも不完全文字列でも構いません。常にバイトシーケンスとして処理されます。

     キーワード引数はquoted-printable-encodeと同じです。

 -- 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. 現在の入力ポートから文字ストリームを読み込み、それをQuoted-printable フォーマットからデコードし、結果のバイトストリームを現在の出力ポートへ書き出します。この変換は、EOFを読み出すと終了します。不正なシーケンス('='の後に16進文字が続かない、など)に出会うと、それらをリテラルのまま出力へコピーします。

 -- Function: quoted-printable-decode-string string
     Decodes a Quoted-printable encoded string STRING and returns the result as a string. Quoted-printableエンコードされた文字列STRINGをデコードし、その結果を文字列で返します。

rfc.sha - SHA message digest
============================

 -- Module: rfc.sha
     This module implements US Secure Hash Algorithm defined in RFC 4634.  It provides SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512 (the latter four are sometimes referred as SHA-2 collectively).

     The module extends util.digest (see Message digester framework). このモジュールは、RFC 4634で定義されている US Secure Hash Algorithmを実装しています。提供されるアルゴリズムはSHA-1, SHA-224, SHA-256, SHA-384および SHA-512です (後の4つを総称してSHA-2と呼ぶこともあります)。

     このモジュールは、util.digest (Message digester framework参照) を拡張しています。

 -- Module: rfc.sha1
     This is the old module that provided only SHA-1.  It is kept as an alias of rfc.sha for the backward compatibility.  New code should use rfc.sha. これはSHA-1だけを提供していた古いモジュールです。互換性のため、この名前はrfc.shaの別名として残されています。新たに書くコードはrfc.shaを使ってください。

 -- Class: <sha1>
 -- Class: <sha224>
 -- Class: <sha256>
 -- Class: <sha384>
 -- Class: <sha512>
     An instance of these class keeps internal state of SHA digest algorithm.

     This class implements util.digest framework interface, digest-update!, digest-final!, digest, and digest-string. See Message digester framework, for detailed explanation of these methods. これらのクラスのインスタンスは、SHAダイジェストアルゴリズムの内部状態を保持しています。

     このクラスは、util.digestフレームワークのインターフェース、 digest-update!、digest-final!、digest、 digest-stringを実装しています。これらのメソッドの詳細な説明は、Message digester frameworkを参照して下さい。

Besides the digester framework, this module provides to short-cut procedures. ダイジェスタフレームワークに加えて、このモジュールはショートカット手続きを提供します。

 -- Function: sha1-digest
 -- Function: sha224-digest
 -- Function: sha256-digest
 -- Function: sha384-digest
 -- Function: sha512-digest
     Reads data from the current input port until EOF, and returns its digest in an incomplete string. 現在の入力ポートからデータをEOFまで読み込み、そのダイジェストを不完全文字列で返します。

 -- Function: sha1-digest-string string
 -- Function: sha224-digest-string string
 -- Function: sha256-digest-string string
 -- Function: sha384-digest-string string
 -- Function: sha512-digest-string string
     Digest the data in STRING, and returns the result in an incomplete string. STRINGのデータをダイジェストし、その結果を不完全文字列で返します。

rfc.tls - Transport layer security
==================================

 -- Module: rfc.tls
     This module handles secure connection over TCP socket. This module is used by rfc.http to realize https connection (see HTTP). このモジュールはTCPソケット上のセキュアな接続を処理します。 rfc.httpで、https接続を実現するのに使われています (HTTP参照)。

CA certificates
---------------

You need CA certificates to verify server certificates properly. Gauche doesn't have its own CA certificates, and relies on the system's certificate store by default.  On Unix-based systems, we search several known locations: On popular Linux distributions we recommend you to install ca-certificates package (or similar one). On OSX, we recommend to install openssl via Homebrew.  On Windows, we use system's certificate store via Wincrypt API. サーバの認証を適切に行うためには、CA証明書が必要です。 Gaucheは自前でCA証明書を持っておらず、デフォルトでシステムのCA証明書バンドルを利用します。 Unixベースのシステムでは、いくつかのよくあるパスを探索します。例えばLinuxディストリビューションならca-certificatesやそれに類するパッケージをインストールしておくと良いでしょう。 OSXではopensslをHomebrewでインストールしておくのをおすすめします。 WindowsではWincrypt API経由でシステムの証明書ストアを使います。

With the default configuration, Gauche checks the availability of the system's certificate store at initilization and use one if available.  You can explicitly give the path of CA certificate bundle, or disable it and provide individual certificate per connection. デフォルトのコンフィグレーションでは、Gaucheは初期化時にシステムのCA証明書バンドルを探し、見つかればそれを使うようになっています。かわりとなるCA証明書バンドルのパスを指定したり、接続毎に独自の証明書を与えることもできます。

If, for some reasons, you cannot install system-wide CA certificate bundle, you can also download Curl's CA certificate bundle https://curl.haxx.se/ca/cacert.pem, and install it in Gauche installation directory.  We have a convenience script. After installing Gauche, run the following command: もし、何らかの理由で、システム全体で使えるCA証明書バンドルがインストールできない場合、独自にCurlのCA証明書バンドルをhttps://curl.haxx.se/ca/cacert.pemからダウンロードしてGaucheのインストールディレクトリに置いておくことができます。便利なスクリプトが用意してあります。 Gaucheをインストールした後、次のコマンドを実行してください。

     gosh rfc/tls/get-cacert.scm

You need curl installed on your system.  If you've installed Gauche with root priviledge, you'll be asked sudo password to install the CA bundle file.

If you decided to do this, make sure you run the above command occasionally to get updated CA certificate bundles, for certificates may expire or be revoked. curlがシステムにインストールされている必要があります。また、Gaucheをインストールする時に root権限で行ったのであれば、このコマンドがCA証明書バンドルをインストールする時に sudoのパスワードを尋ねるでしょう。

もしこの方法を取ることに決めたなら、時々このコマンドを実行してCA証明書バンドルを最新版に更新するのを忘れないようにしてください。 CA証明書は期限が切れたり無効化されることがあります。

 -- Parameter: tls-ca-bundle-path :optional path
     Holds CA certificate bundle to be used.  The value can be either a string path to a CA bundle file, a symbol system, or #f. CA証明書バンドルのパスを保持しています。値は、CA証明書バンドルファイルのパス名、シンボルsystem、あるいは#fのいずれかです。

     If it is system, Gauche uses system's default bundle. An error is signaled on connection if Gauche can't find one. この値がsystemの場合、Gaucheはシステムのデフォルトの証明書バンドルを使おうとします。もしそれが見つからなければ接続時にエラーが報告されます。

     If it is #f, CA certificate won't be loaded automatically, and you have to manually load one using tls-load-object. (Note: This option is only valid with <ax-tls>.  If you're using <mbed-tls>, you need valid CA certificate bundle.) この値が#fの場合、CA証明書は自動的にロードされないので、 tls-load-objectを使って自分で適切な証明書をロードしてやる必要があります。 (このオプションは<ax-tls>のみ有効です。 <mbed-tls>を使う場合は、必ず有効なCA証明書バンドルが必要です。)

     With the default configuration, Gauche scans the system CA bundle when rfc.tls module is initialized, and if it finds one, tls-ca-bundle-path is set to system; otherwise, tls-ca-bundle-path is set to #f.  So if you're using with default configuration and you see its value is system, you can count on the system CA certificate bundle. デフォルトのコンフィグレーションでは、Gaucheはrfc.tlsモジュール初期化時にシステムのCA証明書バンドルが使えるかどうか調べて、使えるならtls-ca-bundle-pathの初期値をsystemに、使えないなら#fにセットします。したがって、デフォルトのコンフィグレーションで使っている限り、この値がsystemであればシステムのCA証明書を使えると考えて良いでしょう。

     This default behavior may be altered if Gauche is configured with --with-ca-bundle option.  You can execute gauche-config --reconfigure command to see if special --with-ca-bundle option is given. このデフォルトの振る舞いはconfigure時に--with-ca-bundleオプションで変えられます。使っているGaucheのコンフィグレーションが変えられているかどうかは、 gauche-config --reconfigureコマンドを実行して--with-ca-bundle オプションがあるかどうかを見ればわかります。

Supported TLS subsystems
------------------------

Gauche supports two TLS subsystems - one based on AxTLS (http://axtls.sourceforge.net/), and the other based on MbedTLS (https://tls.mbed.org/).  Whether they're included depends on the configuration options.  By default, AxTLS support is compiled in, and MbedTLS support is included if the build platform has MbedTLS library installed. Gaucheは二つのTLSサブシステムをサポートしています。ひとつはAxTLS(http://axtls.sourceforge.net/)、もうひとつはMbedTLS(https://tls.mbed.org/)です。 configureのオプションによって組み込まれるものが変わりますが、デフォルトではAxTLSは常に組み込まれ、 MbedTLSはビルド時にシステムにインストールされていれば組み込まれます。

AxTLS library has advanage of being included in Gauche, so that it won't depend on external library, however, its supported ciphers are limited, and it can't connect to some https sites.  MbedTLS has wider cipher support, but it requires MbedTLS dynamic libraries (e.g. libmbedtls.so) at runtime. AxTLSライブラリはGaucheの一部としてコンパイルされるので、使うのに外部ライブラリに依存しないという利点がありますが、サポートしている暗号スイートが限られていて、時々接続できないhttpsサイトがあります。一方、MbedTLSは幅広い暗号スイートをサポートしていますが、実行時に MbedTLSの動的ライブラリ(libmbedtls.soなど)を必要とします。

Gauche chooses available TLS subsystem at runtime, so the user usually does not need to worry about the difference.  If you're building Gauche by yourself, we recommend to use the default configuration, on a system that has MbedTLS installed.   That will give you the most flexible choice. Gaucheは実行時に使える範囲で適切なTLSサブシステムを選択するので、ユーザが違いを意識する必要はほとんどありません。自分でGaucheをビルドする場合は、 MbedTLSがインストールされた環境で、デフォルトのコンフィグレーションでビルドすることを推奨します。それが最も柔軟な選択となるでしょう。

Whether the running Gauche has any of TLS support can be checked with a feature identifier gauche.net.tls.  Availability of each individual subsystems can be checked with feature identifiers gauche.net.tls.axtls and gauche.net.tls.mbedtls, respectively. See Feature conditional, for more about feature identifiers. Gaucheに何らかのTLSサポートが組み込まれているかどうかは機能識別子 gauche.net.tlsで、それぞれのサブシステムが使えるかどうかは機能識別子gauche.net.tls.axtlsとgauche.net.tls.mbedtlsで検査できます。機能識別子についてはFeature conditionalを参照してください。

 -- Class: <tls>
     An abstract base class of TLS implementations.

 -- Class: <ax-tls>
     A class that implements axTLS subsystem interface.

 -- Class: <mbed-tls>
     A class that implements mbedTLS subsystem interface.

 -- Parameter: default-tls-class :optional class
     Set/get the default TLS subsystem to be used.  Without arguments, it return a class (either <ax-tls> or <mbed-tls> to be used. With one argument, which must be either <ax-tls> or <mbed-tls>, changes the default and returns the previous value.

TLS interface
-------------

 -- Function: make-tls initargs ...
     Creates and returns a new TLS instance of the class default-tls-class. The returned TLS instance can be used for the tls procedures below.

     The arguments must be a keyword-value list, and passed to the constructor of the TLS class.

     :server-name
          Server name to be used for TLS Server Name Indication extension.

     :num-sessions
          [AxTLS only] The number of sessions ot be used for session caching. 0 indicates no sessino caching.

     :options
          [AxTLS only] Bitflags of options.  Logical OR of the following numeric constants.

     SSL_SERVER_VERIFY_LATER
          (client only) Let handshake success even the server authentication fails.

     SSL_CLIENT_AUTHENTICATION
          (server only) Request client sertificate to be authenticated.

 -- Function: tls-connect tls socket
     Establishes TLS connection as a client.  The TLS argument must be an unconnected TLS object, and the SOCKET argument must be a connected socket.  On success, it returns TLS, which is in connected state.  It can be used to read/write data from/to the connected peer.

     The SOCKET is owned by TLS object and should not be directly accessed after calling this procedure.

 -- Function: tls-accept tls socket
     Establishes TLS connection as a server.  The TLS argument must be an unconnected TLS object, and the SOCKET argument must be a listening socket.  On success, it returns TLS, which is in connected state.  It can be used to read/write data from/to the connected peer.

 -- Function: tls-close tls
     Shuts down the underling connection.  The peer will notified the connection is closed. Once TLS is closed, it can no longer be used, but the reosurces won't be collected until TLS is GC-ed or tls-destroy is called.  We recommend the user call tls-destroy explicitly.

 -- Function: tls-destroy tls
     Releases resources associated to TLS.

 -- Function: tls-input-port tls
 -- Function: tls-output-port tls
     If TLS is connected, it returns input and output port to communicate with the peer, respectively.

     If TLS is not connected, #f is returned.

 -- Function: tls-load-object tls type filename :optional password
     This procedure is only meaningful for <axl-tls>.  For <mbed-tls>, this procedure does nothing.

     Load private keys or certificates stored in a file specified by FILENAMES.  The type of object is specified by TYPE argument with one of the following numberic constants.  If the file requires a password, it should be given to PASSWORD.

     SSL_OBJ_X509_CERT

     SSL_OBJ_X509_CACERT

     SSL_OBJ_RSA_KEY

     SSL_OBJ_PKCS8

     SSL_OBJ_PKC12

 -- Constant: SSL_OBJ_X509_CERT
 -- Constant: SSL_OBJ_X509_CACERT
 -- Constant: SSL_OBJ_RSA_KEY
 -- Constant: SSL_OBJ_PKCS8
 -- Constant: SSL_OBJ_PKCS12

rfc.uri - URI parsing and construction
======================================

 -- Module: rfc.uri
     Provides a set of procedures to parse and construct Uniform Resource Identifiers defined in RFC 2396 (https://www.ietf.org/rfc/rfc2396.txt), as well as Data URI scheme defined in RFC2397. RFC 2396 (https://www.ietf.org/rfc/rfc2396.txt)で定義されている Uniform Resource Identifiers、またRFC 2397で定義されているData URI Schemeをパーズおよび構築する手続き群を提供します。

First, lets review the structure of URI briefly. The following graph shows how the URI is constructed:

     URI-+-scheme
         |
         +-specific--+--authority-+--userinfo
                     |            +--host
                     |            +--port
                     +--path
                     +--query
                     +--fragment

Not all URIs have this full hierarchy.  For example, mailto:admin@example.com has only scheme (mailto) and specific (admin@example.com) parts.

Most popular URI schemes, however, organize resources in a tree, so they adopt authority (which usually identifies the server) and the hierarchical path.  In the URI http://example.com:8080/search?q=key#results, the authority part is example.com:8080, the path is /search, the query is key and the fragment is results. The userinfo can be provided before hostname, such as anonymous in ftp://anonymous@example.com/pub/.

We have procedures that decompose a URI into those parts, and that compose a URI from those parts.

Parsing URI
-----------

URIのパーズ
-------

 -- Function: uri-ref uri parts
     Extract specific part(s) from the given URI.  You can fully decompose URI by the procedures described below, but in actual applications, you often need only some of the parts.  This procedure comes handy for it.

     The PARTS argument may be a symbol, or a list of symbols, to name the desired parts.  The recognized symbos are as follows.

     scheme
          The scheme part, as string.

     authority
          The authority part, as string. If URI doesn't have the part, #f.

     userinfo
          The userinfo part, as string.  If URI doesn't have the part, #f.

     host
          The host part, as string.  If URI doesn't have the part, #f.

     port
          The port part, as integer.  If URI doesn't have the part, #f.

     path
          The path part, as string.  If URI isn't hierarchical, this returns the specific part.

     query
          The query part, as string. If URI doesn't have the part, #f.

     fragment
          The fragment part, as string.  If URI doesn't have the part, #f.

     scheme+authority
          The scheme and authority part.

     host+port
          The host and port part.

     userinfo+host+port
          The userinfo, host and port part.

     path+query
          The path and query part.

     path+query+fragment
          The path, query and fragment part.

          (define uri "http://foo:bar@example.com:8080/search?q=word#results")

          (uri-ref uri 'scheme)             => "http"
          (uri-ref uri 'authority)          => "//foo:bar@example.com:8080/"
          (uri-ref uri 'userinfo)           => "foo:bar"
          (uri-ref uri 'host)               => "example.com"
          (uri-ref uri 'port)               => 8080
          (uri-ref uri 'path)               => "/search"
          (uri-ref uri 'query)              => "q=word"
          (uri-ref uri 'fragment)           => "results"
          (uri-ref uri 'scheme+authority)   => "http://foo:bar@example.com:8080/"
          (uri-ref uri 'host+port)          => "example.com:8080"
          (uri-ref uri 'userinfo+host+port) => "foo:bar@example.com:8080"
          (uri-ref uri 'path+query)         => "/search?q=word"
          (uri-ref uri 'path+query+fragment)=> "/search?q=word#results"

     You can extract multiple parts at once by specifying a list of parts. A list of parts is returned.

          (uri-ref uri '(host+port path+query))
            => ("example.com:8080" "/search?q=word")

 -- Function: uri-parse uri
 -- 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, since the parts to be decoded differ among the uri schemes.   After parsing uri, use uri-decode below to decode them. URIの一般的なパーザです。これらの関数はURIエンコーディングをデコードしません。URIスキームによってどの部分をデコードすべきかが異なるからです。パージングを行った後に、後述のuri-decode等を使ってデコードを行ってください。

     uri-parse is the most handy procedure.  It breaks the uri into the following parts and returns them as multiple values. If the uri doesn't have the corresponding parts, #f are returned for the parts.

       * URI scheme as a string (e.g. "mailto" in "mailto:foo@example.com").

       * User-info in the authority part (e.g. "anonymous" in ftp://anonymous@ftp.example.com/pub/foo).

       * Hostname in the authority part (e.g. "ftp.example.com" in ftp://anonymous@ftp.example.com/pub/foo).

       * Port number in the authority part, as an integer (e.g. 8080 in http://www.example.com:8080/).

       * Path part (e.g. "/index.html" in http://www.example.com/index.html).

       * Query part (e.g. "key=xyz&lang=en" in http://www.example.com/search?key=xyz&lang=en).

       * Fragment part (e.g. "section4" in http://www.example.com/document.html#section4).

     uri-parseは最も手軽な手続きで、uriを以下に示す部分に分割し、多値で返します。もし該当する部分がuriに無かった場合は、その部分には#fが返ります。

       * URIスキームを文字列で。 (例： "mailto:foo@example.com"の"mailto")。

       * authorityパートのuser-infoを文字列で。 (例： ftp://anonymous@ftp.example.com/pub/fooの"anonymous")。

       * authorityパートのhostnameを文字列で。 (例： ftp://anonymous@ftp.example.com/pub/fooの "ftp.example.com")。

       * authorityパートのport番号を整数で。 (例： http://www.example.com:8080/の8080)。

       * pathパート。 (例： http://www.example.com/index.htmlの"/index.html")。

       * queryパート。 (例： http://www.example.com/search?key=xyz&lang=enの "key=xyz&lang=en")。

       * fragmentパート。 (例： http://www.example.com/document.html#section4の "section4")。

     The following procedures are finer grained and break up uris with different stages. 以下の手続きはより詳細に、段階をふんでuriを分割してゆくものです。

     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 は URI URI を引数に取り、スキーム部分と、そのスキーム特有の部分を表す2つの値を返します。 URI がスキーム部分を持たない場合、#f を返します。

          (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 が階層的な記法を用いている場合、すなわち、 ``//AUTHORITY/PATH?QUERY#FRAGMENT'' のような場合、スキーム特有の部分を uri-decompose-hierarchical に渡すと、AUTHORITY、PATH、QUERY、FRAGMENT の4つの値が返ります。

          (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 の AUTHORITY の部分を uri-decompose-authority に渡すと、USERINFO、 HOST、PORT が返ります。

          (uri-decompose-authority "yyy.jp:8080")
            => #f, "yyy.jp" and "8080"
          (uri-decompose-authority "[::1]:8080")  ;(IPv6 host address)
            => #f, "::1" and "8080"
          (uri-decompose-authority "mylogin@yyy.jp")
            => "mylogin", "yyy.jp" and #f

 -- Function: uri-decompose-data uri
     Parse a Data URI string URI.  You can either pass the entire uri including data: scheme part, or just the specific part. If the passed uri is invalid as a data uri, an error is signalled.

     Returns two values: parsed content type and the decoded data. The data is a string if the content type is text/*, and a u8vector otherwise.

     The content-type is parsed by mime-parse-content-type (see MIME message handling).  The result format is a list as follows: Data URI文字列URIをパーズします。data:スキームは有っても無くても構いません。渡されたuriがdata uriとして無効な文字列であればエラーが投げられます。

     二つの値、パーズされたContent-Typeおよびデコードされたデータを返します。 Content-Typeがtext/*であればデコードされたデータは文字列で、そうでなければu8vectorで返されます。

     Content-Typeはmime-parse-content-typeでパーズされます (MIME message handling参照)。結果のデータ形式は次のようなリストです。

          (type subtype (attribute . value) ...).

     Here are a couple of examples: いくつか例を示します。

          (uri-decompose-data
           "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ==")
            => ("text" "plain" ("charset" . "utf-8")) and "(hello world)"

          (uri-decompose-data
           "data:application/octet-stream;base64,AAECAw==")
            => ("application" "octet-stream") and #u8(0 1 2 3)

Constructing URI
----------------

URIの構築
------

 -- Function: uri-compose :key 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: 与えられたコンポーネントから URI を構成します。妥当な URI を作成するためのコンポーネントの組み合わせはたくさんあります。以下のダイアグラムは、考え得る組み合わせの方法を示しています。

                  /-----------------specific-------------------\
                  |                                            |
           scheme-+------authority-----+-+-------path*---------+-
                  |                    | |                     |
                  \-userinfo-host-port-/ \-path-query-fragment-/

     If #f is given to a keyword argument, it is equivalent to the absence of that keyword argument. It is particularly 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: キーワード引数に #f が与えられた場合、それはキーワード引数が指定されないことと等価です。これは URI をパーズした結果を渡す場合に特に有用です。

     コンポーネントに適切でない文字が含まれている場合は、 url-compose に渡す前に正しくエスケープされなければなりません。

     いくつかの例を示します。

          (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-merge base-uri relative-uri relative-uri2 ...
     Arguments are strings representing full or part of URIs.  This procedure resolves RELATIVE-URI in relative to BASE-URI, as defined in RFC3986 Section 5.2. ``Relative Resolution''.

     If more RELATIVE-URI2s are given, first RELATIVE-URI is merged to BASE-URI, then the next argument is merged to the resulting uri, and so on. 引数は、完全な、あるいは部分的なURIを表す文字列です。この手続きは、RFC3986 Section 5.2. ``Relative Resolution'' に示されるアルゴリズムに従い、RELATIVE-URIをBASE-URIからの相対として解決します。

     RELATIVE-URI2 ... が与えられた場合は、まずRELATIVE-URI がBASE-URIを基準に解決され、その結果を新たな基準として次の RELATIVE-URI2を解決し、以下同様に続けます。

          (uri-merge "http://example.com/foo/index.html" "a/b/c")
           => "http://example.com/foo/a/b/c"

          (uri-merge "http://example.com/foo/search?q=abc" "../about#me")
           => "http://example.com/about#me"

          (uri-merge "http://example.com/foo" "http://example.net/bar")
           => "http://example.net/bar"

          (uri-merge "http://example.com/foo/" "q" "?xyz")
           => "http://example.com/foo/q?xyz"

 -- Function: uri-compose-data data :key content-type encoding
     Creates a Data URI of the given DATA, with specified content-type and transfer encoding.  Returns a string.

     The DATA argument must be a string or a u8vector.

     The CONTENT-TYPE argument can be #f (default), a string that represents a content type (e.g. "text/plain;charset=utf-8"), or a list form of parsed content type (e.g. ("application" "octet-stream").  If it is #f, text/plain with the gauche's native character encoding is used when DATA is a complete string, and application/octet-stream is used otherwise.

     The ENCODING argument can be either #f (default), or a symbol uri or base64.  This is for transfer encoding, not character encoding.  If it is #f, URI encoding is used for text data and base64 encoding is used for binary data. 与えられたDATAからData URIを構築して文字列で返します。

     DATA引数は文字列かu8vectorでなければなりません。

     CONTENT-TYPEキーワード引数は、#f (デフォルト)、 content typeを表現する文字列 (例: "text/plain;charset=utf-8")、もしくはパーズされたcontent type (例: ("application" "octet-stream"))です。 #fである場合は、DATAが完全な文字列であれば text/plainにGaucheのネイティブ文字エンコーディングに基づくcharsetをつけたもの、DATAがそれ以外であればapplication/octet-streamが使われます。

     ENCODINGキーワード引数は#f (デフォルト)、もしくはシンボルuriまたはbase64です。これは文字エンコーディングではなくトランスファーエンコーディングであることに注意。 #fの場合は、テキストデータならuriが、バイナリデータならbase64が使われます。

          (uri-compose-data "(hello world)")
           => "data:text/plain;charset=utf-8,%28hello%20world%29"

          (uri-compose-data "(hello world)" :encoding 'base64)
           => "data:text/plain;charset=utf-8;base64,KGhlbGxvIHdvcmxkKQ=="

          (uri-compose-data '#u8(0 1 2 3))
           => "data:application/octet-stream;base64,AAECAw=="

URI Encoding and decoding
-------------------------

URIのエンコードとデコード
--------------

 -- Function: uri-decode :key :cgi-decode
 -- Function: uri-decode-string string :key :cgi-decode :encoding
     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.

     To uri-decode-string you can provide the external character encoding by the ENCODING keyword argument.  When it is given, the decoded octet sequence is assumed to be in the specified encoding and converted to the Gauche's internal character encoding. URI エンコーディング、すなわち、%でエスケープされた URI 文字列をデコードします。uri-decode は現在の入力ポートから入力を受け取り、デコードした結果を現在の出力ポートに書き出します。 uri-decode-string は STRING を入力とし、デコードした文字列を返します。

     CGI-DECODE が真の場合は、+ がスペース文字に置換されます。

     uri-decode-stringには、外部の文字エンコーディングを指定する ENCODINGキーワード引数を与えることができます。この引数が与えれた場合、デコードされたオクテットの列を指定された文字エンコーディングであるとしてGaucheの内部文字エンコーディングへと変換したものが返されます。

 -- Function: uri-encode :key :noescape
 -- Function: uri-encode-string string :key :noescape :encoding
     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 RFC3986 are escaped.  You can pass different character set to NOESCAPE argument to keep from being encoded. For example, the older RFC2396 has several more ``unreserved'' characters, and passing *rfc2396-unreserved-char-set* (see below) prevents those characters from being escaped.

     The multibyte characters are encoded as the octet stream of Gauche's native multibyte representation by default.  However, you can pass the encoding keyword argument to uri-encode-string, to convert STRING to the specified character encoding. 安全でない文字を、%によるエスケープでエンコードします。 uri-encode は現在の入力ポートから入力を受け取り、結果を現在の出力ポートに書き出します。 uri-encode-string は STRING を入力とし、エンコードした文字列を返します。

     デフォルトでは、RFC3986 で"非予約文字"として規定されていない文字はエスケープされます。NOESCAPE 引数に異なる文字集合を渡すことで、それらがエンコードされるのを抑止することができます。例えば古いRFC2396では"非予約文字"がいくつか多かったのですが、 *rfc2396-unreserved-char-set* (下記参照) を渡すことでそれらの文字がエスケープされるのを防ぐことができます。

     マルチバイト文字は、デフォルトではGauche のネイティブなマルチバイト表現のオクテット・ストリームとしてエンコードされます。ただし uri-encode-stringにはENCODINGキーワード引数を渡すことができて、その場合はまずSTRINGが指定された文字エンコーディングへと変換されます。

 -- Constant: *rfc2396-unreserved-char-set*
 -- Constant: *rfc3986-unreserved-char-set*
     These constants are bound to character sets that represents ``unreserved'' characters defined in RFC2396 and RFC3986, respectively. (See Character sets, and R7RS character sets, for operations on character sets). これらの定数はそれぞれ、RFC2396とRFC3986で定義されている「非予約文字」の文字集合に束縛されています。 (文字集合の操作については、Character setsおよびR7RS character sets を参照して下さい。)

rfc.uuid - UUID
===============

 -- Module: rfc.uuid
     This module implements UUID defined in RFC4122.

     It provides generators of UUID version 1 and 4, and writer/parser of the string represenation of UUIDs.

 -- Class: <uuid>
     Class of UUID instances.

 -- Function: uuid-value uuid
     Returns the raw value of UUID as 16-element u8vector. You shouldn't mutate the returned u8vector.

 -- Function: uuid-version uuid
     Returns the version number of UUID.

 -- Variable: uuid-comparator
     A comparator to compare and hash uuids.  See Basic comparators.

 -- Function: uuid-random-source-set! random-source
     We use PRNG to generate UUIDs.  By default, we internally creates a random source and randomize it.  You can pass in your own random source instead (see Sources of random bits, for the details).

 -- Function: uuid1 :optional node-id
     Generates a uuid with version 1 algorithm (timestamp and node id based). The optional NODE-ID argument must be 48bit exact integer specifing the node ID (IEEE802 MAC address of the machine). If it is omitted, we generate a process-global random node ID (with the multicast bit set to 1, so that it won't conflict with existing MAC address).

 -- Function: uuid4
     Generates a uuid with version 4 algorithm (random numbers).

 -- Function: nil-uuid
     Returns a nil-UUID (all bits zero).

 -- Function: parse-uuid string
     Takes a string representation of UUID, parses it and returns an uuid instance.  If the string isn't a valid UUID representation, an error is thrown.

     Other than XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format, it recognizes the one with urn:uuid: prefix, the one enclosed by curly braces, and the one without hyphens.

 -- Function: write-uuid uuid :optional port
     Writes out a string representation of UUID, in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format, to the given port.  If the port is omitted, current output port is used.

 -- Function: uuid->string uuid
     Returns a string representation of UUID, in XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX format.

rfc.zlib - zlib compression library
===================================

 -- Module: rfc.zlib
     This module provides bindings to zlib compression library. Most features of zlib can be used through this module.

     Zlib supports reading and writing of Zlib compressed data format (RFC1950), DEFLATE compressed data format (RFC1951), and GZIP file format (RFC1052).  It also provides procedures to calculate CRC32 and Adler32 checksums.

     Compression and decompression are done through specialized ports. There are number of parameters to fine-tune compression; refer to zlib documentation for the details. このモジュールは、Zlib圧縮ライブラリに対するバインディングを提供します。 Zlibのほとんどの機能がこのモジュールを通して利用可能です。

     Zlibは、ZLIB圧縮データフォーマット(RFC1950)、DEFLATE圧縮データフォーマット(RFC1951)、GZIPファイルフォーマット(RFC1952)の読み書きをサポートするライブラリです。また、CRC32とAdler32チェックサムの計算のための関数も提供します。

     圧縮・展開機能はポートを通して提供されます。圧縮をチューンするパラメータの詳細については、Zlibのドキュメントも合わせて参照してください。

Condition types
---------------

The following condition types are defined to represent errors during processing by zlib. Zlib処理中のエラーを示すために、以下のコンディションタイプが定義されています。

 -- Condition Type: <zlib-error>
     Subclass of <error> and superclass of the following condition types.  This class is an abstract class to catch any of the zlib-specific errors.  Zlib-specific errors raised by procedures in rfc.zlib are always an instance (or a compound condition including) one of the following specific classes. <error>のサブクラスで、以下のコンディションタイプのスーパークラスです。このクラスはzlib特有のエラーをまとめて捕捉するための抽象クラスとして設けられています。 rfc.zlibが投げるZlib固有のエラーは常に以下の特定のクラスのインスタンス、もしくはそのインスタンスを含む複合コンディションです。

 -- Condition Type: <zlib-need-dict-error>
 -- Condition Type: <zlib-stream-error>
 -- Condition Type: <zlib-data-error>
 -- Condition Type: <zlib-memory-error>
 -- Condition Type: <zlib-version-error>
     Subclasses of <zlib-error>.  Those condition type correspond to zlib's Z_NEED_DICT_ERROR, Z_STREAM_ERROR, Z_DATA_ERROR, Z_MEMORY_ERROR, and Z_VERSION_ERROR errors. <zlib-error>のサブクラスです。それぞれ、Zlibの Z_NEED_DICT_ERROR、 Z_STREAM_ERROR、 Z_DATA_ERROR、 Z_MEMORY_ERROR、 Z_VERSION_ERROR に対応します。

     When an error occurs during reading data, a compound condition of a subclass of <zlib-error> and <io-read-error> is raised. When an error occurs without I/O, a simple condition of a subclass of <zlib-error> is raised. Errors unrelated to zlib, such as invalid argument error, would be a simple <error> condition. データの読み出し時にエラーが発生した場合、 <zlib-error>のサブクラスと <io-read-error>の合成コンディションが投げられます。入力が伴わない場合、例えば圧縮ストリームの初期化エラーのときには、合成されていない<zlib-error>のサブクラスが投げられます。ただの引数の型のエラーのように、Zlibの関数が呼び出されない場合は、ただの<error>が投げられるかもしれません。

Compression/decompression ports
-------------------------------

 -- Class: <deflating-port>
 -- Class: <inflating-port>
     Compression and decompression functions are provided via ports.  A deflating port is an output port that compresses the output data.  An inflating port is an input that reads compressed data and decompress it.

     When an inflating port encounters a corrupted compressed data, a compound condition of <io-read-error> and <zlib-data-error> is raised during read operation. 圧縮と展開の機能はポートを通じて提供されます。 deflating portは出力されたデータを圧縮する出力ポートです。 inflating portは圧縮されたデータソースからデータを展開しつつ読み込む入力ポートです。

     inflating portが読み出す圧縮データが壊れていた場合、読み出し時に <io-read-error>と<zlib-data-error>の合成コンディションが投げられます。

 -- Function: open-deflating-port drain :key compression-level buffer-size window-bits memory-level strategy dictionary owner?
     Creates and returns an instance of <deflating-port>, an output port that compresses the output data and sends the compressed data to another output port DRAIN. This combines the functionality of zlib's deflateInit2() and deflateSetDictionary(). 新たな<deflating-port>のインスタンス、すなわち書き込まれたデータを圧縮し出力ポートDRAINに書き出す出力ポートを作成して、そのポートを返します。Zlibの関数deflateInit2()と deflateSetDictionary()とを合わせた手続きです。

     You can specify an exact integer between 1 and 9 (inclusive) to COMPRESSION-LEVEL.  Larger integer means larger compression ratio. When omitted, a default compression level is used, which is usually 6. COMPRESSION-LEVELには1から9の整数を指定することができ、大きい数が高い圧縮率を意味します。引数が省略された場合は、デフォルトの圧縮レベルと見なされます。これは通常6です。

     The following constants are defined to specify COMPRESSION-LEVEL conveniently: COMPRESSION-LEVELをわかりやすく指定するために以下の定数が定義されています。

      -- Constant: Z_NO_COMPRESSION
      -- Constant: Z_BEST_SPEED
      -- Constant: Z_BEST_COMPRESSION
      -- Constant: Z_DEFAULT_COMPRESSION

     The BUFFER-SIZE argument specifies the buffer size of the port in bytes. The default is 4096. BUFFER-SIZEは、ポートのバッファサイズを指定します。デフォルトは4096バイトです。

     The WINDOW-BITS argument specifies the size of the window in exact integer.   Typically the value should be between 8 and 15, inclusive, and it specifies the base two logarithm of the window size used in compression. Larger number yields better compression ratio, but more memory usage. The default value is 15. WINDOW-BITSはウィンドウサイズを指定します。通常この値は8から15までの整数で、圧縮に使われるウィンドウサイズの 2を底とするlogをとった値です。大きい数であるだけ圧縮率が高くなりますが、そのぶんメモリの使用量が増加します。デフォルトは15です。

     There are a couple of special modes specifiable by WINDOW-BITS. When an integer between -8 and -15 is given to WINDOW-BITS, the port produces a raw deflated data, that lacks zlib header and trailer.  In this case, Adler32 checksum isn't calculated.  The actual window size is determined by the absolute value of WINDOW-BITS. WINDOW-BITSよって、2つばかり特別なモードを指定することができます。 WINDOW-BITSに-8から-15の整数を指定された場合は、 ZLIBヘッダとトレイラのない生のdeflateデータを作成します。この場合Adler32チェックサムも計算されません。実際のウィンドウサイズはWINDOW-BITSの絶対値によって計算されます。

     When WINDOW-BITS is between 24 and 31, the port uses GZIP encoding; that is, instead of zlib wrapper, the compressed data is enveloped by simple gzip header and trailer. The gzip header added by this case doesn't have filenames, comments, header CRC and other data, and have zero modified time, and 255 (unknown) in the OS field.  The zstream-adler32 procedure will return CRC32 checksum instead of Adler32. The actual window size is determined by WINDOW-BITS-16. WINDOW-BITSが24から31の間である場合、ポートはgzipエンコーディングを使うようになります。すなわち、 zlibラッパの代わりに、シンプルなgzipヘッダとトレイラが圧縮データの前後に書き出されます。 gzipヘッダはファイル名やその他のデータ、コメントを持たず、変更時刻は0、ヘッダCRCはなし、OS名は不明を意味する255になります。gzipストリームが書き出されるときは、zstream-adler32で取得できるチェックサムはAdler32 ではなくCRC32になります。実際のウィンドウサイズは WINDOW-BITS-16 で決定されます。

     The MEMORY-LEVEL argument specifies how much memory should be allocated to keep the internal state during compression. 1 means smallest memory, which causes slow and less compression. 9 means fastest and best compression with largest amount of memory. The default value is 8. MEMORY-LEVELは、圧縮の内部状態のためにどれだけのメモリを割り当てるかを指定するパラメータです。1ではメモリの使用量は最小ですが、遅くなり圧縮率が低下します。9では高速な処理のためにメモリが最も多く使われます。デフォルトは8です。

     To fine tune compression algorithm, you can use the STRATEGY argument.  The following constants are defined as the valid value as STRATEGY: STRATEGYで圧縮アルゴリズムをチューンできます。以下の定数がSTRATEGYに有効な値として定義されています。

      -- Constant: Z_DEFAULT_STRATEGY
          The default strategy, suitable for most ordinary data. 通常のデータに適する、デフォルトのアルゴリズムを使います。

      -- Constant: Z_FILTERED
          Suitable for data generated by filters. Filtered data consists mostly of small values with a random distribution, and this makes the compression algorithm to use more huffman encoding and less string match. フィルタにより生成されたデータに適したアルゴリズムを使います。このようなデータは小さな値とランダムな分散を持つことが多いため、このアルゴリズムではハフマンエンコーディングをより優先し、文字列一致の使用をやや抑えます。

      -- Constant: Z_HUFFMAN_ONLY
          Force huffman encoding only (no string match). ハフマンエンコーディングのみを使います (文字列一致を使いません)。

      -- Constant: Z_RLE
          Limit match distance to 1 (that is, to force run-length encoding). It is as fast as Z_HUFFMAN_ONLY and gives better compression for png image data. マッチ距離を1に制限します (ランレングスエンコーディングを強制することになります)。 Z_HUFFMAN_ONLYと同じくらい高速で、かつpngイメージデータに対して良い圧縮率が得られます。

      -- Constant: Z_FIXED
          Prohibits dynamic huffman encoding.  It allows a simple decoder for special applications. 動的ハフマンエンコーディングを禁止します。特殊なアプリケーションで、単純なデコーダを使いたい場合に便利です。

     The choice of STRATEGY only affects compression ratio and speed.  Any choice produces correct and decompressable data. STRATEGYの選択は圧縮率と速度にのみ影響を与えます。どの値を選んでも圧縮されたデータは正しく展開できます。

     You can give an initial dictionary to the DICTIONARY argument to be used in compression. The compressor and decompressor must use exactly the same dictionary. See the zlib documentation for the details. DICTIONARYには圧縮に使う辞書を文字列で与えます。辞書を与える場合、圧縮と展開で全く同じものを使う必要があります。辞書の詳細についてはzlibのドキュメントを参照してください。

     By default, a deflating port leaves DRAIN open after all conversion is done, i.e. the deflating port itself is closed.  If you don't want to bother closing DRAIN, give a true value to the OWNER? argument; then DRAIN is closed after the deflating port is closed and all data is written out. デフォルトでは、deflating portはそれ自身がクローズされても DRAINをクローズしません。DRAINの後始末を気にしたくない場合はOWNER?引数に真の値を与えてください。その場合、deflating portがクローズされすべてのデータが書き出されたのちに DRAINは自動的にクローズされます。

     Note: You must close a deflating port explicitly, or the compressed data can be chopped prematurely. When you leave a deflating port open to be GCed, the finalizer will close it; however, the order in which finalizers are called is undeterministic, and it is possible that the DRAIN port is closed before the deflating port is closed.  In such cases, the deflating port's attempt to flush the buffered data and trailer will fail. 注意: deflating portは必ず明示的にクローズしてください。そうしなければ圧縮データの終わりの部分(バッファされているデータおよびトレイラ)が DRAINに書き出されないかもしれません。ポートを明示的にクローズせずにガベージ・コレクタに任せた場合、出力ポートのクローズ手続きはファイナラザから呼び出されることになります。複数のごみに対してファイナライザの呼ばれる順番は不定なので、 deflating portより先にDRAINのファイナライザが呼ばれてそのポートがクローズされてしまうことがあります。こうなると、圧縮データの終わりの部分の出力がエラーになってしまいます。

 -- Function: open-inflating-port source :key buffer-size window-bits dictionary owner?
     Takes an input port SOURCE from which a compressed data can be read, and creates and returns a new instance of <inflating-port>, that is, a port that allows decompressed data from it. This procedure covers zlib's functionality of inflateInit2() and inflateSetDictionary(). 圧縮データを読み出せる入力ポートSOURCEを取り、新たな<inflating-port>のインスタンス、すなわち展開されたデータを読み出すことのできる入力ポートを作成し、そのポートを返します。これはZlibの関数inflateInit2()、inflateSetDictionary() を合わせた手続きです。

     The meaning of BUFFER-SIZE and OWNER are the same as open-deflating-port. BUFFER-SIZE、OWNER?の意味は open-deflating-portと同じです。

     The meaning of WINDOW-BITS is almost the same, except that if a value increased by 32 is given, the inflating port automatically detects whether the source stream is zlib or gzip by its header. WINDOW-BITSの意味もほぼ同じですが、 32が足された値が与えられた場合にはZLIBとGZIPのヘッダ自動判定が有効になります。

     If the input data is compressed with specified dictionary, the same dictionary must be given to the DICTIONARY argument. Otherwise, a compound condition of <io-read-error> and <zlib-need-dict-error> will be raised. DICTIONARYは圧縮時の辞書と同じものを指定しなければなりません。辞書を使って圧縮されたデータを展開する際に、DICTIONARY引数を指定しなかったり、異なる辞書を与えた場合は <io-read-error>と<zlib-need-dict-error>の合成コンディションが投げられます。

Operations on inflating/deflating ports
---------------------------------------

 -- Function: zstream-total-in xflating-port
 -- Function: zstream-total-out xflating-port
 -- Function: zstream-adler32 xflating-port
 -- Function: zstream-data-type xflating-port
     The XFLATING-PORT argument must be either inflating and deflating port, or an error is raised.

     Returns the value of total_in, total_out, ADLER32, and data_type fields of the z_stream structure associated to the given inflating or deflating port, respectively. XFLATING-PORTはinflating portかdeflating portでなければなりません。さもなくばエラーが通知されます。

     z_stream構造体のtotal_in、total_out、 adlre32およびdata_typeフィールドの値を返します。

     The value of data_type can be one of the following constants: data_typeフィールドの値は以下の定数のうちのいずれかです。

      -- Constant: Z_BINARY
      -- Constant: Z_TEXT
      -- Constant: Z_ASCII
      -- Constant: Z_UNKNOWN

 -- Function: zstream-params-set! deflating-port :key compression-level strategy
     Changes compression level and/or strategy during compressing. 圧縮率とストラテジを動的に変更するための手続きです。

 -- Function: zstream-dictionary-adler32 deflating-port
     When a dictionary is given to open-deflating-port, the dictionary's adler32 checksum is calculated.  This procedure returns the checksum.  If no dictionary has been given, this procedure returns #f. deflating portの作成時に辞書を指定すると、辞書のAdler32チェックサムが計算されます。この手続きはそのチェックサムを返します。 open-deflating-portに辞書を与えなかったなら、#fが返ります。

 -- Function: deflating-port-full-flush deflating-port
     Flush the data buffered in the DEFLATING-PORT, and resets compression state.  The decompression routine can skip the data to the full-flush point by inflate-sync. ポートのデータをフルフラッシュし、圧縮状態をリセットします。展開ルーチンはinflate-sync手続きを使って入力をこの地点までスキップすることができます。

 -- Function: inflate-sync inflating-port
     Skip the (possibly corrupted) compressed data up to the next full-flush point marked by deflating-port-full-flush. You may want to use this procedure when you get <zlib-data-error>.  Returns the number of bytes skipped when the next full-flush point is found, or #f when the input reaches EOF before finding the next point. 圧縮データを、deflating-port-full-flushによってフルフラッシュしたポイントまで読み飛ばします。 <zlib-data-error>が投げられたときに使用するとよいでしょう。フルフラッシュポイントに達したときは読み飛ばしたバイトの数を、EOFまで達したときは#fを返します。

Miscellaneous API
-----------------

 -- Function: zlib-version
     Returns Zlib's version in string. Zlibのバージョンを文字列で返します。

 -- Function: deflate-string string options ...
     Compresses the given string and returns zlib-compressed data in a string.  All optional arguments are passed to open-deflating-port as they are. 与えられた文字列を圧縮し、zlib圧縮されたデータを文字列で返します。すべてのオプション引数はそのままopen-deflating-portに渡されます。

 -- Function: inflate-string string options ...
     Takes zlib-compressed data in string, and returns decompressed data in a string.  All optional arguments are passed to open-inflating-port as they are. Zlib圧縮されたデータを文字列で受け取り、展開されたデータを文字列で返します。すべてのオプション引数はそのままopen-deflating-portに渡されます。

 -- Function: gzip-encode-string string options ...
 -- Function: gzip-decode-string string options ...
     Like deflate-string and inflate-string, but uses the gzip format instead.  It is same as giving more than 15 to the WINDOW-BITS argument of deflate-string and inflate-string. deflate-stringおよびinflate-stringと似ていますが、 GZIPフォーマットを使います。これは deflate-stringおよびinflate-stringの WINDOW-BITSに15以上の値指定するのと同じです。

 -- Function: crc32 string :optional checksum
     Returns CRC32 checksum of STRING.  If optional CHECKSUM is given, the returned checksum is an update of CHECKSUM by STRING. 文字列STRINGのCRC32チェックサムを計算して返します。CHECKSUM 引数が与えられた場合は、それをSTRINGによるチェックサムで更新した値が返されます。

 -- Function: adler32 string :optional checksum
     Returns Adler32 checksum of STRING.  If optional CHECKSUM is given, the returned checksum is an update of CHECKSUM by STRING.

     Calculating Adler32 is faster than CRC32, but it is known to produce uneven distribution of hash values for small input. See RFC3309 for the detailed description.  If it matters, use CRC32 instead. 文字列STRINGのAdler32チェックサムを計算して返します。CHECKSUM 引数が与えられた場合は、それをSTRINGによるチェックサムで更新した値が返されます。

     Adler32はCRC32と比較して高速に計算することが可能なアルゴリズムですが、小さなデータのチェックサムの信頼性にいくらか問題があることがわかっています。詳しくはRFC3309を見てください。これが問題になる場合はCRC32を使用してください。

slib - SLIB interface
=====================

 -- Module: slib
     This module is the interface to the Aubrey Jaffer's SLIB. To use SLIB, say (use slib).   SLIB itself is not included in Gauche distribution.   If you don't have it on your system, get it from http://www-swiss.ai.mit.edu/~jaffer/SLIB.html. このモジュールはAubrey Jaffer氏のSLIBへのインタフェースです。 SLIBがインストールされている場合、(use slib) とすれば SLIBの機能が使えるようになります。 SLIBそのものはGaucheのディストリビューションには含まれていません。あなたのシステムにまだインストールされていない場合は http://www-swiss.ai.mit.edu/~jaffer/SLIB.htmlから入手することができます。

     By default, the SLIB installation is searched from the directory specified at the Gauche configuration.  If SLIB isn't there, an error is signaled.  In that case, you can set the environment variable SCHEME_LIBRARY_PATH to point to the SLIB installation path. デフォルトでは、インストールされたSLIBはGaucheのconfiguration時に指定された場所から探されます。SLIBがそこになければ、エラーが報告されます。その場合、環境変数SCHEME_LIBRARY_PATHでSLIBがインストールされたパスを指定してください。

     This module redefines require, shadowing the Gauche's original require.  If it gets a symbol as an argument, it works as SLIB's require, while if it gets a string, it works as Gauche's require.   The same applies to provide and provided?. このモジュールはrequireを再定義し、Gaucheオリジナルのrequireをシャドウします。requireにシンボルが渡された場合はSLIBのrequire のように動作します。requireに文字列が渡された場合はGaucheのrequire のように動作します。provideとprovided?についても同様です。

     All SLIB symbol bindings, loaded by require, stay in the module slib. requireでロードされる、SLIBで導入されるすべての定義は、 slibモジュール内で行われます。

     (use slib)         ; load and set up slib
     (require 'getopt)  ; load SLIB's getopt module
     (require "foo")    ; load Gauche's foo module

sxml.ssax - Functional XML parser
=================================

 -- Module: sxml.ssax
     sxml.* modules are the adaptation of Oleg Kiselyov's SXML framework (http://okmij.org/ftp/Scheme/xml.html), which is based on S-expression representation of XML structure. sxml.*モジュールは、XML構造のS式表現に基づく Oleg KiselyovのSXMLフレームワーク(http://okmij.org/ftp/Scheme/xml.html)の適合です。

     SSAX is a parser part of SXML framework. This is a quote from SSAX webpage: SSAXは、SXMLフレームワークのパーザ部分です。以下は、 SSAXのウェブページからの引用です。

          A SSAX functional XML parsing framework consists of a DOM/SXML parser, a SAX parser, and a supporting library of lexing and parsing procedures. The procedures in the package can be used separately to tokenize or parse various pieces of XML documents. The framework supports XML Namespaces, character, internal and external parsed entities, attribute value normalization, processing instructions and CDATA sections. The package includes a semi-validating SXML parser : a DOM-mode parser that is an instantiation of a SAX parser (called SSAX). SSAXは関数的なXMLパージングフレームワークで、DOM/SXMLパーザ、SAXパーザ、字句解析・構文解析手続きのサポートライブラリから構成されます。パッケージ内の手続きは、XML文書の様々な部分をトークナイズ、あるいはパーズするために独立して使うことができます。このフレームワークは、XML名前空間、文字、内部および外部解析済み実体、属性値の正規化、処理命令とCDATAセクションをサポートしています。パッケージは、ある程度の妥当性検査を行うSXMLパーザ: SAXパーザのインスタンスであるDOMモードのパーザ(SSAXと呼ばれます)を含んでいます。

     The current version is based on the SSAX CVS version newer than the last 'official' release of SXML toolset (4.9), and SXML-gauche-0.9 package which was based on SXML-4.9. There is an important change from that release. Now the API uses lowercase letter suffix ssax: instead of uppercase SSAX:---the difference matters since Gauche is case sensitive by default. Alias names are defined for backward compatibility, but the use of uppercase suffixed names are deprecated. 現在のバージョンは、SXMLツールセットの最新の'公式な'リリース(4.9)よりも新しい、SSAXのCVSバージョンをベースにしており、パッケージSXML-gauche-0.9は、 SXML-4.9をベースにしています。 SXMLのリリース4.9以降では、重要な変更があります。現在のAPIでは、大文字の接頭辞SSAX:の代わりに小文字のssax:を使います。Gaucheはデフォルトで文字の大小を区別するために、この違いは問題となります。後方互換性のためにエイリアスされた名前が定義されていますが、大文字の接頭辞付きの名前の使用は推奨されません。

I derived the content of this part of the manual from SSAX source code, just by converting its comments into texinfo format. The original text is by Oleg Kiselyov.  Shiro Kawai should be responsible for any typographical error or formatting error introduced by conversion. マニュアルのこのパートの内容はSSAXのソースコードから抽出されたもので、単にそのコメントをTexinfoのフォーマットに変換しただけです。オリジナルのテキストは、Oleg Kiselyovによるものです。変換により生じた誤字・誤植やフォーマットエラーの責任は、 Shiro Kawaiにあります。

The manual entries are ordered in "bottom-up" way, beginning from the lower-level constructs towards the high-level utilities. If you just want to parse XML document and obtain SXML, check out ssax:xml->sxml in SSAX Highest-level parsers - XML to SXML. このマニュアルのエントリは、低レベルの構造から高レベルのユーティリティへと ``ボトムアップ''の方法で並べられています。もし、あなたが単にXMLドキュメントをパーズしたりSXMLを得たいだけならば、 SSAX Highest-level parsers - XML to SXMLのssax:xml->sxmlをチェックして下さい。

SSAX data types
---------------

TAG-KIND
     a symbol 'START, 'END, 'PI, 'DECL, 'COMMENT, 'CDSECT or 'ENTITY-REF that identifies a markup token. シンボル'START、'END、'PI、'DECL、'COMMENT、 'CDSECTは、マークアップトークンを識別するものです。

UNRES-NAME
     a name (called GI in the XML Recommendation) as given in an xml document for a markup token: start-tag, PI target, attribute name. If a GI is an NCName, UNRES-NAME is this NCName converted into a Scheme symbol. If a GI is a QName, UNRES-NAME is a pair of symbols: (PREFIX . LOCALPART) XML文書で、マークアップトークン: 開始タグ、PIターゲット、属性名に与えられる名前(XML勧告ではGIと呼ばれます)です。 GIがNCNameである場合、UNRES-NAMEはこのNCNameが Schemeのシンボルに変換されたものになります。 GIがQNameならば、UNRES-NAMEは、シンボルのペア、 (PREFIX . LOCALPART)となります。

RES-NAME
     An expanded name, a resolved version of an UNRES-NAME. For an element or an attribute name with a non-empty namespace URI, RES-NAME is a pair of symbols, (URI-SYMB . LOCALPART). Otherwise, it's a single symbol. 展開された名前、つまりUNRES-NAMEの解決されたバージョンです。名前空間URIが空でない場合の要素や属性名では、RES-NAMEはシンボルのペア、 (URI-SYMB . LOCALPART)です。そうでない場合は、1つのシンボルです。

ELEM-CONTENT-MODEL
     A symbol: 以下のシンボルのうちの1つです。

     ANY
     anything goes, expect an END tag.
     EMPTY-TAG
     no content, and no END-tag is coming.
     EMPTY
     no content, expect the END-tag as the next token.
     PCDATA
     expect character data only, and no children elements.
     MIXED

     ELEM-CONTENT

     ANY
     何でもよく、ENDタグがあるもの。
     EMPTY-TAG
     内容がなく、ENDタグのないもの。
     EMPTY
     内容がなく、次のトークンがENDタグであるもの。
     PCDATA
     文字データのみで、子要素がないもの。
     MIXED

     ELEM-CONTENT

URI-SYMB
     A symbol representing a namespace URI -- or other symbol chosen by the user to represent URI. In the former case, URI-SYMB is created by %-quoting of bad URI characters and converting the resulting string into a symbol. 名前空間を表すシンボル、あるいはURIを表すためにユーザが選んだ他のシンボルです。前者の場合、URI-SYMBは不正なURI文字が%でクォートされた文字列をシンボルに変換したものです。

NAMESPACES
     A list representing namespaces in effect. An element of the list has one of the following forms: 効力を持つ名前空間を表すリストです。リストの要素は、以下のフォームのうちの1つです。

     (PREFIX URI-SYMB . URI-SYMB)
          or,

     (PREFIX USER-PREFIX . URI-SYMB)
          USER-PREFIX is a symbol chosen by the user to represent the URI.

     (#f USER-PREFIX . URI-SYMB)
          Specification of the user-chosen prefix and a URI-SYMBOL.

     (*DEFAULT* USER-PREFIX . URI-SYMB)
          Declaration of the default namespace

     (*DEFAULT* #f . #f)
          Un-declaration of the default namespace. This notation represents overriding of the previous declaration

     (PREFIX URI-SYMB . URI-SYMB)
          あるいは、

     (PREFIX USER-PREFIX . URI-SYMB)
          USER-PREFIXは、そのURIを表現するためにユーザにより選ばれたシンボル。

     (#f USER-PREFIX . URI-SYMB)
          ユーザが選んだプリフィックスとURI-SYMBOLの指定。

     (*DEFAULT* USER-PREFIX . URI-SYMB)
          デフォルト名前空間の宣言。

     (*DEFAULT* #f . #f)
          デフォルト名前空間を宣言しない。この記法は、それ以前の宣言を上書きすることを表す。

     A NAMESPACES list may contain several elements for the same PREFIX. The one closest to the beginning of the list takes effect. NAMESPACESのリストは、同じPREFIXについていくつかの要素を含むかもしれません。リストの先頭に近いものが効力を持ちます。

ATTLIST
     An ordered collection of (NAME . VALUE) pairs, where NAME is a RES-NAME or an UNRES-NAME. The collection is an ADT. ペア(NAME . VALUE)の順序付きのコレクションで、NAMEは RES-NAMEかUNRES-NAMEです。このコレクションはADTです。

STR-HANDLER
     A procedure of three arguments: (STRING1 STRING2 SEED) returning a new SEED. The procedure is supposed to handle a chunk of character data STRING1 followed by a chunk of character data STRING2. STRING2 is a short string, often "\n" and even "" 3引数の手続き (STRING1 STRING2 SEED)で、新しいSEEDを返します。この手続きは、文字データSTRING2が後に続く、文字データSTRING1を扱うものです。STRING2は、``\n''や``''のような短い文字列です。

ENTITIES
     An assoc list of pairs:

            (NAMED-ENTITY-NAME . NAMED-ENTITY-BODY)

     where NAMED-ENTITY-NAME is a symbol under which the entity was declared, NAMED-ENTITY-BODY is either a string, or (for an external entity) a thunk that will return an input port (from which the entity can be read). NAMED-ENTITY-BODY may also be #f. This is an indication that a NAMED-ENTITY-NAME is currently being expanded. A reference to this NAMED-ENTITY-NAME will be an error: violation of the WFC nonrecursion. ペア (NAMED-ENTITY-NAME . NAMED-ENTITY-BODY)の連想リストで、 NAMED-ENTITY-NAMEはその実体が宣言されたシンボル、 NAMED-ENTITY-BODYは文字列か、(外部実体の場合は) (そこから実体が読み込める)入力ポートを返す手続きです。 NAMED-ENTITY-BODYはまた、#fかも知れません。これは、NAMED-ENTITY-NAMEがその時点で展開されていることを示します。このNAMED-ENTITY-NAMEへの参照は、WFC非再帰違反としてエラーになります。

XML-TOKEN
     A record with two slots, KIND and TOKEN. This record represents a markup, which is, according to the XML Recommendation, "takes the form of start-tags, end-tags, empty-element tags, entity references, character references, comments, CDATA section delimiters, document type declarations, and processing instructions." KINDとTOKENという2つのスロットを持つレコードです。このレコードは、XML勧告によれば、「開始タグ、終了タグ、空要素タグ、実体参照、文字参照、コメント、CDATAセクションの区切り、文書型宣言、処理命令の形を取る」マークアップを表します。

     kind
          a TAG-KIND TAG-KIND。

     head
          an UNRES-NAME. For xml-tokens of kinds 'COMMENT and 'CDSECT, the head is #f UNRES-NAME。'COMMENTと'CDSECTというkindのXMLトークンでは、そのheadは#fになります。

     For example, 例を示します。

          <P>  => kind='START, head='P
          </P> => kind='END, head='P
          <BR/> => kind='EMPTY-EL, head='BR
          <!DOCTYPE OMF ...> => kind='DECL, head='DOCTYPE
          <?xml version="1.0"?> => kind='PI, head='xml
          &my-ent; => kind = 'ENTITY-REF, head='my-ent

     Character references are not represented by xml-tokens as these references are transparently resolved into the corresponding characters. 文字参照は、対応する文字へと透過的に解決されるので、XMLトークンとしては表現されません。

XML-DECL
     A record with three slots, ELEMS, ENTITIES, and NOTATIONS.

     The record represents a datatype of an XML document: the list of declared elements and their attributes, declared notations, list of replacement strings or loading procedures for parsed general entities, etc. Normally an xml-decl record is created from a DTD or an XML Schema, although it can be created and filled in in many other ways (e.g., loaded from a file). ELEMS、ENTITIES、NOTATIONSという3つのスロットを持つレコードです。

     このレコードは、XML文書のデータタイプを表現します。それは、宣言された要素とその属性のリスト、宣言された記法、解析済み一般実体の置換文字列やロードされる手続きのリストなどです。通常、xml-declレコードは、それを作るには他にたくさんの方法 (例えばファイルからロードするなど)があるにも関わらず、DTDかXML Schemaから作られます。

     ELEMS: an (assoc) list of decl-elem or #f. The latter instructs the parser to do no validation of elements and attributes. ELEMS: decl-elemか#fの(連想)リスト。後者は、パーザに、要素と属性の妥当性検査を行わないように指示します。

     DECL-ELEM: declaration of one element: (ELEM-NAME ELEM-CONTENT DECL-ATTRS); ELEM-NAME is an UNRES-NAME for the element. ELEM-CONTENT is an ELEM-CONTENT-MODEL. DECL-ATTRS is an ATTLIST, of (ATTR-NAME . VALUE) associations. This element can declare a user procedure to handle parsing of an element (e.g., to do a custom validation, or to build a hash of IDs as they're encountered). DECL-ELEM: 1つの要素の宣言: (ELEM-NAME ELEM-CONTENT DECL-ATTRS); ELEM-NAMEはその要素のUNRES-NAME。 ELEM-CONTENTはELEM-CONTENT-MODEL。 DECL-ATTRSはATTLISTか、(ATTR-NAME . VALUE)の連想リスト。この要素は、要素のパージングを扱うユーザ手続きを宣言できます。 (例えば、カスタムな妥当性検査を行ったり、タグに出会うたびに IDのハッシュを構築するなど。)

     DECL-ATTR: an element of an ATTLIST, declaration of one attribute (ATTR-NAME CONTENT-TYPE USE-TYPE DEFAULT-VALUE): ATTR-NAME is an UNRES-NAME for the declared attribute; CONTENT-TYPE is a symbol: CDATA, NMTOKEN, NMTOKENS, ...; or a list of strings for the enumerated type. USE-TYPE is a symbol: REQUIRED, IMPLIED, FIXED default-value is a string for the default value, or #f if not given. DECL-ATTR: ATTLISTの要素で、1つの属性 (ATTR-NAME CONTENT-TYPE USE-TYPE DEFAULT-VALUE) の宣言: ATTR-NAMEはその宣言された属性のUNRES-NAME、 CONTENT-TYPEはシンボルCDATA、NMTOKEN、NMTOKENS、あるいは列挙されたタイプの文字列のリスト。 USE-TYPEはシンボルREQUIRED、IMPLIED、FIXED。 default-valueは、デフォルト値としての文字列か、与えられなければ#f。

 -- Function: make-empty-attlist
 -- Function: attlist-add attlist name-value
 -- Function: attlist-null?
 -- Function: attlist-remove-top attlist
 -- Function: attlist->alist attlist
 -- Function: attlist-fold
     Utility procedures to deal with attribute list, which keeps name-value association. 名前-値の属性リストを扱うユーティリティ手続きです。

 -- Function: make-xml-token kind head
 -- Function: xml-token? token
     A constructor and a predicate for a XML-TOKEN record. XML-TOKENレコードのコンストラクタと述語です。

 -- Macro: xml-token-kind token
 -- Macro: xml-token-head token
     Accessor macros of a XML-TOKEN record. XML-TOKENレコードのアクセッサマクロです。

SSAX low-level parsing code
---------------------------

They deal with primitive lexical units (Names, whitespaces, tags) and with pieces of more generic productions. Most of these parsers must be called in appropriate context. For example, ssax:complete-start-tag must be called only when the start-tag has been detected and its GI has been read. これらは、プリミティブな字句解析ユニット(名前、空白、タグ)や、より一般的な断片を扱います。これらのパーザのほとんどは、適切なコンテキストで呼ばれなければなりません。例えば、ssax:complete-start-tagは、開始タグが検知されそのGIが読み込まれたときにのみ呼ばれなければなりません。

 -- Function: ssax:skip-S port
     Skip the S (whitespace) production as defined by 次のように定義されるS(空白)をスキップします。

           [3] S ::= (#x20 | #x9 | #xD | #xA)

     The procedure returns the first not-whitespace character it encounters while scanning the PORT. This character is left on the input stream. この手続きは、PORTのスキャン中に遭遇した最初の空白ではない文字を返します。この文字は、入力ストリームに残されます。

 -- Function: ssax:ncname-starting-char? a-char
     Check to see if a-char may start a NCName. NCNameがa-charで始まるかどうかを検査します。

 -- Function: ssax:read-NCName port
     Read a NCName starting from the current position in the PORT and return it as a symbol. PORTで現在の位置から始まるNCNameを読み込み、それをシンボルとして返します。

 -- Function: ssax:read-QName port
     Read a (namespace-) Qualified Name, QName, from the current position in the PORT.

     From REC-xml-names: (名前空間)完全修飾名、QNameをPORTの現在の位置から読み込みます。

     REC-xml-namesは、

           [6] QName ::= (Prefix ':')? LocalPart
           [7] Prefix ::= NCName
           [8] LocalPart ::= NCName

     Return: an UNRES-NAME. 戻り値は、UNRES-NAMEです。

 -- Variable: ssax:Prefix-XML
     The prefix of the pre-defined XML namespace, i.e. 'xml. 定義済みのXML名前空間の接頭辞、つまり、'xmlです。

 -- Function: ssax:read-markup-token port
     This procedure starts parsing of a markup token. The current position in the stream must be #\<. This procedure scans enough of the input stream to figure out what kind of a markup token it is seeing. The procedure returns an xml-token structure describing the token. Note, generally reading of the current markup is not finished! In particular, no attributes of the start-tag token are scanned.

     Here's a detailed break out of the return values and the position in the PORT when that particular value is returned: この手続きは、マークアップトークンのパージングを開始します。ストリームの現在の位置は、#\<でなければなりません。この手続きは、見ているマークアップトークンがどの種類のものか見当をつけるに十分な程度、入力ストリームをスキャンします。この手続きは、そのトークンを表現するxml-token構造を返します。通常、その時点のマークアップの読み込みは完了していないことに注意して下さい。特に、開始タグトークンの属性はスキャンされていません。

     特定の値が返されたときの戻り値とPORTでの位置を詳細に説明します。

     PI-token
          only PI-target is read. To finish the Processing Instruction and disregard it, call ssax:skip-pi. ssax:read-attributes may be useful as well (for PIs whose content is attribute-value pairs) PIターゲットのみが読み込まれました。処理命令の読み込みを完了してそれを無視するためには、ssax:skip-piを呼びます。 (PIの内容が、属性-値のペアの場合は、)ssax:read-attributesも便利です。

     END-token
          The end tag is read completely; the current position is right after the terminating #\> character. 終了タグが完全に読み込まれました。現在の位置は、終了の#\>文字の直後です。

     COMMENT
          is read and skipped completely. The current position is right after "-->" that terminates the comment. コメントが完全に読み込まれスキップされました。現在の位置は、コメントが終了する``-->''の直後です。

     CDSECT
          The current position is right after "<!CDATA[". Use ssax:read-cdata-body to read the rest. 現在の位置は、"<!CDATA["の直後です。残りを読むためには、ssax:read-cdata-bodyを使います。

     DECL
          We have read the keyword (the one that follows "<!") identifying this declaration markup. The current position is after the keyword (usually a whitespace character) この宣言マークアップを識別するキーワード(``<!''に続くもの)を読み込んだところです。現在の位置は、(通常は空白文字である) そのキーワードの直後です。

     START-token
          We have read the keyword (GI) of this start tag. No attributes are scanned yet. We don't know if this tag has an empty content either. Use ssax:complete-start-tag to finish parsing of the token. この開始タグのキーワード(GI)を読み込んだところです。属性はまだスキャンされていません。また、このタグが空の要素を持つかどうかも分かりません。このトークンのパージングを終了するためには、 ssax:complete-start-tagを使います。

 -- Function: ssax:skip-pi port
     The current position is inside a PI. Skip till the rest of the PI. 現在の位置は、PIの内側です。 PIの残りをスキップします。

 -- Function: ssax:read-pi-body-as-string port
     The current position is right after reading the PITarget. We read the body of PI and return it as a string. The port will point to the character right after '?>' combination that terminates PI. 現在の位置は、PITargetを読み込んだ直後です。 PIのボディを読み込んで、それを文字列として返します。ポートでは、PIを終了する'?>'の直後の文字を指します。

           [16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'

 -- Function: ssax:skip-internal-dtd port
     The current pos in the port is inside an internal DTD subset (e.g., after reading #\[ that begins an internal DTD subset) Skip until the "]>" combination that terminates this DTD ポートでの現在の位置は、内部DTDサブセットの内側です (例えば、内部DTDサブセットの始まりである#\[ を読み込んだところ)。このDTDを終了する、組み合わせとなる``]>''までをスキップします。

 -- Function: ssax:read-cdata-body port str-handler seed
     This procedure must be called after we have read a string "<![CDATA[" that begins a CDATA section. The current position must be the first position of the CDATA body. This function reads lines of the CDATA body and passes them to a STR-HANDLER, a character data consumer. この手続きは、CDATAセクションを開始する文字列、"<![CDATA["を読み込んだ後に呼ばれなければなりません。現在の位置は、CDATAのボディの最初の位置です。この手続きは、CDATAのボディのデータを読み込み、それらを STR-HANDLER(文字データのコンシューマ)へ渡します。

     The str-handler is a STR-HANDLER, a procedure string1 STRING2 SEED. The first STRING1 argument to STR-HANDLER never contains a newline. The second STRING2 argument often will. On the first invocation of the STR-HANDLER, the seed is the one passed to ssax:read-cdata-body as the third argument. The result of this first invocation will be passed as the seed argument to the second invocation of the line consumer, and so on. The result of the last invocation of the STR-HANDLER is returned by the ssax:read-cdata-body.  Note a similarity to the fundamental 'fold' iterator. str-handlerは、string1 STRING2 SEEDを取る手続き STR-HANDLERです。 STR-HANDLERの最初の引数STRING1は、改行を含みません。 2番目の引数STRING2は、改行を含むことがよくあります。 STR-HANDLERの最初の呼び出しでは、seedはssax:read-cdata-bodyの第3引数として渡されるものです。この最初の呼び出しの結果は、文字データのコンシューマの引数seedとして渡され、以降同じように続きます。 STR-HANDLERの最後の呼び出しの結果は、ssax:read-cdata-body から返されるものです。基本的な'fold'イテレータに似ています。

     Within a CDATA section all characters are taken at their face value, with only three exceptions: CDATAセクションでは、以下の3つだけの例外を除いて、全ての文字はその表面上の値を持ちます。

       * CR, LF, and CRLF are treated as line delimiters, and passed as a single #\newline to the STR-HANDLER. CR、LF、CRLFは行区切りとして扱われ、STR-HANDLERへは 1つの#\newlineとして渡されます。

       * "]]>" combination is the end of the CDATA section. 組み合わせとなる``]]>''は、CDATAセクションの終わりであるとされます。

       * &gt; is treated as an embedded #\> character. Note, &lt; and &amp; are not specially recognized (and are not expanded)! &gt;は、#\>文字の埋め込みとして扱われます。 &lt;と&amp;は特別なものとして認識されない(よって展開されない)ことに注意が必要です!

 -- Function: ssax:read-char-ref port

           [66]  CharRef ::=  '&#' [0-9]+ ';'
                            | '&#x' [0-9a-fA-F]+ ';'

     This procedure must be called after we we have read "&#" that introduces a char reference. The procedure reads this reference and returns the corresponding char. The current position in PORT will be after ";" that terminates the char reference. Faults detected: WFC: XML-Spec.html#wf-Legalchar. この手続きは、文字参照を表す``&#''を読み込んだ後に呼ばれなければなりません。この手続きは、この参照を読み込んで対応する文字を返します。 PORTでの現在の位置は、文字参照の終わりとなる``;''の後となります。 WFC: XML-Spec.html#wf-Legalcharも参照のこと。

     According to Section "4.1 Character and Entity References" of the XML Recommendation: XML勧告のセクション``4.1 文字と実体参照''によると、

          "[Definition: A character reference refers to a specific character in the ISO/IEC 10646 character set, for example one not directly accessible from available input devices.]" ``[定義: 文字参照は、ISO/IEC 10646文字集合にある特定の文字を参照する。例えば、利用できる入力デバイスからは直接アクセスできないものなど。]''

     Therefore, we use a ucscode->char function to convert a character code into the character -- regardless of the current character encoding of the input stream. したがって、入力ストリームの現在の文字エンコーディングに関係なく、文字コードを文字に変換するために関数ucscode->charを使います。

 -- Function: ssax:handle-parsed-entity port name entities content-handler str-handler seed
     Expand and handle a parsed-entity reference 解析済み実体参照を展開し処理します。

       * PORT - a PORT PORT - ポート

       * NAME - the name of the parsed entity to expand, a symbol. NAME - 展開する解析済み実体の名前。シンボル。

       * ENTITIES - see ENTITIES ENTITIES - ENTITIESを参照。

       * CONTENT-HANDLER - procedure PORT ENTITIES SEED that is supposed to return a SEED. CONTENT-HANDLER - PORT ENTITIES SEEDを取る手続きで、 SEEDを返す。

       * STR-HANDLER - a STR-HANDLER. It is called if the entity in question turns out to be a pre-declared entity STR-HANDLER - STR-HANDLER。対象となる実体が宣言済み実体となった場合に呼ばれる。

     The result is the one returned by CONTENT-HANDLER or STR-HANDLER. 戻り値は、CONTENT-HANDLERかSTR-HANDLERから返された値です。

     Faults detected: こちらも参照のこと。

            WFC: XML-Spec.html#wf-entdeclared
            WFC: XML-Spec.html#norecursion

 -- Function: ssax:read-attributes port entities
     This procedure reads and parses a production Attribute* この手続きは、Attribute*を読み込みパーズします。

           [41] Attribute ::= Name Eq AttValue
           [10] AttValue ::=  '"' ([^<&"] | Reference)* '"'
                           | "'" ([^<&'] | Reference)* "'"
           [25] Eq ::= S? '=' S?

     The procedure returns an ATTLIST, of NAME (as UNRES-NAME), VALUE (as string) pairs. The current character on the PORT is a non-whitespace character that is not an ncname-starting character. この手続きは、NAME(UNRES-NAME)とVALUE(文字列)のペアである ATTLISTを返します。 PORTでの現在の文字は、NCNameの開始文字ではなく、空白ではない文字です。

     Note the following rules to keep in mind when reading an 'AttValue' "Before the value of an attribute is passed to the application or checked for validity, the XML processor must normalize it as follows: 'AttValue'を読み込むときには、以下のルールに留意して下さい。 ``属性の値がアプリケーションに渡されるか妥当性が検査される前に、 XMLプロセッサはそれを以下のように正規化しなければならない:

       * a character reference is processed by appending the referenced character to the attribute value 文字参照は、属性値に参照された文字を追加することで処理される。

       * an entity reference is processed by recursively processing the replacement text of the entity [see ENTITIES] [named entities amp lt gt quot apos are assumed pre-declared] 実体参照は、その実体のテキストの置換を再帰的に行うことにより処理される。[ENTITIES参照] [名前付きのエンティティ、amp lt gt quot aposは定義済みと想定される]

       * a whitespace character (#x20, #xD, #xA, #x9) is processed by appending #x20 to the normalized value, except that only a single #x20 is appended for a "#xD#xA" sequence that is part of an external parsed entity or the literal entity value of an internal parsed entity 空白文字(#x20、#xD、#xA、#x9)は、外部解析済み実体か内部解析済み実体のリテラルの実体の値の一部である ``#xD#xA''のシーケンスにただ1つの#x20が追加されることを除いて、正規化された値に#x20を追加することで処理される。

       * other characters are processed by appending them to the normalized value " 他の文字は、正規化された値をそれらに追加することにより処理される''

     Faults detected: こちらも参照のこと。

           WFC: XML-Spec.html#CleanAttrVals
           WFC: XML-Spec.html#uniqattspec

 -- Function: ssax:resolve-name port unres-name namespaces apply-default-ns?
     Convert an UNRES-NAME to a RES-NAME given the appropriate NAMESPACES declarations. The last parameter APPLY-DEFAULT-NS? determines if the default namespace applies (for instance, it does not for attribute names)

     Per REC-xml-names/#nsc-NSDeclared, "xml" prefix is considered pre-declared and bound to the namespace name "http://www.w3.org/XML/1998/namespace".

     This procedure tests for the namespace constraints: http://www.w3.org/TR/REC-xml-names/#nsc-NSDeclared. 与えられた適切なNAMESPACESの宣言を用いて、UNRES-NAMEを RES-NAMEに変換する。最後の引数APPLY-DEFAULT-NS?は、デフォルト名前空間の適用を行うかどうかを決めます(例えば、属性名には適用しないなど)。

     REC-xml-names/#nsc-NSDeclaredによれば、接頭辞``xml''は名前空間名``http://www.w3.org/XML/1998/namespace''に定義済みで束縛されているとされます。

     この手続きは、名前空間の制約をテストします: http://www.w3.org/TR/REC-xml-names/#nsc-NSDeclared。

 -- Function: ssax:uri-string->symbol uri-str
     Convert a URI-STR to an appropriate symbol. URI-STRを適切なシンボルに変換します。

 -- Function: ssax:complete-start-tag tag port elems entities namespaces
     This procedure is to complete parsing of a start-tag markup. The procedure must be called after the start tag token has been read. TAG is an UNRES-NAME. ELEM S is an instance of xml-decl::elems; it can be #f to tell the function to do no validation of elements and their attributes. この手続きは、開始タグのマークアップのパージングを完了するためのものです。この手続きは、開始タグトークンが読み込まれた後に呼ばれなければなりません。 TAGはUNRES-NAMEです。 ELEMSはxml-decl::elemsのインスタンスで、手続きに、要素とそれらの属性の妥当性検査を行わないように指示するために、#fを指定することができます。

     This procedure returns several values: この手続きはいくつかの値を返します。

     elem-gi
          a RES-NAME. RES-NAME。

     attributes
          element's attributes, an ATTLIST of (RES-NAME . STRING) pairs. The list does not include xmlns attributes. 要素の属性。(RES-NAME . STRING)というペアのATTLIST。このリストは、xmlns属性を含みません。

     namespaces
          the input list of namespaces amended with namespace (re-)declarations contained within the start-tag under parsing ELEM-CONTENT-MODEL. パージング中の開始タグに含まれる名前空間(再)宣言により修正された後の名前空間の入力リスト。

     On exit, the current position in PORT will be the first character after #\> that terminates the start-tag markup. 終了時のPORTでの現在の位置は、開始タグのマークアップを終了する #\>の後になります。

     Faults detected: こちらも参照のこと。

           VC: XML-Spec.html#enum
           VC: XML-Spec.html#RequiredAttr
           VC: XML-Spec.html#FixedAttr
           VC: XML-Spec.html#ValueType
           WFC: XML-Spec.html#uniqattspec (after namespaces prefixes are resolved)
           VC: XML-Spec.html#elementvalid
           WFC: REC-xml-names/#dt-NSName

     Note, although XML Recommendation does not explicitly say it, XMLNS and XMLNS: attributes don't have to be declared (although they can be declared, to specify their default value). XML勧告では明示されていませんが、XMLNSとXMLNS:属性は、 (そのデフォルト値を指定するために宣言されることが出来ますが) 宣言される必要がないことに注意して下さい。

 -- Function: ssax:read-external-id port
     This procedure parses an ExternalID production. この手続きは、ExternalIDをパーズします。

           [75] ExternalID ::= 'SYSTEM' S SystemLiteral
                           | 'PUBLIC' S PubidLiteral S SystemLiteral
           [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'")
           [12] PubidLiteral ::=  '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
           [13] PubidChar ::=  #x20 | #xD | #xA | [a-zA-Z0-9]
                          | [-'()+,./:=?;!*#@$_%]

     This procedure is supposed to be called when an ExternalID is expected; that is, the current character must be either #\S or #\P that start correspondingly a SYSTEM or PUBLIC token. This procedure returns the SystemLiteral as a string. A PubidLiteral is disregarded if present. この手続きは、ExternalIDが期待されるところで呼ばれます。つまり、現在の文字は、それぞれSYSTEMかPUBLICトークンを開始する #\Sか#\Pでなければなりません。この手続きは、SystemLiteralを文字列として返します。 PubidLiteralは、存在したとしても無視されます。

SSAX higher-level parsers and scanners
--------------------------------------

They parse productions corresponding to the whole (document) entity or its higher-level pieces (prolog, root element, etc). これらは、全体的な実体(ドキュメント)あるいはその高レベルな断片 (プロローグ、ルート要素など)をパーズします。

 -- Function: ssax:scan-Misc port
     Scan the Misc production in the context: そのコンテキストでのMiscをスキャンします。

          [1]  document ::=  prolog element Misc*
          [22] prolog ::= XMLDecl? Misc* (doctypedec l Misc*)?
          [27] Misc ::= Comment | PI |  S

     The following function should be called in the prolog or epilog contexts. In these contexts, whitespaces are completely ignored. The return value from ssax:scan-Misc is either a PI-token, a DECL-token, a START token, or EOF. Comments are ignored and not reported. 以下の関数は、プロローグかエピローグのコンテキストで呼ばれます。これらのコンテキストでは、空白文字は完全に無視されます。 ssax:scan-Miscからの戻り値は、PIトークンかDECLトークン、 STARTトークン、EOFのいずれかです。コメントは無視され報告されません。

 -- Function: ssax:read-char-data port expect-eof? str-handler seed
     This procedure is to read the character content of an XML document or an XML element. この手続きは、XML文書かXML要素の文字内容を読むためのものです。

           [43] content ::=
                  (element | CharData | Reference | CDSect | PI
                   | Comment)*

     To be more precise, the procedure reads CharData, expands CDSect and character entities, and skips comments. The procedure stops at a named reference, EOF, at the beginning of a PI or a start/end tag. 具体的には、この手続きはCharDataを読み込み、CDSectと文字実体を展開し、コメントをスキップします。この手続きは、名前付き参照、EOF、PIあるいは開始/終了タグの開始地点で停止します。

     port
          a port to read 読み込むポート。

     expect-eof?
          a boolean indicating if EOF is normal, i.e., the character data may be terminated by the EOF. EOF is normal while processing a parsed entity. EOFがノーマルかどうか、つまり、文字データがEOFで終わるかどうかを表す真偽値。解析済み実体を処理している間はEOFはノーマル。

     str-handler
          a STR-HANDLER. STR-HANDLER。

     seed
          an argument passed to the first invocation of STR-HANDLER. STR-HANDLERの最初の呼び出し時に渡される引数。

     The procedure returns two results: SEED and TOKEN.

     The SEED is the result of the last invocation of STR-HANDLER, or the original seed if STR-HANDLER was never called. この手続きは2つの結果、SEEDとTOKENを返します。

     SEEDはSTR-HANDLERの最後の呼び出しの結果、あるいは STR-HANDLERが一度も呼ばれなかった場合はオリジナルのseedです。

     TOKEN can be either an eof-object (this can happen only if EXPECT-EOF? was #t), or: TOKENはEOFオブジェクト(これはEXPECT-EOF?が#tの場合のみ)か、

       * an xml-token describing a START tag or an END-tag; For a start token, the caller has to finish reading it. STARTタグかENDタグを表すxml-token。開始トークンの場合は、呼び出し側が読み込みを完了する必要がある。

       * an xml-token describing the beginning of a PI. It's up to an application to read or skip through the rest of this PI; PIの開始を表すxml-token。このPIの残りを読み込むかスキップするかはアプリケーションに任される。

       * an xml-token describing a named entity reference. 名前付き実体参照を表すxml-token。

     CDATA sections and character references are expanded inline and never returned. Comments are silently disregarded.

     As the XML Recommendation requires, all whitespace in character data must be preserved. However, a CR character (#xD) must be disregarded if it appears before a LF character (#xA), or replaced by a #xA character otherwise. See Secs. 2.10 and 2.11 of the XML Recommendation. See also the canonical XML Recommendation. CDATAセクションと文字参照はインラインで展開され返されません。コメントは無視されます。

     XML勧告が要求するように、文字データ中の全ての空白文字は保存されなければなりません。しかし、CR文字(#xD)は、LF文字(#A)の前に現れるか #xA文字で置き換えられた場合は、無視されなければなりません。 XML勧告のセクション2.10と2.11を参照して下さい。また、正規のXML勧告も参照して下さい。

 -- Function: ssax:assert-token token kind gi error-cont
     Make sure that TOKEN is of anticipated KIND and has anticipated GI. Note GI argument may actually be a pair of two symbols, Namespace URI or the prefix, and of the localname. If the assertion fails, ERROR-CONT is evaluated by passing it three arguments: TOKEN KIND GI. The result of ERROR-CONT is returned. TOKENが、予想されたKINDのもので、予想されたGIを持つことを確認します。GI引数は、実際には2つのシンボル、名前空間URIかその接頭辞と、そのローカル名のペアでしょう。アサーションが失敗したら、ERROR-CONTに3つの引数、TOKEN KIND GI を渡されて評価されます。 ERROR-CONTの結果が返されます。

SSAX Highest-level parsers - XML to SXML
----------------------------------------

These parsers are a set of syntactic forms to instantiate a SSAX parser. A user can instantiate the parser to do the full validation, or no validation, or any particular validation. The user specifies which PI he wants to be notified about. The user tells what to do with the parsed character and element data. The latter handlers determine if the parsing follows a SAX or a DOM model. これらのパーザは、SSAXパーザをインスタンス化するための構文的フォームのセットです。ユーザは、完全な妥当性検査、妥当性検査なし、特定の妥当性検査を行うためにこのパーザをインスタンス化できます。ユーザは、どのPIについて通知されたいかを指定します。ユーザは、解析済み文字と要素のデータで何をしたいかを知らせます。後者のハンドラは、パージングがSAXやDOMモデルに従うかを決定します。

 -- Macro: ssax:make-pi-parser my-pi-handlers
     Create a parser to parse and process one Processing Element (PI). 1つの処理命令(PI)をパーズして処理するパーザを作ります。

     MY-PI-HANDLERS: An assoc list of pairs (PI-TAG . PI-HANDLER) where PI-TAG is an NCNAME symbol, the PI target, and PI-HANDLER is a procedure PORT PI-TAG SEED where PORT points to the first symbol after the PI target. The handler should read the rest of the PI up to and including the combination '?>' that terminates the PI. The handler should return a new seed. One of the PI-TAGs may be a symbol *DEFAULT*. The corresponding handler will handle PIs that no other handler will. If the *DEFAULT* PI-TAG is not specified, ssax:make-pi-parser will make one, which skips the body of the PI. MY-PI-HANDLERS: (PI-TAG . PI-HANDLER)のペアの連想リスト。 PI-TAGはNCNAMEのシンボル、PIターゲット。 PI-HANDLERはPORT PI-TAG SEEDを引数とする手続きで、 PORTではPIターゲットの後の最初のシンボルを指しています。ハンドラは、PIを終了する組み合わせとなる'?>'を含む、 PIの残りを読み込みます。ハンドラは新しいseedを返します。 PI-TAGの1つは、シンボル*DEFAULT*でしょう。これに対応するハンドラは、他のハンドラが扱わないPIを処理します。 *DEFAULT* PI-TAGが指定されていない場合は、 ssax:make-pi-parserは、PIのボディをスキップするパーザを作ります。

     The output of the ssax:make-pi-parser is a procedure PORT PI-TAG SEED, that will parse the current PI accoding to user-specified handlers. ssax:make-pi-parserが返すのは、PORT PI-TAG SEEDを取る手続きで、ユーザ指定のハンドラに従い現在のPIをパーズします。

 -- Macro: ssax:make-elem-parser my-new-level-seed my-finish-element my-char-data-handler my-pi-handlers
     Create a parser to parse and process one element, including its character content or children elements. The parser is typically applied to the root element of a document. その文字内容や子要素をも含む１つの要素をパーズし処理するパーザを作ります。このパーザは通常、ドキュメントのルート要素の適用されます。

     my-new-level-seed
          procedure ELEM-GI ATTRIBUTES NAMESPACES EXPECTED-CONTENT SEED

          where ELEM-GI is a RES-NAME of the element about to be processed. This procedure is to generate the seed to be passed to handlers that process the content of the element. ELEM-GI ATTRIBUTES NAMESPACES EXPECTED-CONTENT SEED

          を引数に取る手続きで、ELEM-GIは処理されようとしている要素のRES-NAMEです。この手続きは、要素の内容を処理するハンドラに渡されるseedを生成します。

     my-finish-element
          procedure ELEM-GI ATTRIBUTES NAMESPACES PARENT-SEED SEED

          This procedure is called when parsing of ELEM-GI is finished. The SEED is the result from the last content parser (or from MY-NEW-LEVEL-SEED if the element has the empty content). PARENT-SEED is the same seed as was passed to MY-NEW-LEVEL-SEED. The procedure is to generate a seed that will be the result of the element parser. ELEM-GI ATTRIBUTES NAMESPACES PARENT-SEED SEED

          を引数に取る手続きです。この手続きは、ELEM-GIのパージングが完了した時に呼ばれます。 SEEDは、最後に呼ばれたパーザからの(あるいは、要素が空要素であった場合は、MY-NEW-LEVEL-SEEDからの)結果です。 PARENT-SEEDは、MY-NEW-LEVEL-SEEDへ渡されたのと同じseedです。この手続きは、パーザの結果となるseedを生成するためのものです。

     my-char-data-handler
          A STR-HANDLER. STR-HANDLER。

     my-pi-handlers
          See ssax:make-pi-handler above. ssax:make-pi-handlerを参照して下さい。

     The generated parser is a: procedure START-TAG-HEAD PORT ELEMS ENTITIES NAMESPACES PRESERVE-WS? SEED.

     The procedure must be called after the start tag token has been read. START-TAG-HEAD is an UNRES-NAME from the start-element tag. ELEMS is an instance of xml-decl::elems. See ssax:complete-start-tag::preserve-ws? 生成されたパーザは: START-TAG-HEAD PORT ELEMS ENTITIES NAMESPACES PRESERVE-WS? SEED

     を引数に取る手続きです。この手続きは、開始タグのトークンが読み込まれた後に呼ばれなければなりません。 START-TAG-HEADは要素の開始タグのUNRES-NAMEです。 ELEMSはxml-decl::elemsのインスタンスです。 ssax:complete-start-tag::preserve-ws?も参照して下さい。

     Faults detected: こちらも参照のこと。

           VC: XML-Spec.html#elementvalid
           WFC: XML-Spec.html#GIMatch

 -- Macro: ssax:make-parser user-handler-tag user-handler-proc ...
     Create an XML parser, an instance of the XML parsing framework. This will be a SAX, a DOM, or a specialized parser depending on the supplied user-handlers.

     USER-HANDLER-TAG is a symbol that identifies a procedural expression that follows the tag. Given below are tags and signatures of the corresponding procedures. Not all tags have to be specified. If some are omitted, reasonable defaults will apply. XMLパージングフレームワークのインスタンスである、XMLパーザを作ります。これは、提供されるユーザハンドラによって、SAX、DOM、あるいは特化されたパーザになります。

     USER-HANDLER-TAGはシンボルで、タグに続く手続き的な式を識別します。以下にタグと対応する手続きのシグネチャを示します。全てのタグが指定される必要はありません。いくつかが省略されると、合理的なデフォルトのものが適用されます。

     tag: DOCTYPE
          handler-procedure: PORT DOCNAME SYSTEMID INTERNAL-SUBSET? SEED

          If INTERNAL-SUBSET? is #t, the current position in the port is right after we have read #\[ that begins the internal DTD subset. We must finish reading of this subset before we return (or must call skip-internal-subset if we aren't interested in reading it). The port at exit must be at the first symbol after the whole DOCTYPE declaration.

          The handler-procedure must generate four values:

          ELEMS ENTITIES NAMESPACES SEED

          See xml-decl::elems for ELEMS. It may be #f to switch off the validation. NAMESPACES will typically contain USER-PREFIXes for selected URI-SYMBs. The default handler-procedure skips the internal subset, if any, and returns (values #f '() '() seed). ハンドラ手続きの引数: PORT DOCNAME SYSTEMID INTERNAL-SUBSET? SEED

          INTERNAL-SUBSET?が#tなら、ポートでの現在の位置は内部DTDサブセットの開始となる#\[を読んだ直後です。手続きから戻る前に、このサブセットの残りの読み込みを完了しなければなりません (あるいは、それを読むことに興味がなければ、skip-internal-subsetを呼ばなければなりません)。終了時のポートでの位置は、DOCTYPE宣言全体のあとの最初のシンボルでなければなりません。

          ハンドラ手続きは4つの値:

          ELEMS ENTITIES NAMESPACES SEED

          を生成しなければなりません。 ELEMSについては、xml-decl::elemsを参照して下さい。妥当性検査をオフにするためには、#fになるでしょう。 NAMESPACESは、通常、選択されたURI-SYMBに対してUSER-PREFIXを含むでしょう。デフォルトのハンドラ手続きは、内部サブセットがあってもそれをスキップし、 (values #f '() '() seed)を返します。

     tag: UNDECL-ROOT
          handler-procedure: ELEM-GI SEED

          where ELEM-GI is an UNRES-NAME of the root element. This procedure is called when an XML document under parsing contains no DOCTYPE declaration. The handler-procedure, as a DOCTYPE handler procedure above, must generate four values:

          ELEMS ENTITIES NAMESPACES SEED

          The default handler-procedure returns (values #f '() '() seed). ハンドラ手続きの引数: ELEM-GI SEED

          ELEM-GIはルート要素のUNRES-NAMEです。この手続きは、パージング中のXML文書がDOCTYPE宣言を含まない時に呼ばれます。ハンドラ手続きは、上ではDOCTYPEハンドラですが、4つの値:

          ELEMS ENTITIES NAMESPACES SEED

          を生成しなければなりません。デフォルトのハンドラ手続きは、(values #f '() '() seed)を返します。

     tag: DECL-ROOT
          handler-procedure: ELEM-GI SEED

          where ELEM-GI is an UNRES-NAME of the root element. This procedure is called when an XML document under parsing does contains the DOCTYPE declaration. The handler-procedure must generate a new seed (and verify that the name of the root element matches the doctype, if the handler so wishes). The default handler-procedure is the identity function. ハンドラ手続きの引数: ELEM-GI SEED

          ELEM-GIは、ルート要素のUNRES-NAMEです。この手続きは、パージング中のXML文書がDOCTYPE宣言を含む場合に呼ばれます。このハンドラ手続きは、新しいseedを生成しなければなりません (そして、ハンドラが望めば、ルート要素の名前がDOCTYPEにマッチするかを検証します)。デフォルトのハンドラ手続きは、それ自身を返す手続きです。

     tag: NEW-LEVEL-SEED
          handler-procedure: see ssax:make-elem-parser, MY-NEW-LEVEL-SEED ハンドラ手続きの引数: ssax:make-elem-parserとMY-NEW-LEVEL-SEEDを参照して下さい。

     tag: FINISH-ELEMENT
          handler-procedure: see ssax:make-elem-parser, MY-FINISH-ELEMENT ハンドラ手続きの引数: ssax:make-elem-parserとMY-FINISH-ELEMENTを参照して下さい。

     tag: CHAR-DATA-HANDLER
          handler-procedure: see ssax:make-elem-parser, MY-CHAR-DATA-HANDLER ハンドラ手続きの引数: ssax:make-elem-parserとMY-CHAR-DATA-HANDLERを参照して下さい。

     tag: PI
          handler-procedure: see ssax:make-pi-parser.

          The default value is '(). ハンドラ手続きの引数: ssax:make-pi-parserを参照して下さい。

          デフォルトの値は、'()です。

     The generated parser is a

     procedure PORT SEED

     This procedure parses the document prolog and then exits to an element parser (created by ssax:make-elem-parser) to handle the rest. 生成されるパーザは、

     PORT SEEDを取る手続き、

     です。

     この手続きは、ドキュメントのプロローグをパーズして、その残りを処理するために(ssax:make-elem-parserで作られた)パーザへ引き継いで終了します。

           [1]  document ::=  prolog element Misc*
           [22] prolog ::= XMLDecl? Misc* (doctypedec | Misc*)?
           [27] Misc ::= Comment | PI |  S

           [28] doctypedecl ::=  '<!DOCTYPE' S Name (S ExternalID)? S?
                                  ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
           [29] markupdecl ::= elementdecl | AttlistDecl
                                | EntityDecl
                                | NotationDecl | PI
                                | Comment

A few utility procedures that turned out useful. いくつかの便利なユーティリティ手続きがあります。

 -- Function: ssax:reverse-collect-str fragments
     given the list of FRAGMENTS (some of which are text strings) reverse the list and concatenate adjacent text strings. FRAGMENTS(そのいくつかはテキスト文字列)のリストを渡すと、そのリストを逆順にして隣り合ったテキスト文字列を連結します。

 -- Function: ssax:reverse-collect-str-drop-ws fragments
     given the list of fragments (some of which are text strings) reverse the list and concatenate adjacent text strings. We also drop "unsignificant" whitespace, that is, whitespace in front, behind and between elements. The whitespace that is included in character data is not affected. We use this procedure to "intelligently" drop "insignificant" whitespace in the parsed SXML. If the strict compliance with the XML Recommendation regarding the whitespace is desired, please use the ssax:reverse-collect-str procedure instead. fragments(そのいくつかはテキスト文字列)のリストを渡すと、そのリストを逆順にして隣り合ったテキスト文字列を連結します。 ``重要でない''空白文字、つまり、最初や最後、要素の間にある空白文字を削除します。文字データに含まれる空白文字には影響を与えません。この手続きは、パーズされたSXMLにある``重要でない''空白文字を ``知的に''削除するために使います。空白文字に関して、厳密に XML勧告に準拠したい場合は、代わりに手続き ssax:reverse-collect-strを使って下さい。

 -- Function: ssax:xml->sxml port namespace-prefix-assig
     This is an instance of a SSAX parser above that returns an SXML representation of the XML document to be read from PORT. NAMESPACE-PREFIX-ASSIG is a list of (USER-PREFIX . URI-STRING) that assigns USER-PREFIXes to certain namespaces identified by particular URI-STRINGs. It may be an empty list. The procedure returns an SXML tree. The port points out to the first character after the root element. これは、上のSSAXパーザのインスタンスで、PORTから読み込まれる XMLドキュメントのSXML表現を返します。 NAMESPACE-PREFIX-ASSIGは、(USER-PREFIX . URI-STRING) のリストで、特定のURI-STRINGで識別されるある名前空間を USER-PREFIXに割り当てます。これは空リストでも構いません。この手続きは、SXMLツリーを返します。ポートでの位置は、ルート要素の後の最初の文字を指します。

sxml.sxpath - SXML query language
=================================

 -- Module: sxml.sxpath
     SXPath is a query language for SXML, an instance of XML Information set (Infoset) in the form of s-expressions.

     It is originally written by Oleg Kiselyov, and improved by Dmitry Lizorkin and Kirill Lisovsky. This module also incorporates various procedures written for SXPath by Dmitry Lizorkin and Kirill Lisovsky.

     Current version is based on sxpathlib.scm,v 3.915, sxpath.scm,v 1.1, and sxpath-ext.scm,v 1.911. SXPathは、XML Information set (Infoset)のインスタンスのS式フォームである SXMLのためのクエリ言語です。

     これは最初にOleg Kiselyovによって書かれ、Dmitry LizorkinとKirill Lisovsky によって改良されました。このモジュールにはまた、Dmitry LizorkinとKirill LisovskyによりSXPathのために書かれたたくさんの手続きが盛り込まれています。

     現在のバージョンは、sxpathlib.scm v3.915、sxpath.scm v1.1、sxpath-ext.scm v1.911をベースにしています。

This manual is mostly derived from the comments in the original source files.

The module consists of three layers. このマニュアルは、そのほとんどがオリジナルのソースファイルのコメントより導出されています。

このモジュールは3つのレイヤから構成されます。

 1. Basic converters and applicators, which provides the means to access and translate SXML tree. SXMLツリーへのアクセスやその変換の手段を提供する基本的なコンバータやアプリケータ(適用子)。

 2. High-level query language compiler, which takes abbreviated SXPath and returns a Scheme function that selects a nodeset that satisfies the specified path from the given nodeset. 省略形のSXPathを取り、与えられたノードセットから指定されたパスを満足するノードセットを選択するScheme関数を返す、高レベルなクエリ言語コンパイラ。

 3. Extension libraries, which implements SXML counterparts to W3C XPath Core Functions Library. W3CのXPathコア関数ライブラリのSXML版を実装する拡張ライブラリ。

SXPath basic converters and applicators
---------------------------------------

A converter is a function コンバータは、以下を満たす関数です。

       type Converter = Node|Nodeset -> Nodeset

A converter can also play a role of a predicate: in that case, if a converter, applied to a node or a nodeset, yields a non-empty nodeset, the converter-predicate is deemed satisfied. Throughout this file a nil nodeset is equivalent to #f in denoting a failure. コンバータは、述語としての役割を担うこともあります。その場合、コンバータが、ノードやノードセットに適用され、空ではないノードセットを返す場合、述語としてのコンバータは満足したものとみなされます。このファイルを通して、nilノードセットは失敗を表す#fと等価です。

 -- Function: nodeset? x
     Returns #t if given object is a nodeset. 与えられたオブジェクトがノードセットならば、#tを返します。

 -- Function: as-nodeset x
     If X is a nodeset - returns it as is, otherwise wrap it in a list. Xがノードセットならば、それをそのまま返し、そうでなければそれをリストでラップして返します。

 -- Function: sxml:element? obj
     Predicate which returns #t if OBJ is SXML element, otherwise returns #f. OBJがSXMLの要素であれば#tを返し、そうでなければ#fを返す述語です。

 -- Function: ntype-names?? crit
     The function ntype-names?? takes a list of acceptable node names as a criterion and returns a function, which, when applied to a node, will return #t if the node name is present in criterion list and #f otherwise. 関数ntype-names??は、判定基準として受け付け可能なノード名のリストを取り、関数を返します。この関数は、ノードに適用された際、そのノード名が判定基準リストに含まれていれば#tを、含まれていなければ#fを返す関数です。

           ntype-names?? :: ListOfNames -> Node -> Boolean

 -- Function: ntype?? crit
     The function ntype?? takes a type criterion and returns a function, which, when applied to a node, will tell if the node satisfies the test. 関数ntype??は、型に関する判定基準を取り、関数を返します。この関数は、ノードに適用された際、そのノードがそのテストを満足するかを返します。

            ntype?? :: Crit -> Node -> Boolean

     The criterion CRIT is one of the following symbols: 判定基準CRITは、以下のシンボルのうちの1つです。

     id
          tests if the Node has the right name (id) そのノードが正しい名前(id)を持っているかをテストします。

     @
          tests if the Node is an ATTRIBUTES-LIST. そのノードがATTRIBUTES-LISTであるかをテストします。

     *
          tests if the Node is an ELEMENT. そのノードがELEMENTであるかをテストします。

     *text*
          tests if the Node is a text node. そのノードがテキストノードであるかをテストします。

     *data*
          tests if the Node is a data node (text, number, boolean, etc., but not pair). そのノードがデータノード(テキスト、数値、真偽値などで、ペアではない)であるかをテストします。

     *PI*
          tests if the Node is a PI node. そのノードがPIノードであるかをテストします。

     *COMMENT*
          tests if the Node is a COMMENT node. そのノードがCOMMENTノードであるかをテストします。

     *ENTITY*
          tests if the Node is a ENTITY node. そのノードがENTITYノードであるかをテストします。

     *any*
          #t for any type of Node. どんなタイプのノードに対しても#tを返します。

 -- Function: ntype-namespace-id?? ns-id
     This function takes a namespace-id, and returns a predicate Node -> Boolean, which is #t for nodes with this very namespace-id. NS-ID is a string. (ntype-namespace-id?? #f) will be #t for nodes with non-qualified names. この関数は、名前空間IDを取り、述語Node -> Booleanを返します。この述語はまさにその名前空間IDを持つノードに対しては #tを返します。NS-IDは文字列です。 (ntype-namespace-id?? #f)は、完全修飾されていない名前を持つノードに対して#tを返します。

 -- Function: sxml:invert pred
     This function takes a predicate and returns it inverted . That is if the given predicate yields #f or '() the inverted one yields the given node (#t) and vice versa. この関数は、述語を取り、それを反対にして返します。与えられた述語が#fや'()を返す場合、反対にされたものは与えられたノード(#t)を返します。

 -- Function: node-eq? other
 -- Function: node-equal? other
     Curried equivalence converter-predicates, i.e. 等価な述語としてのコンパータにカリー化します。すなわち、

            ((node-eq? a) b)    == (eq? a b)
            ((node-equal? a) b) == (equal? a b)

 -- Function: node-pos n

           node-pos:: N -> Nodeset -> Nodeset, or
           node-pos:: N -> Converter

     Select the N'th element of a Nodeset and return as a singular Nodeset; Return an empty nodeset if the Nth element does not exist. ((node-pos 1) Nodeset) selects the node at the head of the Nodeset, if exists; ((node-pos 2) Nodeset) selects the Node after that, if exists. N can also be a negative number: in that case the node is picked from the tail of the list. ((node-pos -1) Nodeset) selects the last node of a non-empty nodeset; ((node-pos -2) Nodeset) selects the last but one node, if exists. ノードセットのN番目の要素を選択し、1つの要素を持つノードセットを返します。 N番目の要素が存在しなければ、空のノードセットを返します。 ((node-pos 1) Nodeset)は、ノードセットの先頭ノードがあればそれを選択します。 ((node-pos 2) Nodeset)は、2番目のノードがあればそれを選択します。 Nは負の数でも構いません。その場合、ノードはリストの末尾から数えられます。 ((node-pos -1) Nodeset)は、空ではないノードセットの最後のノードを選択します。 ((node-pos -2) Nodeset)は、最後から2番目のノードがあればそれを選択します。

 -- Function: sxml:filter pred?

           filter:: Converter -> Converter

     A filter applicator, which introduces a filtering context. The argument converter is considered a predicate, with either #f or nil result meaning failure. フィルタリングを行う、フィルタアプリケータです。引数のコンバータは、#fあるいはnilとなることが失敗を意味する述語とみなされます。

 -- Function: take-until pred?

           take-until:: Converter -> Converter, or
           take-until:: Pred -> Node|Nodeset -> Nodeset

     Given a converter-predicate and a nodeset, apply the predicate to each element of the nodeset, until the predicate yields anything but #f or nil. Return the elements of the input nodeset that have been processed till that moment (that is, which fail the predicate). take-until is a variation of the filter above: take-until passes elements of an ordered input set till (but not including) the first element that satisfies the predicate. The nodeset returned by ((take-until (not pred)) nset) is a subset -- to be more precise, a prefix -- of the nodeset returned by ((filter pred) nset). 述語としてのコンバータとノードセットが与えられると、ノードセットの各要素に述語を適用し、述語が#fあるいはnil以外を返すと、 (その述語が失敗した)その時点までに処理された要素を返します。 take-untilは、上のフィルタのバリエーションの1つです。 take-untilは、その述語を満足する最初の要素(それ自体は含まない)まで、順序付けられた入力のセットの要素をパスします。 ((take-until (not pred)) nset)により返されるノードセットは、 ((filter pred) nset)により返されるノードセットのサブセット -- 具体的には接頭辞 --になります。

 -- Function: take-after pred?

          take-after:: Converter -> Converter, or
          take-after:: Pred -> Node|Nodeset -> Nodeset

     Given a converter-predicate and a nodeset, apply the predicate to each element of the nodeset, until the predicate yields anything but #f or nil. Return the elements of the input nodeset that have not been processed: that is, return the elements of the input nodeset that follow the first element that satisfied the predicate. take-after along with take-until partition an input nodeset into three parts: the first element that satisfies a predicate, all preceding elements and all following elements. 述語としてのコンバータとノードセットを与えると、述語をノードセットの各要素に適用し、述語が#fかnil以外を返すと、まだ述語が適用されていない要素を返します。つまり、述語を満足する最初の要素の後に続く要素を返します。 take-afterとtake-untilを一緒に使うと、入力のノードセットを3つのパート: 述語を満足する最初の要素、その要素の前の部分、その要素の後の部分に分けます。

 -- Function: map-union proc lst
     Apply proc to each element of lst and return the list of results. If proc returns a nodeset, splice it into the result.

     From another point of view, map-union is a function Converter->Converter, which places an argument-converter in a joining context. procをlstの各要素に適用し、結果のリストを返します。 procがノードセットを返す場合、それを結果につなぎ合わせます。

     別の観点から見ると、map-unionはConverter->Converter関数で、結合を行いたいコンテキストでの引数としてのコンバータに位置します。

 -- Function: node-reverse node-or-nodeset

          node-reverse :: Converter, or
          node-reverse:: Node|Nodeset -> Nodeset

     Reverses the order of nodes in the nodeset. This basic converter is needed to implement a reverse document order (see the XPath Recommendation). ノードセットでのノードの順番を逆順にします。この基本的なコンバータは、逆順のドキュメントオーダーを実装するために必要です。(XPath勧告を参照して下さい。)

 -- Function: node-trace title

           node-trace:: String -> Converter

     (node-trace title) is an identity converter. In addition it prints out a node or nodeset it is applied to, prefixed with the 'title'. This converter is very useful for debugging. (node-trace title)は、それ自身を返すコンバータです。また、自身が適用されるノードやノードセットを、'title'というプリフィックスを付けてプリントします。このコンバータは、デバッグの際にとても便利です。

What follow are Converter combinators, higher-order functions that transmogrify a converter or glue a sequence of converters into a single, non-trivial converter. The goal is to arrive at converters that correspond to XPath location paths.

From a different point of view, a combinator is a fixed, named pattern of applying converters. Given below is a complete set of such patterns that together implement XPath location path specification. As it turns out, all these combinators can be built from a small number of basic blocks: regular functional composition, map-union and filter applicators, and the nodeset union. コンバータの組み合わせに続くものは、コンバータを一変させる、あるいはコンバータのシーケンスを1つの強力なコンバータにつなぎ合わせる高階関数です。そのゴールは、XPathのロケーションパスに対応するコンバータとなることです。

別の観点から見ると、コンバータは、コンバータ群の適用の固定され名前の付いたパターンとみなせます。以下に挙げるのは、XPathのロケーションパスの仕様を実装するそのようなパターンの完全なセットです。結局のところ、これら全てのコンビネータはいくつかの基本的なブロック、通常の関数的なコンポジション、map-unionとfilterアプリケータ、ノードセットユニオンなどから構築することができます

 -- Function: select-kids test-pred?

          select-kids:: Pred -> Node -> Nodeset

     Given a Node, return an (ordered) subset its children that satisfy the Pred (a converter, actually). ノードを与えると、述語(実際はコンバータ)を満足するその子要素の (順序付けられた)サブセットを返します。

          select-kids:: Pred -> Nodeset -> Nodeset

     The same as above, but select among children of all the nodes in the Nodeset. 上と同じですが、ノードセットの全てのノードの子要素から選択します。

 -- Function: node-self pred

           node-self:: Pred -> Node -> Nodeset, or
           node-self:: Converter -> Converter

     Similar to select-kids but apply to the Node itself rather than to its children. The resulting Nodeset will contain either one component, or will be empty (if the Node failed the Pred). select-kidsに似ていますが、自身をその子要素に適用するのではなく、ノードそれ自身に適用します。結果のノードセットは、1つのコンポーネントを含むか、空(ノードが述語を満足しない場合)になります。

 -- Function: node-join . selectors

           node-join:: [LocPath] -> Node|Nodeset -> Nodeset, or
           node-join:: [Converter] -> Converter

     join the sequence of location steps or paths as described in the title comments above. 上のタイトルコメントで説明されるようなロケーションステップあるいはロケーションパスのシーケンスをつなぎ合わせます。

 -- Function: node-reduce . converters

           node-reduce:: [LocPath] -> Node|Nodeset -> Nodeset, or
           node-reduce:: [Converter] -> Converter

     A regular functional composition of converters. From a different point of view, ((apply node-reduce converters) nodeset) is equivalent to (foldl apply nodeset converters) i.e., folding, or reducing, a list of converters with the nodeset as a seed. コンバータの通常の関数的なコンポジションです。見方を変えると、((apply node-reduce converters) nodeset)は (foldl apply nodeset converters)と等価です。すなわち、コンバータのリストをノードセットをseedとして畳み込みや分解を行うようなものです。

 -- Function: node-or . converters

           node-or:: [Converter] -> Converter

     This combinator applies all converters to a given node and produces the union of their results. This combinator corresponds to a union, '|' operation for XPath location paths. このコンビネータは、全てのコンバータを与えられたノードに適用し、それらの結果のユニオンを作ります。このコンビネータは、XPathのロケーションパスでの'|'オペレーションであるユニオンに対応します。

 -- Function: node-closure test-pred?

           node-closure:: Converter -> Converter

     Select all descendants of a node that satisfy a converter-predicate. This combinator is similar to select-kids but applies to grand... children as well. This combinator implements the "descendant::" XPath axis. Conceptually, this combinator can be expressed as 述語としてのコンバータを満足するノードの全ての子孫を選択します。このコンビネータはselect-kidsに似ていますが、孫要素やその子要素達にも適用を行います。このコンビネータは、XPathの軸である``descendant::''を実装します。概念的には、このコンビネータは以下のように表現することができます。

           (define (node-closure f)
                (node-or
                  (select-kids f)
          	 (node-reduce (select-kids (ntype?? '*)) (node-closure f))))

     This definition, as written, looks somewhat like a fixpoint, and it will run forever.  It is obvious however that sooner or later (select-kids (ntype?? '*)) will return an empty nodeset. At this point further iterations will no longer affect the result and can be stopped. この定義は、字面の通り、フィックスポイントのような何かで、永久に実行し続けます。しかし、いつかは(select-kids (ntype?? '*)) が空のノードセットを返すことは明白です。その時点では、以降のイテレーションはその結果に影響を及ぼさず停止されることができます。

SXPath query language
---------------------

 -- Function: sxpath abbrpath . ns-binding
     Evaluates an abbreviated SXPath. Returns a procedure that when applied on a node or nodeset will return a nodeset matching the given path.

           sxpath:: AbbrPath -> Converter, or
           sxpath:: AbbrPath -> Node|Nodeset -> Nodeset

     ABBRPATH is a list or a string. If it is a list, it is translated to the full SXPath according to the following rewriting rules. More informal explanation follows shortly. If it is a string, it is an XPath query.

     Note that these are abstract rules to show how it works, and not the running code examples. The nonterminals sxpath1 and sxpathr don't exist as APIs. The term txpath is an internal function that interprets XPath query given as a string.

           (sxpath '()) -> (node-join)
           (sxpath '(path-component ...)) ->
                          (node-join (sxpath1 path-component) (sxpath '(...)))
           (sxpath1 '//) -> (node-or
                               (node-self (ntype?? '*any*))
                               (node-closure (ntype?? '*any*)))
           (sxpath1 '(equal? x)) -> (select-kids (node-equal? x))
           (sxpath1 '(eq? x))    -> (select-kids (node-eq? x))
           (sxpath1 '(or@ ...))  -> (select-kids (ntype-names??
                                                    (cdr '(or@ ...))))
           (sxpath1 '(not@ ...)) -> (select-kids (sxml:invert
                                                   (ntype-names??
                                                    (cdr '(not@ ...)))))
           (sxpath1 '(ns-id:* x)) -> (select-kids
                                                (ntype-namespace-id?? x))
           (sxpath1 ?symbol)     -> (select-kids (ntype?? ?symbol))
           (sxpath1 ?string)     -> (txpath ?string)
           (sxpath1 procedure)   -> procedure
           (sxpath1 '(?symbol ...)) -> (sxpath1 '((?symbol) ...))
           (sxpath1 '(path reducer ...)) ->
                          (node-reduce (sxpath path) (sxpathr reducer) ...)
           (sxpathr number)      -> (node-pos number)
           (sxpathr path-filter) -> (filter (sxpath path-filter))

     SXPath in its simplest form is a list of path components. The result procedure will follow the same path and return the matching node list. For example (one two three) will find element one then two inside it and three inside element two. The equivalent XPath would be one/two/three.

     There are a few special path components (see ntype?? for the complete list):

     *
          matches an element node.

     //
          matches any one or many consecutive path components.

     *text*
          matches a text node (text() in XPath).

     *data*
          matches any data node (e.g. text, number, boolean, etc., but not pair).

     @
          selects the attribute list node.

     A path component could be a list in one of these forms:

     (equal? x)
          matches if the node under examination matches X using node-equal?

     (eq? x)
          matches if the node under examination matches X using node-eq?

     (or@ ...)
          matches if the element name is one of the specified symbols.

     (not@ ...)
          matches if the element name is not one of the specified symbols.

     (ns-id:* x)
          matches the node if it's with namespace X

     (<path> n)
          matches the N-th node matching same path component. N starts from 1. Negative numbers start from the end of the node list backward. This is path[n] syntax in XPath.

     (<path> (<predicate>...))
          matches a path component PATH and (sxpath (<predicate>...)) on those nodes are not empty. This is path[predicate...] syntax in XPath.

     If the path component is a string, it is interpreted as an XPath query string.

     If the path component is a procedure, the procedure takes three arguments: the nodeset being examined, the root node and the variable bindings.

     The root node is usually the entire sxml being applied. However if you apply the result sxpath procedure with two arguments, root-node will be the second argument.

     When applied with three arguments, the variable bindings are the third one. This lets you pass arguments to the procedure.

          ;; select all <book> elements whose style attribute value is equal to
          ;; the <bookstore> element's specialty attribute value.
          (sxpath "//book[/bookstore/@specialty=@style]")
          ;; a similar query but this time make sure specialty of _all_
          ;; bookstores is matched
          (let ([match-specialty
                 (lambda (node root var-binding)
                   (let ([style (car ((sxpath '(@ style *text*)) node))]
                         [all-specialty ((sxpath '(bookstore @ specialty *text*)) node)])
                     (fold (lambda (specialty last-result)
                             (and last-result (string=? style specialty)))
                                  #t
                                  all-specialty)))])
            (sxpath `(// (book (,match-specialty)))))

          ;; select all <bookstore> elements that are inside top-level <book>
          ;; element
          (sxpath '(book bookstore))
          ;; select all <bookstore> elements from anywhere
          (sxpath '(// bookstore))
          ;; select attribute "name" in the top-level <book> element
          (sxpath '(book @ name))
          ;; select all <bookstore> and <bookshop> elements that are inside
          ;; top-level <book> element
          (sxpath '(book (or@ bookstore bookshop)))
          ;; select all elements except <movie> that are inside top-level <book>
          ;; element
          (sxpath '(book (not@ movie @)))
          ;; select the attribute "name" of the second <bookstore> element
          (sxpath '(book (bookstore 2) @ name))
          ;; select the attribute "name" of all <bookstore> elements that has
          ;; attribute "recommended"
          (sxpath '(book (bookstore (@ recommended)) @ name))
          ;; select the attribute "name" of all <bookstore> elements whose
          ;; "rating" attribute is 3
          (sxpath '(book (bookstore (@ rating (eq? 3))) @ name))
          ;; select the attribute "rating" whose value is greater than 3 from
          ;; all <bookstore> elements
          (let ([greater (lambda (nodeset root-node var-binding)
                           (filter (lambda (node)
                                     (> (string->number (sxml:string-value node))
                                        3))
                                   nodeset))])
            (sxpath `(book bookstore @ rating ,greater)))

Some wrapper functions around sxpath: sxpathには、いくつかのラッパ関数があります。

 -- Function: if-sxpath path
     sxpath always returns a list, which is #t in Scheme. if-sxpath returns #f instead of empty list. sxpathは、常にリストを返し、それはSchemeでは#tとなります。 if-sxpathは、空リストの代わりに#fを返します。

 -- Function: if-car-sxpath path
     Returns first node found, if any. Otherwise returns #f. もし存在すれば、最初に見つかったノードを返します。そうでなければ、#fを返します。

 -- Function: car-sxpath path
     Returns first node found, if any. Otherwise returns empty list. もし存在すれば、最初に見つかったノードを返します。そうでなければ、空リストを返します。

 -- Function: sxml:id-alist node . lpaths
     Built an index as a list of (ID_VALUE . ELEMENT) pairs for given node.  LPATHS are location paths for attributes of type ID. 与えられたノードについて、(ID_VALUE . ELEMENT)のペアのリストをインデックスとして構築します。 LPATHSは、タイプIDの属性のロケーションパスです。

SXPath extension
----------------

SXML counterparts to W3C XPath Core Functions Library. W3CのXPathコア関数ライブラリのSXML版です。

 -- Function: sxml:string object
     The counterpart to XPath string function (section 4.2 XPath Rec.) Converts a given object to a string. NOTE: XPathのstring関数(XPath勧告のセクション4.2)に対応するものです。与えられたオブジェクトを文字列に変換します。注意:

      1. When converting a nodeset - a document order is not preserved ノードセットを変換する時は、ドキュメントオーダーは保持されません。

      2. NUMBER->STRING function returns the result in a form which is slightly different from XPath Rec. specification NUMBER->STRING関数は、その結果をXPath勧告の仕様とは少し違ったフォームで返します。

 -- Function: sxml:boolean object
     The counterpart to XPath boolean function (section 4.3 XPath Rec.) Converts its argument to a boolean. XPathのboolean関数(XPath勧告のセクション4.3)に対応するものです。引数を真偽値に変換します。

 -- Function: sxml:number obj
     The counterpart to XPath number function (section 4.4 XPath Rec.) Converts its argument to a number NOTE: XPathのnumber関数(XPath勧告のセクション4.4)に対応するものです。引数を数値に変換します。注意:

      1. The argument is not optional (yet?). 引数は(まだ?)オプションではありません。

      2. string->number conversion is not IEEE 754 round-to-nearest. string->numberの変換は、IEEE 754の四捨五入ではありません。

      3. NaN is represented as 0. NaNは、0として表現されます。

 -- Function: sxml:string-value node
     Returns a string value for a given node in accordance to XPath Rec. 5.1 - 5.7 XPath勧告のセクション5.1 - 5.7にしたがって、与えられたノードの文字列値を返します。

 -- Function: sxml:node? node
     According to XPath specification 2.3, this test is true for any XPath node. For SXML auxiliary lists and lists of attributes has to be excluded. XPathの仕様2.3にしたがい、このテストはいかなるXPathノードに対しても真を返します。 SXMLの補助的なリストや属性のリストは除外されます。

 -- Function: sxml:attr-list obj
     Returns the list of attributes for a given SXML node. Empty list is returned if the given node is not an element, or if it has no list of attributes 与えられたSXMLノードの属性のリストを返します。与えられたノードが要素ではないか、属性のリストを持っていない場合は、空リストが返されます。

 -- Function: sxml:id id-index
     Select SXML element by its unique IDs.  (XPath Rec. 4.1) Returns a converter that takes OBJECT, which is a nodeset or a datatype which can be converted to a string by means of a 'string' function.

     ID-INDEX is ( (id-value . element) (id-value . element) ... ).

     This index is used for selection of an element by its unique ID. SXML要素を、そのユニークなIDによって選択します(XPath勧告 4.1)。 OBJECTを引数に取るコンバータを返します。このOBJECTは、ノードセットか、'string'関数により文字列に変換できるデータタイプです。

     ID-INDEXは、( (id-value . element) (id-value . element) ... )です。

     このインデックスは、要素をそのユニークなIDによって選択するために使われます。

Comparators for XPath objects: XPathオブジェクトの比較子:

 -- Function: sxml:equality-cmp bool-op number-op string-op
     A helper for XPath equality operations: = , != BOOL-OP, NUMBER-OP and 'STRING-OP are comparison operations for a pair of booleans,  numbers and strings respectively. XPathの等値比較: =、!=のためのヘルパです。 BOOL-OP、NUMBER-OP、'STRING-OPはそれぞれ、真偽値、数値、文字列のペアのための比較子です。

 -- Function: sxml:equal? a b
 -- Function: sxml:not-equal? a b
     Counterparts of XPath equality operations: = , !=, using default equality tests. XPathの等値比較: =、!=に対応するもので、デフォルトの等値テストを使います。

 -- Function: sxml:relational-cmp op
     Creates a relational operation ( < , > , <= , >= ) for two XPath objects. op is comparison procedure: < , > , <= or >=. 2つのXPathオブジェクトの関係比較( <、>、<=、>= ) を作ります。 opは、比較を行う手続き: <、>、<=、>=です。

XPath axises. An order in resulting nodeset is preserved. XPathの軸。結果のノードセットにおける順序は維持されます。

 -- Function: sxml:attribute test-pred?
     Attribute axis. 属性の軸です。

 -- Function: sxml:child test-pred?
     Child axis. This function is similar to 'select-kids', but it returns an empty child-list for PI, Comment and Entity nodes. 子要素の軸です。この関数は、'select-kids'に似ていますが、処理命令やコメント、実体ノードについては、空の子リストを返します。

 -- Function: sxml:parent test-pred?
     Parent axis.

     Given a predicate, it returns a function RootNode -> Converter which yields a node -> parent converter then applied to a rootnode.

     Thus, such a converter may be constructed using ((sxml:parent test-pred) rootnode) and returns a parent of a node it is applied to. If applied to a nodeset, it returns the list of parents of nodes in the nodeset. The rootnode does not have to be the root node of the whole SXML tree -- it may be a root node of a branch of interest. The parent:: axis can be used with any SXML node. 親の軸です。

     述語を与えると、RootNode -> Converter関数を返します。この関数は、rootnodeに適用されると、node -> parentとなります。

     このようなコンバータは、 ((sxml:parent test-pred) rootnode) を使って構築され、それが適用されたノードの親を帰します。ノードセットに適用された場合、そのノードセットにあるノードの親のリストを返します。 rootnodeはSXMLツリー全体のルートノードである必要はありません。興味の対象となるブランチ(枝)のルートノードでも構いません。 parent::軸は、どんなSXMLノードにも使えます。

 -- Function: sxml:ancestor test-pred?
     Ancestor axis 祖先の軸です。

 -- Function: sxml:ancestor-or-self test-pred?
     Ancestor-or-self axis 祖先と自分の軸です。

 -- Function: sxml:descendant test-pred?
     Descendant axis 子孫の軸です。

 -- Function: sxml:descendant-or-self test-pred?
     Descendant-or-self axis 子孫と自分の軸です。

 -- Function: sxml:following test-pred?
     Following axis 後続するものの軸です。

 -- Function: sxml:following-sibling test-pred?
     Following-sibling axis 後続する兄弟の軸です。

 -- Function: sxml:namespace test-pred?
     Namespace axis 名前空間の軸です。

 -- Function: sxml:preceding test-pred?
     Preceding axis 先行するものの軸です。

 -- Function: sxml:preceding-sibling test-pred?
     Preceding-sibling axis 先行する兄弟の軸です。

Popular shortcuts: ポピュラーなショートカット:

 -- Function: sxml:child-nodes nodeset

          ((sxml:child sxml:node?) nodeset)

 -- Function: sxml:child-elements nodeset

          ((select-kids sxml:element?) nodeset)

sxml.tools - Manipulating SXML structure
========================================

 -- Module: sxml.tools

     This module is a port of Kirill Lisofsky's sxml-tools, a collection of convenient procedures that work on SXML structure. The current version is derived from sxml-tools CVS revision 3.13.

     The manual entry is mainly derived from the comments in the original source code. 現在のバージョンは、sxml-toolsのCVSのリビジョン3.13から導出されています。

     マニュアルのエントリは主に、オリジナルのソースコードから導出されています。

SXML predicates
---------------

 -- Function: sxml:empty-element? obj
     A predicate which returns #t if given element OBJ is empty. Empty element has no nested elements, text nodes, PIs, Comments or entities but it may contain attributes or namespace-id. It is a SXML counterpart of XML empty-element. 与えられた要素OBJが空なら#tを返す述語です。空要素は、ネストした要素、テキストノード、PI、コメントや実体を持ちませんが、属性や名前空間IDは持つかもしれません。それは、XMLのempty-elementのSXML版です。

 -- Function: sxml:shallow-normalized? obj
     Returns #t if the given OBJ is shallow-normalized SXML element. The element itself has to be normalized but its nested elements are not tested. 与えられたOBJが浅く正規化されたSXML要素であれば#tを返します。要素それ自体は正規化されていなければなりませんが、ネストした要素はテストされません。

 -- Function: sxml:normalized? obj
     Returns #t if the given OBJ is normalized SXML element. The element itself and all its nested elements have to be normalised. 与えられたOBJが正規化されたSXML要素であれば#tを返します。要素それ自体とその全てのネストした要素が正規化されていなければなりません。

 -- Function: sxml:shallow-minimized? obj
     Returns #t if the given OBJ is shallow-minimized SXML element. The element itself has to be minimised but its nested elements are not tested. 与えられたOBJが浅く最小化されたSXML要素であれば#tを返します。要素それ自体は最小化されていなければなりませんが、そのネストした要素はテストされません。

 -- Function: sxml:minimized? obj
     Returns #t if the given OBJ is minimized SXML element. The element itself and all its nested elements have to be minimised. 与えられたOBJが最小化されたSXML要素であれば#tが返されます。要素それ自体とその全てのネストした要素が最小化されていなければなりません。

SXML accessors
--------------

 -- Function: sxml:name obj
     Returns a name of a given SXML node. It's just an alias of car, but introduced for the sake of encapsulation. 与えられたSXMLノードの名前を返します。これは単にcarのエイリアスに過ぎませんが、カプセル化のために導入されています。

 -- Function: sxml:element-name obj
     A version of sxml:name, which returns #f if the given OBJ is not a SXML element. Otherwise returns its name. sxml:nameの、与えられたOBJがSXML要素ではない場合は#fを返すバージョンです。OBJがSXML要素であれば、その名前を返します。

 -- Function: sxml:node-name obj
     Safe version of sxml:name, which returns #f if the given OBJ is not a SXML node. Otherwise returns its name. sxml:nameの、与えられたOBJがSXMLノードでない場合は#fを返す、安全なバージョンです。OBJがSXMLノードであれば、その名前を返します。

 -- Function: sxml:ncname obj
     Returns Local Part of Qualified Name (Namespaces in XML production [6]) for given obj, which is ":"-separated suffix of its Qualified Name. If a name of a node given is NCName (Namespaces in XML production [4]), then it is returned as is. Please note that while SXML name is a symbol this function returns a string. 与えられたobjの完全修飾名(Namespaces in XML production [6])のローカルパート、つまりその完全修飾名を``:''で分割した後ろの部分を返します。与えられたノードの名前がNCName(Namespaces in XML production [4])であれば、それをそのまま返します。 SXMLの名前はシンボルですが、この関数は文字列を返すことに注意して下さい。

 -- Function: sxml:name->ns-id sxml-name
     Returns namespace-id part of given name, or #f if it's LocalName 与えられた名前の名前空間ID部分を返します。与えられた名前がLocalNameの場合は#fを返します。

 -- Function: sxml:content obj
     Returns the content of given SXML element or nodeset (just text and element nodes) representing it as a list of strings and nested elements in document order.  This list is empty if OBJ is empty element or empty list. 与えられたSXML要素かノードセット(テキストノードと要素ノードのみ)の内容を、ドキュメントオーダーにしたがった文字列のリストとネストした要素として返します。このリストは、OBJが空要素や空リストの場合は空です。

 -- Function: sxml:content-raw obj
     Returns all the content of normalized SXML element except ATTR-LIST and AUX-LIST. Thus it includes PI, COMMENT and ENTITY nodes as well as TEXT and ELEMENT nodes returned by sxml:content. Returns  a list of nodes in document order or empty list if OBJ is empty element or empty list. This function is faster than sxml:content. 正規化されたSXML要素の全ての内容を、ATTR-LISTとAUX-LISTを除いて返します。したがってそれは、PI、COMMENT、ENTITY ノードとともに、sxml:contentによって返されるTEXTやELEMENTも含みます。戻り値は、ドキュメントオーダーにしたがったノードのリストか、 OBJが空要素や空リストの場合は空リストになります。この関数は、sxml:contentよりも高速です。

In SXML normal form, an element is represented by a list as this: SXMLの通常のフォームでは、1つの要素は次のようなリストで表現されます。

       (NAME ATTR-LIST AUX-LIST CONTENT ...)

where ATTR-LIST is a list beginning with @, and AUX-LIST is a list beginning with @@.

In the minimized form, AUX-LIST can be omitted when it is empty. ATTR-LIST can be omitted when it is empty and AUX-LIST is absent.

The following procedures extract ATTR-LIST and AUX-LIST. ATTR-LISTは@で始まるリストで、AUX-LISTは@@で始まるリストです。

最小化されたフォームでは、AUX-LISTは空であれば省略できます。 ATTR-LISTは、それが空でかつAUX-LISTがなければ省略できます。

以下の手続きは、ATTR-LISTとAUX-LISTを抽出するものです。

 -- Function: sxml:attr-list-node obj
     Returns ATTR-LIST for a given OBJ, or #f if it is absent 与えられたOBJのATTR-LISTを返します。 ATTR-LISTが存在しなければ#fを返します。

 -- Function: sxml:attr-as-list obj
     Returns ATTR-LIST wrapped in list, or '((@)) if it is absent and AUX-LIST is present, or '() if both lists are absent. ATTR-LISTをリストにラップして返します。 ATTR-LISTが存在せずAUN-LISTがある場合は'((@))を返します。両方とも存在しない場合には'()を返します。

 -- Function: sxml:aux-list-node obj
     Returns AUX-LIST for a given OBJ, or #f if it is absent. 与えられたOBJのAUX-LISTを返します。 ATTR-LISTが存在しなければ#fを返します。

 -- Function: sxml:aux-as-list obj
     Returns AUX-LIST wrapped in list, or '() if it is absent. AUX-LISTをリストにラップして返します。 AUX-LISTが存在しなければ'()を返します。

 -- Function: sxml:attr-list-u obj
     Returns the list of attributes for given element or nodeset. Analog of ((sxpath '(@ *)) OBJ). Empty list is returned if there is no list of attributes.

     The -u suffix indicates it can be used for non-normalized SXML node.  ('u' stands for 'universal'). 与えられた要素かノードセットの属性のリストを返します。 ((sxpath '(@ *)) OBJ)と類似です。属性のリストがない場合は空リストが返されます。

 -- Function: sxml:aux-list obj
     Returns the list of auxiliary nodes for given element or nodeset. Analog of ((sxpath '(@@ *)) OBJ). Empty list is returned if a list of auxiliary nodes is absent. 与えられた要素かノードセットの補助ノードのリストを返します。 ((sxpath '(@@ *)) OBJ)と類似です。補助ノードのリストがない場合は空リストが返されます。

 -- Function: sxml:aux-list-u obj
     Returns the list of auxiliary nodes for given element or nodeset. Analog of ((sxpath '(@@ *)) OBJ). Empty list is returned if a list of auxiliary nodes is absent.

     The -u suffix indicates it can be used for non-normalized SXML node.  ('u' stands for 'universal'). 与えられた要素かノードセットの補助ノードのリストを返します。 ((sxpath '(@@ *)) OBJ)と類似です。補助ノードのリストがない場合は空リストが返されます。

     -uが付くものは、正規化されていないSXMLノードに対しても使えるということを示しています。('u'は'universal'の意味です。)

 -- Function: sxml:aux-node obj aux-name
     Return the first aux-node with AUX-NAME given in SXML element OBJ or #f is such a node is absent. Note: it returns just the first node found even if multiple nodes are present, so it's mostly intended for nodes with unique names . 与えられたSXML要素OBJでAUX-NAMEという名前の付いている最初の補助ノードを返します。そのようなノードがない場合は#fを返します。注意: 複数のノードがあっても最初に見つかったノードのみを返します。したがって、ユニークな名前を持っているノード群に対して使われることを意図しています。

 -- Function: sxml:aux-nodes obj aux-name
     Return a list of aux-node with AUX-NAME given in SXML element OBJ or '() if such a node is absent. 与えられたSXML要素OBJでAUX-NAMEとうい名前の付いている補助ノードのリストを返します。そのようなノードがなければ'()を返します。

 -- Function: sxml:attr obj attr-name
     Accessor for an attribute ATTR-NAME of given SXML element OBJ. It returns: the value of the attribute if the attribute is present, or #f if there is no such an attribute in the given element. 与えられたSXML要素OBJのATTR-NAMEという属性へのアクセッサです。戻り値は、その属性が存在すればその属性の値、与えられた要素にそのような属性がなければ#fです。

 -- Function: sxml:num-attr obj attr-name
     Accessor for a numerical attribute ATTR-NAME of given SXML element OBJ. It returns: a value of the attribute as the attribute as a number if the attribute is present and its value may be converted to number using string->number, or #f if there is no such an attribute in the given element or its value can't be converted to a number. 与えられたSXML要素OBJのATTR-NAMEという数値の属性へのアクセッサです。戻り値は、その属性が存在してその値がstring->numberにより数値へ変換できる場合はその属性を数値としてその属性の値、与えられた要素にそのような属性がないかその値が数値へ変換できない場合は #fです。

 -- Function: sxml:attr-u obj attr-name
     Accessor for an attribute ATTR-NAME of given SXML element OBJ which may also be an attributes-list or nodeset (usually content of SXML element).

     It returns: the value of the attribute if the attribute is present, or #f if there is no such an attribute in the given element.

     The -u suffix indicates it can be used for non-normalized SXML node.  ('u' stands for 'universal'). 与えられたSXML要素OBJのATTR-NAMEという名前の属性へのアクセッサです。OBJは、(通常はSXML要素の内容である) 属性リストやノードセットでも構いません。

     戻り値は、その属性が存在すればその属性の値、与えられた要素にそのような属性がない場合は#fです。

     -uが付くものは、正規化されていないSXMLノードに対しても使えるということを示しています。('u'は'universal'の意味です。)

 -- Function: sxml:ns-list obj
     Returns the list of namespaces for given element. Analog of ((sxpath '(@@ *NAMESPACES* *)) OBJ) Empty list is returned if there is no list of namespaces. 与えられた要素の名前空間のリストを返します。 ((sxpath '(@@ *NAMESPACES* *)) OBJ)と類似です。名前空間のリストがない場合は空リストが返されます。

 -- Function: sxml:ns-id->nodes obj namespace-id
     Returns the list of namespace-assoc's for given NAMESPACE-ID in SXML element OBJ. Analog of ((sxpath '(@@ *NAMESPACES* namespace-id)) OBJ). Empty list is returned if there is no namespace-assoc with NAMESPACE-ID given. SXML要素OBJで、与えられたNAMESPACE-IDに対応する名前空間の連想リストのリストを返します。 ((sxpath '(@@ *NAMESPACES* namespace-id)) OBJ)と類似です。与えられたNAMESPACE-IDに対応する名前空間の連想リストがない場合は空リストが返されます。

 -- Function: sxml:ns-id->uri obj namespace-id
     Returns a URI for NAMESPACE-ID given, or #f if there is no namespace-assoc with NAMESPACE-ID given. 与えられたNAMESPACE-IDに対応するURIを返します。与えられたNAMESPACE-IDに対応する名前空間の連想リストがない場合は #fを返します。

 -- Function: sxml:ns-uri->id obj uri
     Returns a namespace-id for namespace URI given. 与えられた名前空間URIに対応する名前空間IDを返します。

 -- Function: sxml:ns-id ns-assoc
     Returns namespace-id for given namespace-assoc list. 与えられた名前空間連想リストに対応する名前空間IDを返します。

 -- Function: sxml:ns-uri ns-assoc
     Returns URI for given namespace-assoc list. 与えられた名前空間連想リストに対応するURIを返します。

 -- Function: sxml:ns-prefix ns-assoc
     It returns namespace prefix for given namespace-assoc list. Original (as in XML document) prefix for namespace-id given has to be strored as the third element in namespace-assoc list if it is different from namespace-id. If original prefix is omitted in namespace-assoc then namespace-id is used instead. 与えられた名前空間連想リストに対応する名前空間接頭辞を返します。与えられた名前空間IDの(XML文書における)オリジナルの接頭辞は、それが名前空間IDと異なる場合は、名前空間連想リストの3番目の要素として格納されなければなりません。名前空間連想リストでオリジナルの接頭辞が省略されている場合は、代わりに名前空間IDが使われます。

SXML modifiers
--------------

Constructors and mutators for normalized SXML data. These functions are optimized for normalized SXML data. They are not applicable to arbitrary non-normalized SXML data.

Most of the functions are provided in two variants: 正規化されたSXMLデータのコンストラクタやミューテータです。これらの関数は、正規化されたSXMLデータに最適化されています。任意の正規化されていないSXMLデータには適用できません。

ほとんどの関数には2つのバージョンがあります。

 1. side-effect intended functions for linear update of given elements. Their names are ended with exclamation mark. Note that the returned value of this variant is unspecified, unless explicitly noted. An example: sxml:change-content!. 与えられた要素のその場での更新のために副作用が意図された関数。これらの名前はエクスクラメーションマークで終わっています。このバージョンの戻り値は、特に断りのない限り未定義です。例としては、sxml:change-content!が挙げられます。

 2. pure functions without side-effects which return modified elements. An example: sxml:change-content. 変更された要素を返す、副作用のない純粋な関数。例としては、sxml:change-contentが挙げられます。

 -- Function: sxml:change-content obj new-content
 -- Function: sxml:change-content! obj new-content
     Change the content of given SXML element to NEW-CONTENT. If NEW-CONTENT is an empty list then the OBJ is transformed to an empty element. The resulting SXML element is normalized. 与えられたSXML要素の内容を、NEW-CONTENTに変更します。 NEW-CONTENTが空リストの場合は、OBJは空要素に変更されます。結果のSXML要素は正規化されています。

 -- Function: sxml:change-attrlist obj new-attrlist
 -- Function: sxml:change-attrlist! obj new-attrlist
     The resulting SXML element is normalized. If NEW-ATTRLIST is empty, the cadr of OBJ is (@). 結果のSXML要素は正規化されています。 NEW-ATTRLISTが空の場合は、OBJのcadrは(@)になります。

 -- Function: sxml:change-name obj new-name
 -- Function: sxml:change-name! obj new-name
     Change a name of SXML element destructively. SXML要素の名前を破壊的に変更します。

 -- Function: sxml:add-attr obj attr
     Returns SXML element OBJ with attribute ATTR added, or #f if the attribute with given name already exists. ATTR is (ATTR-NAME ATTR-VALUE). Pure functional counterpart to sxml:add-attr!. 属性ATTRが追加されたSXML要素OBJを返します。与えられた名前の属性がすでに存在する場合は#fを返します。 ATTRは(ATTR-NAME ATTR-VALUE)です。 sxml:add-attr!に対応する純粋関数的な関数です。

 -- Function: sxml:add-attr! obj attr
     Add an attribute ATTR for an element OBJ. Returns #f if the attribute with given name already exists. The resulting SXML node is normalized. Linear update counterpart to sxml:add-attr. 要素OBJに属性ATTRを追加します。与えられた名前の属性がすでに存在する場合は#fを返します。結果のSXMLノードは正規化されています。 sxml:add-attrに対応するその場で更新する関数です。

 -- Function: sxml:change-attr obj attr
     Returns SXML element OBJ with changed value of attribute ATTR, or #f if where is no attribute with given name. ATTR is (ATTR-NAME ATTR-VALUE). 属性ATTRの値が変更されたSXML要素OBJを返します。与えられた名前の属性がない場合は#fを返します。 ATTRは(ATTR-NAME ATTR-VALUE)です。

 -- Function: sxml:change-attr! obj attr
     Change value of the attribute for element OBJ. ATTR is (ATTR-NAME ATTR-VALUE). Returns #f if where is no such attribute. 要素OBJの属性の値を変更します。 ATTRは(ATTR-NAME ATTR-VALUE)です。そのような属性がない場合は#fを返します。

 -- Function: sxml:set-attr obj attr
 -- Function: sxml:set-attr! obj attr
     Set attribute ATTR of element OBJ. If there is no such attribute the new one is added. 要素OBJの属性ATTRをセットします。そのような属性がない場合は新しい属性として追加されます。

 -- Function: sxml:add-aux obj aux-node
     Returns SXML element OBJ with an auxiliary node AUX-NODE added. 補助ノードAUX-NODEが追加されたSXML要素OBJを返します。

 -- Function: sxml:add-aux! obj aux-node
     Add an auxiliary node AUX-NODE for an element OBJ. 要素OBJに補助ノードAUX-NODEを追加します。

 -- Function: sxml:squeeze obj
 -- Function: sxml:squeeze! obj
     Eliminates empty lists of attributes and aux-lists for given SXML element OBJ and its descendants ("minimize" it). Returns a minimized and normalized SXML element. 与えられたSXML要素OBJとその子孫について、空のリストである属性および補助リストを排除します(最小化)。最小化され、正規化されたSXML要素が返されます。

 -- Function: sxml:clean obj
     Eliminates empty lists of attributes and all aux-lists for given SXML element OBJ and its descendants. Returns a minimized and normalized SXML element. 与えられたSXML要素OBJとその子孫について、空リストである属性と、全ての補助リストを削除します。最小化され、正規化されたSXML要素が返されます。

SXPath auxiliary utilities
--------------------------

These are convenience utilities to extend SXPath functionalities. これらは、SXPathの機能を拡張する便利なユーティリティです。

 -- Function: sxml:add-parents obj . top-ptr
     Returns an SXML nodeset with a 'parent pointer' added. A parent pointer is an aux node of the form (*PARENT* THUNK), where THUNK returns the parent element. SXMLノードセットに'親へのポインタ'を追加したものを返します。親へのポインタは、(*PARENT* THUNK)というフォームを持つ補助ノードです。THUNKは親要素を返します。

 -- Function: sxml:node-parent rootnode
     Returns a fast 'node-parent' function, i.e. a function of one argument - SXML element - which returns its parent node using *PARENT* pointer in aux-list. '*TOP-PTR* may be used as a pointer to root node. It return an empty list when applied to root node. 高速な'node-parent'関数を返します。すなわち、SXML要素を1引数として取り、補助リストで *PARENT*ポインタを使ってその親ノードを返す関数を返します。 '*TOP-PTR*はルートノードへのポインタとして使われます。ルートノードに対して適用されると空リストを返します。

 -- Function: sxml:lookup id index
     Lookup an element using its ID. 要素をそのIDを使って探します。

SXML to markup conversion
-------------------------

Procedures to generate XML or HTML marked up text from SXML. For more advanced conversion, see the SXML serializer (Serializing XML and HTML from SXML).

SXMLからXMLやHTMLなどのマークアップされたテキストを生成する手続き。もっと高尚な変換器を得たいだけならば、 Serializing XML and HTML from SXMLをチェックして下さい。

 -- Function: sxml:clean-feed . fragments
     Filter the 'fragments'. The fragments are a list of strings, characters, numbers, thunks, #f -- and other fragments. The function traverses the tree depth-first, and returns a list of strings, characters and executed thunks, and ignores #f and '().

     If all the meaningful fragments are strings, then (apply string-append ... ) to a result of this function will return its string-value.

     It may be considered as a variant of Oleg Kiselyov's SRV:send-reply: While SRV:send-reply displays fragments, this function returns the list of meaningful fragments and filter out the garbage. 'fragments'をフィルタします。 fragmentsは、文字列、文字、数値、手続き、#f、他のフラグメントのリストです。この関数はツリーを深さ優先でトラバースし、文字列、文字、実行された手続きのリストを返し、 #fと'()を無視します。

     全ての意味のあるフラグメントは文字列で、この関数の結果に(apply string-append ... )を適用すると、そのstring-valueを返します。

     これは、Oleg KiselyovのSRV:send-replyの変種であるとみなすことができるでしょう。 SRV:send-replyはフラグメントを印字(display)しますが、この関数は意味のあるフラグメントのリストを返し、ごみをふるい落とします。

 -- Function: sxml:attr->xml attr
     Creates the XML markup for attributes. 属性のXMLマークアップを作ります。

 -- Function: sxml:string->xml string
     Return a string or a list of strings where all the occurrences of characters <, >, &, ", or ' in a given string are replaced by corresponding character entity references. See also sxml:string->html. 与えられた文字列中の全ての<、>、&、``、 'を対応する文字実体参照に置き換えた、文字列あるいは文字列のリストを返します。 sxml:string->htmlも参照して下さい。

 -- Function: sxml:sxml->xml tree
     A version of dispatch-node specialized and optimized for SXML->XML transformation. SXML->XML変換に特化され最適化されたバージョンのノードディスパッチです。

 -- Function: sxml:attr->html attr
     Creates the HTML markup for attributes. 属性のHTMLマークアップを作ります。

 -- Function: sxml:string->html string
     Given a string, check to make sure it does not contain characters <, >, &, " that require encoding. See also html-escape-string in Simple HTML document construction. 与えられた文字列で、それがエンコーディングを必要とする文字、 <、>、&、``を含まないことをチェックします。 Simple HTML document constructionの html-escape-stringも参照して下さい。

 -- Function: sxml:non-terminated-html-tag? tag
     This predicate yields #t for "non-terminated" HTML 4.0 tags. この述語は、``終了タグのない''HTML 4.0のタグに対して#tを返します。

 -- Function: sxml:sxml->html tree
     A version of dispatch-node specialized and optimized for SXML->HTML transformation. SXML->HTML変換に対して特化され最適化されたバージョンのノードディスパッチです。

sxml.serializer - Serializing XML and HTML from SXML
====================================================

 -- Module: sxml.serializer
     This module contains a full-featured serializer from SXML into XML and HTML, partially conforming to XSLT 2.0 and XQuery 1.0 Serialization (http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/). It's more powerful than sxml:sxml->xml and sxml:sxml->html from sxml.tools.

     The manual entry is mainly derived from the comments in the original source code. このモジュールはSXMLからXMLとHTMLへの変換を行う、様々な機能を持つシリアライザを提供します。XSLT2.0とXQuery1.0に部分的に適合しています。 (http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/)。 sxml.toolsのsxml:sxml->xmlとsxml:sxml->htmlよりも強力です。

     マニュアルのエントリは主に、オリジナルのソースコードから取られてています。

Simple SXML serializing
-----------------------

The SXML serializer provides some convenient high-level converters which should be enough for most tasks. 高レベルの、簡単に使えるシリアライザです。大抵の目的にはこれで十分使えるでしょう。

 -- Function: srl:sxml->xml sxml-obj :optional port-or-filename
     Serializes the SXML-OBJ into XML, with indentation to facilitate readability by a human.

     If PORT-OR-FILENAME is not supplied, the functions return a string that contains the serialized representation of the SXML-OBJ.

     If PORT-OR-FILENAME is supplied and is a port, the functions write the serialized representation of SXML-OBJ to this port and return an unspecified result.

     If PORT-OR-FILENAME is supplied and is a string, this string is treated as an output filename, the serialized representation of SXML-OBJ is written to that filename and an unspecified result is returned. If a file with the given name already exists, the effect is unspecified. SXML-OBJをXMLへと変換します。出力は人間が読みやすいようにインデントされます。

     PORT-OR-FILENAMEが与えられなければ、戻り値はSXML-OBJの変換結果の文字列になります。

     PORT-OR-FILENAMEがポートならば、そのポートにXMLを書き出します。戻り値は不定です。

     PORT-OR-FILENAMEが文字列ならば、その名のファイルにXMLを書き出します。戻り値は不定です。そのようなファイルが既に存在する場合、結果は不定です。

 -- Function: srl:sxml->xml-noindent sxml-obj :optional port-or-filename
     Serializes the SXML-OBJ into XML, without indentation.

     Argument PORT-OR-FILENAME works like described in srl:sxml->xml. srl:sxml->xmlと同じように動作しますが、インデントを行いません。

     引数PORT-OR-FILENAMEはsrl:sxml->xmlと同様に動作します。

 -- Function: srl:sxml->html sxml-obj :optional port-or-filename
     Serializes the SXML-OBJ into HTML, with indentation to facilitate readability by a human.

     Argument PORT-OR-FILENAME works like described in srl:sxml->xml. SXML-OBJをHTMLへと変換します。出力は人間が読みやすいようにインデントされます。

     引数PORT-OR-FILENAMEはsrl:sxml->xmlと同様に動作します。

 -- Function: srl:sxml->html-noindent sxml-obj :optional port-or-filename
     Serializes the SXML-OBJ into HTML, without indentation.

     Argument PORT-OR-FILENAME works like described in srl:sxml->xml. srl:sxml->htmlと同じように動作しますが、インデントを行いません。

     引数PORT-OR-FILENAMEはsrl:sxml->xmlと同様に動作します。

Custom SXML serializing
-----------------------

These functions provide full access to all configuration parameters of the XML serializer. 以下の手続きはXMLシリアライザの全ての設定パラメータへのアクセスを提供します。

 -- Function: srl:parameterizable sxml-obj :optional port-or-filename params*
     Generalized serialization procedure, parameterizable with all the serialization parameters supported by this implementation. 汎用シリアライズ手続、この実装でサポートするすべてのシリアライズパラメータのパラメータ化。

     SXML-OBJ - an SXML object to serialize SXML-OBJ - シリアライズするSXMLオブジェクト。

     PORT-OR-FILENAME - either #f, a port or a string; works like in srl:sxml->xml (Simple SXML serializing). PORT-OR-FILENAME - #fあるいはポートあるいは文字列のどれか。 srl:sxml->xmlのものと同じ働きをします(Simple SXML serializing)。

     PARAMS - each parameter is a cons of param-name (a symbol) and param-value.  The available parameter names and their values are described below: PARAMS - 各パラメータはパラメータ名(シンボル)とパラメータ値とのコンス対。利用可能なパラメータ名とその値については後述。

     method - Either the symbol xml or html.  For a detailed explanation of the difference between XML and HTML methods, see XSLT 2.0 and XQuery 1.0 Serialization (http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/). method - シンボルxmlかhtmlのどちらか。XMLメソッドとHTMLメソッドの相違についての詳しい説明は、XSLT 2.0 と XQuery Serialization (http://www.w3.org/TR/2005/CR-xslt-xquery-serialization-20051103/) を参照してください。

     indent - Whether the output XML should include whitespace for human readability (#t or #f).  You can also supply a string, which will be used as the indentation unit. indent - 出力の XML が読みやすさのために空白を含むかどうか (#tあるいは#f)。文字列を設定することもでき、その場合インデント単位に使われます。

     omit-xml-declaration? - Whether the XML declaration should be omitted.  Default: #t. omit-xml-declaration? - XML宣言を省略するかどうか。デフォルトは #t。

     standalone - Whether to define the XML document as standalone in the XML declaration.  Should be one of the symbols yes, no or omit, the later causing standalone declaration to be suppressed.  Default: omit. standalone - XML ドキュメントを XML 宣言でスタンドアローンとして定義するかどうか。yes、no、omitのうちいずれかのシンボルでなければならない。デフォルトは omit

     version - The XML version used in the declaration.  A string or a number.  Default: "1.0". version - XML宣言中のXMLバージョン。文字列または数。デフォルトは"1.0"。

     cdata-section-elements - A list of SXML element names (as symbols).  The contents of those elements will be escaped as CDATA sections. cdata-section-elements - SXML要素の名前(シンボル)のリスト。これらの要素の中身はCDATAセクションと同様にエスケープされる。

     ns-prefix-assig - A list of (cons prefix namespace-uri), where each prefix is a symbol and each namespace-uri a string.  Will serialize the given namespaces with the corresponding prefixes. ns-prefix-assig - (cons prefix namespace-uri)のリスト。各prefixはシンボルで、namespace-uriは文字列。対応する接頭辞をつけて与えられた名前空間をシリアライズする。

     ATTENTION: If a parameter name is unexpected or a parameter value is ill-formed, the parameter is silently ignored! 注意： パラメータ名が期待された名前ではない場合、あるいはパラメータ値が不正な形式である場合にはそのようなパラメータは警告なしで無視されます。

     Example usage:

          (srl:parameterizable
            '(tag (@ (attr "value")) (nested "text node") (empty))
            (current-output-port)
            '(method . xml)  ; XML output method is used by default
            '(indent . "\t")  ; use a single tabulation to indent
            '(omit-xml-declaration . #f)  ; add XML declaration
            '(standalone . yes)  ; denote a standalone XML document
            '(version . "1.0"))  ; XML version

     使用実例：

          (srl:parameterizable
            '(tag (@ (attr "value")) (nested "text node") (empty))
            (current-output-port)
            '(method . xml)  ; XML出力をデフォールト
            '(indent . "\t")  ; インデントは一つのタブ
            '(omit-xml-declaration . #f)  ; XML宣言をつける
            '(standalone . yes)  ; 「standalone」宣言もつける
            '(version . "1.0"))  ; XMLのバージョン

          param ::= (cons param-name param-value)
          param-name ::= symbol

          cdata-section-elements
          value ::= (listof sxml-elem-name)
          sxml-elem-name ::= symbol

          indent
          value ::= 'yes | #t | 'no | #f | whitespace-string

          method
          value ::= 'xml | 'html

          ns-prefix-assig
          value ::= (listof (cons prefix namespace-uri))
          prefix ::= symbol
          namespace-uri ::= string

          omit-xml-declaration?
          value ::= 'yes | #t | 'no | #f

          standalone
          value ::= 'yes | #t | 'no | #f | 'omit

          version
          value ::= string | number

 -- Function: srl:sxml->string sxml-obj cdata-section-elements indent method ns-prefix-assig omit-xml-declaration? standalone version
     Same as srl:parameterizable returning a string and without the overhead of parsing parameters.  This function interface may change in future versions of the library. srl:parameterizableと同様ですが、文字列を返し、パラメータ解析のオーバヘッドはありません。この関数のインタフェースはこのライブラリの将来のバージョンでは変更されるかもしれません。

 -- Function: srl:display-sxml sxml->obj port-or-filename cdata-section-elements indent method ns-prefix-assig omit-xml-declaration? standalone version
     Same as srl:parameterizable writing output to PORT-OR-FILENAME and without the overhead of parsing parameters. This function interface may change in future versions of the library. srl:parameterizableと同様ですが、結果を PORT-OR-FILENAMEに書き出します。パラメータ解析のオーバーヘッドはありません。この関数のインタフェースはこのライブラリの将来のバージョンでは変更されるかもしれません。

text.console - Text terminal control
====================================

 -- Module: text.console
     This module provides a simple interface for character terminal control. Currently we support vt100 compatible terminals and Windows console.

     This module doesn't depend on external library such as curses and works with Gauche alone, but what it can do is limited; for example, you can't get an event when shift key alone is pressed.  For finer controls, you need some extension libraries.

     For an example of the features in this module, see snake.scm in the examples directory of Gauche source distribution. このモジュールは文字端末を制御する簡単なインタフェースを提供します。今のところ、vt100互換端末とWindowsコンソールがサポートされています。

     curses等の外部ライブラリには依存しておらず、Gaucheだけで使うことができますが、出来ることは限られています。例えばシフトキーだけが押されたタイミングでイベントを受け取ることはできません。より細かい制御には、何らかの外部拡張ライブラリが必要になるでしょう。

     このモジュールの機能の例としては、 Gaucheソースのexamplesディレクトリにあるsnake.scmを見てください。

Console objects
---------------

コンソールオブジェクト
-----------

 -- Class: <vt100>
     Represents a vt100-compatible terminal.   An instance of this class can be passed to the ``console'' argument of the following generic functions. vt100互換端末を表します。このクラスのインスタンスは以降のジェネリックファンクションの ``console'' 引数に渡せます。

      -- Instance Variable of <vt100>: iport
          Input port connected to the terminal.  The default value is the standard input port. 端末に接続されている入力ポートです。デフォルトは標準入力です。

      -- Instance Variable of <vt100>: oport
          Output port connected to the terminal.  The default value is the standard output port. 端末に接続されている出力ポートです。デフォルトは標準出力です。

      -- Instance Variable of <vt100>: input-delay
          The terminal send back special keys encoded in an input escape sequence. In order to distinguish such keys from the actual ESC key, we time the input---if the subsequent input doesn't come within input-delay microseconds, we interpret the input as individual keystroke, rather than a part of an escape sequence.  The default value is 1000 (1ms). 端末は、特殊キーが押された場合、ESCから始まるエスケープシーケンスを送って来ます。実際にESCキーが押された場合と区別するために、入力の間隔を測っています。後続の入力がinput-delayμs以内に来なかった場合はそこでシーケンスが終了したとみなし、受け取っているシーケンスが有効なエスケープシーケンスを構成しなければ個別にキー入力されたとみなします。デフォルトは1000、すなわち1msです。

 -- Class: <windows-console>
     Represents Windows console.  This class is defined on all platforms, but its useful methods are only available on Windows-native runtime.

     It doesn't have public slots. Windowsコンソールを表します。このクラス自体は全てのプラットフォームで定義されていますが、有用なメソッドはWindowsネイティブのランタイムでしか提供されません。

     パブリックなスロットはありません。

The application has to check the runtime to see what kind of console is available.  A suggested flow is as follows. アプリケーションは実行時にどの種類のコンソールが利用可能かを見極めなければなりません。推奨される手順は次のとおりです。

  * If has-windows-console? returns true, create <windows-console> instance. You don't need cond-expand; has-windows-console? returns #f on non-Windows platforms. has-windows-console?が真の値を返したなら、<windows-console>のインスタンスを作ります。 has-windows-console?はWindowsプラットフォーム以外では常に#fを返すので、cond-expandは不要です。

  * Check the environment variable TERM.  If it is set and satisfies vt100-compatible?, you can create <vt100> instance. (Note: It is possible that you end up using <vt100> console on Windows; e.g. gosh running on MSYS shell.) 環境変数TERMを調べます。それが定義されていて、vt100-compatible?を満たすなら、<vt100>のインスタンスを作ります。 (Windows上でも<vt100>端末を使うことになる可能性もあります。例えばgoshがMSYSシェルから使われている場合です。)

  * Otherwise, console isn't available. いずれでもなければ、端末は使えません。

The following procedure packages this flow. 次の手続きは上の手順を実装しています。

 -- Function: make-default-console :key if-not-available
     Determines a suitable console class of the running process and returns its instance.

     If no suitable console is available, the behavior depends on the IF-NOT-AVAILABLE keyword argument.  If it is :error, which is default, an error is signalled.  If it is #f, the procedure returns #f. 実行中のプロセスで使える端末のインスタンスを作成して返します。

     適切な端末クラスが無い場合、振る舞いはIF-NOT-AVAILABLEキーワード引数に依存します。デフォルトである:errorの場合はエラーが報告されます。 #fの場合はこの手続きが#fを返します。

 -- Function: vt100-compatible? string
     Given the string value of the environment variable TERM, returns #t if the terminal can be handled by <vt100> console, #f otherwise. 環境変数TERMの値を文字列で受け取り、それが<vt100>端末として扱えるなら#tを、そうでなければ#fを返します。

Console control
---------------

 -- Generic function: call-with-console console proc :key mode
     Takes over the control of the console, and calls PROC with CONSOLE as the only argument.   The console is set to the MODE, which must be a symbol with-terminal-mode accepts: raw, rare or cooked.  By default the console is set to rare mode, which turn off the echoing and passes most of keystrokes to the program, but it intercepts terminal controls (like Ctrl-C for interrupt and Ctrl-Z for suspend; the actual key depends on terminal settings, though.)

     If PROC raises an unhandled error, this generic function resets the terminal mode before returning.  It does not clear the screen.

 -- Generic function: putch console char
     Display a character at the current cursor position, and move the current cursor position.

 -- Generic function: putstr console string
     Display a string from the current cursor position, and move the current cursor position.

 -- Generic function: beep console
     Ring the beep, or flash the screen (visible bell) if possible.

 -- Generic function: getch console
     Fetch a keypress from the console.  This blocks until any key is pressed.

     The return value may be one of the following values:

     A character
          A key for the character is pressed.  It may be a control code if the control key is pressed with the key; that is, if the user presses Ctrl-A, #\x01 will be returned.

     A symbol
          Indicates a special key; the following keys are supported: KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT, KEY_HOME, KEY_END, KEY_INS, KEY_DEL, KEY_PGDN, KEY_PGUP, KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_F11, KEY_F12. (Note: DELETE key is usually mapped to #\x7f, but it depends on the terminal).

     A list of symbol ALT and a character.
          Indicates the character key is pressed with Alt key.  For example, if the user presses Alt-a, (ALT #\a) is returned (assuming CAPSLOCK is off).

     EOF
          Indicates the input is closed somehow.

     Modifier keys except ALT are not treated separately but included in the returned keycode.  Assuming CAPSLOCK is off, if the user press a, Shift+a, and Ctrl+a, the returned value is #\a, #\A and #\x01, respectively. Ctrl+Shift+a can't be distinguished from Ctrl+a.  ALT+a, ALT+Shift+a, and ALT+Ctrl+a will be (ALT #\a), (ALT #\A) and (ALT #\x01), respectively.

 -- Generic function: chready? console
     Returns true if there's a key sequence to be read in the console's input.

 -- Generic function: query-cursor-position console
     Returns two values, the current cursor's x and y position. The top-left corner is (0,0).

 -- Generic function: move-cursor-to console row column
     Move cursor to the specified position.  The top-left corner is (0,0).

 -- Generic function: reset-terminal console
     Reset terminal.  Usually this sets the character attributes to the default, clears the screen, and moves the cursor to (0, 0).

 -- Generic function: clear-screen console
     Clear entire screen.

 -- Generic function: clear-to-eol console
     Clear characters from the current cursor position to the end of the line.

 -- Generic function: clear-to-eos console
     Clear characters from the current cursor position to the end of the screen.

 -- Generic function: hide-cursor console
 -- Generic function: show-cursor console
     Hide/show the cursor.

 -- Generic function: cursor-down/scroll-up console
     If the cursor is at the bottom line of the screen, scroll up the contents and clear the bottom line; the cursor stays the same position.  If the cursor is not at the bottom line of the screen, move the cursor down.

 -- Generic function: cursor-up/scroll-down console
     If the cursor is at the top line of the screen, scroll down the contents and clear the top line; the cursor stays the same position.  If the cursor is not at the top line of the screen, move the cursor up.

 -- Generic function: query-screen-size console
     Returns two values, the width and height of the screen.

     Note: This may affect what's shown in the console. It is recommended that you only call this before redrawing the entire screen and save the result.

 -- Generic function: set-character-attribute console spec
     Set the console so that the subsequent characters will be written with attributes specified by SPEC.

     The character attributes spec is a list in the following format:

          (<fgcolor> [<bgcolor> . <option> ...])

     where:

          <fgcolor> : <color> | #f     ; #f means default
          <bgcolor> : <color> | #f
          <color>  : black | red | green | yellow | blue | magenta | cyan | white
          <option> : bright | reverse | underscore

     For example, you can set characters to be written in red with black background and underscore, you can call:

          (set-character-attribute con '(red black underscore))

     That the options may seem rather limited in the age of full-color bitmap displays.  That's what it used to be, young lads.

 -- Generic function: reset-character-attribute console
     Reset character attributes to the default.

 -- Generic function: with-character-attribute console attrs thunk
     Sets the console's attributes to ATTRS and calls THUNK, then restores the attributes.  Even if THUNK throws an error, attributes are restored.

     Note: You should be able to nest this, but currently nesting isn't working.

text.csv - CSV tables
=====================

 -- Module: text.csv
     Provides a function to parse/generate CSV (comma separated value) tables, including the format defined in RFC4180.  You can customize the separator and quoter character to deal with variations of CSV formats.

     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. RFC4180に定義されたフォーマットを含む、 CSV (カンマ区切りの値) の表をパーズ/生成するための手続きを提供します。区切り文字やクオート文字をカスタマイズすることで、CSVに似たフォーマットを広くカバーすることができます。

     CSV の表は、改行で区切られた RECORD の連続で構成されます。それぞれのレコードは、区切り文字(デフォルトではカンマ)で区切られた複数の FIELD を含みます。フィールドは、クォートされている (二重引用符で囲まれている)場合は、カンマや改行を含むことができます。クォートされたフィールドに二重引用符を含めるには、2つの連続する二重引用符を使います。通常、フィールドの前後の空白は無視されます。

     Since use cases of CSV-like files vary, we provide layered API to be combined flexibly. CSV様のファイルの使われ方は多様なので、このモジュールでは柔軟に組み合わせることが出来る多層的なAPIを提供します。

Low-level API
-------------

低レベルAPI
-------

The bottom layer of API is to convert text into list of lists and vice versa. 一番下の層のAPIは、テキストとリストのリストとを相互変換するものです。

 -- Function: make-csv-reader separator :optional (quote-char #\")
     Returns a procedure with one optional argument, an input port. When the procedure is called, it reads one record from the port (or, if omitted, from the current input port) and returns a list of fields. If input reaches EOF, it returns EOF. 入力ポートを省略可能引数として取る手続きを返します。手続きが呼ばれると、ポート(省略された場合は現在の入力ポート)からレコードを1つ読み込み、フィールドのリストを返します。入力ポートが EOF に達すると、EOF を返します。

 -- Function: make-csv-writer separator :optional newline (quote-char #\") special-char-set
     Returns a procedure with two arguments, output port and a list of fields.  When the procedure is called, it outputs a SEPARATOR-separated fields with proper escapes, to the output port.   Each field value must be a string. The separator argument can be a character or a string. 出力ポートとフィールドのリストの2つの引数を取る手続きを返します。手続きが呼ばれると、SEPARATOR で区切られたフィールドを正しくエスケープして出力ポートに出力します。各フィールドの値は文字列でなければなりません。 SEPARATORは文字または文字列です。

     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. レコードの区切り文字列をNEWLINE で指定することもできます。例えば、ファイルが Windows のプログラムでも読めるように、"\r\n" を渡すことができます。

     The output of field is quoted when it contains special characters--- which automatically includes characters in SEPARATOR, QUOTE-CHAR and NEWLINE argument, plus the characters in the char-set given to SPECIAL-CHAR-SET; its default is #[;\s]. フィールドの出力は、その中に特殊文字が含まれていた場合にクオートされます。 SEPARATOR, QUOTE-CHAR, NEWLINEに含まれる文字は自動的に特殊文字と認識されます。さらに SPECIAL-CHAR-SETに文字集合を渡すと、それも特殊文字として扱われます。省略時は#[;\s]が使われます。

Middle-level API
----------------

中レベルAPI
-------

Occasionally, CSV files generated from spreadsheet contains superfluous rows/columns and we need to make sense of them. Here are some utilities to help them. スプレッドシート等で作成されたCSVファイルはしばしば、不要な行や列を含んでいたり、行や列の内容から有効なデータの場所を探したりする必要があります。そのために役に立つユーティリティが用意してあります。

A typical format of such spreadsheet-generated CSV file has the following properties: スプレッドシート等によって生成される典型的なCSVには以下の特徴があります。

 1. There's a ``header row'' near the top; not necessarily the very first row, but certainly it comes before any real data.  It signifies the meaning of each column of the data. There may be superfluous columns inserted just for cosmetics, and sometimes the order of columns are changed when the original spreadsheet is edited.  So we need some flexibility to interpret the input data. 最初の方に、「ヘッダ行」があります。一番最初の行とは限りませんが、データの実体より前に現れ、データの各列の意味を決めます。しばしば、見た目のためだけに余分な列が挿入されたり、編集によって列が入れ替わったりすることもあるので、ヘッダ行を見てどの列に何があるか判断する必要があります。

 2. ``Record rows'' follow the header row.  It contains actual data. There may be superfluous rows inserted just for cosmetics. Also, it's often the case that the end of data isn't marked clearly (you find large number of rows of empty strings, for example). ヘッダ行の後に続く「レコード行」。ここにデータの実体があります。見た目のためだけに余分な行が挿入されていることもあります。また、データの終わりがきちんと示されていないことも多いです (例えば、 CSVの末尾に全ての列が空文字列である行がぞろぞろとくっついている、等。)

The main purpose of middle-level CSV parser is to take the output of low-level parser, which is a list of lists of strings, and find the header row, and then convert the subsequent record rows into tuples according to the header row.  A tuple is just a list of strings, but ordered in the same way as the specified header spec. 中レベルCSVパーザの主目的は、低レベルパーザの出力である文字列のリストのリストを受け取って、ヘッダ行を探し出し、続くレコード行をヘッダ行の内容に沿ってタプルに変換することにあります。ここで、タプルは単なる文字列のリストですが、指定されたヘッダ仕様に沿った順序で並べてあるものとします。

 -- Function: csv-rows->tuples rows header-specs :key required-slots allow-gap?
     Convert input rows (a list of lists of strings) to a list of tuples. A tuple is a list of slot values.

     First, it looks for a header row that matches the given HEADER-SPEC.  Once the header row is found, parse the subsequent rows as record row according to the header and convert them to tuples. If no header is found, #f is returned. 入力行(文字列のリスト)のリストを、タプルのリストに変換します。タプルはスロットの値のリストです。

     まずHEADER-SPECにマッチするヘッダ行が探されます。ヘッダ行が見つかったら、それにしたがって後続の行をレコード行として解釈し、各行をタプルへと変換します。ヘッダ行が見つからなければ、#fが返されます。

     HEADER-SPECS is a list of header spec, each of which can be either a string, a regexp, or a predicate on a string.  If it's a string, a column that exactly matches the string is picked.  If it's a regexp, a column that matches the regexp is picked.  And if it's a predicate, as you might have already guessed, a column that satisfies the predicate is picked.

     The order fo HEADER-SPECS determines the order of columns of output tuples. HEADER-SPECSはヘッダ仕様のリストです。各要素は文字列、正規表現、あるいは文字列を取る述語手続きのいずれかです。文字列の場合、その文字列と正確に一致する内容を持つ列が選ばれます。正規表現なら内容がそれと一致する列、述語手続きなら、内容がその述語を満たすような列がそれぞれ選ばれます。

     HEADER-SPECSに現れる順番が、出力タプルの列の順番を決めます。

     REQUIRED-SLOTS determines if the input row is a valid record row or not.  The structure of REQUIRED-SLOTS is as follows: REQUIRED-SLOTSは、入力行が有効なレコード行かそうでないかを決めます。 REQUIRED-SLOTSの構造は以下のとおりです。

             <required-slots> : (<spec> ...)
             <spec> : <header-spec> | (<header-spec> <predicate>)

     The <header-spec> compared to the elements of HEADER-SLOT (by equal?) to figure out which columns to check.  A single <header-spec> in <spec> means that the column shouldn't be empty for a valid record row.  If <SPEC> is a list of <header-spec> and <predicate>, then the value of the column corresponds to the <HEADER-SPEC> is passed to <PREDICATE> to determine if it's a valid record row.

     If REQUIRED-SLOTS is omitted or an empty list, any row with at least one non-empty column to be included in the tuple. <header-spec>はどの列の要素をチェックすべきかを指定します。 HEADER-SLOTに現れる要素のいずれかとequal?でなければなりません。 <header-spec>だけが<spec>として与えられていた場合は、その列が空であってはいけない、ということを意味します。 <header-spec>と<predicate>が与えられた場合は、レコード行の該当列の値(文字列)が述語手続き<predicate>に与えられ、それが偽を返したらその行は有効でないということになります。

     If ALLOW-GAP? is #t, it keeps reading rows until the end, skipping invalid rows.  If ALLOW-GAP? is #f (default), it stops reading once it sees an invalid row after headers. ALLOW-GAP?が#tであった場合、無効な行を飛ばしながら、入力データは最後まで処理されます。ALLOW-GAP?が#fであった場合(デフォルト)は、無効な行が出てきた時点で処理を打ちきります。

     Let's see an example.  Suppose we have the following CSV file as data.csv.  It has extra rows and columns, as is often seen in spreadsheet-exported files. 例を見てみましょう。次のデータがdata.csvというファイルに書かれているとします。スプレッドシートからエクスポートされるデータによくあるように、不要な行や列が混ざっています。

          ,,,,,,,,
          "Exported data",,,,,,,,
          ,,,,,,,,
          ,,Year,Country,,Population,GDP,,Note
          ,,1958,"Land of Lisp",,39994,"551,435,453",,
          ,,1957,"United States of Formula Translators",,115333,"4,343,225,434",,Estimated
          ,,1959,"People's Republic of COBOL",,82524,"3,357,551,143",,
          ,,1970,"Kingdom of Pascal",,3785,,,"GDP missing"
          ,,,,,,,,
          ,,1962,"APL Republic",,1545,"342,335,151",,

     You can extract tuples of Country, Year, GDP and Population, as follows: ここから、Country, Year, GDP, Populationの値からなるタプルのリストを次のとおり取り出せます。

          (use text.csv)
          (use gauche.generator)

          (call-with-input-file "data.csv"
            (^p (csv-rows->tuples
                 (generator->list (cute (make-csv-reader #\,) p))
                 '("Country" "Year" "GDP" "Population"))))
           =>
            (("Land of Lisp" "1958" "551,435,453" "39994")
             ("United States of Formula Translators" "1957" "4,343,225,434" "115333")
             ("People's Republic of COBOL" "1959" "3,357,551,143" "82524")
             ("Kingdom of Pascal" "1970" "" "3785"))

     Note that irrelevant rows are skipped, and columns in the results are ordered as specified in the HEADER-SPECS. 無関係な行は無視されており、また結果の列はHEADER-SPECSに渡した順序に整列されていることに注目してください。

     Since there's a gap (empty row) after the ``Kingdom of Pascal'' entry, csv-rows->tuples stops processing there by default.  If you want to include ``APL Republic'', you have to pass :allow-gap? #t to csv-rows->tuples. ``Kingdom of Pascal''の列の後にギャップ(空の列)があるため、 csv-rows->tuplesはそこで処理を打ち切っています。ギャップの後の``APL Republic''まで含めたければ、csv-rows->tuplesに :allow-gap? #tを渡してください。

     The next example gives :required-slots option to eliminate rows with missing some of Year, Country or GDP---thus ``Kingdom of Pascal'' is omitted from the result, while ``APL Republic'' is included because of :allow-gap? argument. (It also checks Year has exactly 4 digits.) 次の例では、:required-slots引数を与えて、 Year、Country、GDPのデータの一つ以上が欠けている行を除外しています。したがって``Kingdom of Pascal''は結果から除かれます。一方、 :allow-gap?引数のために``APL Republic''が含まれます。 (この例ではYearが4桁ぴったりの数値であるかどうかもチェックしています。)

          (call-with-input-file "data.csv"
            (^p (csv-rows->tuples
                 (generator->list (cute (make-csv-reader #\,) p))
                 '("Country" "Year" "GDP" "Population")
                  :required-slots '(("Year" #/^\d{4}$/) "Country" "GDP")
                  :allow-gap? #t)))
           =>
           (("Land of Lisp" "1958" "551,435,453" "39994")
            ("United States of Formula Translators" "1957" "4,343,225,434" "115333")
            ("People's Republic of COBOL" "1959" "3,357,551,143" "82524")
            ("APL Republic" "1962" "342,335,151" "1545"))

The following two procedures are ingredients of csv-rows->tuples: 以下の二つの手続きはcsv-rows->tuplesの材料です。

 -- Function: make-csv-header-parser header-specs
     Create a procedure that takes a row (a list of strings) and checks if if it matches the criteria specified by HEADER-SPECS. (See csv-rows->tuples above about HEADER-SPECS.) If the input satisfies the spec, it returns a permuter vector that maps the tuple positions to the input column numbers. Otherwise, it returns #f. 行(文字列のリスト)を受け取り、それがHEADER-SPECSで指定される条件に一致するかどうかを調べます。 (HEADER-SPECSについては上のcsv-rows->tuplesを見てください。) もし引数が条件を満たしたなら、置換ベクタを返します。置換ベクタはタプルの位置を入力行の列番号へとマップするもので。一致しなかった場合は#fを返します。

     The permuter vector is a vector of integers, where K-th element being I means the K-th item of the tuple should be taken from I-th column. 置換ベクタは整数のベクタです。K番目の要素がIであることは、タプルのK番目の要素が入力のI番目の列から取られることを示します。

     Let's see the example.  Suppose we know that the input contains the following row as the header row: 例を見てみましょう。入力に、以下の形の行がヘッダ行として含まれていることがわかっているとします。

          (define *input-row*
            '("" "" "Year" "Country" "" "Population" "GDP" "Notes"))

     We want to detect that row, but we only needs Country, Year, GDP and Population columns, in that order.  So we create a header parser as follows: こういう形の行を見つけたいわけですが、取り出すデータとしては、 Country、Year、GDP、Populationだけがこの順で必要であるとします。この場合、ヘッダパーザを次のとおり構成できます。

          (define header-parser
            (make-csv-header-parser '("Country" "Year" "GDP" "Population")))

     Applying this header parser to the input data returns the permuter vector: このヘッダパーザを想定される入力行に適用すれば、置換ベクタが返ってきます:

          (header-parser *input-row*)
           => #(3 2 6 5)

     It means, the first item of tuple (Country) is in the 3rd column of the input, the second item of tuple (Year) is in the 2nd column of the input, and so on.  This permuter vector can be used to parse record rows to get tuples. 返り値の意味は、タプルの第0要素(Country)は入力の第3列にあり、タプルの第1要素(Year)は入力の第2列にある、といった具合です。置換ベクタはレコード行をパーズしてタプルを生成するのに使えます。

 -- Function: make-csv-record-parser header-slots permuter :optional required-slots
     Create a procedure that converts one input row into a tuple.

     PERMUTER is the vector returned by make-csv-header-parser.

     See cvs-rows->tuples above for HEADER-SLOTS and REQUIRED-SLOTS arguments. 入力の1行をタプルへと変換する手続きを作って返します。

     PERMUTERはmake-csv-header-parserが返す置換ベクタです。

     HEADER-SLOTS及びREQUIRED-SLOTS引数については上のcvs-rows->tuplesを見てください。

text.diff - Calculate difference of text streams
================================================

 -- Module: text.diff
     This module calculates the difference of two text streams or strings, using util.lcs (see The longest common subsequence). このモジュールでは、util.lcs (The longest common subsequence参照)を使って、2つのテキストストリーム、あるいは2つの文字列の相違点を計算します。

 -- Function: diff src-a src-b :key reader eq-fn
     Generates an "edit list" from text sources SRC-A and SRC-B.

     Each of text sources, SRC-A and SRC-B, can be either an input port or a string.  If it is a string, it is converted to a string input port internally.  Then, the text streams from both sources are converted to sequences by calling READER repeatedly on them; the default of READER is read-line, and those sequences are passed to lcs-edit-list to calculate the edit list. The equality function EQ-FN is also passed to lcs-edit-list.

     An edit list is a set of commands that turn the text sequence from src-a to the one from src-b. See the description of lcs-edit-list for the detailed explanation of the edit list. テキストソースSRC-AとSRC-Bから``編集リスト''を生成します。

     それぞれのテキストソース、SRC-AとSRC-Bは入力ポートか文字列です。もし文字列であれば、それは内部的に文字列ポートに変換されます。そして、2つのソースからのテキストストリームは、それらに対してREADERを繰り返し呼ぶことによってシーケンスに変換されます。デフォルトのREADERはREAD-LINEで、 2つのシーケンスは編集リストを計算するためにlcs-edit-listに渡されます。 lcs-edit-listには、等値を検査する関数EQ-FNも渡されます。

     編集リストとは、src-aからsrc-bへテキストシーケンスを変更するためのコマンドのセットです。編集リストの詳細な説明は、 lcs-edit-listを参照してください。

          (diff "a\nb\nc\nd\n" "b\ne\nd\nf\n")
          =>
            (((- 0 "a"))
             ((- 2 "c") (+ 1 "e"))
             ((+ 3 "f")))

 -- Function: diff-report src-a src-b :key reader eq-fn writer
     A convenience procedure to take the diff of two text sources and display the result nicely.  This procedure calls lcs-fold to calculate the difference of two text sources.  The meanings of SRC-A, SRC-B, READER and EQ-FN are the same as diff's. 2つのテキストソースのdiffをとって、その結果をきれいに表示するための簡易手続きです。この手続きは、2つのテキストソースの相違点を計算するためにlcs-foldを呼び出します。SRC-A、SRC-B、 READER、EQ-FNの意味は、diffの場合と同じです。

     WRITER is a procedure that takes two arguments, the text element and a type, which is either a symbol +, a symbol -, or #f.   If the text element is only in SRC-A, WRITER is called with the element and -.  If the text element is only in SRC-B, it is called with the element and +.  If the text element is in both sources, it is called with the element and #f.   The default procedure of WRITER prints the passed text element to the current output port in unified-diff-like format: WRITERは2つの引数、テキスト要素とタイプ(シンボル+、シンボル-、あるいは#fのいずれか)を取る手続きです。テキスト要素がSRC-Aにしかない場合は、WRITERがそのテキスト要素と -とともに呼ばれます。テキスト要素がSRC-Bにしかない場合は、 WRITERはそのテキスト要素と+とともに呼ばれます。テキスト要素が両方のソースにある場合は、WRITERはそのテキスト要素と #fとともに呼ばれます。WRITERのデフォルトの手続きは、渡されたテキスト要素を現在の出力ポートにユニファイドdiffのようなフォーマットで出力します。

          (diff-report "a\nb\nc\nd\n" "b\ne\nd\nf\n")

     displays:

          - a
            b
          - c
          + e
            d
          + f

text.edn - EDN parsing and construction
=======================================

 -- Module: text.edn
     EDN (Extensible Data Notation) is a subset of Clojure literals for data exchange.  This module provides utilities to read and write EDN format.  See https://github.com/edn-format/edn for the details of EDN. EDN (Extensible Data Notation)はデータ交換用に定められた、 Clojureのリテラル構文のサブセットです。このモジュールはEDNの読み書きをするユーティリティを提供します。EDNの詳細については https://github.com/edn-format/ednを参照してください。

     EDN   Gauche   Note
     true   #t
     false   #f
     nil   nil
     Clojure's nil is not a symbol but a special value; since Clojure
     can't have a symbol named nil, we can map it to Gauche's symbol nil.
     Clojureのnilはシンボルではなく特殊な値ですが、
     Clojureにはnilというシンボルは存在できないので、
     Gaucheのシンボルnilに対応させています。
     number   <real>
     Integers and floating point numbers.
     The N and M suffixes in Clojure are ignored.
     整数と浮動小数点数。
     ClojureのNとMサフィックスは無視されます。
     symbol   <symbol>
     Clojure's symbol name has some restrictions, so not all Gauche symbols
     map to EDN symbols.
     Clojure's namespace-prefixed symbol, e.g. foo/bar simply maps to
     Gauche's symbol foo/bar; we provide utility procedure to extract
     namespace and basename parts.
     Clojureのシンボル名には制約があるので、
     全てのGaucheのシンボルがEDNシンボルとして使えるわけではありません。
     Clojureの名前空間つきシンボル(例: foo/bar) はGauche側では
     単にfoo/barという名前を持つシンボルの扱いになります。
     この名前から名前空間とシンボル名を取り出すユーティリティが提供されます。
     keyword   <keyword>
     Clojure has keywords distinct from symbols.  They are mapped to Gauche's
     keywords (which is a subtype of symbols).
     Gauche's keywords can also be symbols, but
     no Clojure symbols begin with : so there won't be a conflict.
     Clojureはキーワードとシンボルを別の型にしています。
     ClojureキーワードはGaucheキーワード(シンボルのサブタイプ)に対応します。
     Clojureのシンボルは:で始まることはないので、混同が起きることはありません。
     list   <list>
     Clojure lists are Gauche lists.  Note that Clojure doesn't allow
     improper lists.
     ClojureのリストはGaucheのリストになります。
     Clojureにはドットリスト(improper list)が無いことに注意してください。
     vector   <vector>
     Clojure vectors are Gauche vectors.
     ClojureのベクタはGaucheのベクタになります。
     map   <hash-table>
     Clojure's map becomes Gauche's hashtable with edn-comparator
     for hashing and comparison.
     Clojureのマップは、Gaucheではedn-comparatorをハッシュ関数と比較に
     使うハッシュテーブルになります。
     set   <set>
     Clojure's set becomes Gauche's set with edn-comparator
     for comparison.  See R7RS sets for interface of sets.
     Clojureのセットは、Gaucheではedn-comparatorを比較に使う
     <set>オブジェクトになります。<set>についてはsee R7RS sets参照。
     tagged object   <edn-object>
     Tagged objects are mapped to <edn-object> by default.
     You can customize the parser/writer to map tagged objects with a
     specific tag to a specific Gauche objects.
     タグつきオブジェクトはデフォルトで<edn-object>のインスタンスになります。
     タグつくオブジェクトの解釈をカスタマイズして、特定のGaucheオブジェクトに結びつけることも
     できます。

Parsing
-------

パーザ
---

 -- Condition Type: <edn-parse-error>
     When the parser encounters an error, this condition is thrown. Inherits <error>. パーザのエラーはこのコンディションで通知されます。<error>を継承しています。

 -- Function: parse-edn :optional iport
     Read one EDN representation from the given input port, and returns Gauche object created from it.  If IPORT is omitted, current input port is assumed.

     When the parser encounters unparsable sequence, it raises <edn-parse-error>.

     Note that IPORT may be read ahead for characters. Suppose the input consists of abc{:a b}, i.e. a symbol immediately followed by a map.  The parser need to read { to know the end of the symbol. The read-ahead brace isn't pushed back to the IPORT.  So it would be a problem if you keep reading more EDN subsequently.   Use parse-edn* if you want to read multiple objects. EDN表現を与えられた入力ポートから読み込み、パーズ結果をGaucheオブジェクトとして返します。IPORTが省略された場合は現在の入力ポートが使われます。

     パーズが失敗した場合は<edn-parse-error>が投げられます。

     IPORTから文字が先読みされる可能性があることに注意してください。例えば入力がabc{:a b}、つまりシンボルの直後にマップが来ていたとします。パーザは{まで読んでシンボルの終了を知り、シンボルabcを返しますが、その時点で読まれていた{はポートに戻されないので、続けてIPORTからEDNを読む場合に問題となります。複数のEDNオブジェクトを読み込む場合はparse-edn*を使ってください。

 -- Function: parse-edn* :optional iport
     Read EDN representations repeatedly from the given input port and returns a list of them.  If IPORT is omitted, current input port is assumed.

     When the parser encounters unparsable sequence, it raises <edn-parse-error>. 与えられた入力ポートから、EOFに達するまでEDN表現を読み込み、結果のGaucheオブジェクトのリストを返します。IPORTが省略された場合は現在の入力ポートが使われます。

     パーズが失敗した場合は<edn-parse-error>が投げられます。

 -- Function: parse-edn-string str
     A convenience procedure to parse EDN representation in a string STR, and returns the read object.

     When the parser encounters unparsable sequence, it raises <edn-parse-error>. EDN表現を文字列から読み込む便利手続きです。

     パーズが失敗した場合は<edn-parse-error>が投げられます。

          (parse-edn-string "[1 2 (3 4) {:a 5}]")
           => #(1 2 (3 4) #<hash-table general 0x1f05780>)

Constructing
------------

構築
--

 -- Function: construct-edn obj :optional oport
     Write out an EDN representation of object OBJ to the output port OPORT.  If OPORT is omitted, current output port is assumed.

     If OBJ contains an object that doesn't have a defined EDN representation, a generic function EDN-WRITE is called on it.  See Customization heading below.  If no method is defined for the object, an error is signaled. オブジェクトOBJのEDN表現を出力ポートOPORTに書き出します。 OPORTが省略された場合は現在の出力ポートが使われます。

     OBJ中にEDNで表現できないオブジェクトがあった場合、ジェネリック関数EDN-WRITEが呼ばれます。下のカスタマイズの項を参照してください。適切なメソッドが定義されていなけばエラーが投げられます。

 -- Function: construct-edn-string obj
     Returns an EDN representation of OBJ in a string.

     If OBJ contains an object that doesn't have a defined EDN representation, a generic function EDN-WRITE is called on it.  See Customization heading below.  If no method is defined for the object, an error is signaled. OBJのEDN表現を文字列で返します。

     OBJ中にEDNで表現できないオブジェクトがあった場合、ジェネリック関数EDN-WRITEが呼ばれます。下のカスタマイズの項を参照してください。適切なメソッドが定義されていなけばエラーが投げられます。

     (construct-edn-string '#(1 2 "abc")) => "[1 2 \"abc\"]"

Utilities
---------

ユーティリティ
-------

 -- Function: edn-equal? a b
     Test equality of two objects that are read from EDN representation. EDN表現から読まれた二つのオブジェクトが、EDNのセマンティクスで等しいかどうかを調べます。

 -- Variable: edn-comparator
     A comparator that uses edn-equal? for the equality predicate. Corresponding has function is also included. EDN maps and sets become Gauche hash-tables and sets with this comparator. edn-equal?で等価性を判定する比較器です。ハッシュ関数も含まれます。 EDNのマップとセットは、この比較器を使うGaucheのハッシュテーブルとセットになります。

 -- Function: edn-map key value ...
 -- Function: edn-set item ...
     Convenience procedures to create hash-tables and sets compatible for EDN. EDNに使えるハッシュテーブルとセットを構築する便利手続きです。

 -- Class: <edn-object>
     EDN tagged object becomes an instance of this class by default. The instance has the following slots, both are immutable: EDNのタグつきオブジェクトは、デフォルトではこの暮らすのインスタンスになります。以下のスロットがあります。どちらも変更不可です。

      -- Instance Variable of <edn-object>: tag
          Object's tag.  A symbol. シンボル。オブジェクトのタグです。

      -- Instance Variable of <edn-object>: payload
          Object's payload.  Can be any object that can be representable in EDN. オブジェクトの内容です。EDNで表現可能なオブジェクト。

     For example, when you read #myobject {:a 1 :b 2}, the tag is myobject and the payload is a hashtable containing mapping {:a 1 :b 2}. 例えば、#myobject {:a 1 :b 2}を読んだ場合、タグはmyobject、内容は{:a 1 :b 2}を読んだ結果のハッシュテーブルになります。

 -- Function: make-edn-object tag payload
     Returns a new <edn-object> instance. Note: Arguments are not checked.  It's caller's responsibility to pass valid arguments to guarantee it's serializable as EDN. 新たな<edn-object>のインスタンスを作って返します。引数がEDN表現可能かどうかのチェックはされません。呼び出し側が有効な引数を渡す必要があります。

 -- Function: edn-object? obj
     Returns #t iff OBJ is an instance of <edn-object>. OBJが<edn-object>のインスタンスなら#tを、そうでなければ #fを返します。

 -- Function: edn-object-tag edn-object
 -- Function: edn-object-payload edn-object
     Returns the tag and the payload of EDN-OBJECT, respectively. EDN-OBJECTのタグと内容をそれぞれ返します。

 -- Function: edn-symbol-prefix symbol
 -- Function: edn-symbol-basename symbol
     Return prefix and basename part of the symbol, respectively. シンボルの、プリフィクスとベース名をそれぞれ返します。

          (edn-symbol-prefix 'foo/bar) => foo
          (edn-symbol-basename 'foo/bar) => bar

          (edn-symbol-prefix 'bar) => #f
          (edn-symbol-basename 'bar) => bar

 -- Function: edn-valid-symbol-name? str
     Returns #t iff a string STR can be a valid Clojure symbol name. It may have namespace prefix. 文字列STRがClojureのシンボル名として有効なら#tを、そうでなければ #fを返します。STRには名前空間を含めることもできます。

Customization
-------------

カスタマイズ
------

You can map EDN tagged objects to other Gauche objects. EDNのタグつきオブジェクトを、他のGaucheオブジェクトへとマップすることが出来ます。

 -- Function: register-edn-object-handler! tag handler
     TAG is a symbol, and HANDLER is #f or a procedure that takes a tag symbol and a payload object.

     TAG must have a name valid as Clojure symbol, or an error is signaled.

     After the parser reads a tagged object with a symbol TAG and payload, it calls HANDLER, and the returned object becomes the result of the parser, instead of <edn-object>. Registering #f removes the previously registered handler.

     This procedure is thread-safe.

     The following example makes EDN #u8vector[1 2 3 4] to be read as #u8(1 2 3 4): TAGはシンボル、HANDLERは#fもしくはタグと内容を引数に取る手続きです。

     TAGはClojureのシンボルとして有効な名前でなければなりません。さもなくばエラーが投げられます。

     パーザがTAGをタグに持つタグつきオブジェクトを読んだら、そのタグと内容を引数にしてHANDLERを呼び出し、返り値をパーズ結果とします。HANDLERに#fを渡した場合は既に登録されたハンドラを(もしあれば)削除します。

     この手続きはスレッドセーフです。

     以下の例はEDNの#u8vector[1 2 3 4]を #u8(1 2 3 4)として読み込みます。

          (register-edn-object-handler! 'u8vector
                                        (^[tag vec] (vector->u8vector vec)))

 -- Function: edn-object-handler tag
     Returns a handler registered with a symbol TAG.  If a handler is not registered for TAG, #f is returned. This procedure is thread-safe. TAGに登録されたハンドラを返します。ハンドラが登録されていなければ#fを返します。この手続きはスレッドセーフです。

 -- Generic Function: edn-write obj
     Write EDN representation of OBJ to the current output port. The construct-edn procedure calls this internally.

     To write out a Gauche object as EDN tagged object, define a method to this generic function.   In the method you can call edn-write recursively to write out components of the object.

     The following example writes #u8(1 2 3 4) as EDN #u8vector[1 2 3 4]: OBJのEDN表現を現在の出力ポートに書き出します。 construct-ednは内部的にこれを呼んでいます。

     GaucheオブジェクトをEDNタグつきオブジェクトとして書き出したい場合に、このジェネリック関数にメソッドを定義します。メソッド中で、オブジェクトの要素を再帰的に書き出す場合はそれぞれにedn-writeを呼び出してください。

     以下の例は、#u8(1 2 3 4)をEDNの#u8vector[1 2 3 4]として書き出します。

          (define-method edn-write ((x <u8vector>))
            (display "#u8vector")
            (edn-write (u8vector->vector x)))

text.external-editor - Running external editor
==============================================

 -- Module: text.external-editor
     A convenience module to invoke external editor program. This is mainly to be used from REPL, but can be useful for other purposes.

 -- Function: ed path-or-proc :key editor load-after
     Starts an external editor.  The editor program path is determined in the following order:

       * The EDITOR keyword argument, if it's a string.

       * The value of *editor* in the user module, if defined.

       * The value of the environment variable GAUCHE_EDITOR.

       * The value of the environment variable EDITOR.

       * If none works, the behavior depends on the value of :editor keyword argument:

          #f
               Just returns #f.

          error
               Throws an error.

          ask
               Asks the user.

          message
               Prints message and returns #f.

     Returns #t for normal termination.

     The editor program may be called in one of the following way:

          EDITOR filename
          EDITOR +lineno filename

     The latter expects to locate the cursor on the specified line number in the filename.

     The file to open is determined by a generic function ed-pick-file. It should return (FILENAME LINENO), or #f to indicate that it couldn't determine the file to edit.

     The LOAD-AFTER argument controls whether the file is loaded into the process after the file is modified.  It must be one of the following values:

     #t
          Load the file once editor exits and the file is modified.

     #f
          Do not load the file.

     ask
          Ask the user if the file should be loaded or not.

     NB: Common Lisp's ed can be invoked without argument.  For our usage, though, that feature doesn't seem too useful---it's more likely that repl IS inside an editor so we only need to open a specific file in a buffer.  Emacsclient requires filename, so it further complicates things. For now we just require one argument.

 -- Function: ed-string string :key editor
     Invoke an external editor (as described in ed) with STRING being the initial content.  Once editor exits, returns the edited content as a string.

 -- Generic Function: ed-pick-file obj
     Determine what to edit.  It must return a list of filename and line number, or #f if it can't find appropriate file to edit.

     Methos for strings, procedures and <top> are already defined. If OBJ is a string, it is taken as a filename. If OBJ is a procedure and its source location is available, the source file and the location is returned. Otherwise, #f is returned.

text.gap-buffer - Gap buffer
============================

 -- Module: text.gap-buffer
     This module provides a gap buffer, a data structure useful for editable text.

     A gap buffer is a vector of characters with a ``cursor'', where you can insert or delete a character in O(1) time.  Most of the editing API operate on the current cursor position.

 -- Function: make-gap-buffer :key initial-capacity
     Creates a fresh gap buffer and returns it.  The initial content is emtpy.

     The keyword argument INITIAL-CAPACITY must be a positive exact integer if given, and specifies the initial capacity of the buffer.  The buffer is automatically extended if necessary, so the argument is only a hint; if you know you'll insert a long string, for example, you can create a buffer that's large enough to hold it to avoid reallocation overhead.

 -- Function: string->gap-buffer string :optional pos whence start end
     Creates a gap buffer large enough to contain the given STRING, and returns it.

     The initial cursor position is set at the end of the string by default. The POS and WHENCE argument can set the initial cursor position.  The WHENCE argument must be either a symbol beginning or a symbol end, and POS must be an exact integer offset from the whence.  For example, POS = 10 and WHENCE = beginning sets the cursor at the 10th character of the string from the beginning, and POS = -1 and WHENCE = end sets the cursor position at one character before the end of the string.  If the combination of POS and WHENCE points the outside of the string, an error is signaled.

     The optional START and END trims the input string before creating the gap buffer.

 -- Function: gap-buffer? obj
     Returns #t iff OBJ is a gap buffer.

 -- Function: gap-buffer-copy gbuf
     Returns a fresh copy of a gap buffer GBUF, with the same content and cursor position.

 -- Function: gap-buffer->string gbuf :optional start end
 -- Function: gap-buffer->generator gbuf :optional start end
     Retrieve the content of a gap buffer GBUF as a string or a generator of characters, respectively.  The optional START and END arguments are nonnegative exact integers of character index in the content of the buffer, and limits the output within the specified range.

     If you modify the content of gap buffer before the returned generator is exhausted, consistent behavior isn't guaranteed.

 -- Function: gap-buffer-pos gbuf
     Returns the current cursor position of GBUF, in a nonnegative exact integer.

 -- Function: gap-buffer-capacity gbuf
     Returns the currently allocated storage size of GBUF. If you insert more characters into GBUF, the storage is automatically expanded.

 -- Function: gap-buffer-content-length gbuf
     Returns the length of current content of GBUF, in the number of characters.

 -- Function: gap-buffer-gap-at? gbuf whence
     The WHENCE argument must be either a symbol beginning or a symbol end.  Returns #t iff the current cursor position of GBUF is at the beginning or at the end, respectively.

 -- Function: gap-buffer-ref gbuf index :optional fallback
     Returns INDEX-th character of GBUF.  If INDEX is out of range, FALLBACK is returned if given, or an error is raised.

 -- Function: gap-buffer-set! gbuf index char
     Replaces INDEX-th character of GBUF with CHAR. If INDEX is out of range, an error is signaled.

 -- Function: gap-buffer-move! gbuf pos :optional whence
     Moves the cursor position of GBUF to a position POS, which must be an exact integer.  The position POS is relative to WHENCE, which must be either one of the symbols beginning, CURRENT or end.

 -- Function: gap-buffer-insert! gbuf content
     Inserts CONTENT, which must be a character or a string, at the current cursor position of GBUF. The current cursor position is moved to the end of the inserted content.

 -- Function: gap-buffer-delete! gbuf size
     Delets SIZE characters from the current cursor position of GBUF.  It is an error if SIZE overruns.

 -- Function: gap-buffer-clear! gbuf
     Makes GBUF empty.

 -- Function: gap-buffer-replace! gbuf size content
     This is a combination of (gap-buffer-delete! gbuf size) and (gap-buffer-insert! gbuf content). The SIZE argument must be a nonnegative exact integer, and the CONTENT argument must be either a string or a character.

 -- Function: gap-buffer-edit! gbuf edit-command
     This is a convenience procedure to ``replay'' editing of the gap buffer GBUF.  The EDIT-COMMAND argument must be either one of the following:

     (i POS STRING)
          Insert STRING at a position POS.

     (d POS LENGTH)
          Delete LENGTH characters from a position POS.

     (c POS LENGTH STRING)
          Change: Delets LENGTH characters from a position POS, then insert STRING.

     Here, POS must be a nonnegative exact integer specifying the position in the gap buffer.

     One of the appliations of this procedure is to handle undo/redo list.

text.gettext - Localized messages
=================================

 -- Module: text.gettext
     This module provides utilities to deal with localized messages. The API is compatible to GNU's gettext, and the messages are read from *.po and *.mo files, so that you can use the GNU gettext toolchain to prepare localized messages. However, the code is written from scratch by Alex Shinn and doesn't depend on GNU's gettext library. このモジュールは地域化メッセージを扱うユーティリティを提供します。 API は GNU の gettext と互換性があり、メッセージは *.po および *.mo ファイルから読み込まれます。それゆえ、GNU の gettext toolchain をつかって地域化メッセージを準備することができます。しかし、このコードは Alex Shinn によってスクラッチから書き起こされたものであり、GNU の gettext ライブラリには依存していません。

     This implementation extends GNU's gettext API in the following ways:

       * It can read from multiple message files in cascaded way, allowing applications to share a part of message files.

       * It supports multiple locale/domain simultaneously.

     この実装は GNU の gettext API を以下のように拡張したものです。

       * 複数のメッセージファイルから、カスケードされた方法で読み込むことができます。これにより、アプリケーションはメッセージファイルの部分を共有できます。

       * 複数のロケール/ドメインを同時に扱えます。

     SRFI-29 (see Localization) provides another means of message localization.  A portable program may wish to use srfi-29, but generally text.gettext is recommended in Gauche scripts because of its flexibility and compatibility to existing message files. SRFI-29 (Localization参照) はこれとは別のメッセージの地域化機構を提供しています。ポータブルなプログラムでは、SRFI-29 の方がよいこともありますが、一般には、Gauche スクリプトでは、text.gettext の方を推奨します。それは、既存のメッセージファイルとの互換性と柔軟性のためです。

Gettext-compatible API
----------------------

gettext-互換の API
---------------

 -- Function: textdomain domain-name :optional locale dirs cdir cached? lookup-cached?
     Sets up the default domain and other parameters for the application.  The setting affects to the following gettext call.

     DOMAIN is a string or list of strings specifying the domain (name of .mo or .po files) as in C gettext. You can pass #f as DOMAIN-NAME just to get the default domain accessor procedure. You can alo pass multiple domains to DOMAIN-NAME. アプリケーション用に、デフォルトのドメインとそのほかのパラメータを設定します。この設定は、以降の gettext の呼出しに影響を与えます。

     DOMAIN は文字列または文字列のリストで、ドメイン(.mo あるいは .po ファイル名)を C の gettext と同じように指定します。 #f を DOMAIN-NAME として渡すと、デフォルトのドメインアクセサ手続きが得られます。また、複数のドメインを DOMAIN-NAMEにあたえることができます。

          (textdomain '("myapp" "gimp"))  ; search 1st myapp, then gimp
          (gettext "/File/Close")         ; "Close" from gimp unless overridden

     LOCALE is a string or list of strings in the standard Unix format of LANG[_REGION][.ENCODING].  You can also pass a list of locales to specify fallbacks. LOCALE は文字列または文字列のリストで、標準的なUnixのフォーマット LANG[_REGION][.ENCODING] です。フォールバックを指定するロケールのリストを渡すこともできます。

          (textdomain "myapp" '("ru" "uk"))  ; search 1st Russian then Ukranian,
          (gettext "Hello, World!")          ; which are somewhat similar

     DIRS is the search path of directories which should hold the LOCALE/CDIR/ directories which contain the actual message catalogs. This is always appended with the system default, e.g. "/usr/share/locale", and may also inherit from the GETTEXT_PATH colon-delimited environment variable.

     CDIR is the category directory, defaulting to either the LC_CATEGORY environment variable or the appropriate system default (e.g. LC_MESSAGES).  You generally won't need this.

     CACHED? means to cache individual messages, and defaults to #t.

     LOOKUP-CACHED? means to cache the lookup dispatch generated by these parameters, and defaults to #t.

     Textdomain just passes these parameters to the internal make-gettext, and binds the result to the global dispatch used by gettext. You may build these closures manually for convenience in using multiple separate domains or locales at once (useful for server environments). See the description of make-gettext below.

     Textdomain returns an accessor procedure which packages information of the domain.  See make-gettext below for the details. DIRS は実際のメッセージカタログを含む LOCALE/CDIR/ ディレクトリのサーチパスです。これは常にシステムのデフォルト(たとえば、 "/usr/share/locale")に追加されます。そして、コロンで区切られた GETTEXT_PATH 環境変数を継承します。

     CDIR はカテゴリーディレクトリで、既定値を LC_CATEGORY 環境変数または、適当なシステム既定値(たとえば LC_MESSAGES)に設定します。一般にはこれを指定する必要はありません。

     CACHED? は個別のメッセージをキャッシュするかを意味し、デフォルトは #t です。

     LOOKUP-CACHED? は、これらのパラメータで生成されるディスパッチをキャッシュするかどうかを意味し、デフォルトは #t です。

     textdomain はこれらのパラメータを内部の make-gettext に渡し、その結果を、gettext で使われるグローバルなディスパッチに束縛します。これらのクロージャを複数の別々のドメインやロケールを一度に扱うのに便利なように、手で構築することができます。(これらはサーバ環境で便利です。) 後述の make-gettext を参照してください。

     textdomain はそのドメインの情報をもつ アクセサ手続きを返します。詳細については、後述の make-gettext を参照してください。

 -- Function: gettext msg-id
     Returns a translated message of MSG-ID.  If there's no translated message, MSG-ID itself is returned. MSG-ID の翻訳されたメッセージを返します。もし、翻訳されたメッセージがなければ、MSG-ID それ自身を返します。

 -- Function: ngettext msg-id :optional msg-id2 num
     Similar to GETTEXT, but it can be used to handle plural forms. Pass a singular form to MSG-ID, and plural form to msg-id2.  The NUM argument is used to determine the plural form.  If no message catalog is found, MSG-ID is returned when NUM is 1, and MSG-ID2 otherwise. GETTEXTと似ていますが、複数形を処理するのに使うことができます。単数形のメッセージを MSG-ID へ、複数形のメッセージを msg-id2 に渡します。NUM 引数は、複数形を決定するのに使われます。もし、メッセージカタログが見つからなければ、 NUM が 1 のときは、MSG-ID が返り、そうでなければ、 MSG-ID2 が返ります。

 -- Function: bindtextdomain domain dirs
     Sets the search path of domain DOMAIN to DIRS, which may be just a single directory name or a list of directory names. ドメイン DOMAIN のサーチパスを DIRS に設定します。単一のディレクトリ名であったり、ディレクトリのリストであったりします。

 -- Function: dgettext domain msg-id
 -- Function: dcgettext domain msg-id locale
     Returns a translated message of MSG-ID in DOMAIN. Dcgettext takes LOCALE as well. DOMAIN 中の MSG-ID の翻訳されたメッセージを返します。 dcgettext は LOCALE も引数としてとります。

Low-level flexible API
----------------------

低水準の柔軟な API
-----------

The following procedure is more flexible interface, on top of which the gettext-compatible APIs are written. 以下の手続きはより柔軟性のあるインタフェースで、この上で、gettext-互換の API が書かれています。

 -- Function: make-gettext :optional domain locale dirs gettext-cached? lookup-cached?
     Creates and returns an accessor procedure, which encapsulates methods to retrieve localized messages.

     The meaning of arguments are the same as textdomain above. Indeed, textdomain just calls make-gettext, and later it binds the result to the global parameter.   If you wish to have multiple independent domains within a single program, you can call make-gettext directly and manage the created accessor procedure by yourself. アクセサ手続き を生成して返します。返された手続きは、地域化されたメッセージを検索するメソッドをカプセル化しています。

     引数の意味は上述の textdomain と同じです。実際は、textdomain は make-gettext を呼び、その後、それは、結果をこのグローバルパラメータに束縛します。make-gettext を直接呼んで、自分自身で、アクセサ手続きを管理することもできます。

          (define my-gettext (make-gettext "myapp"))
          (define _ (my-gettext 'getter))
          (_ "Hello, World!")

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 ドキュメントを簡単に構築するための手続きを提供します。例えば、以下のコードは HTML のテーブルを構築します。

          (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'. 詳細については、以下の html:ELEMENT の説明を見てください。

     このモジュールでは生成されたHTMLドキュメントに関して、例えばアトリビュートに有効な値が入っているか、要素の内容はDTDを満たしているか、等のチェックをほとんど行いません。また、HTMLをパーズする関数も提供されません。それが「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. HTML に含まれる"安全でない"文字をエスケープします。 html-escape は、現在の入力ポートから文字列を読み込み、結果を現在の出力ポートへ書き出します。html-escape-string は STRING を入力とし、文字列を返します。

 -- Function: html-doctype :key type
     Returns a doctype declaration for an HTML document. TYPE can be either one of the followings (default is :html-4.01-strict). HTML ドキュメントの文書型宣言を返します。 TYPE は、以下のいずれかを指定します (デフォルトは:html-4.01-strict です)。

     :html-4.01-strict, :html-4.01, :strict
          HTML 4.01 Strict DTD

     :html-4.01-transitional, :transitional
          HTML 4.01 Transitional DTD

     :html-4.01-frameset, :frameset
          HTML 4.01 Frameset DTD

     :xhtml-1.0-strict, :xhtml-1.0
          XHTML 1.0 Strict DTD

     :xhtml-1.0-transitional
          XHTML 1.0 Transitional DTD

     :xhtml-1.0-frameset
          XHTML 1.0 Frameset DTD

     :xhtml-1.1
          XHTML 1.1 DTD

 -- 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). ELEMENT の HTML 要素を構築します。現時点では以下の要素がサポートされています。 (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       frame       frameset
          h1       h2         h3         h4          h5        h6
          head     hr         html       i           iframe    img
          input    ins        kbd        label       legend    li
          link     map        meta       noframes    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 Lazy text construction).

     You can specify attributes of the element by using a keyword-value notation before the actual content. これらの手続きは、テキスト・セグメントのツリーを返すので、 write-tree でポートに書き出したり、tree->string で文字列に変換したりできます (Lazy text construction参照)。

     要素のアトリビュートは要素の内容に先立つキーワード-値の表記で指定することができます。

          (tree->string (html:a :href "http://foo/bar" "foobar"))
            =>
            "<a href=\"http://foo/bar\">foobar</a\n>"

          (tree->string
            (html:table :width "100%" :cellpadding 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 rendered without a value. If #f is given, the attribute is not rendered. 属性に与える真偽値は特別な意味を持ちます。 #t が与えられると、属性は値なしでレンダリングされます。 #f が与えられると、属性それ自体がレンダリングされません。

          (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. 属性の値における特別な文字は、手続きによってエスケープされますが、要素の内容にある特別な文字はエスケープされません。それをエスケープするのは呼び出し側の責任です。

     内容を持たない HTML 要素に内容を与えると手続きはエラーを通知します。手続きは、与えられた属性が妥当であるか、与えられた内容がその要素にとって妥当であるかのチェックはしません。

     Note: You might have noticed that these procedures insert a newline before > of the closing tag.  That is, the rendered HTML would look like this: 注意: これらの手続は改行を終了タグの>の前に挿入することに注意してください。つまり、HTMLをレンダリングすると以下のようになります。

          <table><tr><td>foo</td
          ><td>bar</td
          ></tr
          ></table
          >

     We intentionally avoid inserting newlines after the closing tag, since it depends on the surrounding context whether the newline is significant or not.  We may be able to insert newlines after the elements directly below a <head> element, for example, but we cannot in a <p> element, without affecting the content. 終了ダグの後に改行をいれないのは意図的なものです。改行が意味をもつかどうかは外側の文脈に依存するからです。たとえば、<head>要素の直下にある要素の後に改行を入れてもテキストの内容には影響を与えませんが、 <p>要素中で改行を入れるとそれは内容の一部となってしまいます。

     There are three possible solutions: (1) not to insert newlines at all, (2) to insert newlines within tags, and (3) to insert newlines only at the safe position.  The first one creates one long line of HTML, and although it is still valid HTML, it is inconvenient to handle it with line-oriented tools. The third one requires the rendering routine to be aware of DTD.  So we took the second approach. 3つ可能性があって、(1) 改行は全く入れない、(2) タグの中だけで改行を入れる。(3) 安全な場所にのみ改行をいれる。最初の場合はHTMLは一行になり、正当なHTMLではあるものの、行指向のツールで処理するには不便です。3番目の場合はレンダリングするのにDTDをちゃんと見るツールが必要になります。というわけで、ここでは2番目のアプローチを取っています。

text.pager - Display with pager
===============================

 -- Module: text.pager
     A convenience module to present long text nicely to the user.

 -- Parameter: pager-program
     A parameter containing a list of pager program and its arguments (e.g. ("/usr/bin/less" "-M")).

     The program must take input from the standard input.

     The default value is taken from the environment variable PAGER if set, or either less or more if those programs are available on the system.

 -- Function: display/pager string
     Display STRING by a pager subprocess specified by the parameter pager-program.  The procedure returns when the subprocess exits.

     If the terminal is not suitable for control (e.g. TERM is dumb or emacs), STRING is simply displayed without a pager.

     If you're running MinGW version of gosh on mintty, calling subprocess pager doesn't work well, so the procedure emulate the pager behavior (pager-program is ignored).

 -- Function: with-output-to-pager thunk
     Call THUNK with its current output port to a string buffer, then show the buffered output using display/pager.

     Note that the output begins after THUNK returns.

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 (http://okmij.org/ftp/Scheme/parsing.html). His library is used in lots of other libraries, notably, a full-Scheme XML parser/generator SSAX (http://okmij.org/ftp/Scheme/xml.html).

     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. 入力ポートに対して単純な解析を行うユーティリティのコレクションです。 API は Oleg Kiselyov 氏の入力解析ライブラリ (http://okmij.org/ftp/Scheme/parsing.html) に触発され、互換性を持つものです。氏のライブラリは、他のたくさんのライブラリで使われています。特に、Scheme のみで書かれたパーサ/ジェネレータである SSAX (http://okmij.org/ftp/Scheme/xml.html) が挙げられます。

     このモジュールは、氏の input-parse.scm や look-for-str.scm の代わりに使うことができます。

     Gauche で効果的になるように手続きを再実装しました。特に、string-set! の使用は完全に取り除きました。インターフェースを少し拡張したので、文字集合や述語、文字のリストにも使うことができます。

     これらの手続きは、与えられた入力ポートに対してシーケンシャルに動作します。それは、ポートから必要なだけ読み、余分な文字をバッファリングしないということです。

 -- 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. 入力ポート IN-PORT から、文字列 STR を探します。オプショナル引数 MAX-NO-CHARS は、ポートから読み込まれる最大文字数を制限します。省略されると、検索する範囲は EOF までとなります。

     STR が見つかると、手続きはすでに読み込んだ文字の数を返します。 IN-PORT の次回の読み込みは、STR の次の文字を返します。 STR が見つからない場合、#f が返ります。

     注意: この手続きはその名前に「?」がつきますが、Scheme の慣習に反し、真偽値ではない値を返すことがあります。

 -- 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. 現在の文字を破棄し、PORT から次の文字を読みます。一文字先読みするのに便利です。PORT が省略されると、現在の入力ポートが使われます。

In the following functions, CHAR-LIST refers to one of the followings:

  * A character set.

  * A list of characters, character sets and/or symbol *eof*.

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. 以下の手続きでは、CHAR-LIST は次のどれかを意味します。

  * 文字集合。

  * 文字、文字集合、シンボル *eof* の任意の組み合わせのリスト。

これらにより文字の集合が表現されます。シンボル *eof* が含まれる場合、 EOF の条件もまた含まれます。*eof* が含まれない場合、EOF の条件はエラーとして扱われます。

 -- 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. PORT から文字を読みます。その文字が CHAR-LIST に含まれている場合はその文字を返します。そうでなければ、STRING を含むメッセージとともにエラーを通知します。

 -- 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 reads that many characters and returns #f. If the input is not long enough, an error is signaled. 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. CHAR-LIST/NUMBER は、文字のリストか数です。数の場合、たくさんの文字を読んで、#f を返します。入力が十分に長くない場合は、エラーが通知されます。 CHAR-LIST/NUMBER が文字のリストの場合、その文字リストに属する文字に出会うまで PORT を読み込み、その文字を返します。 PORT が省略された場合、現在の入力ポートが使われます。

 -- 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. CHAR-LIST に属しない文字に出会うまで、PORT を読み込みます。文字はストリームに残されます。EOF に達したら EOF が返されます。 PORT が省略された場合、現在の入力ポートが使われます。

     この例では、入力から空白スペースをスキップしています。ポートからの次の読み込みは、最初の空白スペースでない文字を返します。

          (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 signaled with COMMENT is included in the message. PREFIX-CHAR-LIST に含まれる文字はいくつでもスキップします。そして、BREAK-CHAR-LIST に含まれる文字に出会うまで、文字を蓄積します。蓄積された文字群は文字列として返されます。中断文字は PORT に残されます。

     手続きが EOF に達し、*eof* が BREAK-CHAR-LIST に含まれていない場合、COMMENT が含まれたメッセージとともにエラーが通知されます。

 -- 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. 読み込んだ文字が CHAR-LIST/PRED にある限り蓄積し、文字列として返します。CHAR-LIST/PRED に含まれない最初の文字はポートに残されます。

     CHAR-LIST/PRED は文字のリストか文字を取る述語です。述語の場合、それぞれの文字がその述語に渡され、真の値が返る場合はその文字は CHAR-LIST/PRED に属するとみなされます。

 -- Function: read-string n :optional port
     This is like built-in read-string (see Reading data), except that this returns "" when the input already reached EOF.

     Provided for the compatibility for the code that depends Oleg's library. 組み込みのread-string (Reading data参照) とほぼ同じですが、入力が既にEOFに達していた場合は""を返します。

     Olegのライブラリに依存しているコードの互換性のために用意されています。

text.progress - Showing progress on text terminals
==================================================

 -- Module: text.progress
     This module provides a utility to report a progress of processing on a text terminal, using characters to display bar chart. このモジュールはバーチャートを文字を用いて表示し、テキスト端末上に処理の進行状況を出すためのユーティリティです。

     The generic format of a progress bar consists of a single line of text, which is splitted into several parts; a header, which displays the title; followed by a bar, a numeric part, and a time part, as shown in the following example (only the line beginning with ``foo'' is actually displayed). 進捗を示すプログレスバーの汎用的なフォーマットは1行のテキストで構成されます。この1行はいくつかの部分に分解できます。タイトルを表示するヘッダ部、その後にプログレスバーがあって、数値部、時間部と続きます。以下がその例です(foo からはじまる1行だけが実際に表示されます。

          <-header-> <-------bar---------> <-num-><-time->      <---info---->
          foo       |#############        |123/211   01:21 ETA  compiling...
                    ^
                    separator

     Various things like the character used in the bar chart or the format of the numeric progress can be configured. バーチャートに使う文字などのいろいろなバリエーションや、数値で表わす進捗のフォーマットなども設定可能です。

     Internally a progress bar maintains two numbers, the maximum (goal) value and the current value.  The bar shows the proportion of the current value relative to the maximum value.  The numeric progress shows the current value over the maximum value by default, but you can configure it to show only the current value or percentage, for example. 内部的にはプログレスバーは2つの数値、最大値(ゴール)と現在の値を保持しています。バーは最大値に対する現在の値の比を示すものです。数値で表わす進捗はデフォルトでは最大値の上に現在の値を表示します。しかし、たとえば、現在の値だけを表示するとか、100分率で表示するなどの設定が可能です。

     A progress bar also has two states, ``in progress'' and ``finished''. When it is in progress, every time the text is displayed it is followed by #\return, so that the next display overwrites the bar, and the time part shows ETA (estimated time of arrival). Once it becomes finished, the last line of text is displayed with #\newline, and the time part shows the actual time it took to finish. プログレスバーは2つの状態「進捗中」および「終了」のどちらかの状態を保持しています。「進捗中」なら、どの時点でも表示されるテキストには #\returnが続きます。これにより次の表示が前の表示を上書きすることになります。時間部はETA(残り時間)を表示します。終了してしまえば、最後の行の後に#\newlineが続きます。時間部には終了までにかかった時間が表示されます。

This module provides only one procedure, make-text-progress-bar, which packages the progress bar feature in a closure and returns it. このモジュールはmake-text-progress-barという手続きを1つだけ提供します。この手続きはプログレスバーの機能をクロージャに包んでそれを返します。

 -- Function: make-text-progress-bar :key header header-width bar-char bar-width num-width num-format time-width info info-width separator-char max-value port
     Returns a procedure that packages operations on the progress bar. The procedure can be called with a symbol indicating an operation, and an optional numeric argument. プログレスバー上の操作を包んだ手続きを返します。返された手続きに操作を示すシンボルとオプションで数値を引数として渡して使います。

     PROC 'show
          Redisplays the progress bar.  All other operations implies redisplay, so you don't need to use this unless you have a specific reason to redisplay the current state. プログレスバーを再表示する。他のどの操作も状態の再表示を行います。したがって、現在のステータスを再表示しなければない特別な理由がないかぎりこれを使う必要はありません。

     PROC 'set VALUE
          Sets the current value to VALUE, then redisplays the progress bar. If VALUE exceeds the max value, it is clipped by the max value. 現在の値をVALUEにセットし、プログレスバーを再表示します。 VALUEが最大値を超えていたら、超過分を切り捨て最大値にします。

     PROC 'inc VALUE
          Increments the current value by VALUE, then redisplays the progress bar. If the current value exceeds the max value, it is clipped by the max value. VALUE分だけ現在の値を増し、プログレスバーを再表示します。現在の値が最大値を超えたら、超過分を切り捨て最大値にします。

     PROC 'finish
          Puts the progress bar to the ``finished'' state, then redisplays it. The time part shows the total elapsed time, and the line is terminated by #\newline so that it won't be clobbered.   Once a progress bar becomes ``finished'', there's no way to put it back ``in progress''. プログレスバーを「終了」状態にし、再表示します。時間部はトータルの経過時間を表示します。また、表示行末は#\newlineとし、上書きされないようにします。プログレスバーはいったん「終了」状態になれば、「進捗中」状態に戻す方法はありません。

     PROC 'set-info TEXT
          Changes the text displayed in the ``info'' part.  To use the info part, you have to give a positive value to INFO-WIDTH keyword argument of make-text-progress-bar. ``info''部に表示されるテキストを変更します。 info部を使うには、make-text-progress-barのINFO-WIDTHキーワード引数に正の値が指定されている必要があります。

     PROC 'set-header TEXT
          Changes the text displayed in the ``header' area. ``header''部に表示されるテキストを変更します。

     The keyword arguments are used to customize the display: キーワード引数を使って表示をカスタマイズできます。

     header
          The text to be displayed in the header part. This can be changed later, by sending set-header message to the created progress bar. ヘッダ部に表示するテキスト。このテキストは、作られたプログレスバーに set-headerメッセージを送ることで後で変更可能です。

     header-width
          The width of the header part, in number of characters. The header text is displayed left-aligned in the part. If the header text is longer than the width, the excess characters are omitted.  The default is 14. ヘッダ部の幅、文字数で指定します。ヘッダ部のテキストは左詰めです。ヘッダ部に置くテキストが幅よりも長い場合には超過分の文字は切り捨てられます。デフォルトは14文字です。

     bar-char
          A character used to draw a bar chart.  The default is #\#. バーチャートを描くのに使う文字。デフォルトは#\#です。

     bar-width
          The width of the bar chart part, in number of characters. The default is 40. バーチャート部の幅で、文字数で指定します。デフォルトでは40文字です。

     num-width
          The width of the numeric part, in number of characters. The default is 9.  Setting this to 0 hides the numeric part. 数値部の幅で、文字数で指定します。デフォルトでは9で、これを0に設定すると数値部を隠せます。

     num-format
          A procedure to format the numeric part.  Two arguments are passed; the current value and the maximum value.  It must return a string.  The default is the following procedure. 数値部を整形する手続き。引数が2つ渡されます。ひとつは現在の値、もうひとつは最大値です。この手続きは文字列を返さなければなりません。デフォルトでは以下の手続きです。

               (lambda (cur max)
                 (format "~d/~d" cur max))

     time-width
          The width of the time part, in number of characters. The default is 7.  Settings this to 0 hides the time part. 時間部の幅で、文字数で指定します。デフォルトでは7文字で、これを0に設定すると時間部を隠せます。

     info
          The text to be displayed in the info part.  This text can be changed later by sending set-info message to the created progress bar.  Note that you have to give a positive number to INFO-WIDTH keyword argument to enable the info part. info部に表示されるテキストです。このテキストは、作られたプログレスバーに set-infoメッセージを送ることで後から変更できます。 info部を表示するには、INFO-WIDTHキーワード引数に正の値を与えておく必要があります。

     info-width
          The width of the info part.  The default value is zero, which means the info part is not displayed. info部の表示幅です。デフォルトは0で、info部は表示されません。

     separator-char
          A character put around the bar part.  Default is #\|. You can pass #f not to display the separators. バー部分の前後に置く文字です。デフォルトでは#\|です。セパレータを表示したくなければ、#fを渡します。

     max-value
          The maximum value of the progress bar.  Must be a positive real number. Default is 100. プログレスバーの最大値です。正の実数でなければなりません。デフォルトでは100です。

     port
          An output port to which the progress bar is displayed.  The default value is the current output port when make-text-progress-bar is called. プログレスバーを表示する出力ポートです。デフォルト値は make-text-progress-barが呼ばれた時点での現在の出力ポートです。

Here's a simple example, using customized numeric part: 以下は簡単なカスタマイズをした例です。

     (use text.progress)

     (define (main args)
       (define (num-format cur max)
         (format "~d/~d(~3d%)" cur max
                 (round->exact (/. (* cur 100) max))))

       (let ((p (make-text-progress-bar :header "Example"
                                        :header-width 10
                                        :bar-char #\o
                                        :num-format num-format
                                        :num-width 13
                                        :max-value 256)))
         (do ((i 0 (+ i 1)))
             ((= i 256) (p 'finish))
           (p 'inc 1)
           (sys-select #f #f #f 50000))))

text.sql - SQL parsing and construction
=======================================

 -- Module: text.sql
     This module provides a utility to parse and construct SQL statement. このモジュールはSQL文のパーズと構築のためのユーティリティを提供します。

     It is currently under development, and we only have a tokenization routine. The plan is to define S-expression syntax of SQL and provides a routine to translate one form to the other. このモジュールは現在まだ開発途上にあります。まだトークン列を生成するルーチンしかありません。SQLのS式構文を定義して、SQLとその構文との間の変換ルーチンを提供する計画です。

     Note: If you're looking for a routine to escape strings to be safe in SQL, see dbi-escape-sql in DBI user API. 註: SQLに安全に渡せるように文字列をエスケープするルーチンをお探しなら、 DBI user APIのdbi-escape-sqlを見てください。

 -- Function: sql-tokenize sql-string
     Tokenize a SQL statement SQL-STRING.  The return value is a list of tokens, where each token is represented by one of the following forms. SQL文SQL-STRINGをトークン列に分解します。返り値はトークンのリストで、各トークンは以下の形式のひとつで表現されます。

          <symbol>              Special delimiter.  One of the followings:
                                + - * / < = > <> <= >= ||
          <character>           Special delimiter.  One of the followings:
                                #\, #\. #\( #\) #\;
          <string>              Regular identifier
          (delimited <string>)  Delimited identifier
          (parameter <num>)     Positional parameter (?)
          (parameter <string>)  Named parameter (:foo)
          (string    <string>)  Character string literal
          (number    <string>)  Numeric literal
          (bitstring <string>)  Binary string.  <string> is like "01101"
          (hexstring <string>)  Binary string.  <string> is like "3AD20"

          <symbol>              特殊区切り子、以下のどれか
                                + - * / < = > <> <= >= ||
          <character>           特殊区切り子、以下のどれか
                                #\, #\. #\( #\) #\;
          <string>              通常の識別子
          (delimited <string>)  区切られた識別子
          (parameter <num>)     位置パラメータ (?)
          (parameter <string>)  名前つきパラメータ (:foo)
          (string    <string>)  文字列リテラル
          (number    <string>)  数値リテラル
          (bitstring <string>)  バイナリ文字列  <string> は "01101" な感じ
          (hexstring <string>)  Binary string.  <string> は "3AD20" な感じ

     If it encounters an untokenizable string, it raises an <sql-parse-error> condition. トークンに分解できない文字列がくると<sql-parse-error>コンディションがあがります。

 -- Condition Type: <sql-parse-error>
     A condition to indicate an SQL parse error.  Inherits <error>. SQLパーズエラーを示すコンディション。<error>を継承。
      -- Instance Variable of <sql-parse-error>: sql-string
          Holds the source SQL string. 元のSQL文字列を保持。

text.template - Simple template expander
========================================

 -- Module: text.template
     This module lifts Gauche's built-in string interpolation feature to be more general template engine. このモジュールは、Gauche組み込みの文字列補間機能をより一般的なテンプレートエンジンとして使えるようにするものです。

     Gauche's string interpolation syntax is expanded at read time and then handled by macro expanders, and becomes a simple Scheme code fragment. For example, if you have this: Gaucheの文字列補間構文はソース読み込み時にマクロ呼び出しへと展開され、さらにマクロ展開器により展開されて単純なSchemeコード片となります。例えば、次のソースコードがある場合:

          (let ([x 10])
            #"The square of x is ~(* x x).")

     It is eventually converted to this after macro expansion: マクロ展開後の最終形は次のコードになります:

          (let ([x 10])
            (string-append '"The square of x is " (x->string (* x.0 x.0)) '"."))

     It is a kind of template expansion, but you have to have the template string as a literal, so it's restricted.  With this module, you can feed template string and the bindings of the value at the runtime: これも一種のテンプレート展開と言えるのですが、文字列補間ではテンプレート文字列が文字列リテラルとしてソースコード上に現れていなければならないという制限があります。このモジュールでは、文字列と束縛を実行時に与えることができます:

          (define *template* "The square of x is ~(* x x).")

          (expand-template-string *template*
            (make-template-environment :bindings '(x 10)))
            => "The square of x is 100."

     The syntax of template strings is the same as string interpolation (see String interpolation); that is, tokens following ~ is read as a Scheme expression.  In case if the token is a symbol and you need to delimit it from subsequent characters, you can use symbol escape by |. テンプレート文字列の構文は文字列補間のそれと同じです(String interpolation参照)。すなわち、~に続くトークンがScheme式として呼ばれます。もしトークンがシンボルで、その後の続く文字から区切る必要がある場合は、|によるシンボルエスケープが使えます。

     You also need to provide a template environment, where the expressions in the template is evaluated.  Note that, unlike string interpolation, those expressions can't refer to the local bindings. また、テンプレート展開時には、テンプレート中の式を評価するためのテンプレート環境を与える必要があります。文字列補間と違って、テンプレート中の式がローカル束縛を参照することはできません。

 -- Function: expand-template-string template env
     Expands a template string TEMPLATE with a template environment ENV, and returns the result string. テンプレート文字列TEMPLATEを、テンプレート環境ENVのもとで展開し、結果の文字列を返します。

 -- Function: expand-template-file filename env :optional paths
     Reads a template string from a file named by FILENAME, expands it with a template environment ENV, and returns the result string.

     If FILENAME is not an absolute path, it is looked in the directories listed in PATHS. テンプレート文字列をFILENAMEで指定されるファイルから読み込み、テンプレート環境ENVのもとでそれを展開し、結果の文字列を返します。

     FILENAMEが絶対パスでない場合は、PATHS中のディレクトリからの相対パスで探されます。

 -- Function: make-template-environment :key extends imports bindings
     Creates and returns a template environment.   A template environment is like a module (see Modules): It maps symbols to values, and it can import bindings from other modules, or extend other modules. テンプレート環境を作成して返します。テンプレート環境はモジュールのようなものです (Modules参照)。それはシンボルを値にマップし、また他のモジュールから束縛をインポートしたり、他のモジュールをextendしたりできます。

     The keyword arguments EXTENDS and IMPORTS must be a list of symbols; they specify names of modules to inherit from or to import from. キーワード引数EXTENDSとIMPORTSはシンボルのリストを取り、それぞれ継承元のモジュール、あるいはインポート元のモジュールを指定します。

     The keyword arguments BINDINGS must either be a dictionary (anything that inherits <dictionary>), or a key-value list. The mappings represented by it are incorporated to the environment. キーワード引数BINDINGSはディクショナリ(<dictionary>のサブクラスのインスタンス)か、key-valueリストでなければなりません。それにより表される束縛が環境に取り込まれます。

text.tr - Transliterate characters
==================================

 -- Module: text.tr
     This module implements a transliterate function, that substitutes characters of the input string. This functionality is realized in Unix tr(1) command, and incorporated in various programs such as sed(1) and perl.

     Gauche's tr is aware of multibyte characters. このモジュールは、入力ストリームから指定の文字を置き換えて出力する、文字変換(transliterate)機能を提供します。 Unixのtr(1)コマンドで実装され、sedやperlにも採り入れられている機能です。

     Gaucheのtrはマルチバイト文字／文字列を正しく扱います。

 -- Function: tr from-list to-list :key :complement :delete :squeeze :table-size :input :output
     Reads from INPUT and writes to OUTPUT, with transliterating characters in FROM-LIST to the corresponding ones in TO-LIST.  Characters that doesn't appear in FROM-LIST are passed through. INPUTから文字を読み込み、その文字がFROM-LIST内にあれば対応するTO-LIST内の文字に置き換えて、OUTPUTへと書き出します。 FROM-LISTに無い文字はそのままOUTPUTへと渡されます。

     The default values of INPUT and OUTPUT are current input port and current output port, respectively. INPUTとOUTPUTの既定値はそれぞれ現在の入力ポートと出力ポートです。

     Both FROM-LIST and TO-LIST must be strings. They may contain the following special syntax. Other characters that doesn't fits in the syntax are taken as they are. FROM-LISTとTO-LISTは文字列でなければなりません。その中には次のような表記を使うことができます。それ以外の文字はそのまま使われます。

     x-y
          Expanded to the increasing sequence of characters from x to y, inclusive.  The order is determined by the internal character encoding system; generally it is safer to limit use of this within the range of the same character class.   The character x must be before y. 文字xから文字yまでの文字の昇順の並びと解釈されます。 xとyは含まれます。文字の並びはGaucheの内部文字エンコーディングによって決定されるので、一般にはxとyは同じキャラクタクラスの中に止めておいた方が安全でしょう。xはyより小さくなければなりません。

     x*n
          Repeat x for n times.  n is a decimal number notation. Meaningful only in TO-LIST; it is an error to use this form in FROM-LIST. If n is omitted or zero, x is repeated until TO-LIST matches the length of FROM-LIST (any character after it is ignored). 文字xのn個の並び。nは10進数で表記された数値です。これはTO-LISTでのみ有効で、FROM-LISTで使うとエラーになります。 nが省略されるか0の場合、xはTO-LISTの長さがFROM-LIST の長さに達するまで繰り返されます(その場合、TO-LISTの残りは無視されます)。

     \x
          Represents x itself.  Use this escape to avoid a special character to be interpreted as itself.   Note that if you place a backslash in a string, you must write \\, for the Scheme reader also interprets backslash as a special character.

          There's no special sequence to represent non-graphical characters, for you can put such characters by the string syntax. 文字xそれ自身。特殊文字そのものを埋め込みたい場合に使います。文字列のリーダも\を解釈するので、\\と書かねばならないことに注意して下さい。

          グラフィカルでない文字のための構文はありません。文字列リーダの構文を使ってそのような文字を文字列に含めることができます。

     Here's some basic examples.

          ;; swaps case of input
          (tr "A-Za-z" "a-zA-Z")

          ;; replaces 7-bit non-graphical characters to `?'
          (tr "\x00-\x19\x7f" "?*")

     いくつか例を挙げます。

          ;; 大文字と小文字を交換します
          (tr "A-Za-z" "a-zA-Z")

          ;; ひらがなとかたかなを交換します
          (tr "ぁ-んァ-ン" "ァ-ンぁ-ん")

          ;; 7ビットのノングラフィカルな文字を`?'に変換します
          (tr "\x00-\x19\x7f" "?*")

     If TO-LIST is shorter than FROM-LIST, the behavior depends on the keyword argument DELETE.  If a true value is given,  characters that appear in FROM-LIST but not in TO-LIST are deleted.   Otherwise, the extra characters in FROM-LIST are just passed through. TO-LISTがFROM-LISTより短い場合、動作はキーワード引数DELETEに依存します。もし真の値がDELETEに与えられれば、FROM-LISTに現われて TO-LISTに対応するものがない文字は入力から取り除かれます。そうでなければそのような文字はそのまま出力されます。

     When a true value is specified to COMPLEMENT, the character set in FROM-LIST is complemented. Note that it implies huge set of characters, so it is not very useful unless either output character set is a single character (using `*') or used with delete keyword. 真の値がCOMPLEMENTに与えられた場合、FROM-LISTの文字の補集合がFROM-LISTとして使われます。この文字集合は極めて大きくなる可能性があることに注意してください。従って、一般にこのオプションは TO-LISTに`*'を使ってそれらの文字を一文字にマッピングするか、 deleteオプションと併用するかしないとあまり意味がありません。

     When a true value is specified to SQUEEZE, the sequence of the same replaced characters is squeezed to one. If TO-LIST is empty, the sequence of the same characters in FROM-LIST is squeezed. 真の値がSQUEEZEに与えられた場合、同じ文字への置換が2つ以上並ぶ場合に 2つめ以降の文字が削除されます。TO-LISTが空の場合は、FROM-LIST に含まれる文字で同一文字が並んだ場合に2つめ以降の文字が削除されます。

     Internally, tr builds a table to map the characters for efficiency.  Since Gauche can deal with potentially huge set of characters, it limits the use of the table for only smaller characters (<256 by default).  If you want to transliterate multibyte characters on the large text, however, you might want to use larger table, trading off the memory usage.  You can specify the internal table size by TABLE-SIZE keyword argument. For example, if you transliterate lots of EUC-JP hiragana text to katakana, you may want to set table size greater than 42483 (the character code of the last katakana). 内部的に、trはキャラクタのマッピングのためにテーブルを使用します。但し、Gaucheでは極めて大きな文字集合を扱うため、テーブルはキャラクタコードの小さい文字のみに対して使われます(デフォルトではコード255以下の文字)。もし、より大きな文字を頻繁に変換することが分かっていて、メモリを余分に使っても速度を上げたい場合は、このテーブルの大きさをTABLE-SIZEキーワード引数で指定することができます。例えばEUC-JPコードで大量の平仮名と片仮名を変換する場合は、 TABLE-SIZEを42483以上にすると、全ての変換がテーブルルックアップで行われます。

     Note that the pre-calculation to build the transliterate table needs some overhead.  If you want to call tr many times inside loop, consider to use build-transliterator described below. trが変換テーブルを計算するのにいくらかオーバーヘッドがあることに注意して下さい。内側のループでtrを繰り返し呼ぶような場合は下に示すbuild-transliteratorを使った方が良いでしょう。

 -- Function: string-tr string from-list to-list :key :complement :delete :squeeze :table-size
     Works like tr, except that input is taken from a string STRING. 入力をSTRINGから取って変換結果を文字列で返す以外はtrと同じです。

 -- Function: build-transliterator from-list to-list :key :complement :delete :squeeze :table-size :input :output
     Returns a procedure that does the actual transliteration.  This effectively ``pre-compiles'' the internal data structure.   If you want to run tr with the same sets repeatedly, you may build the procedure once and apply it repeatedly, saving the overhead of initialization. 実際の変換動作をする手続きを作成して返します。内部データのセットアップを済ませるため、同じ文字変換セットに対してtrを繰り返し呼ぶような場合は、この手続きを用いることで初期化のオーバヘッドを軽減することができます。

     A note for an edge case: When INPUT and/or OUTPUT keyword arguments are omitted, the created transliterator is set up to use current-input-port and/or current-output-port at the time transliterator is called. 註記：INPUTやOUTPUTキーワード引数が省略された場合、作成される変換手続きは、それが使用された時点でのカレント入出力ポートを参照します。

          (with-input-from-file "huge-file.txt"
            (lambda ()
              (let loop ((line (read-line)))
                (unless (eof-object? line) (tr "A-Za-z" "a-zA-Z")))))

          ;; runs more efficiently...
          ;; 以下の方が効率良く動作します...

          (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))))))

text.tree - Lazy text construction
==================================

 -- Module: text.tree
     Defines simple but commonly used functions for a text construction.

     When you generate a text by a program, It is a very common operation to concatenate text segments. However, using string-append repeatedly causes unnecessary copying of intermediate strings, and sometimes such intermediate strings are discarded due to the error situation (for example, think about constructing an HTML document in the CGI script).

     The efficient technique is to delay concatenation of those text segments until it is needed.  In Scheme it is done very easily by just consing the text segments together, thus forming a tree of text, and then traverse the tree to construct a text. You can even directly writes out the text during traversal, avoiding intermediate string buffer. (Hans Boehm's ``cord'' library, which comes with his garbage collector library, uses this technique and proves it is very efficient for editor-type application).

     Although the traversal of the tree can be written in a few lines of Scheme, I provide this module in the spirits of OnceAndOnlyOnce.   Also it's easier if we have a common interface. テキストを生成する場合によく使われるシンプルな手続きを定義します。

     プログラムでテキストを生成する場合、テキストの断片をつなぎ合わせて行く操作が非常に多く現われます。しかし単純にstring-appendを繰り返し呼んでしまうと、中間結果の文字列を保持するためだけにメモリアロケーションが多発しますし、途中でエラーが発生した場合にその中間結果は結局捨てられてしまうかもしれません (例えば、CGIスクリプト中でHTMLドキュメントを構築してゆくような場合を考えてみて下さい)。

     よく知られた効率の良い方法は、テキストの断片をつなぎ合わせるのを本当に必要になるまで遅らせることです。Schemeではそれは非常に簡単です。単に断片をコンスしていって木構造を作り、最後にそれをトラバースしてテキストを作成するのです。場合によっては、トラバースしながらテキストを出力すれば事足りてしまうので、中間結果のバッファを持つ必要さえありません。 (Hans Boehmのガベージコレクションライブラリに附属している ``cord'' ライブラリはこのテクニックを実装したもので、エディタ等のアプリケーションで非常に効率良く動作することが知られています)。

     木構造をトラバースする手続きなどほんの2〜3行で書けてしまいますが、「一度、そして一度だけ」の精神の下に、このモジュールを提供します。インタフェースが統一されてたほうが便利ですしね。

 -- Generic Function: write-tree tree :optional out
     Writes out an TREE as a tree of text, to the output port OUT. If OUT is omitted, the current output port is used.

     Two methods are defined for this generic function, as shown below. If you have more complex behavior, you can define more methods to customize the behavior. TREEをテキストの木構造とみなして、出力ポートOUTに出力します。 OUTが省略された場合は現在の出力ポートが使われます。

     下に示す2つのメソッドが定義されています。より複雑な動作をさせたい場合は、単純なリストの替わりにノードとなるクラスを定義して、それにメソッドを定義するようにすれば動作をカスタマイズできます。

 -- Method: write-tree ((tree <list>) out)
 -- Method: write-tree ((tree <top>) out)
     Default methods.  For a list, write-tree is recursively called for each element.  Any objects other than list is written out using display. write-treeの既定の動作です。TREEがリストなら、その要素それぞれについてwrite-treeを呼び出します。それ以外のオブジェクトに関しては displayを呼んで出力します。

 -- Function: tree->string tree
     Just calls the write-tree method for TREE using an output string port, and returns the result string. 出力文字列ポートを作成してwrite-treeを呼び、生成された文字列を返します。

util.combinations - Combination library
=======================================

 -- Module: util.combinations
     This module implements several useful procedures of combinations, permutations and related operations.

     Most procedures in the module have two variants: a procedure without star (e.g. permutations) treats all elements in the given set distinct, while a procedure with star (e.g. permutations*) considers duplication.  The procedures with star take optional EQ argument that is used to test equality, which defaults to eqv?. このモジュールは、いくつかの便利なコンビネーションや順列とそれに関連する操作の手続きを実装しています。

     このモジュールのほとんどの手続きは2つのバージョンを持っています。 1つはアスタリスクの付かない手続き(例えば、permutations)で、与えられたセットにある全ての要素を区別して扱います。もう1つは、アスタリスクの付く手続き(例えば、permutations*)で、重複を考慮します。アスタリスクの付く手続きは、オプショナルなEQ引数を取ります。それは等値性のテストに使われ、デフォルトはeqv?です。

 -- Function: permutations set
 -- Function: permutations* set :optional eq
     Returns a list of all permutations of a list SET. リストSETの全ての順列のリストを返します。

          (permutations '(a b c))
            => ((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))

          (permutations '(a a b))
            => ((a a b) (a b a) (a a b) (a b a) (b a a) (b a a))

          (permutations* '(a a b))
            => ((a a b) (a b a) (b a a))

     The number of possible permutations explodes if SET has more than several elements.  Use with care.  If you want to process each permutation at a time, consider permutations-for-each below. SETがある程度の要素を持っている場合、可能性のある順列の数は爆発的に大きくなります。注意して使って下さい。一度にそれぞれの順列を処理したい場合は、下記のpermutations-for-eachの使用を考慮して下さい。

 -- Function: permutations-for-each proc set
 -- Function: permutations*-for-each proc set :optional eq
     For each permutation of a list SET, calls PROC. Returns an undefined value. リストSETのそれぞれの順列に対して、PROCを呼び出します。戻り値は未定義値です。

 -- Function: combinations set n
 -- Function: combinations* set n :optional eq
     Returns a list of all possible combinations of N elements out of a list SET. リストSETのN個の要素の可能性のある全ての順列のリストを返します。

          (combinations '(a b c) 2)
            => ((a b) (a c) (b c))

          (combinations '(a a b) 2)
            => ((a a) (a b) (a b))

          (combinations* '(a a b) 2)
            => ((a a) (a b))

     Watch out the explosion of combinations when SET is large. SETが大きいときは、組み合わせの爆発について注意して下さい。

 -- Function: combinations-for-each proc set n
 -- Function: combinations*-for-each proc set n :optional eq
     Calls PROC for each combination of N elements out of SET. Returns an undefined value. SETのN個の要素のそれぞれの組み合わせについてPROCを呼び出します。戻り値は未定義値です。

 -- Function: power-set set
 -- Function: power-set* set :optional eq
     Returns power set (all subsets) of a list SET. リストSETの累乗集合(全てのサブセット)を返します。

          (power-set '(a b c))
            => (() (a) (b) (c) (a b) (a c) (b c) (a b c))

          (power-set* '(a a b)
            => (() (a) (b) (a a) (a b) (a a b))

 -- Function: power-set-for-each proc set
 -- Function: power-set*-for-each proc set :optional eq
     Calls PROC for each subset of SET. SETのそれぞれのサブセットについてPROCを呼び出す。

 -- Function: power-set-binary set
     Returns power set of SET, like power-set, but in different order. Power-set-binary traverses subset space in depth-first order, while power-set in breadth-first order. power-setのように、SETの累乗集合を返しますが、順番が異なります。 power-set-binaryはサブセットの空間を深さ優先でトラバースしますが、 power-setは横型探索を行います。

          (power-set-binary '(a b c))
            => (() (c) (b) (b c) (a) (a c) (a b) (a b c))

 -- Function: cartesian-product list-of-sets
 -- Function: cartesian-product-right list-of-sets
     Returns a cartesian product of sets in LIST-OF-SETS. Cartesian-product construct the result in left fixed order (the rightmost element varies first), while cartesian-product-right in right fixed order (the leftmost element varies first). LIST-OF-SETSにあるセットのデカルト積を返します。 cartesian-productは左固定順で結果を構築しますが (一番右の要素がまず異なる)、 cartesian-product-rightは右固定順で行います (一番左の要素がまず異なる)。

          (cartesian-product '((a b c) (0 1)))
            => ((a 0) (a 1) (b 0) (b 1) (c 0) (c 1))

          (cartesian-product-right '((a b c) (0 1)))
            => ((a 0) (b 0) (c 0) (a 1) (b 1) (c 1))

util.digest - Message digester framework
========================================

 -- Module: util.digest
     This module provides a base class and common interface for message digest algorithms, such as MD5 (see MD5 message digest) and SHA (see SHA message digest). このモジュールは、MD5 (MD5 message digest参照)や SHA (SHA message digest参照)などの、メッセージダイジェストアルゴリズムのためのベースクラスと一般的なインターフェースを提供します。

 -- Class: <message-digest-algorithm-meta>
     A metaclass of message digest algorithm implementation. メッセージダイジェストアルゴリズムの実装のメタクラスです。

      -- Instance Variable of <message-digest-algorithm-meta>: hmac-block-size
          Specifies the block size (in bytes), which is specific to each algorithm. (This is a slot for each class object that implements the algorithm, not for instance of such classes.  Only the author of such digest classes needs to care.  See ext/digest/sha.scm in the source tree for more details.) 各アルゴリズムに固有のブロックサイズをバイト数で指定します。 (これはアルゴリズムを実装する各クラスオブジェクトのスロットで、それらのクラスのインスタンスのスロットではありません。通常、新たなダイジェストアルゴリズムクラスを実装する人のみが気にすれば良いスロットです。具体例はソースツリーのext/digest/sha.scmを見てください。)

 -- Class: <message-digest-algorithm>
     A base class of message digest algorithm implementation. メッセージダイジェストアルゴリズムの実装のベースクラスです。

The concrete subclass of message digest algorithm has to implement the following methods. メッセージダイジェストアルゴリズムの具体サブクラスは、以下のメソッドを実装しなければなりません。

 -- Generic function: digest-update! algorithm data
     Takes the instance of massage-digest algorithm, and updates it with the data DATA, which can be either a u8vector or a (possibly incomplete) string. メッセージダイジェストアルゴリズムのインスタンスを取り、それをu8vectorか(不完全な可能性のある)文字列のデータDATAで更新します。

 -- Generic function: digest-final! algorithm
     Finalizes the instance of message-digest algorithm, and returns the digest result in an incomplete string. メッセージダイジェストアルゴリズムのインスタンスを終了させ、そのダイジェストの結果を不完全文字列で返します。

 -- Generic function: digest class
     A wrapper of digest routines.  Given message-digest algorithm CLASS, this function reads the input data from current input port until EOF, and returns the digest result in an incomplete string. ダイジェストルーチンのラッパです。メッセージダイジェストアルゴリズム CLASSを与え、現在の入力ポートから入力データをEOFまで読み込み、そのダイジェストの結果を不完全文字列で返します。

 -- Generic function: digest-string class string
     A wrapper of digest routines.  Given message-digest algorithm CLASS, this function reads the input data from STRING, and returns the digest result in an incomplete string. ダイジェストルーチンのラッパです。メッセージダイジェストアルゴリズム CLASSを与え、入力データをSTRINGから読み込み、そのダイジェストの結果を不完全文字列で返します。

 -- Function: digest-hexify digest-result
     An utility procedure.  Given the result of digest, DIGEST-RESULT, which can be an u8vector or a (possibly incomplete) string, converts it to a hexified string. ユーティリティ手続きです。ダイジェストの結果、DIGEST-RESULT (u8vectorか(不完全かもしれない)文字列) 与えると、それを16進文字列に変換します。

util.dominator - Calculate dominator tree
=========================================

 -- Module: util.dominator
     Dominator tree is an auxiliary structure for control flow graphs. It is frequently used in the flow analysis of compilers, but also useful for handling general directed graphs. 支配木(dominator tree)は制御フローグラフで補助的に使われる構造です。コンパイラのフロー解析によく使われることが多いですが、一般の有向グラフでも有用です。

 -- Function: calculate-dominators start upstreams downstreams node-comparator
     The four arguments represent a directed, possibly cyclic, graph. Here, we use Node to denote an abstract type of a node of the graph.  It can be anything---the algorithm is oblivious on the actual type of nodes. 4つの引数で有向グラフが表現されます。循環があっても構いません。以下ではグラフのノードがNodeという型を持つとして説明します。実際にはノードの型は何であっても構いません。アルゴリズムはノードの実際の型とは無関係に動作します。

     START :: Node
          The start node, or the enter node, of the graph. フローの起点となるノード。startノードとかenterノードとも呼ばれます。

     UPSTREAMS :: Node -> (Node ...)
          A procedure that takes a node, and returns its upstream (immediate ancestor) nodes. ノードを取り、その直接の上流ノードのリストを返す関数。

     DOWNSTREAMS :: Node -> (Node ...)
          A procedure that takes a node, and returns its downstream (immediate descendant) nodes. ノードを取り、その直接の下流ノードのリストを返す関数。

     NODE-COMPARATOR
          A comparator that is used to determine if two nodes are equal to each other. It doesn't need to have comparison procedure (we don't need to see which is smaller than the other), but it has to have hash function, for we use hashtables internally.  (see Basic comparators, for the details of comparators.) 二つのノードが等しいかどうかを決定する比較器。大小比較関数を持っている必要はありませんが、アルゴリズム内部でハッシュテーブルを使うので、ハッシュ関数は持っている必要があります。比較器について詳しくはBasic comparatorsを参照してください。

     The procedure returns a list of (node1 node2), where node2 is the immediate dominator of node1. 返り値は(node1 node2)を要素に持つリストです。ここで、 node2はnode1の直接支配ノード(immediate dominator)です。

     If there are node in the given graph that are unreachable from START, such nodes are ignored and not included in the result. 与えられたグラフの中にSTARTから到達不可能なノードがあった場合、それは単に無視され、結果に含まれません。

     (A bit of explanation: Suppose you want to go to node X from START. There may be multiple routes, but if you have to pass node Y no matter which route you take, then Y is a dominator of X.  There may be many dominators of X.  Among them, there's always one dominator such that all other X's dominators are also its dominators---in other words, the closest dominator of X---which is called the immediate dominator of X.) (ちょっとした説明: STARTからノードXに行きたいとします。複数の経路がありえますが、どの経路を取っても必ずノードYを通らないと Xに行けない場合、YをXの支配ノード(dominator)と呼びます。支配ノードは複数ありえますが、その中で一つだけ、他のXの支配ノード全てがそのノードの支配ノードでもあるようなノードがあります(言い換えれば、 Xに一番「近い」支配ノードです)。それをXの直接支配ノードと呼びます。)

     Let's see an example.  You have this directed graph: 例を見てみましょう。こんな有向グラフがあるとします。

                    A (start)
                    |
                    v
                    B <-------+
                    |         |
              ------+-----    |
              |          |    |
              v          v    |
              C -------> D ---+
              |          |
              v          v
              E <------- F

     Let's represent the graph by a list of (x y z ...) where x can directly go to either y z .... このグラフをリストのリストで表現してみましょう。ここで、内側のリスト(x y z ...)は、xからはyやzに直接行ける、ということを表します。

          (define *graph* '((A B)
                            (B C D)
                            (C D E)
                            (D F B)
                            (F E)))

     Then you can calculate the immediate dominator of each node as follows: すると、各ノードの直接支配ノードが次の通り計算できます。

          (calculate-dominators 'A
            (^n (filter-map (^g (and (memq n (cdr g)) (car g))) *graph*))
            (^n (assoc-ref *graph* n '()))
            eq-comparator)
            => ((E B) (F D) (D B) (C B) (B A))

     That is, E's immediate dominator is B, F's is D, and so on. つまり、Eの直接支配ノードはBであり、 FのはDである、という具合です。

     The result itself can be viewed as a tree.  It is called a dominator tree. この結果自体を木と解釈することができます。これを支配木(dominator tree)と呼びます。

                        F
                        |
                        v
                  E     D     C
                  |     |     |
                  |     v     |
                  +---> B <---+
                        |
                        v
                        A

util.isomorph - Determine isomorphism
=====================================

 -- Module: util.isomorph
     Provides a procedure that determines whether two structures are isomorphic. 二つの構造が同型かどうかを判定する手続きを提供するモジュールです。

 -- Function: isomorphic? obj1 obj2 :optional context
     Returns #t if OBJ1 and OBJ2 are isomorphic.

     CONTEXT is used if you want to call isomorphic? recursively inside object-isomorphic? described below. OBJ1とOBJ2が同型であれば#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
     With this method, you can customize how to determine isomorphism of two objects.  Basically, you will call isomorphic? recursively for each slots of object you want to traverse; the method should return #t if all of the test succeeds, or return #f otherwise. CONTEXT is an opaque structure that keeps the traversal context, and you should pass it to isomorphic? as is.

     The default method returns #t if OBJ1 and OBJ2 are equal (in the sense of equal?). このメソッドで、二つのオブジェクトの同型判定処理をカスタマイズできます。基本的には、オブジェクトのトラバースしたいスロットに対してisomorphic?を順に適用し、全てが成功すれば#tを、一つでも失敗すれば#fを返すようにします。 CONTEXTはトラバースのコンテクストを保持しているオブジェクトです。そのまま isomorphic?に渡して下さい。

     デフォルトメソッドは、OBJ1とOBJ2がequal?の意味で等しければ #tを返します。

util.lcs - The longest common subsequence
=========================================

 -- Module: util.lcs
     This module implements the algorithm to find the longest common subsequence of two given sequences.  The implemented algorithm is based on Eugene Myers' O(ND) algorithm (Eugene Myers, An O(ND) Difference Algorithm and Its Variations, Algorithmica Vol. 1 No. 2, pp. 251-266, 1986.).

     One of the applications of this algorithm is to calculate the difference of two text streams; see Calculate difference of text streams. このモジュールは、与えられた2つのシーケンスの最長共通サブシーケンスを見つけるアルゴリズムを実装しています。アルゴリズムは、Eugene Myersの O(ND)アルゴリズムに基づいています (Eugene Myers, An O(ND) Difference Algorithm and Its Variations, Algorithmica Vol. 1 No. 2, pp. 251-266, 1986.)。

     このアルゴリズムを使うアプリケーションの1つは、2つのテキストストリームの相違点を計算するCalculate difference of text streamsです。

 -- Function: lcs seq-a seq-b :optional eq-fn
     Calculates and returns the longest common sequence of two lists, SEQ-A and SEQ-B. Optional EQ-FN specifies the comparison predicate; if omitted, equal? is used. 2つのリスト、SEQ-AとSEQ-Bの最長共通シーケンスを計算して返します。オプションのEQ-FNでは、比較を行う述語を指定します。省略されると、equal?が使われます。

          (lcs '(x a b y) '(p a q b))
           => (a b)

 -- Function: lcs-with-positions seq-a seq-b :optional eq-fn
     This is the detailed version of lcs. The arguments are the same.

     Returns a list of the following structure: lcsの詳細バージョンです。引数は同じです。

     以下の構造のリストを返します。

          (LENGTH ((ELT A-POS B-POS) ...))

     LENGTH is an integer showing the length of the found LCS. What follows is a list of elements of LCS; each sublist consists of the element, the integer position of the element in SEQ-A, then the integer position of the element in SEQ-B. LENGTHは、見つかったLCS(最長共通サブシーケンス)の長さを表す整数です。それに続くのは、LCSの要素のリストで、その要素を構成するそれぞれのサブリスト、 SEQ-Aの中での要素の位置(整数)、SEQ-Bの中での要素の位置(整数) となります。

          (lcs-with-positions '(a) '(a))
           => (1 ((a 0 0)))

          (lcs-with-positions '(x a b y) '(p q a b))
           => (2 ((a 1 2) (b 2 3)))

          (lcs-with-positions '(x a b y) '(p a q b))
           => (2 ((a 1 1) (b 2 3)))

          (lcs-with-positions '(x y) '(p q))
           => (0 ())

 -- Function: lcs-fold a-proc b-proc both-proc seed a b :optional eq-fn
     A fundamental iterator over the "edit list" derived from two lists A and B.

     A-PROC, B-PROC, BOTH-PROC are all procedures that take two arguments.   The second argument is a intermediate state value of the calculation.  The first value is an element only in A for A-PROC, or an element only in B for B-PROC, or an element in both A and B for BOTH-PROC.  The return value of each procedure is used as the state value of the next call of either one of the procedures. SEED is used as the initial value of the state value. The last state value is returned from lcs-fold.

     The three procedures are called in the following order: Suppose the sequence A consists of A'CA'', and B consists of B'CB'', where A', B', A'', and B'' are subsequences, and C is the head of the LCS of A and B.   Then A-PROC is called first on each element in A', B-PROC is called second on each element in B', then BOTH-PROC is called on C. Afterwards, the process is repeated using A'' and B''. 2つのリストAとBから引き出された``編集リスト''に対する基本的なイテレータです。

     A-PROC、B-PROC、BOTH-PROCは全て2引数を取る手続きです。 2番目の引数は、計算の中間の値です。最初の値は、A-PROCではAにしかない要素、 B-PROCではBにしかない要素、BOTH-PROCではAとBの両方にある要素となります。それぞれの手続きが返す値は、次に呼び出される手続きのうちの1つの状態を表す値として使われます。SEEDは、状態を表す値の初期値として使われます。 lcs-foldが返す値は、最後の状態を表す値です。

     これらの3つの手続きは、以下の順番で呼ばれます。ここでは、シーケンスAは A'CA''、BはB'CB''となっているとすると、ここではA'、B'、A''、B''はサブシーケンスで、 CはAとBのLCSの先頭になります。そして、A-PROCはまず A'のそれぞれの要素に対して呼ばれ、B-PROCがB'のそれぞれの要素に対して呼ばれ、BOTH-PROCがCに対して呼ばれます。その後、このプロセスはA''とB''を使って繰り返されます。

 -- Function: lcs-edit-list a b :optional eq-fn
     Calculates 'edit-list' from two lists A and B, which is the smallest set of commands (additions and deletions) that changes A into B. This procedure is built on top of lcs-fold above.

     Returns a list of hunks, which is a contiguous section of additions and deletions.  Each hunk consists of a list of directives, which is a form of: 2つのリストAとBから``編集リスト''を計算します。それは、 AをBに変更するためのコマンド(追加と削除)の最小セットです。この手続きは、上のlcs-foldの上に構築されています。

          (+|- POSITION ELEMENT)

     Here's an example.  Suppose A and B are the following lists, respectively. 例を挙げます。AとBがそれぞれ以下のようなリストだとします。

          A == ("A" "B" "C" "E" "H" "J" "L" "M" "N" "P")
          B == ("B" "C" "D" "E" "F" "J" "K" "L" "M" "R" "S" "T")

     Then, (lcs-edit-list a b equal?) returns the following list. すると、(lcs-edit-list a b equal?)は以下のリストを返します。

          (((- 0 "A"))
           ((+ 2 "D"))
           ((- 4 "H") (+ 4 "F"))
           ((+ 6 "K"))
           ((- 8 "N") (- 9 "P") (+ 9 "R") (+ 10 "S") (+ 11 "T"))
          )

     The result consists of five hunks.  The first hunk consists of one directive, (- 0 "A"), which means the element "A" at the position 0 of list A has to be deleted. The second hunk also consists of one directive, (+ 2 "D"), meaning the element "D" at the position 2 of list B has to be added.  The third hunk means "H" at the position 4 of list A should be removed and "F" at the position 4 of list B should be added, and so on.

     If you are familiar with Perl's Algorithm::Diff module, you may notice that this is the same structure that its diff procedure returns. 結果は5つの片からなります。最初のものは1つのディレクティブ、(- 0 ``A'')からなり、これはリストAの位置0にある要素``A''が削除されることを意味します。 2番目のものはまた1つのディレクティブ、(+ 2 ``D'')からなり、これはリストBの位置2にある要素``D''が追加されることを意味します。 3番目のものは、リストAの位置4にある``H''は削除され、リストBの位置4にある``F''が追加される、などとなります。

     もしあなたがPerlのAlgorithm::Diffモジュールを良く知っていれば、そのdiff手続きが返すものと同じ構造だということが分かるでしょう。

util.levenshtein - Levenshtein edit distance
============================================

 -- Module: util.levenshtein
     This module provides procedures to calculate edit distance between two sequences.  Edit distance is the minimum number of edit operations required to match one sequence to another. Three algorithms are implemented: このモジュールは二つのシーケンスの間の編集距離を計算する手続きを提供します。編集距離とは、ひとつのシーケンスからもうひとつのシーケンスへと変更する編集操作の数です。3つのアルゴリズムが実装されています。

     Levenshtein distance
          Count deletion of one element, insertion of one element, and substitution of one element. 1要素の削除、1要素の追加、1要素の置き換えそれぞれを1操作と数えます。

     Damerau-Levenshtein distance
          Besides deletion, insertion and substitution, we allow transposition of adjacent elements. 削除、追加、置き換えに加え、隣合った要素の入れ替えも1操作と数えます。

     Restricted edit distance
          Also called optimal string alignment distance.  Like Damerau-Levenshtein, but once transposition is applied, no further editing on those elements are allowed. Optimal string alignmentとも呼ばれます。Damerau-Levenshteinと似ていますが、隣合った要素の入れ替えを行った場合、それらの要素は以降の編集を受けません。

     These algorithms are often used to compare strings, but the procedures in this module can handle any type of sequence (see Sequence framework). これらのアルゴリズムは文字列に対して使われることが多いですが、このモジュールの手続きはシーケンスになら何でも使えます (Sequence framework参照)。

 -- Function: l-distance seq-A seq-B :key elt= cutoff
 -- Function: l-distances seq-A seq-Bs :key elt= cutoff
 -- Function: re-distance seq-A seq-B :key elt= cutoff
 -- Function: re-distances seq-A seq-Bs :key elt= cutoff
 -- Function: dl-distance seq-A seq-B :key elt= cutoff
 -- Function: dl-distances seq-A seq-Bs :key elt= cutoff
     Calculates Levenshtein distance (l-*), restricted edit distance (re-*) and Damerau-Levenshtein distance (dl-*) between sequences, respectively.  Each algorithm comes in two flavors: The singular form *-distance takes two sequences, SEQ-A and SEQ-B, and calculates distance between them. The plural form *-distances takes a sequence SEQ-A and a list of sequences SEQ-BS, and calculates distances between SEQ-A and each in SEQ-BS. それぞれ、与えられたシーケンス間のLevenshtein距離(l-*)、 Restricted edit距離(re-*)およびDamerau-Levenshtein距離(dl-*)を計算します。アルゴリズム毎にふたつのAPIが提供されます。単数形の*-distanceは、二つのシーケンスSEQ-AとSEQ-Bを取り、両者の間の距離を計算します。複数形の*-distancesは、一つのシーケンスSEQ-AとシーケンスのリストSEQ-BSをとり、SEQ-BSの各シーケンスと SEQ-Aとの距離を計算します。

     If you need to calculate distances from a single sequence to many sequences, using the plural version is much faster than repeatedly calling the singular version, for the plural version can reuse internal data structures and save allocation and setup time. あるシーケンスと、多数のシーケンスとの間の距離を計算したいなら、単数形のAPIを繰り返し呼ぶより複数形のAPIを使う方が効率的です。複数形のAPIでは内部で使うデータ構造を再利用するので、重複するアロケーションと初期化の時間を節約できます。

     Sequences can be any object that satisfy the <sequence> protocol (see Sequence framework). シーケンスは、<sequence>プロトコルを満足するオブジェクトであれば何でも構いません (Sequence framework参照)。

     The keyword argument ELT= is used to compare elements in the sequences.  Its default is eqv?. キーワード引数ELT=はシーケンスの要素同士を比較するのに使われます。デフォルトはeqv?です。

     The keyword argument CUTOFF must be, if given, a nonnegative exact integer.  Once the possible minimum distance between two sequences becomes greater than this number, the algorithm stops and gives #f as the result, and moves on to the next calculation. This is useful when you run the algorithm on large set of sequences and you only need to look for the pairs closer than the certain limit. キーワード引数CUTOFFは非負の正確な整数でなければなりません。与えられた場合、二つのシーケンスの距離を比較していて、それがCUTOFF以上になることがわかったら、それ以上の計算を打ち切り#fを結果とします。これは、特にたくさんのシーケンスから、ごく限られた限度以下の距離を持つものを探す場合に便利です。

     In our implementation, Levenshtein is the fastest, Damerau-Levenshtein is the slowest and Restricted edit is somewhere inbetween.  If you don't need to take into account of transpositions, use Levenshtein; it counts 2 for cat -> act, while other algorithms yield 1 for it. If you need to consider transpositions, choose either re- or dl-.  The catch in re- is that it does not satisfy triangular inequality, i.e. for given three sequences X, Y and Z, (Damerau-)Levenshtein distance L always satisfy L(X;Z) <= L(X;Y) + L(Y;Z), but restricted edit distance doesn't guarantee that. 現在の実装ではだいたい、Levenshteinが最も速く、Damerau-Levenshteinが最も遅く、 Restricted editがその中間です。置換を1操作と考える必要がなければ、 Levenshteinを使うのが良いでしょう。catからactは Levenshtein距離では2ですが他の距離では1です。置換を1操作とする必要があれば、re-かdl-を使うことになります。re-の落とし穴は、それが三角不等式を満たさないことです。つまり、3つのシーケンスX, Y, Zがある時、 (Damerau-)Levenshtein距離Lは常に L(X;Z) <= L(X;Y) + L(Y;Z) を満たしますが、Restricted edit距離にはその保証がありません。

          (l-distance "cat" "act")  => 2
          (l-distances "cat" '("Cathy" "scathe" "stack")
            :elt= char-ci=?)
            => (2 3 4)

          (re-distance "cat" "act") => 1

          (re-distances "pepper"
            '("peter" "piper" "picked" "peck" "pickled" "peppers")
            :cutoff 4)
            => (2 2 4 4 #f 1)

          (dl-distance '(a b c d e) '(c d a b e)) => 4

     Note: If you pass a list of sequences to the second argument of the singular version by accident, you might not get an error immediately because a list is also a sequence. 註: 単数形のAPIの第2引数にうっかりシーケンスのリストを渡してしまった場合でも、直ちにエラーになるとは限らないことに注意。リスト自体もシーケンスだからです。

util.match - Pattern matching
=============================

 -- Module: util.match
     This module is a port of Andrew Wright's pattern matching macro library. It is widely used in the Scheme world, and ported to various Scheme implementations, including Chez Scheme, PLT Scheme, Scheme48, Chicken, and SLIB. It is similar to, but more powerful than Common Lisp's destructuring-bind. このモジュールは Andrew Wright のパターンマッチングマクロライブラリをポートしたものです。このライブラリは Scheme 界では広くつかわれており、 Chez Scheme、PLT Scheme、Scheme48、Chicken および SLIB を含む、様々な Scheme の実装にポートされています。この機能は Common Lisp の destructuring-bind に似ていますがより強力です。

     This version retains compatibility of the original Wright's macro, except (1) BOX is not supported since Gauche doesn't have one, and (2) structure matching is integrated to Gauche's object system. この版では、オリジナルの Wright's macro のマクロとの互換性が保たれています。ただし、例外がふたつあって、それは、(1) BOX はサポートされていません。Gauche にそれがないからです。(2) 構造のマッチングは Gauche のオブジェクトシステムに統合されています。

We show a list of APIs first, then the table of complete syntax of patterns, followed by examples. まず API のリストを示し、それからパターンの完全な構文のテーブルを示し、そして例を示します。

Pattern matching API
--------------------

パターンマッチング API
-------------

 -- Macro: match expr clause ...
     Each CLAUSE is either one of the followings: それぞれの CLAUSE は以下のうちどちらかです。

          (PAT BODY ...)
          (PAT (=> IDENTIFIER) BODY ...)

     First, the EXPR is matched against PAT of each clauses. The detailed syntax of the pattern is explained below. まず、EXPR を各節の PAT に照合します。パターンの詳しい構文については後述します。

     If a matching PAT is found, the pattern variables in PAT are bound to the corresponding elements in EXPR, then BODY ... are evaluated.  Then match returns the value(s) of the last expression of BODY .... PAT にマッチする部分が見つかれば、PAT 中の パターン変数は、EXPR 中の対応する要素に束縛され、その後、BODY ... が評価されます。matchはBODY ...の最後の式の値を返します。

     If the clause is the second form, IDENTIFIER is also bound to the failure continuation of the CLAUSE.  It is a procedure with no arguments, and when called, it jumps back to the matcher as if the matching of PAT is failed, and match continues to try the rest of clauses. So you can perform extra tests within BODY ... and if you're not satisfied you can reject the match by calling (IDENTIFIER).  See the examples below for more details. 節が 2つ目の形式である場合、IDENTIFIER は CLAUSE の失敗継続に束縛されます。これは引数をもたない手続きで、呼ばれると、あたかも、 PAT の照合に失敗したかの如くマッチャーに戻り、match が残りの節について試行を続けます。それゆえ、BODY ... 内部で追加のテストを実行することが可能で、もし、満足いくものでなければ、 (IDENTIFIER) を呼ぶことで、照合結果を拒絶することができます。より詳しくは、後述の例を見てください。

     If no PAT matches, match reports an error. どの PAT もマッチしなければ、match はエラーを報告します。

 -- Macro: match-lambda clause ...
     Creates a function that takes one argument and performs match on it, using CLAUSE ....  It's functionally equivalent to the following expression: ひとつの引数をとり、それに対して CLAUSE ... を用いて、 match を実行する関数を生成します。機能としては以下の式と同等です。

          (lambda (expr) (match expr CLAUSE ...))

     Example: 例:

          (map (match-lambda
                 ((item price-per-lb (quantity 'lbs))
                  (cons item (* price-per-lb quantity)))
                 ((item price-per-lb (quantity 'kg))
                  (cons item (* price-per-lb quantity 2.204))))
               '((apple      1.23 (1.1 lbs))
                 (orange     0.68 (1.4 lbs))
                 (cantaloupe 0.53 (2.1 kg))))
           => ((apple . 1.353) (orange . 0.952)
                      (cantaloupe . 2.4530520000000005))

 -- Macro: match-lambda* clause ...
     Like match-lambda, but performs match on the list of whole arguments. It's functionally equivalent to the following expression: match-lambda と同じですが、match をすべての引数のリストに対して実行します。機能としては以下の式と同等です。

          (lambda expr (match expr CLAUSE ...))

 -- Macro: match-let ((pat expr) ...) body-expr ...
 -- Macro: match-let name ((pat expr) ...) body-expr ...
 -- Macro: match-let* ((pat expr) ...) body-expr ...
 -- Macro: match-letrec ((pat expr) ...) body-expr ...
     Generalize let, let*, and letrec to allow patterns in the binding position rather than just variables. Each EXPR is evaluated, and then matched to PAT, and the bound pattern variables are visible in BODY-EXPR .... 束縛部分が単なる変数ではなく、パターンを許す、一般化された let、 let* および letrec です。各 EXPR が評価され、その後、PAT と照合され、束縛されたパターン変数が BODY-EXPR ... から見えるようになります。

          (match-let (
                       (((ca . cd) ...)   '((a . 0) (b . 1) (c . 2)))
                     )
            (list ca cd))
           => ((a b c) (0 1 2))

     If you're sick of parenthesis, try match-let1 below. 括弧はうんざりという向きには、以下の match-let1 をおためしあれ。

 -- Macro: match-let1 pat expr body-expr ...
     This is a Gauche extension and isn't found in the original Wright's code. This one is equivalent to the following code: これは Gauche での拡張で、オリジナルの Wright のコードにはありません。これは以下のコードと同等です。

          (match-let ((PAT EXPR)) BODY-EXPR ...)

     Syntactically, match-let1 is very close to the Common Lisp's destructuring-bind. 構文としては match-let1 は Common Lisp の destructuring-bind に非常によく似ています。

          (match-let1 ('let ((var val) ...) body ...)
                      '(let ((a b) (c d)) foo bar baz)
            (list var val body))
           => ((a c) (b d) (foo bar baz))

 -- Macro: match-define pat expr
     Like toplevel define, but allows a pattern instead of variables. トップレベルの define と同様ですが、変数の代りにパターンが許されます。

          (match-define (x . xs) (list 1 2 3))

          x  => 1
          xs => (2 3)

Pattern syntax
--------------

パターンの構文
-------

Here's a summary of pattern syntax. The asterisk (*) after explanation means Gauche's extension which does not present in the original Wright's code. ここにあるのはパターンの構文の要約です。説明の後にあるアスタリスク (*) はオリジナルの Wright のコードにはない、Gauche の拡張であることを意味します。

     pat : PATVAR                       ;; anything, and binds pattern var
         | _                            ;; anything
         | ()                           ;; the empty list
         | #t                           ;; #t
         | #f                           ;; #f
         | STRING                       ;; a string
         | NUMBER                       ;; a number
         | CHARACTER                    ;; a character
         | 'SEXP                        ;; an s-expression
         | 'SYMBOL                      ;; a symbol (special case of s-expr)
         | (PAT1 ... PATN)              ;; list of n elements
         | (PAT1 ... PATN . PATN+1)     ;; list of n or more
         | (PAT1 ... PATN PATN+1 ooo)   ;; list of n or more, each element
                                        ;;   of remainder must match PATN+1
         | #(PAT1 ... PATN)             ;; vector of n elements
         | #(PAT1 ... PATN PATN+1 ooo)  ;; vector of n or more, each element
                                        ;;   of remainder must match PATN+1
         | ($ CLASS PAT1 ... PATN)      ;; an object (PATK matches in slot order)
         | (struct CLASS PAT1 ... PATN) ;; ditto (*)
         | (@ CLASS (SLOT1 PAT1) ...)   ;; an object (using slot names) (*)
         | (object CLASS (SLOT1 PAT1) ...) ;; ditto (*)
         | (= PROC PAT)                 ;; apply proc, match the result to pat
         | (and PAT ...)                ;; if all of pats match
         | (or PAT ...)                 ;; if any of pats match
         | (not PAT ...)                ;; if all pats don't match at all
         | (? PREDICATE PAT ...)        ;; if predicate true and all pats match
         | (set! PATVAR)                ;; anything, and binds setter
         | (get! PATVAR)                ;; anything, and binds getter
         | `qp                          ;; a quasi-pattern

     patvar : a symbol except _, quote, $, struct, @, object, =, and, or,
              not, ?, set!, get!, quasiquote, ..., ___, ..k, __k.

     ooo : ...                          ;; zero or more
         | ___                          ;; zero or more
         | ..k                          ;; k or more, where k is an integer.
                                        ;;   Example: ..1, ..2 ...
         | __k                          ;; k or more, where k is an integer.
                                        ;;   Example: __1, __2 ...

     pat : PATVAR                       ;; 任意のオブジェクトにマッチし、patvarを束縛
         | _                            ;; 任意のオブジェクト
         | ()                           ;; 空リスト
         | #t                           ;; #t
         | #f                           ;; #f
         | STRING                       ;; 文字列
         | NUMBER                       ;; 数
         | CHARACTER                    ;; 文字
         | KEYWORD                      ;; キーワード (*)
         | 'SEXP                        ;; Ｓ式
         | 'SYMBOL                      ;; シンボル(Ｓ式の特殊ケース)
         | (PAT1 ... PATN)              ;; n 要素のリスト
         | (PAT1 ... PATN . PATN+1)     ;; n 以上の要素を含むリスト
         | (PAT1 ... PATN PATN+1 ooo)   ;; n 以上の要素を含むリスト、残りの各要素は
                                        ;; PATN+1 にマッチしなければならない
         | #(PAT1 ... PATN)             ;; n 要素のベクタ
         | #(PAT1 ... PATN PATN+1 ooo)  ;; n 以上の要素を含むベクタ、残りの各要素は
                                        ;; PATN+1 にマッチしなければならない
         | ($ CLASS PAT1 ... PATN)      ;; オブジェクト (PATK はスロット順でマッチ)
         | (struct CLASS PAT1 ... PATN) ;; 同上 (*)
         | (@ CLASS (SLOT1 PAT1) ...)  ;; オブジェクト (スロット名を使う) (*)
         | (object CLASS (SLOT1 PAT1) ...) ;; 同上 (*)
         | (= PROC PAT)                 ;; procを適用し、結果を pat にマッチさせる
         | (and PAT ...)                ;; すべての pat にマッチするか
         | (or PAT ...)                 ;; マッチする pat があるか
         | (not PAT ...)                ;; どの pat もマッチしないか
         | (? PREDICATE PAT ...)        ;; predicate が真、かつ、全 pat がマッチ
         | (set! PATVAR)                ;; 任意のオブジェクトにマッチし、セッタを束縛
         | (get! PATVAR)                ;; 任意のオブジェクトにマッチし、ゲッタを束縛
         | `qp                          ;; 擬似パターン

     patvar : a symbol except _, quote, $, struct, @, object, =, and, or,
              not, ?, set!, get!, quasiquote, ..., ___, ..k, __k.

     ooo : ...                          ;; ゼロまたはそれ以上
         | ___                          ;; ゼロまたはそれ以上
         | ..k                          ;; k またはそれ以上。kは整数。
                                        ;;   例: ..1, ..2 ...
         | __k                          ;; k またはそれ以上。kは整数。
                                        ;;   例: __1, __2 ...

  * A bare symbol is a "pattern variable"; it matches anything, and the matched part of the expression is bound to the symbol. The following symbols have special meanings and cannot be used as a pattern variable: _, quote, $, struct, @, object, =, and, or, not, ?, set!, get!, quasiquote, ..., ___, and ..k and __k where k is an integer. 素のシンボルは「パターン変数」で、あらゆるものとマッチし、式のマッチした部分がそのシンボルに束縛されます。以下のシンボルは特別な意味をもち、パターン変数としては使えません。 _、quote、$、struct、@、object、 =、and、or、not、?、set!、 get!、quasiquote、...、___ および ..k と __k (ここで、k は整数)。

  * A symbol _ matches anything, without binding a pattern variable. It can be used to show "don't care" placeholder. シンボル _ はあらゆるものマッチし、パターン変数は束縛しません。プレースホルダであることを示すのに用います。

  * Literals such as emptylist, booleans, strings, numbers, characters and keywords match the same object (in the sense of equal?). 空リスト、真偽値、文字列、数、文字およびキーワードのリテラルは (equal?という意味で)同じオブジェクトとマッチします。

  * Quoted expression matches the same expression (in the sense of equal?). You can use a quoted symbol to match the symbol itself. クウォートされた式は(equal? という意味で)同じ式とマッチします。クウォートされたシンボルをそれ自身とマッチさせるのに使えます。

  * A keyword, without a quote, used to match the same keyword object. Since we're in the process of unifying keywords and symbols, the user is recommended to write keywords with a quote in a pattern in order to match the keyword in the input.  See Keyword and symbol integration, for the details. キーワードは、以前はクオート無しで同じキーワードにマッチしていました。しかし現在は、キーワードとシンボルの統合に移行中なので、キーワードにマッチさせるためにパターンにキーワードを含める際には常にクオートしてください。詳しくはKeyword and symbol integration参照。

  * A list and a vector in general match a list or a vector whose elements matches the elements in the pattern recursively, unless the first element of the list is one of the special symbols listed above, it has a special meaning. 通常リストおよびベクタは、それぞれ、パターン中の要素にマッチする要素をもつリストまたはベクタとマッチします。ただし、最初の要素が上であげた特別なシンボルではない限りです。そのような場合には特別な意味を持ちます。

     As a special case, the last element of a vector or a list can be followed by a symbol ....  In that case, the pattern just before the symbol ... can be applied repeatedly until it consumes all the elements in the given expression.  A symbol ___ can be used in place of ...; it is useful when you want to produce a pattern by syntax-rules macro. 特別な場合として、ベクタあるいはリストの最後の要素のあとにシンボル ... を付加することができます。この場合には、... シンボル直前のパターンが与えられた式のすべての要素を尽すまで繰り返し適用されます。シンボル ___ は ... の場所で使えます。構文規則マクロによってパターンを生成したいときに便利です。

     For a list pattern, you can also use a symbol ..1, ..2, ..., which specifies the minimum number of repetition. リストのパターンに対しては、シンボル ..1、..2、... が使えます。これは繰り返しの最小値を指定するものです。

  * ($ class pat1 ...) matches an instance of a class class. Each pattern pat1 ... matches each value of slots, in order of (class-slots class) by default. (Records are exception; they match the same order as their default constructor since 0.9.6.) ($ class pat1 ...) は class クラスのインスタンスとマッチします。各パターン pat1 ... はデフォルトではスロットの各値と (class-slots class) の順にマッチします。 (レコードは例外で、0.9.6からデフォルトコンストラクタの順序と同じ順序になりました。)

     (struct class pat1 ...) has the same meaning.  Although the original Wright's code doesn't have struct, PLT Scheme has it in its extended match feature, and it is more descriptive. (struct class pat1 ...) は同じ意味です。オリジナルの Wright のコードには、struct はありませんが、PLT Scheme の拡張照合機能にはそなわっています。こちらの方がより説明的です。

     This is an adaptation of the original feature that can match structures. It is useful to match a simple instance that you know the order of slots; for example, a simple record created by define-record-type (see Record types) would be easy to match by positioned values. これはオリジナルの機能を構造(structure)にもマッチするように調整したものです。スロットの順番が予め分るような単純なインスタンスをマッチするのに便利です。たとえば、define-record-type (Record types参照)で作成した簡単なレコードは簡単に位置指定された値でマッチすることができます。

     If the instance's class uses inheritances, it is a bit difficult to match by positions.  You can use @ or object pattern below to match using slot names. インスタンスのクラスが継承を使っている場合、位置によるマッチをおこなうのは少々難しくなります。以下の @ あるいは object パターンを使って、スロット名でマッチを行うことができます。

  * (object class (slot1 pat1) ...) matches an instance of a class class whose value of SLOT1 ... matches PAT1 ....  This is Gauche's extension.  @ can be used in place of object, but object is recommended because of descriptiveness. (object class (slot1 pat1) ...) は SLOT1 ... の値が PAT1 ... にマッチするような class クラスのインスタンスとマッチします。これは、 Gauche の拡張です。@ は object と同じ場所で使えます。ただし、object の方が説明的でわかりやすいので、こちらを推奨します。

  * (= proc pat) first applies PROC to the corresponding expression, then match the result with PAT. (= proc pat) は最初に PROC を対応する式に適用し、その結果と PAT をマッチさせます。

  * (and pat ...), (or pat ...), and (not pat ...) are boolean operations of patterns. (and pat ...)、(or pat ...) および (not pat ...) はパターンの真偽値演算子です。

  * (? predicate pat ...) first applies a predicate to the corresponding expression, and if it returns true, applies each pat ... to the expression. (? predicate pat ...) は最初、述語を対応する式に適用し、真が返れば、各 pat ... をその式に適用します。

  * (set! patvar) matches anything, and binds an one-argument procedure to a pattern variable PATVAR.  If the procedure is called, it replaces the value of matched pattern for the given argument. (set! patvar) はあらゆるものにマッチし、一引数の手続きをパターン変数 PATVAR に束縛します。その手続きが呼ばれると、マッチしたパターンの値を与えられた引数で置き換えます。

  * (get! patvar) matches anything, and binds a zero-argument procedure to a pattern variable PATVAR.  If the procedure is called, it returns the matched value. (get! patvar) はあらゆるものにマッチし、引数なしの手続きをパターン変数 PATVAR に束縛します。その手続きが呼ばれると、マッチしたパターンの値を返します。

  * `qp is a quasipattern.  QP is quoted, in the sense that it matches itself, except the pattern that is unquoted. (Don't confuse quasipattern to quasiquote, though the functions are similar.  Quasiquote turns off evaluation except unquoted subtree. Quasiquote turns off the special pattern syntax except unquoted subtree. See the examples below). `qpはquasipatternです。QPは、クオートされたパターンと同様、それそのものにマッチしますが、その中にアンクオートされているパターンがあると、その部分だけは通常のパターンとして解釈されます。 (準クオート(quasiquote)とquasipatternを混同しないようにしてください。機能的に両者は似ていますが、準クオートがアンクオートされた部分木以外の部分の評価をoffにするのに対し、quasipatternはアンクオートされた部分木以外の部分のパターン構文を無効にします。下の例も参照して下さい。)

Pattern examples
----------------

パターン例
-----

A simple structure decomposition: 単純な構造の分解

     (match '(0 (1 2) (3 4 5))
       [(a (b c) (d e f))
        (list a b c d e f)])
      => (0 1 2 3 4 5)

Using predicate patterns: 述語パターンの使用

     (match 123
       [(? string? x) (list 'string x)]
       [(? number? x) (list 'number x)])
      => (number 123)

Extracting variables and expressions from let. Uses repetition and predicate patterns: let から変数と式を取り出す反復および述語パターンの利用

     (define let-analyzer
       (match-lambda
         [('let (? symbol?)
                ((var expr) ...)
            body ...)
          (format "named let, vars=~s exprs=~s" var expr)]
         [('let ((var expr) ...)
            body ...)
          (format "normal let, vars=~s exprs=~s" var expr)]
         [_
          (format "malformed let")]))

     (let-analyzer '(let ((a b) (c d)) e f g))
      => "normal let, vars=(a c) exprs=(b d)"

     (let-analyzer '(let foo ((x (f a b)) (y (f c d))) e f g))
      => "named let, vars=(x y) exprs=((f a b) (f c d))"

     (let-analyzer '(let (a) b c d))
      => "malformed let"

Using = function application.  The pattern variable M is matched to the result of application of the regular expression. = 関数適用。パターン変数 M は正規表現の適用結果にマッチする

     (match "gauche-ref.texi"
       ((? string? (= #/(.*)\.([^.]+)$/ m))
        (format "base=~a suffix=~a" (m 1) (m 2))))
      => "base=gauche-ref suffix=texi"

An example of quasipattern.   In the first expression, the pattern except value is quoted, so the symbols the, answer, and is are not pattern variables but literal symbols.   The second expression shows that; input symbol was does not match the literal symbol is in the pattern. If we don't use quasiquote, all symbols in the pattern are pattern variables, so any four-element list matches as the third expression shows. quasipatternの例です。最初の式では、パターンのうちvalue以外の部分がクオートされたことになり、従ってシンボルthe, answer, isはパターン変数ではなくリテラルシンボルとなります。 2番目の式がそのことを示しています。入力にあるシンボルwasはパターンのisとマッチしません。もしクオートを行わないと、全てのシンボルはパターン変数となるので、3番目の例に示すように任意の4つの要素を持つリストとマッチしてしまいます。

     (match '(the answer is 42)
       [`(the answer is ,value) value]
       [else #f])
      => 42

     (match '(the answer was 42)
       [`(the answer is ,value) value]
       [else #f])
      => #f

     (match '(a b c d)
       [(the answer is value) value]
       [else #f])
      => d

An example of matching records. The following code implements ``rotation'' operation to balance a red-black tree. レコードのマッチングの例です。次のコードは赤黒木をバランスさせる「ローテーション」操作を実装しています。

     (define-record-type T #t #t
       color left value right)

     (define (rbtree-rotate t)
       (match t
         [(or ($ T 'B ($ T 'R ($ T 'R a x b) y c) z d)
              ($ T 'B ($ T 'R a x ($ T 'R b y c)) z d)
              ($ T 'B a x ($ T 'R ($ T 'R b y c) z d))
              ($ T 'B a x ($ T 'R b y ($ T 'R c z d))))
          (make-T 'R (make-T 'B a x b) y (make-T 'B c z d))]
         [else t]))

util.record - SLIB-compatible record type
=========================================

 -- Module: util.record
     This module provides a Guile and SLIB compatible record type API. It is built on top of Gauche's object system.

     See also Record types, which provides a convenience macro define-record-type. このモジュールは、Guile と SLIB とに互換性のあるレコード型 API を提供します。これは、Gauche のオブジェクトシステム上に構築されています。

     便利なマクロ define-record-type を提供する Record types も参照してください。

 -- Function: make-record-type type-name field-names
     Returns a new class which represents a new record type. (It is what is called record-type descriptor in SLIB). In Gauche, the new class is a subclass of <record> (see Record types).

     TYPE-NAME is a string that is used for debugging purposes. It is converted to a symbol and set as the name of the new class. FIELD-NAMES is a list of symbols of the names of fields. Each field is implemented as a slot of the new class. あらしいレコード型を表わす新しいクラスを返します。 (これは SLIB では レコード型記述子とよばれているものです。) Gauche では、この新しいクラスは <record> のサブクラスです (Record types 参照)。

     TYPE-NAME はデバッグの目的で使われる文字列です。これは、シンボルに変換され、この新しいクラスの名前として設定されます。 FIELD-NAMES はフィールド名のシンボルのリストです。各々のフィールドはこの新しいクラスのスロットとして実装されます。

In the following procedures, RTD is the record class created by make-record-type. 以下の手続きでは、RTD は make-record-type によって生成されたクラスです。

 -- Function: record-constructor rtd :optional field-names
     Returns a procedure that constructs an instance of the record type of given RTD.  The returned procedure takes exactly as many arguments as FIELD-NAMES, which defaults to '().  Each argument sets the initial value of the corresponding field in FIELD-NAMES. 与えられた RTD レコード型のインスタンスを構築する手続きを返します。返された手続きは FIELD-NAMES とちょうど同じ数の引数をとります。FIELD-NAMES のデフォルトは '() です。それぞれの引数は FIELD-NAMES の対応するフィールドの初期値を設定します。

 -- Function: record-predicate rtd
     Returns a procedure that takes one argument, which returns #t iff the given argument is of type of RTD. 一つの引数をとり、与えられた引数が RTD と同じ型であり、その場合に限り #t を返す手続きを返します。

 -- Function: record-accessor rtd field-name
     Returns an accessor procedure for the field named by FIELD-NAME of type RTD.  The accessor procedure takes an instance of RTD, and returns the value of the field. RTD 型の FIELD-NAME によって名付けられたフィールドへのアクセサ手続きを返します。このアクセサ手続きは、RTD のインスタンスを一つとり、そのフィールドの値を返します。

 -- Function: record-modifier rtd field-name
     Returns a modifier procedure for the field named by FIELD-NAME of type RTD.  The modifier procedure takes two arguments, an instance of RTD and a value, and sets the value to the specified field. RTD 型の FIELD-NAME によって名付けられたフィールドへのモディファイア手続きを返します。このモディファイア手続きは、 RTD のインスタンスと値のふたつの引数をとり、その引数を指定されたフィールドに設定します。

     (define rtd (make-record-type "my-record" '(a b c)))

     rtd => #<class my-record>

     (define make-my-record (record-constructor rtd '(a b c)))

     (define obj (make-my-record 1 2 3))

     obj => #<my-record 0x819d9b0>

     ((record-predicate? rtd) obj)  => #t

     ((record-accessor rtd 'a) obj) => 1
     ((record-accessor rtd 'b) obj) => 2
     ((record-accessor rtd 'c) obj) => 3

     ((record-modifier rtd 'a) obj -1)

     ((record-accessor rtd 'a) obj) => -1

util.relation - Relation framework
==================================

 -- Module: util.relation
     Provides a set of common operations for relations. リレーションに対する共通の操作を提供します。

     Given set of values S1, S2, ..., Sn, a relation R is a set of tuples such that the first element of a tuple is from S1, the second from S2, ..., and the n-th from Sn.  In another word, R is a subset of Cartesian product of S1, ..., Sn. (The definition, as well as the term relation, is taken from the Codd's 1970 paper, "A Relational Model of Data for Large Shared Data Banks", in CACM 13(6) pp.377--387.) 値の集合を S1, S2, ..., Sn とするとリレーション R はタプルの集合で、タプルの最初の要素は S1 からの値で、2番目は S2 から、で n 番目は Sn からとなっている。いいかえれば、R は S1, ..., Sn の直積です。 (この定義とリレーションという用語は 1970年のCoddのペーパー "A Relational Model of Data for Large Shared Data Banks", in CACM 13(6) pp.377--387.によるものです。)

     This definition can be applied to various datasets: A set of Gauche object system instances is a relation, if you view each instance as a tuple and each slot value as the actual values.  A list of lists can be a relation.  A stream that reads from CSV table produces a relation. Thus it would be useful to provide a module that implements generic operations on relations, no matter how the actual representation is. この定義はいろいろなデータベースセットにあてはまります。各インスタンスをタプルとみなし、各スロット値を実際の値と見ると、Gaucheのオブジェクトシステムの集合はリレーションです。リストのリストもリレーションです。 CSVテーブルからの読み出しストリームはリレーションを生成します。このようことから、表現に依存しないリレーション上のジェネリックな操作を実装するモジュールを用意することは有意義です。

     From the operational point of view, we can treat any datastructure that provides the following four methods; relation-rows, which retrieves a collection of tuples (rows); relation-column-names, relation-accessor, and relation-modifier, which provide the means to access meta-information. All the rest of relational operations are built on top of those primitive methods. 操作という観点からいえば、以下の4つのメソッドがあれば、どのようなデータ構造もあつかえます。タプルのコレクション(行)を取り出す relation-rows、それから、relation-column-names、 relation-accessor、relation-modifier、これらはメタ情報にアクセスする方法を提供しています。これ以外のすべてのリレーション操作は上のプリミティブメソッドを使って組まれています。

     A concrete implementation of relation can use duck typing, i.e. it doesn't need to inherit a particular base class to use the relation methods.  However, for the convenience, a base class <relation> is provided in this module. It works as a mixin class---a concrete class typically wants to inherit <relation> and <collection> or <sequence>.  Check out the sample implementations in the lib/util/relation.scm in the source tree, if you're curious. リレーションの具体的な実装にはダックタイピングが適用できます。すなわち、リレーションメソッドを使うのに特定のベースクラスを継承する必要はありません。しかし、利便のためにこのモジュールには、ベースクラス <relation>が用意されています。これは、ミックスインクラスのような働きをします。具象クラスは典型的には<relation>および <collection>または<sequence>を継承することになるでしょう。興味があれば、ソースツリーにあるlib/util/relation.scmに含まれるサンプル実装をチェックするとよいでしょう。

     This module is still under development. The plan is to build useful relational operations on top of the common methods. このモジュールは現時点では開発途上にあります。計画では共通メソッド上に有用なリレーション操作関数群を構築することになっています。

Basic class and methods
-----------------------

基本となるクラスとメソッド
-------------

 -- Class: <relation>
     An abstract base class of relations. リレーションの抽象ベースクラス

 -- Method: relation-column-names (r <relation>)
     A subclass must implement this method. It should return a sequence of names of the columns. The type of column names is up to the relation; we don't place any restriction on it, as far as they are different each other in terms of equal?.

サブクラスではこのメソッドを必ず実装しなければなりません。カラムの名前のシーケンスを返す必要があります。カラム名の型はリレーションによります。equal?の意味で相互に異っているかぎり、カラム名について特に制限はありません。

 -- Method: relation-accessor (r <relation>)
     A subclass must implement this method. It should return a procedure that takes two arguments, a row from the relation R and a column name, and returns the value of the specified column. サブクラスではこのメソッドは必ず実装しなければなりまん。2つの引数をとり、リレーションRの行とカラム名をとり、指定したカラムの値を返す手続を返さなければなりません。

 -- Method: relation-modifier (r <relation>)
     A subclass must implement this method. It should returns a procedure that takes three arguments, a row from the relation R, a column name, and a value to set. サブクラスではこのメソッドは必ず実装しなければなりまん。 3つの引数、リレーションRの行、カラム名、値をとり、その値をセットする手続を返さなければなりません。

     If the relation is read-only, this method returns #f. リレーションが読み込み専用の場合はこのメソッドは#fを返します。

 -- Method: relation-rows (r <relation>)
     A subclass must implement this method. It should return the underlying instance of <collection> or its subclass (e.g.  <sequence>) サブクラスではこのメソッドは必ず実装しなければなりまん。基盤となっている<collection>クラスまたはそのサブクラス(たとえば <sequence>)のインスタンスを返さなければなりません。

The rest of method are built on top of the above four methods. A subclass of <relation> may overload some of the methods below for better performance, though. のこりのメソッドは上の4つのメソッドを使って組まれています。とはいえ、 <relation> のサブクラスでは以下のメソッドを性能を得るためにオーバーロードすることもできます。

 -- Method: relation-column-name? (r <relation>) column
     Returns true iff COLUMN is a valid column name for the relation R. COLUMNがリレーションRにおいて有効なカラム名である場合にのみ真を返します。

 -- Method: relation-column-getter (r <relation>) column
 -- Method: relation-column-setter (r <relation>) column
     Returns a procedure to access the specified column of a row from the relation R.  Relation-column-getter should return a procedure that takes one argument, a row. Relation-column-setter should return a procedure that takes two arguments, a row and a new value to set. リレーションRの行の指定したカラムにアクセスする手続を返します。 Relation-column-getterは、1つの引数、行をとる手続きを返さなければなりません。Relation-column-setterは2つの引数、行と新しくセットする値を取る手続きを返さなければなりません。

     If the relation is read-only, relation-column-setter returns #f. リレーションが読み込み専用の場合はrelation-column-setter は#fを返します。

 -- Method: relation-ref (r <relation>) row column :optional default
     ROW is a row from the relation R.  Returns value of the COLUMN in ROW.  If COLUMN is not a valid column name, DEFAULT is returned if it is given, otherwise an error is signaled. ROWはリレーションRの行です。ROWのCOLUMNの値を返します。COLUMNが不正なカラム名である場合、DEFAULTが与えられていればそれを返し、そうでなければ、エラーを示すシグナルがあがります。

 -- Method: relation-set! (r <relation>) row column value
     ROW is a row from the relation R.  Sets VALUE as the value of COLUMN in ROW.  This may signal an error if the relation is read-only. ROWはリレーションRの行です。VALUEをROWの COLUMNに設定します。リレーションが読み込み専用の場合にはエラーを示すシグナルがあがります。

 -- Method: relation-column-getters (r <relation>)
 -- Method: relation-column-setters (r <relation>)
     Returns full list of getters and setters.  Usually the default method is sufficient, but the implementation may want to cache the list of getters, for example. ゲッタとセッタの完全なリストを返します。通常はデフォルトのメソッドで十分ですが、たとえばゲッタのリストをキャッシュしたいときもあるでしょう。

 -- Method: relation-coercer (r <relation>)
     Returns a procedure that coerces a row into a sequence. If the relation already uses a sequence to represent a row, it can return row as is. 行をシーケンスに変換する手続きを返します。行がすでにシーケンスで表現されているリレーションであれば、行をそのまま返す手続きです。

 -- Method: relation-insertable? (r <relation>)
     Returns true iff new rows can be inserted to the relation R. リレーションRに新しい行を挿入可能な場合にのみ真を返します。

 -- Method: relation-insert! (r <relation>) row
     Insert a row ROW to the relation R. リレーションRに行ROWを挿入します。

 -- Method: relation-deletable? (r <relation>)
     Returns true iff rows can be deleted from the relation R. リレーションRから行を削除可能である場合にのみ真を返します。

 -- Method: relation-delete! (r <relation>) row
     Deletes a row ROW from the relation R. リレーションRから行ROWを削除します。

 -- Method: relation-fold (r <relation>) proc seed column ...
     Applies PROC to the values of COLUMN ... of each row, passing SEED as the state value.  That is, for each row in R, PROC is called as follows: PROCを各行のカラムCOLUMN ... の値に適用します。 SEEDは状態の値として渡されます。すなわち、リレーションRの各行ごとに以下のようにPROCを呼びます。

          (PROC V_0 V_1 ... V_I SEED)

           where V_K = (relation-ref R ROW COLUMN_K)

     The result of the call becomes a new seed value, and the final result is returned from RELATION-FOLD. 呼び出しの結果があたらしいシードの値となり、最終の結果が RELATION-FOLDから返ります。

     For example, if a relation has a column named amount, and you want to sum up all of them in a relation R, you can write like this: たとえば、リレーションが amount という名前のカラムをもつものとし、リレーション R 内にあるそのカラムをすべて足しあわせたいとすると以下のように書けます。

          (relation-fold r + 0 'amount)

Concrete classes
----------------

具象クラス
-----

 -- Class: <simple-relation>

 -- Class: <object-set-relation>

util.stream - Stream library
============================

 -- Module: util.stream
     This module provides a library of lazy streams, including the functions and syntaxes defined in srfi-40 and srfi-41, the latter of which became a part of R7RS large (as (scheme stream),

     Gauche has a built-in lazy sequences (see Lazy sequences), which is a lazy stream integrated to a list so that you can use all list procedures on it.  Lazy streams provided in this module are somewhat heavier than lazy sequences and you need to use special procedures, but it is strictly lazy (while a lazy sequence evaluates one element ahead) and portable. このモジュールは遅延ストリームのライブラリを提供します。このモジュールにはsrfi-40とsrfi-41で定義されている関数および構文が含まれています。後者は(scheme stream)としてR7RS largeの一部になっています。

     Gaucheには遅延ストリームとリストを統合したような、組み込みの遅延シーケンスがあります (Lazy sequences)参照。そちらは通常のリスト手続きを使って扱うことができます。このモジュールで提供される遅延ストームは、遅延シーケンスより重く、扱うために専用の手続きが必要です。ただ、要素の評価は必要になるぎりぎりまで遅延され (遅延シーケンスでは必要な要素のひとつ先まで評価されます)、またポータブルです。

Stream primitives
-----------------

 -- Function: stream? obj
     [R7RS stream] Returns #t iff OBJ is a stream created by a procedure of util.stream. OBJがutil.streamの手続きによって作成されたストリームである場合にかぎり#tを返します。

 -- Variable: stream-null
     [R7RS stream] The singleton instance of NULL stream. NULLストリームのシングルトンインスタンス。

 -- Macro: stream-cons object stream
     [R7RS stream] A fundamental constructor of a stream.  Adds OBJECT to the head of a STREAM, and returns a new stream. ストリームの基本構成子。OBJECTをSTREAMの先頭に追加し、新しいストリームを返します。

 -- Function: stream-null? obj
     [R7RS stream] Returns #t iff OBJ is the null stream. OBJがNULLストリームの場合にのみ#tを返します。

 -- Function: stream-pair? obj
     [R7RS stream] Returns #t iff OBJ is a non-null stream. OBJがNULLストリームではないストリームのときにのみ#tを返します。

 -- Function: stream-car s
     [R7RS stream] Returns the first element of the stream S. ストリームSの最初の要素を返します。

 -- Function: stream-cdr s
     [R7RS stream] Returns the remaining elements of the stream S, as a stream. ストリームSの最初の要素を除いた残りの要素をストリームとして返します。

 -- Macro: stream-delay expr
     [SRFI-40] Returns a stream which is a delayed form of EXPR. EXPRの遅延形式であるストリームを返します。

     As a rule of thumb, any stream-producing functions should wrap the resulting expression by stream-delay. (Or you can use stream-lambda, stream-let or stream-define, described below.) 原則として、ストリームを生成する関数はすべからく結果を stream-delayでラップすべきです。 (以下に述べるstream-lambda, stream-let, stream-defineを使う手もあります)。

 -- Macro: stream-lambda formals body body2 ...
     [R7RS stream] A convenience macro to create a function that returns a stream. Effectively, (stream-lambda formals body body2 ...) is the same as (lambda formals (stream-delay body body2 ...)). ストリームを返す関数を作る簡易マクロです。 (stream-lambda formals body body2 ...)は (lambda formals (stream-delay body body2 ...))と同じです。

Stream constructors
-------------------

 -- Function: stream obj ...
     [SRFI-40] Returns a new stream whose elements are OBJ .... 要素がOBJ ...であるような新しいストリームを返します。

     Note: This differs from srfi-41's (scheme.stream's) stream, which is a macro so that arguments are lazily evaluated.  Srfi-41's stream is provided as stream+ in this module. 註：これはsrfi-41 (scheme.stream)のstreamとは異なります。 srfi-41の方はマクロで、引数の評価が遅延されます。srfi-41版はこのモジュールでは stream+と言う名前で提供されます。

          (stream 1 2 3))     => a stream that contains (1 2 3)
          (stream 1 (/ 1 0))) => error

 -- Macro: stream+ expr ...
     Returns a new stream whose elements are the result of EXPR ....

     This is the same as srfi-41(scheme.stream)'s stream. Each EXPR isn't evaluated until it is accessed. 要素がEXPR ...の結果であるような新たなストリームを作って返します。

     これはsrfi-41(scheme.stream)のstreamと同じです。各EXPRはアクセスされるまで評価されません。

          (define s (stream+ 1 (/ 1 0)))  ;; doesn't yield an error

          (stream-car s)  => 1

          (stream-cadr s) => error

 -- Function: stream-unfold f p g seed
     [R7RS stream] Creates a new stream whose element is determined as follows:

       * A ``go'' predicate P is called on the current seed value. If it yields #f, the stream terminates.

       * Otherwise, (f s) is the element of the stream, and (g s) becomes the next seed value, where s is the current seed value.  The initial seed value is given by SEED.

     Note: Unfortunately, the order of arguments differs from other *-unfold procedures, which takes p f g (predicate, value-generator and seed-generator).  Furthermore, the predicate is stop-predicate (returning true stops iteration). 次の手順で生成される要素をもつ新たなストリームを作成して返します。

       * 「続行」述語Pが現在のシード値を引数として呼ばれます。もし#fが返されたら、ストリームはそこで終了です。

       * そうでなければ、sを現在のシード値として、(f s)をストリームの現在の要素とし、(g s)を次のシード値とします。 SEEDはシード値の初期値を与えます。

     註：残念なことに、この手続きは他の *-unfold 系手続きと異なる順序で引数を取ります。他の手続きはp f g (述語、値生成、シード生成) の順です。さらに、他の手続きでは述語は停止する時に真を返します。

          (stream->list
           (stream-unfold integer->char (cut < <> 58) (cut + 1 <>) 48))
           => (#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9)

 -- Function: stream-unfoldn f seed n
     [SRFI-40] Creates N streams related each other, whose contents are generated by F and SEED. 互いに関連する N 本のストリームを生成します。それぞれの内容は FおよびSEEDを使って生成します。

     The F is called with the current seed value, and returns N+1 values: Fは現在のシード値とともに呼ばれ、N+1個の値を返します。

          (F SEED)
            => seed result_0 result_1 ... result_n-1

     The first value is to be the next seed value. RESULT_K must be one of the following forms:

     (val)
          VAL will be the next car of K-th stream.

     #f
          No new information for K-th stream.

     ()
          The end of K-th stream has been reached.

     最初の値は次のシード値になります。RESULT_Kは以下の形式のどれかでなければなりません。

     (val)
          VALはK-番目のストリームの次のcar部になります。

     #f
          K-番目のストリームの新しい情報はありません。

     ()
          K-番目のストリームの最後に到達しました。

     The following example creates two streams, the first one produces an infinite series of odd numbers and the second produces evens. 以下の例では2つのストリームが作られます。最初のものは奇数の無限ストリームで、2つめのものは偶数の無限ストリームです。

          gosh> (define-values (s0 s1)
                  (stream-unfoldn (lambda (i)
                                    (values (+ i 2)          ;; next seed
                                            (list i)         ;; for the first stream
                                            (list (+ i 1)))) ;; for the second stream
                                  0 2))
          #<undef>
          gosh> (stream->list (stream-take s0 10))
          (0 2 4 6 8 10 12 14 16 18)
          gosh> (stream->list (stream-take s1 10))
          (1 3 5 7 9 11 13 15 17 19)

 -- Function: stream-unfolds f seed
     [R7RS stream] Like stream-unfoldn, but the number of created streams is determined by the number fo return values from F.  See stream-unfoldn above for the details. stream-unfoldnと似ていますが、結果のストリームの数は Fの戻り値の数により決定されます。詳しくは上のstream-unfoldnの説明を参照してください。

 -- Function: stream-constant obj ...
     [R7RS stream] Returns an infinite stream that repeats OBJ .... OBJ ...を繰り返す無限ストリームを返します。

          (stream->list 10 (stream-constant 1 2))
            => (1 2 1 2 1 2 1 2 1 2)

 -- Function: make-stream n :optional init
     Creates a new stream of N elements of INIT. If INIT is omitted, #f is used. Specifying a negative number to N creates an infinite stream. N個のINITを要素とする新しいストリームを生成します。 INITが省略された場合#fが使われます。Nを負の値にすると無限ストリームが生成されます。

 -- Function: stream-tabulate n init-proc
     Creates a new stream of N elements. The K-th element is obtained by applying INIT-PROC to K.  Specifying a negative number to N creates an infinite stream. N個の要素をもつ新しいストリームを生成します。K-番目の要素は INIT-PROC を K に適用して得られます。Nを負の値にすると無限ストリームが生成されます。

 -- Function: stream-iota :optional count start step
     Creates a new stream of numbers, starting from START and incrementing STEP.  The length of stream is maximum integer not greater than nonnegative real number COUNT. The default values of count, START and STEP are +inf.0, 0 and 1, respectively.

     If START and STEP are exact, and COUNT is exact or infinite, a sequence of exact numbers are created.  Otherwise, a sequence of inexact numbers are created. STARTからはじまり、STEPずつ要素が増加する数値のストリームを生成します。ストリームの長さは非負の実数COUNTを越えない最大の整数値です。 COUNT, START, STEPのデフォルト値はそれぞれ +inf.0, 0 および 1です。

     STARTとSTEPが正確数で、COUNTが正確数か無限大の場合、正確数のストリームが作られます。そうでなければ非正確数のストリームになります。

 -- Function: stream-range start :optional end step
     [R7RS stream] Creates a new stream of real numbers, starting from START and stops before END, stepping by STEP. If END is omitted, positive infinity is assumed. If STEP is omitted, 1 is assumed if END is greater than START, and -1 if END is less than START.

     The generated numbers are exact if START and STEP are exact and END is either exact or infinite.  Otherwise, inexact numbers are generated.

     In R7RS scheme.stream, END argument is required. STARTから始まりSTEPおきにENDの手前まで続く実数のストリームを作って返します。ENDが省略された場合は正の無限大が使われます。 STEPが省略された場合、STARTがENDより小さければ1が、大きければ-1が使われます。

     STARTとSTEPが正確数で、ENDが正確数か無限大の場合は、正確数のシーケンスが、そうでない場合は非正確数のシーケンスが生成されます。

     R7RSのscheme.streamでは、END引数は必須です。

          (stream->list (stream-range 0 10))
           => (0 1 2 3 4 5 6 7 8 9)

 -- Function: stream-from start :optional step
     [R7RS stream] This is yet another number sequence generator.  Generates an infinite sequence whose I-th element is (+ START (* i STEP)). If STEP is omitted, 1 is assumed.  If both START and STEP are exact, exact numbers are generated.  Otherwise, inexact numbers are generated. もうひとつの数値シーケンス生成手続きです。I番目の項が (+ START (* i STEP))であるような無限シーケンスを返します。 STEPが省略されたら1が使われます。 STARTとSTEPが正確数なら、正確数のシーケンスが、そうでなければ非正確数のシーケンスが返されます。

 -- Function: stream-iterate f seed
     [R7RS stream] Returns a stream starting from SEED, and each successive element is calculated by (F S) where S is the previous element. SEEDを初期値とし、ひとつ前の要素Sから次の要素を(F S)で計算するような無限長のストリームを返します。

          (stream->list 5 (stream-iterate (cut cons 'x <>) '()))
            => (() (x) (x x) (x x x) (x x x x))

     See also literate in gauche.lazy (see Lazy sequence utilities). gauche.lazyのliterateも参照 (Lazy sequence utilities).

 -- Function: stream-xcons a b
     (stream-cons b a).  Just for convenience. (stream-cons b a)のこと。利便性のためだけにある。

 -- Function: stream-cons* elt ... stream
     Creates a new stream which appends ELT ... before STREAM. STREAMの前にELT ...を連結した新しいストリームを生成します。

 -- Function: list->stream list
     [R7RS stream] Returns a new stream whose elements are the elements in LIST. LISTの要素を要素とする新たなストリームを作って返します。

 -- Function: string->stream string :optional tail-stream
     Converts a string to a stream of characters.  If an optional TAIL-STREAM is given, it becomes the tail of the resulting stream. 文字列を文字のストリームに変換します。TAIL-STREAMが与えられた場合は、文字ストリームの後にそれが付け加えられます。

     (stream->list (string->stream "abc" (list->stream '(1 2 3)))) => (#\a #\b #\c 1 2 3)

 -- Function: stream-format fmt arg ...
     Returns a stream which is a result of applying string->stream to (format fmt arg ...). string->streamを(format fmt arg ...)に適用した結果のストリームを返します。

 -- Function: port->stream :optional iport reader closer
     [R7RS stream] Creates a stream, whose elements consist of the items read from the input port IPORT. The default IPORT is the current input port. The default READER is read-char.

     The result stream terminates at the point where READER returns EOF (EOF itself is not included in the stream). The port won't be closed by default when it reaches EOF.

     If CLOSER is given, it is called with IPORT as an argument just after READER reads EOF.  You can close the port with it.

     The READER and CLOSER arguments are Gauche's extension. R7RS scheme.stream only takes one optional argument, IPORT. IPORTからREADERを使って読み出されるデータを要素とする新たなストリームを作って返します。IPORTのデフォルトは現在の入力ポート、 READERのデフォルトはread-charです。

     READERがEOFを返したらストリームの終端となります (EOF自体はストリームには含まれません)。 EOFに達してもポートはクローズされません。

     もしCLOSER引数が与えられたら、それがIPORTを引数として EOFが読まれた直後に呼ばれます。そこでポートをクローズするこはできます。

     READERとCLOSER引数はR7RSのscheme.streamでは定義されない、Gaucheの拡張です。

 -- Function: generator->stream gen
     Creates a lazy stream of values generated by a generator GEN. A generator is a thunk that returns a value every time it is called, with returning EOF to indicate the end of the input. See Generators, for the details of generators. ジェネレータGENが生成する値の列からなる遅延ストリームを作って返します。ジェネレータは引数を取らない手続きで、呼ばれる度に値を返し、EOFを返すことで終端を示すものです(EOFはストリームには含まれません)。詳しくはGeneratorsを参照してください。

     See also generator->lseq, which is another way to get a lazy sequence from a generator (see Lazy sequences, for the details). 似た手続きに、ジェネレータから遅延シーケンスを得るgenerator->lseqもあります(Lazy sequences参照)。

 -- Function: iterator->stream iter
     A generic procedure to turn an internal iterator ITER into a stream of iterated results. イテレータITERから遅延シーケンスを作る手続きです。

     The ITER argument is a procedure that takes two arguments, NEXT and END, where NEXT is a procedure that takes one argument and END is a thunk. ITER is supposed to iterate over some set and call NEXT for each argument, then call END to indicate the end of the iteration.  Here's a contrived example: ITERは二つの引数NEXTとENDを取る手続きです。 NEXTは一つの引数を取る手続き、ENDは引数を取らない手続きです。 ITER手続きは、その中で何らかの値の集合に対して順にNEXT手続きを呼び、最後にEND手続きを呼びます。次はわざとらしい例です:

          (stream->list
           (iterator->stream
            (lambda (next end) (for-each next '(1 2 3 4 5)) (end))))
           => (1 2 3 4 5)

     Internally iterator->stream uses the ``inversion of iterator'' technique, so that ITER only iterates to the element that are needed by the stream.  Thus ITER can iterate over an infinite set.  In the following example, ITER is an infinite loop calling NEXT with increasing integers, but only the first 10 elements are calculated because of stream-take: 内部的に、iterator->streamはいわゆる「イテレータの反転」テクニックを使っていて、ITERは必要なだけしかイテレーションを行いません。なので ITERは無限の要素を扱うこともできます。例えば次の例では、ITERは増加する整数に対してNEXTを無限に呼び出すようになっていますが、stream-takeによって最初の10要素しか計算されません。

          (stream->list
           (stream-take
            (iterator->stream
             (lambda (next end)
               (let loop ((n 0)) (next n) (loop (+ n 1)))))
            10))
           => (0 1 2 3 4 5 6 7 8 9)

 -- Macro: stream-of elt-expr clause ...
     [R7RS stream] Stream comprehension.  Returns a stream in which each element is computed by ELT-EXPR. The CLAUSE creates scope of ELT-EXPR and controls iterations.  Each CLAUSE can be one of the following forms: ストリーム内包表記。各要素がELT-EXPRで計算されるストリームを返します。 CLAUSEはELT-EXPRのスコープを作り、繰り返しを制御します。各CLAUSEは以下の形のいずれかです：

     (X in STREAM-EXPR)
          Iterate over STREAM-EXPR, binding X to each element in each iteration.  The variable X is visible in successive CLAUSEs and ELT-EXPR STREAM-EXPRが返すストリームの各要素を、Xに束縛して繰り返します。変数Xのスコープは後続のCLAUSEおよびELT-EXPRです。

     (X is EXPR)
          Bind a variable X with the value of EXPR.  The variable X is visible in successive CLAUSEs and ELT-EXPR. 変数Xに値EXPRの結果を束縛します。Xのスコープは後続のCLAUSEおよびELT-EXPRです。

     expr
          If EXPR evaluates to #f, this iteration is skipped without generating a new element. EXPRが#fに評価されたらこの回は値を生成せずに打ちきられ、次の繰り返しに進みます。

     The following comprehension generates infinite sequence of pythagorean triples: 次の内包表記はピタゴラス数の無限シーケンスを生成します：

          (define pythagorean-triples
            (stream-of (list a b c)
              (c in (stream-from 3))
              (b in (stream-range 2 c))
              (a in (stream-range 1 b))
              (= (square c) (+ (square b) (square a)))))

          (stream->list 5 pythagorean-triples)
            => ((3 4 5) (6 8 10) (5 12 13) (9 12 15) (8 15 17))

Stream binding
--------------

 -- Macro: define-stream (name . formals) body body2 ...
     [R7RS stream] A convenient macro to define a procedure that yields a stream. Same as the following form: ストリームを作って返す関数を手軽に定義するマクロです。次のフォームと同じです:

          (define (name . formals)
            (stream-delay
              (let () body body2 ...)))

 -- Macro: stream-let loop-var ((var init) ...) body body2 ...
     [R7RS stream] A handy macro to write a lazy named-let loop.  It is the same as the following: lazyなnamed-letによるループを書くときに便利なマクロです。次のフォームと同じです:

          (let loop-var ((var init) ...)
            (stream-delay
              (let () body body2 ...)))

 -- Macro: stream-match stream-expr clause ...
     [R7RS stream] This allows accessing streams via simple pattern matching. The STREAM-EXPR argument is evaluated and must yield a stream. Each CLAUSE must be either a form of (PATTERN EXPR) or (PATTERN FENDER EXPR).

     The content of the stream is matched to each PATTERN, which must have one of the following forms: このマクロは簡単なパターンマッチングを使ってストリームの要素にアクセスします。 STREAM-EXPRはストリームを返す式でなければなりません。各CLAUSEは(PATTERN EXPR)か (PATTERN FENDER EXPR)という形です。

     入力ストリームは各PATTERNに順マッチするかどうかテストされます。 PATTERNには以下の形のいずれかです:

     ()
          Matches a null stream. 空のストリームとマッチします。

     (P0 P1 ...)
          Matches a stream that has exactly the same number of elements as the number of pattern elements. パターン内の要素の数と入力ストリームの要素数が一致した時にマッチします。

     (P0 P1 ... . PREST)
          Matches a stream that has at least the same number of elements as the number of pattern elements except PREST.  The rest of stream matches with PREST. 入力ストリームの要素数が、PRESTを除いたパターン内の要素の数以上であればマッチします。PRESTにはストリームの残りがマッチします。

     PREST
          Matches an entire stream. 入力ストリーム全体とマッチします。

     Each pattern element can be an identifier or a literal underscore.  If it is an identifier, it is bound to the matched element while evaluating the corresponding FENDER and EXPR. パターンの各要素は識別子かリテラルのアンダースコア_です。アンダースコア以外の識別子の場合は、それらが対応する入力ストリームの要素に束縛された環境でFENDERとEXPRが評価されます。

     If FENDER is present in the CLAUSE, it is evaluated; if it yields #f, the match of the clause fails and next clauses will be tried. もしFENDERがあれば、まずそれが評価され、#fであったらそのCLAUSEのマッチは失敗となり、次のCLAUSEが試されます。

     Otherwise, EXPR is evaluated and the result(s) becomes the result(s) of stream-match. そうでなければEXPRが評価され、その結果がstream-matchの結果となります。

     Only the elements from the stream that is required to match are accessed. 入力ストリームの要素はマッチに必要なだけ取り出されます。

     The following example defines a procedure to count the number of true values in the stream: 次の例は、ストリーム中の真の値の数を数えています:

          (define (num-trues strm)
            (stream-match strm
              (() 0)
              ((head . tail) head (+ 1 (num-trues tail)))
              ((_ . tail) (num-trues tail))))

          (num-trues (stream #f #f #t #f #t #f #t #t))
            => 4

Stream consumers
----------------

These procedures takes stream(s) and consumes its/their elements until one of the streams is exhausted. これらの手続きはストリームを取り、その要素を消費し尽します。

 -- Function: stream-for-each func . streams
     [R7RS stream] Applies FUNC for each element of STREAMS. Terminates if one of STREAMS reaches the end. FUNCをSTREAMSの各要素に適用します。 STREAMSが終端に達したところで停止します。

 -- Function: stream-fold f seed stream
     [R7RS stream] Apply F on the current seed value and an element from STREAM to obtain the next seed value, and repeat it until STREAM is exhausted, then returns the last seed value. The initial seed value is given by SEED.

     Note: The argument order of F differs from other *-fold procedures, e.g. fold (see Walking over lists) takes the element first, then the seed value. Fを現在のシード値とSTREAMの要素に適用し、その結果を次のシード値として STREAMが終端に達するまで繰り返します。最初のシード値はSEED引数で与えられます。最後のシード値が返されます。

     註: Fの引数順は、他の*-fold系関数のそれと異なることに注意してください。例えばfold (Walking over lists参照) では最初に要素、次にシード値が渡されます。

          (stream-fold - 0 (stream 1 2 3 4 5))
            => -15

Stream operations
-----------------

 -- Function: stream-append stream ...
     [R7RS stream] Returns a new stream which is concatenation of given STREAMs. 与えられたSTREAMを全部つないだ新たなストリームを返します。

 -- Function: stream-concat streams
 -- Function: stream-concatenate streams
     [R7RS stream] R7RS scheme.stream defines stream-concat.  Gauche had stream-concatenate, and keeps it for the backward compatibility. Both are the same.

     The STREAMS argument is a stream of streams.  Returns a new stream that is concatenation of them.  Unlike stream-append, STREAMS can generate infinite streams. R7RS scheme.streamはstream-concatを定義しました。 Gaucheにはstream-concatenateがあったので互換性のためにそちらも残しています。どちらも同じです。

     STREAMSはストリームのストリームです。各ストリームを連結したストリームを作って返します。stream-appendと違い、STREAMSは無限個のストリームを生成することができます。

 -- Function: stream-map func stream stream2 ...
     [R7RS stream] Returns a new stream, whose elements are calculated by applying FUNC to each element of STREAM .... STREAMSの各要素にFUNCを適用した値を要素とする新しいストリームを返します。

 -- Function: stream-scan func seed stream
     [R7RS stream] Returns a stream of SEED, (FUNC SEED E0), (FUNC (FUNC SEED E0) E1), ..., where E0, E1 ... are the elements from the input STREAM. If STREAM is finite, the result stream has one more elements than the number of elements in the original stream. SEED、 (FUNC SEED E0)、 (FUNC (FUNC SEED E0) E1) ... で構成されるストリームを返します。ここで E0、E1 ...は入力ストリームSTREAMの要素です。 STREAMが有限なら、その要素よりひとつ多い要素が出力ストリームには含まれます。

          (stream->list
            (stream-scan xcons '() (stream 1 2 3 4 5)))
           => (() (1) (2 1) (3 2 1) (4 3 2 1) (5 4 3 2 1))

 -- Function: stream-zip stream ...
     [R7RS stream] Returns a new stream whose elements are lists of corresponding elements from input STREAMs.  The output stream ends when one of input streams is exhausted. 入力ストリームの対応する要素のリストを要素とするストリームを作って返します。入力ストリームのいずれかが終端に達した時に出力ストリームも終わります。

          (stream->list
           (stream-zip (stream 1 2 3) (stream 'a 'b 'c 'd)))
           => ((1 a) (2 b) (3 c))

 -- Function: stream-filter pred stream
     [R7RS stream] Returns a new stream including only elements passing PRED. PREDをパスする要素のみからなる新しいストリームを返します。

 -- Function: stream-remove pred stream
     Returns a new stream including only elements that doesn't satisfy PRED. 述語PREDを満たさない要素のみからなる新しいストリームを返します。

 -- Function: stream-partition pred stream
     Returns two streams, one consists of the elements in STREAM that satisfy PRED, the other consists of the ones that doesn't satisfy PRED. 二つのストリームを返します。最初のストリームはSTREAMの要素のうち述語PREDを満たすもの、次のストリームはPREDを満たさないもので構成されます。

 -- Function: stream->list stream
 -- Function: stream->list n stream
     [R7RS stream] Converts a stream to a list.  In the first form, all elements from STREAM are taken (thus it never returns if STREAM is infinite). In the second form, at most N elements are taken, where N must be a nonnegative exact integer.

     Note: In usual Scheme conventions, the optional N comes after the main argument (STREAM). ストリームをリストに変換します。最初の形式では、STREAMの全ての要素が取り出されます (従ってSTREAMが無限ストリームであればこの関数は永遠に戻りません)。二番めの形式では最大でN要素までがストリームから取り出されそのリストが返されます。 Nは非負の正確な整数でなければなりません。

     註:通常のSchemeの慣例では、省略可能なNはSTREAMの後に来ますが、この関数はそうでないことに注意。

 -- Function: stream->string stream
     Converts a stream to a string. All elements of STREAM must be characters, or an error is signaled. ストリームを文字列に変換します。 STREAMの全ての要素は文字でなければなりません。そうでない場合はエラーが投げられます。

 -- Function: stream-lines stream
     Splits STREAM where its element equals to #\n, and returns a stream of splitted streams.  The character #\n won't be included in the results. STREAMを、文字#\nが要素である箇所で分割し、分割されたストリームのストリームを返します。#\n自体は結果に含まれません。

          (stream->list
           (stream-map stream->string
                       (stream-lines (string->stream "abc\ndef\nghi"))))
           => ("abc" "def" "ghi")

 -- Function: stream= elt= stream ...
     Returns true iff each corresponding element of STREAM ... are the same in terms of ELT=, which takes two arguments. This procedure won't terminate if all of STREAMs is infinite. 引数のストリームの全ての対応する要素がそれぞれ、2引数を取るELT=で比較して等しい場合に #tを、そうでなければ#fを返します。全てのSTREAMが無限である場合、この手続きは終了しません。

 -- Function: stream-prefix= stream prefix :optional elt=
     Compares initial elements of STREAM against a list PREFIX by ELT=.  Returns true iff they match. Only as many elements of STREAM as PREFIX has are checked. STREAMの最初の方の要素をリストPREFIXと比較します。各要素は ELT=で比較されます。PREFIXと全てマッチしたら#tを、そうでなければ#fを返します。最大でもPREFIXの要素分だけSTREAMから要素が取り出されます。

 -- Function: stream-caar s
 -- Function: stream-cadr s
     ...

 -- Function: stream-cdddar s
 -- Function: stream-cddddr s
     (stream-caar s) = (stream-car (stream-car s)) etc.

 -- Function: stream-ref stream pos
     [R7RS stream] Returns the POS-th element in the stream.  POS must be a nonnegative exact integer. ストリームのPOS番目の要素を返します。POSは非負の正確な整数でなければなりません。

 -- Function: stream-first s
 -- Function: stream-second s
 -- Function: stream-third s
 -- Function: stream-fourth s
 -- Function: stream-fifth s
 -- Function: stream-sixth s
 -- Function: stream-seventh s
 -- Function: stream-eighth s
 -- Function: stream-ninth s
 -- Function: stream-tenth s
     (stream-first s) = (stream-ref s 0) etc.

 -- Function: stream-take stream count
 -- Function: stream-take-safe stream count
     Returns a new stream that consists of the first COUNT elements of the given stream.   If the given stream has less than COUNT elements, the stream returned by stream-take would raise an error when the elements beyond the original stream is accessed.  On the other hand, the stream returned by stream-take-safe will return a shortened stream when the given stream has less than COUNT elements.

          (stream->list (stream-take (stream-iota -1) 10))
           => (0 1 2 3 4 5 6 7 8 9)

          (stream-take (stream 1 2) 5)
           => stream

          (stream->list (stream-take (stream 1 2) 5))
           => error

          (stream->list (stream-take-safe (stream 1 2) 5))
           => (1 2)

     Note: srfi-41 (scheme.stream) also defines stream-take, but the argument order is reversed, and also it allows STREAM to have less than count elements.

 -- Function: stream-drop stream count
 -- Function: stream-drop-safe stream count
     Returns a new stream that consists of the elements in the given stream except the first COUNT elements. If the given stream has less than COUNT elements, stream-drop returns a stream that raises an error if its element is accessed, and stream-drop-safe returns an empty stream.

     Note: srfi-41 (scheme.stream) also defines stream-drop, but the argument order is reversed, and also it allows STREAM to have less than count elements.

 -- Function: stream-intersperse stream element
     Returns a new stream in which ELEMENT is inserted between elements of STREAM.

 -- Function: stream-split stream pred
     Split STREAM on elements that satisfy PRED, and returns a stream of splitted streams.  The delimiting element won't be included in the result.

 -- Function: stream-last stream
     Returns the last element of STREAM.  If STREAM is infinite, this procedure won't return.

 -- Function: stream-last-n stream count
     Returns a stream that contains the last COUNT elements in STREAM.  The COUNT argument must be a nonnegative exact integer.  If the length of STREAM is smaller than COUNT, the resulting stream is the same as STREAM. If STREAM is infinite, this procedure won't return.

 -- Function: stream-butlast stream
     Returns a stream which is the same as STREAM but without the last element.  If STREAM is empty, an empty stream is returned.

 -- Function: stream-butlast-n stream count
     Returns a stream which is the same as STREAM but without the last COUNT elements.  The COUNT argument must be a nonnegative exact integer.  If STREAM is shorter than COUNT, a null stream is returned.

 -- Function: stream-length stream
     [R7RS stream] Returns the number of elements in STREAM.  It diverges if STREAM is infinite.

 -- Function: stream-length>= stream n
 -- Function: stream-length= stream n
     Returns true iff the length of STREAM is greater than or equal to, and exactly equal to, N, respectively. These procedures only realizes STREAM up to N elements.

 -- Function: stream-reverse stream :optional tail-stream
     [R7RS stream] Returns a stream that returns the elements of STREAM in reverse order. If TAIL-STREAM is given, it is added after the reversed stream.

     The optional argument is Gauche's extension.  The description of reverse (see Other list procedures) for more details. STREAMの要素を逆順にしたストリームを返します。TAIL-STREAMが与えられた場合、逆順にしたストリームの後にそれ付け加えられます。

     省略可能なTAIL-STREAMはGaucheの拡張です。詳しくは reverseの説明を参照してください (Other list procedures)。

 -- Function: stream-count pred stream ...

 -- Function: stream-find pred stream

 -- Function: stream-find-tail pred stream

 -- Function: stream-take-while pred stream
     [R7RS stream]

 -- Function: stream-drop-while pred stream
     [R7RS stream]

 -- Function: stream-span pred stream

 -- Function: stream-break pred stream

 -- Function: stream-any pred stream ...

 -- Function: stream-every pred stream ...

 -- Function: stream-index pred stream ...

 -- Function: stream-member obj stream :optional elt=
 -- Function: stream-memq obj stream
 -- Function: stream-memv obj stream

 -- Function: stream-delete obj stream :optional elt=

 -- Function: stream-delete-duplicates stream :optional elt=

 -- Function: stream-grep re stream

 -- Function: write-stream stream :optional oport writer

util.toposort - Topological sort
================================

 -- Module: util.toposort
     Implements topological sort algorithm. トポロジカルソートのアルゴリズムを実装します。

 -- Function: topological-sort graph :optional eqproc
     GRAPH represents a directed acyclic graph (DAG) by a list of connections, where each connection is the form

          (<node> <downstream> <downstream2> ...)

     that means a node <node> is connected to other nodes <downstream> etc.   <node> can be arbitrary object, as far as it can be compared by the procedure EQPROC, which is EQV? by default (see Equality). Returns a list of <node>s sorted topologically.

     If the graph contains circular reference, an error is signaled. GRAPHは有向非循環グラフ(DAG)を表現するリストです。リストの各要素は次の形をしています。

          (<node> <downstream> <downstream2> ...)

     これで、ノード<node>から別のノード<downstream>等への接続があることを表現します。<node>はどんなオブジェクトであっても構いませんが、同一性の判定がEQPROCで行えなければなりません。EQPROCの既定値は eqv?です (Equality参照)。トポロジカルにソートされたノードのリストを返します。

     グラフに循環が検出された場合はエラーとなります。

util.unification - Unification
==============================

 -- Module: util.unification
     Implements unification algorithm. ユニフィケーションのアルゴリズムを実装します。

     The base API operates on abstract trees, while it is agnostic to the actual representation of the tree. The caller passes comparators and operators along the trees to unify. 基本APIは、抽象的な木に対して動作しますが、木が実際にどう実装されているかは関知しません。呼び出し側は、ユニファイする木といっしょに、比較器や操作手続きを渡します。

     We assume the abstract tree has the following structure: 抽象的な木は、次の構造を持っていると考えます。

          Tree : Variable | Value | Tuple
          Tuple : { Tree ... }

     Here, {...} just represents a sequence of trees. ここで、{...}は単に木の並びを表します。

     A variable can be bound to a tree.  A value can only match itself. 変数(Variable)は木に束縛されます。値(Value)はそれ自身とのみマッチします。

     To operate on this tree, we need the following comparators and procedures, which the API takes as arguments: この木を扱うために、APIは以下の比較器と手続きを引数として取ります。

     Variable comparator: var-cmpr
          A comparator to see if an item is a variable, and also check equality of two variables.  It must be hashable. See Basic comparators, for the details of comparators. 要素が変数であるかどうかを調べ、また二つの変数が同じかどうかを判定するための比較器です。ハッシュ可能でなければなりません。比較器についてはBasic comparatorsを参照してください。

     Value comparator: val-cmpr
          A comparator to see if an item is a value, and also check equality of two values. Note that if a tree satisfies neither VAR-CMPR nor VAL-COMPR, it is regarded as a tuple. 要素が値であるかどうかを調べ、また二つの値が等しいかどうかを判定するための比較器です。VAR-CMPRもVAL-CMPRも満たさない要素はタプルであるとみなされます。

     Tuple folder: tuple-fold
          A procedure (tuple-folde proc seed tuple1 [tuple2]). This procedure should work like fold (see Walking over lists) over the elements in the tuple(s).  It is only called with either one or two tuples. (tuple-folde proc seed tuple1 [tuple2])の形で呼び出される手続きです。この手続きは、タプル中の要素についてfoldのように動作します (Walking over lists参照)。常にひとつかふたつのタプルを引数とします。

     Tuple constructor: make-tuple
          A procedure (make-tuple proto elements), where PROTO is a tuple and ELEMENTS are a list of trees. It must return a new tuple with the given elements, while all other properties are the same as PROTO. This procedure isn't needed by unify. (make-tuple proto elements)の形式で呼び出される手続きです。 PROTOはタプルで、ELEMENTSは木のリストです。 PROTOと同じ型のタプルで、要素だけをELEMENTSと置き換えた新たなタプルを作成して返します。 unifyはこの手続きを必要としません。

 -- Function: unify a b var-cmpr val-cmpr tuple-fold
     Unify two trees A and B and returns a substitution dictionary, which is a dictionary that maps variables to its bounded trees. 二つの木、AとBを単一化し、置換辞書を返します。置換辞書は、変数をその値にマップするものです。

     See the entry of util.unification above for the description of VAR-CMPR, VAL-CMPR and TUPLE-FOLD. 引数VAR-CMPR、VAL-CMPR、TUPLE-FOLDに関しては上のutil.unificationの説明を参照してください。

          (dict->alist (unify '(a 3 (c b)) '(c b (2 e))
                              symbol-comparator
                              number-comparator
                              fold))
           => ((e . 3) (a . c) (b . 3) (c . 2))

     As you can see in the example above, a variable may be mapped to another variable, or even to a tree that contains variables.  If you apply the substitution to the original tree, you must do it recursively until all the variables in the dictionary is eliminated. この例にも見られるように、一つの変数の値が別の変数であったり、別の変数を含む木であったりする場合があります。元の木に置換を適用する場合は、辞書にある変数がすべて消去されるまで再帰的に置換を行う必要があります。

     If two trees cannot be unified, #f is returned. 二つの木が単一化できない場合は#fが返されます。

          (unify '(a (a)) '(x x) symbol-comparator number-comparator fold)
           => #f

 -- Function: unify-merge a b var-cmpr val-cmpr tuple-fold make-tuple
     Unify two trees A and B, and apply the result substitutions to create a new tree eliminating variables. 二つの木、AとBを単一化し、結果の置換を適用して変数を消去した新たな木を返します。

     See the entry of util.unification above for the description of VAR-CMPR, VAL-CMPR, TUPLE-FOLD and MAKE-TUPLE. 引数VAR-CMPR、VAL-CMPR、TUPLE-FOLD、MAKE-TUPLEに関しては上のutil.unificationの説明を参照してください。

          (unify-merge '(a 3 (c b)) '(c b (2 e))
                       symbol-comparator
                       number-comparator
                       fold
                       (^[_ elts] elts))
           => (2 3 (2 3))

     If two trees can't be unified, #f is returned. 二つの木が単一化できなければ、#fが返されます。

www.cgi - CGI utility
=====================

 -- Module: www.cgi
     Provides a few basic functions useful to write a CGI script.

     In order to write CGI script easily, you may want to use other modules, such as rfc.uri (see URI parsing and construction), text.html-lite (see Simple HTML document construction) and text.tree (see Lazy text construction).

     Note: it seems that there is no active formal specification for CGI. See http://w3c.org/CGI/ for more information. CGIスクリプトを書くのに便利ないくつかの基本的な手続きを提供します。

     CGIスクリプトを手軽に書くにはこのモジュールの他に、 rfc.uri (URI parsing and construction)、 text.html-lite (Simple HTML document construction)、 text.tree (Lazy text construction) 等のモジュールを併せて使うとよいでしょう。

     注：現在有効な、CGIに関する「正式な」仕様というのはどうも無いようです。 http://w3c.org/CGI/あたりを参照して下さい。

Metavariables
-------------

メタ変数
----

 -- Parameter: cgi-metavariables :optional metavariables
     Normally, httpd passes a cgi program various information via environment variables. Most procedures in www.cgi refer to them (meta-variables). However, it is sometimes inconvenient to require environment variable access while you're developing cgi-related programs. With this parameter, you can overrides the information of meta-variables.

     METAVARIABLES should be a list of two-element lists. Car of each inner list names the variable, and its cadr gives the value of the variable by string.

     For example, the following code overrides REQUEST_METHOD and QUERY_STRING meta-variables during execution of my-cgi-procedure.  (see Parameters, for the details of parameterize). 通常、httpdはcgiプログラムに様々な情報を環境変数経由で渡します。 www.cgi中の多くの手続きはその情報(メタ変数)を参照します。しかし、cgiに関連するプログラムを開発中に環境変数にアクセスするのは不便な場合もあります。このパラメータを使うと、メタ変数をオーバライドすることができます。

     METAVARIABLESは2要素のリストのリストです。内側のリストは、最初の要素が変数名を、2つめの要素がその値を、それぞれ文字列で与えます。

     例えば次のコードはREQUEST_METHODと QUERY_STRINGのメタ変数をmy-cgi-procedureの実行期間中に上書きします。(parameterizeの詳細については Parametersを参照して下さい)。

          (parameterize ((cgi-metavariables '(("REQUEST_METHOD" "GET")
                                              ("QUERY_STRING" "x=foo"))))
            (my-cgi-procedure))

 -- Function: cgi-get-metavariable name
     Returns a value of cgi metavariable NAME. This function first searches the parameter cgi-metavariables, and if the named variable is not found, calls sys-getenv.

     CGI scripts may want to use cgi-get-metavariable instead of directly calling sys-getenv; doing so makes reuse of the script easier. NAMEで指定されるCGIメタ変数の値を返します。この関数はまずパラメータcgi-metavariablesを探し、指定されたメタ変数が見つからなければsys-getenvを呼びます。

     CGIスクリプトは、なるべくsys-getenvを直接呼ぶのではなく cgi-get-metavariableを使うのが良いでしょう。スクリプトの再利用もしやすくなります。

Parameter extraction
--------------------

パラメータの取得
--------

 -- Function: cgi-parse-parameters :key :query-string :merge-cookies :part-handlers
     Parses query string and returns associative list of parameters. When a keyword argument QUERY-STRING is given, it is used as a source query string.  Otherwise, the function checks the metavariable REQUEST_METHOD and obtain the query string depending on the value (either from stdin or from the metavariable QUERY_STRING). If such a metavariable is not defined and the current input port is a terminal, the function prompts the user to type parameters; it is useful for interactive debugging. CGIプログラムに渡されたquery stringをパーズして、パラメータの連想リストにして返します。文字列がキーワード引数QUERY-STRINGに与えられればそれがパーズすべき query stringとなります。その引数が渡されなければこの手続きはメタ変数REQUEST_METHODを参照し、その値によって標準入力もしくはメタ変数QUERY_STRINGからquery stringが取られます。そのようなメタ変数が定義されておらず、かつ現在の入力ポートが端末である場合、インタラクティブにデバッグをしているものと考えて、この手続きはプロンプトを出してユーザにパラメータの入力を促します。

     If REQUEST_METHOD is POST, this procedure can handle both application/x-www-form-urlencoded and multipart/form-data as the enctype.  The latter is usually used if the form has file-uploading capability.

     When the post data is sent by multipart/form-data, each content of the part is treated as a value of the parameter. That is, the content of uploaded file will be seen as one big chunk of a string.  The other information, such as the original file name, is discarded.   If it is not desirable to read entire file into a string, you can customize the behavior by the PART-HANDLER argument.  The details are explained in the "Handling file uploads" section below. REQUEST_METHODがPOSTの場合、この手続きはenctypeとして application/x-www-form-urlencodedとmultipart/form-dataの両方を処理できます。後者は通常、ファイルアップロード機能を持つフォームに使われます。

     POSTデータがmultipart/form-dataで送られて来た場合、各パートの内容がパラメータの値となります。すなわち、アップロードされたファイルはその内容がひとつの文字列として得られることになります。元のファイル名のようなその他の情報は捨てられます。これが望ましい動作でない場合は、PART-HANDLERS引数によって動作をカスタマイズすることができます。詳しくは下の「ファイルアップロードの処理」で説明します。

     When a true value is given to MERGE-COOKIES, the cookie values obtained from the metavariable HTTP_COOKIE are appended to the result. キーワード引数MERGE-COOKIESに真の値が与えられた場合は、メタ変数HTTP_COOKIEからクッキーの値が読まれ、解析されて結果に追加されます。

     Note that the query parameter may have multiple values, so cdr of each element in the result is a list, not an atom. If no value is given to the parameter, #t is placed as its value. See the following example: パラメータは複数の値を取り得るため、結果のパラメータに対応する値は常にリストになります。パラメータに値が与えられていなければ、結果のパラメータに対する値には#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 :key :default :list :convert
     A convenient function to obtain a value of the parameter NAME from parsed query string PARAMS, which is the value cgi-parse-parameters returns.  NAME should be a string. cgi-parse-parametersが返す、パーズされたQuery文字列PARAMSから、名前NAMEを持つパラメータの値を簡単に取り出すための手続きです。 NAMEは文字列です。

     Unless true value is given to LIST, the returned value is a scalar value.  If more than one value is associated to NAME, only the first value is returned.  If LIST is true, the returned value is always a list, even NAME has only one value. キーワード引数LISTに真の値が与えられていなければ、返される値はスカラー値です。パラメータNAMEに複数の値が与えられた場合でも、最初の値のみが返されます。LISTに真の値が与えられれば、返されるのは常に値のリストとなります。

     After the value is retrieved, you can apply a procedure to convert the string value to the appropriate type by giving a procedure to the CONVERT argument.  The procedure must take one string argument.  If LIST is true, the convert procedure is applied to each values. キーワード引数CONVERTに手続きを与えると、対応する値が取り出された後でその手続きが値を引数として呼ばれます。これによって値を文字列から必要な型へと変換することができます。LISTに真の値が与えられている場合、変換手続きは各値に対して呼ばれ、その結果のリストがCGI-GET-PARAMETERから返されます。

     If the parameter NAME doesn't appear in the query, a value given to the keyword argument DEFAULT is returned; the default value of DEFAULT is #f if LIST is false, or () otherwise. パラメータNAMEがQuery中に現れなかった場合は、 DEFAULTに与えられた値がそのまま返されます。DEFAULTが省略された場合、LISTが偽であれば#fが、真であれば()が返されます。

Output generation
-----------------

出力の生成
-----

 -- Function: cgi-header :key status content-type location cookies
     Creates a text tree (see Lazy text construction) for the HTTP header of the reply message.  The most simple form is like this: HTTPリプライメッセージのヘッダを、テキストツリー形式(Lazy text construction参照) で作成して返します。最も簡単な呼び出しでは次のようになります。

          (tree->string (cgi-header))
            => "Content-type: text/html\r\n\r\n"

     You can specify alternative content-type by the keyword argument CONTENT-TYPE.   If you want to set cookies to the client, specify a list of cookie strings to the keyword argument COOKIES. You can use construct-cookie-string (see HTTP cookie handling) to build such a list of cookie strings. キーワード引数CONTENT-TYPEによってContent typeを指定できます。また、COOKIESにクッキー文字列のリストを渡すことにより、クライアントにクッキーを設定できます。クッキー文字列を構築するには手続き construct-cookie-string (HTTP cookie handling参照) が使えます。

     The keyword argument LOCATION may be used to generate a Location: header to redirect the client to the specified URI. You can also specify the Status: header by the keyword argument STATUS.   A typical way to redirect the client is as follows: キーワード引数LOCATIONは、Locationヘッダを作成してクライアントを別のURIに誘導するのに使えます。また、Statusヘッダを指定するためにSTATUSキーワード引数が使えます。クライアントを別URIに転送するよくある方法は次のようなものです。

          (cgi-header :status "302 Moved Temporarily"
                      :location target-uri)

 -- Parameter: cgi-output-character-encoding :optional encoding
     The value of this parameter specifies the character encoding scheme (CES) used for CGI output by cgi-main defined below. The default value is Gauche's native encoding. If the parameter is set other than the native encoding, cgi-main converts the output encoding by gauche.charconv module (see Character code conversion). このパラメータの値は次に説明するcgi-mainが出力するデータの文字符合化法(CES)を指定します。デフォルトの値はGaucheのネイティブエンコーディングです。それ以外の値がセットされている場合、cgi-mainは gauche.charconvモジュールを用いて出力のエンコーディングの変換を行います。 (Character code conversion参照)。

Convenience procedures
----------------------

便利な手続き
------

 -- Function: cgi-main proc :key on-error merge-cookies output-proc part-handlers
     A convenient wrapper function for CGI script. This function calls cgi-parse-parameters, then calls PROC with the result of cgi-parse-parameters. The keyword argument MERGE-COOKIES is passed to cgi-parse-parameters. CGIスクリプトのための便利なラッパー手続きです。この手続きは、まずcgi-parse-parametersを呼び出してCGIスクリプトに渡されたパラメータを解析し、続いてその結果を引数としてPROCを呼び出します。キーワード引数MERGE-COOKIESは、与えられればそのまま cgi-parse-parametersに渡されます。

     PROC has to return a tree of strings (see Lazy text construction), including the HTTP header. cgi-main outputs the returned tree to the current output port by write-tree, then returns zero. 手続きPROCはHTTPヘッダを含むドキュメントをテキストツリー構造(Lazy text construction参照)で返さなければなりません。cgi-mainはそれをwrite-treeを使って現在の出力ポートに書き出し、0を返します。

     If an error is signaled in PROC, it is caught and an HTML page reporting the error is generated.  You can customize the error page by providing a procedure to the ON-ERROR keyword argument. The procedure takes an <condition> object (see Conditions), and has to return a tree of string for the error reporting HTML page, including an HTTP header. もしPROC内でエラーが起こった場合、そのエラーは捕捉されて、エラーを報告する HTMLページが作成されて出力されます。このエラーページは、ON-ERRORキーワード引数に手続きを渡すことでカスタマイズできます。ON-ERRORに渡された手続きはエラー発生時に<condition>オブジェクト(Conditions参照) を引数として呼ばれ、HTTPヘッダを含むドキュメントをテキストツリー構造で返さねばなりません。

     When output the result, cgi-main refers to the value of the parameter cgi-output-character-encoding, and converts the character encoding if necessary. cgi-mainは最終的な結果を出力を書き出す時にパラメータcgi-output-character-encodingを参照し、必要ならば出力の文字エンコーディングを変換します。

     The output behavior of cgi-main can be customized by a keyword argument OUTPUT-PROC; if it is given, the text tree (either the normal return value of PROC, or an error page constructed by the error handler) is passed to the procedure given to OUTPUT-PROC.  The procedure is responsible to format and output a text to the current output port, including character conversions, if necessary. cgi-mainの出力のふるまいはキーワード引数OUTPUT-PROCでカスタマイズできます。OUTPUT-PROCが渡された場合、それは PROCの戻り値、あるいはエラーハンドラが作成したテキストツリー構造を受け取る手続きでなければなりません。その手続きはテキストツリーをフォーマットして現在の出力ポートに出力しなければなりません。必要ならば文字エンコーディングの変換もその手続き内で行います。

     The keyword argument PART-HANDLERS are simply passed to cgi-parse-parameters, by which you can customize how the file uploads should be handled.  See the "Handling file uploads" section below for the details.

     If you specify to use temporary file(s) by it, cgi-main makes sure to clean up them whenever PROC exits, even by error.   See cgi-add-temporary-file below to utilize this feature for other purpose. キーワード引数PART-HANDLERSは、そのままcgi-parse-parameters に渡されます。この引数によって、ファイルアップロードの際の動作をカスタマイズできます。詳しくは下の「ファイルアップロードの処理」の項を参照して下さい。

     この引数で、一時ファイルを使うように指定した場合、cgi-mainは PROCから抜ける際に(エラーでも正常終了でも)一時ファイルを消去します。この機能を他でも利用するにはcgi-add-temporary-fileの項を参考にして下さい。

     Before calling PROC, cgi-main changes the buffering mode of the current error port to :line (See port-buffering in Common port operations for the details about the buffering mode). This makes the error output easier for web servers to capture. PROCを呼ぶ前に、cgi-mainはカレントエラーポートのバッファリングモードを:lineに変更します。 (バッファリングモードの詳細についてはCommon port operationsの port-bufferingの項を参照してください)。これはwebサーバがcgiスクリプトのエラー出力を捕捉しやすくするためです。

     The following example shows the parameters given to the CGI program. 以下の例は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))))
                 ))))

 -- Function: cgi-add-temporary-file filename
     This is supposed to be called inside PROC of cgi-main. It registers FILENAME as a temporary file, which should be unlinked when PROC exits.  It is a convenient way to ensure that your cgi script won't leave garbages even if it throws an error. It is OK in PROC to unlink or rename FILENAME after calling this procedure. この手続きはcgi-mainに渡されるPROC中で呼ばれることを想定しています。この手続きは、FILENAMEを一時ファイルとして登録し、PROCが終了する際に消去されるようにします。cgiスクリプトがエラー終了した場合などでもごみを残さないようにする便利な方法です。この手続きを呼んだ後で、PROCがFILENAMEを消去したり名前を変えたりしても構いません。

 -- Parameter: cgi-temporary-files
     Keeps a list of filenames registered by cgi-add-temporary-file. cgi-add-temporary-fileで登録された一時ファイルを保持するパラメータです。

Handling file uploads
---------------------

ファイルアップロードの処理
-------------

As explained in cgi-parse-parameters above, file uploads are handled transparently by default, taking the file content as the value of the parameter.   Sometimes you might want to change this behavior, for the file might be quite big and you don't want to keep around a huge chunk of a string in memory.  It is possible to customize handling of file uploads of cgi-parse-parameters and cgi-main by PART-HANDLERS argument. (The argument is only effective for the form data submitted by multipart/form-data enctype) cgi-parse-parametersの項で説明したように、ファイルアップロードはデフォルトでは透過的に扱われます。すなわち、アップロードされたファイルの内容がパラメータの値となります。これは望みの動作ではないかもしれません。例えばアップロードされるファイルが巨大であることが予想されるなら、それを全てメモリに読み込んで持ち回りたくはないかもしれません。cgi-parse-parametersやcgi-mainの PART-HANDLERS引数によって、ファイルアップロードの処理をカスタマイズすることが可能です。 (この引数は、フォームデータがmultipart/form-data enctypeで送られた場合にのみ意味を持ちます)。

The PART-HANDLERS argument is, if given, a list of lists; each inner list is a form of (NAME-PATTERN ACTION KV-LIST ...). Each uploaded file with a matching parameter name with NAME-PATTERN is handled according to ACTION.  (Here, a parameter name is the 'name' attribute given to the input element in the submitted form, not the name of the uploaded file). PART-HANDLERS引数が与えられている場合、それはリストのリストで、内部のリストは(NAME-PATTERN ACTION KV-LIST ...) の形式でなければなりません。アップロードされたファイルは、そのパラメータ名がNAME-PATTERNにマッチした場合にACTIONで指示されるように処理されます。 (ここで、パラメータ名とはsubmitされたフォームのinput要素に与えられた 'name'属性のことです。アップロードされたファイルの名前ではありません)。

NAME-PATTERN must be either a list of string (matches one of them), a regexp, or #t (matches anything). NAME-PATTERNは文字列のリストか、正規表現か、#tです。文字列のリストの場合はそれのいずれかとパラメータ名が等しければマッチとみなされます。#tは全てのものにマッチします。

ACTION must be either one of the followings:

#f
     Default action, i.e. the content of the uploaded file is turned into a string and becomes the value of the parameter.

ignore
     The uploaded content is discarded.

file
     The uploaded content is saved in a temporary file.  The value of the parameter is the pathname of the temporary file.

     For this action, you can write an entry like (NAME-PATTERN file PREFIX), to specify the prefix of the pathname of the temporary file.  For example, if you specify ("image" file "/var/mycgi/incoming/img"), the file uploaded as "image" parameter will be stored as something like /var/mycgi/incoming/img49g2Ua.

     The application should move the temporary file to appropriate location; if you're using cgi-main, the temporary files created by this action will be unlinked when cgi-main exits.

file+name
     Like file, but the value of the parameter is a list of temporary filename and the filename passed by the client. It is useful if you want to use client's filename (but do not blindly assume the client sends a valid pathname; for example, you shouldn't use it to rename the uploaded file without validating it).

PROCEDURE
     In this case, PROCEDURE is called to handle the uploaded contents.  It is called with four arguments: (procedure NAME FILENAME PART-INFO IPORT).

     NAME is the name of the parameter.  FILENAME is the name of the original file (pathname in the client). PART-INFO is a <mime-part> object that keeps information about this mime part,  and IPORT is where the body can be read from. For the details about these arguments, see MIME message handling; you might be able to use procedures provided by rfc.mime, such as mime-retrieve-body, to construct your own procedure.

     If you create a temporary file in PROCEDURE, you can call cgi-add-temporary-file to make sure it is removed even if an error occurs during cgi processing.

actionは次のいずれかの値でなければなりません。

#f
     デフォルトのアクションです。すなわち、アップロードされたファイルの内容が文字列として読み込まれ、パラメータの値となります。

ignore
     アップロードされたファイルの内容を無視します。

file
     アップロードされたファイルの内容は一時ファイルへと格納されます。パラメータの値は、一時ファイルの名前となります。

     このアクションを使う場合は、エントリを (NAME-PATTERN file PREFIX) のように書くこともでき、その場合はPREFIXが一時ファイルのパス名のプリフィクスとして使われます。例えば("image" file "/var/mycgi/incoming/img") のようにしておくと、"image"パラメータとしてアップロードされたファイルが/var/mycgi/incoming/img49g2Uaのような一時ファイルに格納されることになります。

     アプリケーションは、この一時ファイルを(必要ならば)適切な場所に移動しなければなりません。cgi-mainを用いている場合は、一時ファイルはcgi-mainを抜ける際に(まだあれば)unlinkされます。

file+name
     fileと同様ですが、パラメータの値が一時ファイル名とクライアントが送ってきたファイル名からなるリストになります。クライアントが送信したファイル名を利用したい場合に便利です (ただ、クライアントが常に正しいファイル名を送って来ると仮定してはいけません。例えば、アップロードされたファイルをチェック無しにクライアントが送ってきた名前にrenameするというようなことは避けてください)。

PROCEDURE
     この場合、アップロードされた内容を処理するために、手続きPROCEDUREが呼ばれます。手続きは4つの引数を伴って呼ばれます： (procedure NAME FILENAME PART-INFO IPORT).

     NAMEはパラメータの名前、FILENAMEはオリジナルファイルの名前 (クライアント側でのパス名)です。PART-INFOは<mime-part>オブジェクトで、このMIMEパートの情報を保持しており、そしてIPORTは内容を読むための入力ポートです。これらの引数の詳しい意味についてはMIME message handlingを参照して下さい。独自のPROCEDUREを書く際に、rfc.mimeの mime-retrieve-bodyのような手続きが使えるかもしれません。

     PROCEDURE内で一時ファイルを作る場合は、それを cgi-add-temporary-fileで登録しておけば、cgi処理中にエラーが起きた場合でも一時ファイルが消去されるようにすることができます。

If KV-LIST is given after ACTION, it must be a keyword-value list and further modifies action.  The following keywords are supported. ACTIONの後ろにKV-LISTが与えられた場合、それはキーワード-値リストでなければなりません。次のキーワードがサポートされています。

:prefix
     Valid only if ACTION is either file or file+name. Specifies the prefix of the temporary file.  If you give :prefix "/tmp/foo", for example, the file is saved as something like /tmp/fooxAgjeQ. ACTIONがfileかfile+nameの時のみ有効です。一時ファイルのプリフィクスを指定します。例えば:prefix "/tmp/foo"を与えると、ファイルは/tmp/fooxAgjeQのような名前でセーブされます。

:mode
     Valid only if ACTION is either file or file+name. Specifies the mode of the temporary file in unix-style integer.  By default it is #o600. ACTIONがfileかfile+nameの時のみ有効です。一時ファイルのモードをunix式の整数で指定します。デフォルトは#o600です。

Note that the parameters that are not file uploads are not the subject of PART-HANDLERS; such parameter values are always turned into a string. ファイルアップロード以外のパラメータはPART-HANDLERSの対象外であることに注意して下さい。それらのパラメータの値は常に文字列へと変換されます。

Here's a short example.  Suppose you have a form like this: 簡単な例を示します。例えば次のようなフォームがあったとします。

     <form enctype="multipart/form-data" method="POST" action="mycgi.cgi">
     <input type="file" name="imagefile" />
     <input type="text" name="description" />
     <input type="hidden" name="mode" value="normal" />
     </form>

If you use cgi-parse-parameters in mycgi.cgi without PART-HANDLERS argument, you'll get something like the following as the result. (The actual values depend on how the web client filled the form). mycgi.cgi内で、cgi-parse-parametersを PART-HANDLERS引数なしで使った場合は、例えば次のようなリストがパラメータパージングの結果として得られるでしょう。 (実際の値は、webクライアントがどのようにフォームを埋めたかに依存します)。

     (("imagefile" #*".....(image file content as a string)....")
      ("description" "my image")
      ("mode" "normal"))

If you pass '(("imagefile" file :prefix "/tmp/mycgi")) to PART-HANDLERS instead, you might get something like the following, with the content of uploaded file saved in /tmp/mycgi7gq0B ここでもし、'(("imagefile" file :prefix "/tmp/mycgi"))を PART-HANDLERSに渡したなら、替わりに次のような結果が得られるでしょう。ここで、アップロードされたファイルは/tmp/mycgi7gq0Bにセーブされていることになります。

     (("imagefile" "/tmp/mycgi7gq0B")
      ("description" "my image")
      ("mode" "normal"))

If you use a symbol file+name instead of file above, you'll get something like ("/tmp/mycgi7gq0B" "logo.jpg") as the value of "imagefile", where "logo.jpg" is the client-side filename.   (Note: the client can send any string as the name of the file, so never assume it is a valid pathname). 上の例でシンボルfileのかわりにfile+nameを使えば、例えば"imagefile"の値として("/tmp/mycgi7gq0B" "logo.jpg") のようなものが得られるでしょう。ここで"logo.jpg"はアップロードされたファイルのクライアント側でのパス名です。 (注意：クライアントは任意の文字列をファイル名として送信することができるため、その文字列が有効なパス名であることを仮定してはなりません。)

www.cgi.test - CGI testing
==========================

 -- Module: www.cgi.test
     This module defines a useful procedures to test CGI script. The test actually runs the named script, with specified environment variable settings, and retrieve the output.  Your test procedure then examine whether the output is as expected or not. CGIスクリプトをテストするための便利な手続きを定義しています。このテストは、指定された環境変数をセットし、実際にスクリプトを実行し、出力を取得します。ユーザのテスト手続きは、その出力が期待したものであるかどうかを検査します。

 -- Function: cgi-test-environment-ref envvar-name
 -- Function: (setter cgi-test-environment-ref) envvar-name value
     The module keeps a table of default values of environment variables with which the cgi script will be run.  These procedures allow the programmer to get/set those default values.

     Note that you can override these default values and/or pass additional environment variables for each call of cgi script. モジュールにより、CGIスクリプトが実行される際の環境変数のデフォルト値のテーブルが保持されます。プログラマは、これらの手続きを使ってそのデフォルト値を取得したり設定したりできます。

     CGIスクリプトの呼び出し毎に、これらのデフォルト値を上書きしたり、追加の環境変数を渡したりできます。

     The following environment variables are set by default. デフォルトでは、下記の環境変数が設定されています。

     Name   Value
     SERVER_SOFTWARE
     cgitest/1.0
     SERVER_NAME
     localhost
     GATEWAY_INTERFACE
     CGI/1.1
     SERVER_PROTOCOL
     HTTP/1.1
     SERVER_PORT
     80
     REQUEST_METHOD
     GET
     REMOTE_HOST
     remote
     REMOTE_ADDR
     127.0.0.1

 -- Function: call-with-cgi-script script proc :key (environment ()) (parameters #f)
     Runs a script with given environment, and calls PROC with one argument, an input port which is connected to the pipe of script's standard output. 与えられた環境でスクリプトを実行し、そのスクリプトの標準出力のパイプに接続された入力ポートを1つ引数に取る PROC を呼び出します。

     The argument SCRIPT should be a list of program name and its arguments.  Each element are passed to x->string first to stringify. 引数 SCRIPT は、プログラムの名前とその引数のリストでなければなりません。リストの要素はそれぞれ、文字列化されるためにまず x->stringに渡されます。

     The script is run under the environment given by ENVIRONMENT variable and the default test environment described above. The ENVIRONMENT argument must be an associative list, in which each key (car) is the name of the environment variable and its cdr is the value.  Both are passed to x->string first. If the same environment variable appears in ENVIRONMENT and the default test environment, the one in ENVIRONMENT is used. スクリプトは、変数 ENVIRONMENT で与えられる環境と、上述したデフォルトのテスト環境の下で実行されます。 ENVIRONMENTは、キー(car)がその環境変数の名前、 cdrが対応する値であるような連想リストでなければなりません。両方ともまず x->string に渡されます。 ENVIRONMENT とデフォルトのテスト環境に同じ環境変数がある場合は、 ENVIRONMENT にあるものが使われます。

     Additionally, if an associative list is given to the PARAMETERS argument, a query string is built from it and passed the script. The actual method to pass the query string depends on the value of REQUEST_METHOD environment variable in the setting. If REQUEST_METHOD is either GET or HEAD, the query string is put in an environment variable QUERY_STRING. If it is POST, the query string is fed to the standard input of the script.  In the latter case, CONTENT_TYPE is set to application/x-www-form-urlencoded and CONTENT_LENGTH are set to the length of QUERY_STRING automatically.  If REQUEST_METHOD is other values, PARAMETERS is ignored. You can bypass this mechanism and set up environment variable QUERY_STRING directly, if you wish. さらに、引数 PARAMETERS に連想リストが渡された場合、そこからクエリストリングが作られスクリプトに渡されます。クエリストリングを渡す実際のメソッドは、環境変数 REQUEST_METHODの値に依存します。REQUEST_METHOD が GET か HEAD である場合は、クエリストリングは環境変数 QUERY_STRING に置かれます。 REQUEST_METHOD が POST の場合は、クエリストリングはスクリプトの標準入力から取得されます。後者の場合、CONTENT_TYPE には application/x-www-form-urlencodedが、 CONTENT_LENGTH には QUERY_STRINGの長さが、それぞれ自動的にセットされます。REQUEST_METHOD がその他の値の場合は、 PARAMETERS は無視されます。必要であれば、このメカニズムをバイパスして、環境変数 QUERY_STRING を直接セットアップすることも可能です。

 -- Function: run-cgi-script->header&body script reader :key environment parameters
     A convenient wrapper of call-with-cgi-script. The SCRIPT, ENVIRONMENT and PARAMETERS are passed to call-with-cgi-script as they are. The output of the script is parsed by run-cgi-script->header&body. First, the RFC2822 header fields are parsed by rfc822-read-headers (see RFC822 message parsing). Then, the READER is called with an input port which is piped to the script's output. call-with-cgi-script の便利なラッパー手続きです。 SCRIPT、ENVIRONMENT、PARAMETERSは、そのまま call-with-cgi-scriptに渡されます。スクリプトの出力は、run-cgi-script->header&bodyによりパーズされます。最初に、RFC2822ヘッダフィールドが rfc822-read-headers (RFC822 message parsing参照)によりパーズされます。次に、READERが、スクリプトの出力にパイプされた入力ポートとともに呼ばれます。

     Run-cgi-script->header&body returns two values, the list of headers (as parsed by rfc822-read-headers), and the return value of READER. run-cgi-script->header&bodyは、ヘッダのリスト (rfc822-read-headersによりパーズされたもの)と READERの戻り値の2つの値を返します。

 -- Function: run-cgi-script->sxml script :key environment parameters
     This is a procedure that uses ssax:xml->sxml (see Functional XML parser) as the READER in run-cgi-script->header&body. Useful when you're testing a cgi script that produces well-formed HTML and/or XML document. この手続きでは、run-cgi-script->header&bodyの READERとして、ssax:xml->sxml (Functional XML parser参照)を使います。整形式(Well-formed)のHTMLやXMLドキュメントを生成する CGIスクリプトをテストする場合に便利です。

 -- Function: run-cgi-script->string script :key environment parameters
 -- Function: run-cgi-script->string-list script :key environment parameters
     These procedures use port->string and port->string-list (see Input utility functions) as the READER in run-cgi-script->header&body, respectively. これらの手続きは、run-cgi-script->header&bodyの READERとして、それぞれ port->string、 port->string-listを使います。

An example: 例:

     (run-cgi-script->string-list "bbs.cgi"
                                  :environment '((REMOTE_ADDR . "12.34.56.78"))
                                  :parameters '((command . "view")
                                                (page . 1234)))

www.css - CSS parsing and construction
======================================

 -- Module: www.css
     This module provides tools to convert between S-expression and CSS.

     The S-expression CSS (SxCSS) is a convenient way to manipulate CSS in Scheme. このモジュールはS式とCSSを相互変換するツールを提供します。

     S式CSS(SxCSS)はCSSをSchemeから操作するのに便利な方法です。

For example, the following CSS and SxCSS are equivalent, and can be converted back and forth: 例えば、次のCSSとSxCSSは等価で、相互に変換可能です。

CSS:

     body { padding-left: 11em;
            font-family: Georgia, "Times New Roman", Times, serif;
            color: purple;
            background-color: #d8da3d }
     ul.navbar li { background: white;
                    margin: 0.5em 0;
                    padding: 0.3em;
                    border-right: 1em solid black }
     ul#spec > a { text-decoration: none }
     a:visited { color: purple !important }

SxCSS:

     ((style-rule body
        (padding-left (11 em))
        (font-family (:or Georgia "Times New Roman" Times serif))
        (color purple)
        (background-color (color "d8da3d")))
      (style-rule ((ul (class navbar)) li)
        (background white)
        (margin #((0.5 em) 0))
        (padding (0.3 em))
        (border-right #((1 em) solid black)))
      (style-rule ((ul (id spec)) > a) (text-decoration none))
      (style-rule (a (: visited)) (color purple !important)))

See the ``CSS in S-expression'' section below for the complete specification. 完全な仕様については下の ``S式CSS'' を参照してください。

Constructing CSS
----------------

CSSの構築
------

 -- Function: construct-css sxcss :optional oport
     Take SxCSS and writes out CSS to the given port, defaulted to the current output port. SxCSSを取り、与えられたポートにCSSを書き出します。OPORTのデフォルトは現在の出力ポートです。

Parsing CSS
-----------

CSSのパーズ
-------

 -- Function: parse-css :optional iport
     Read CSS from the given port, defaulted to the current input port, and returns SxCSS.

     When it encounters unparsable CSS (either a malformed CSS, or unsupported syntax), it emits a warning message, ignore the unparsable part and tries to continue reading the rest.

     NB: Currently we don't handle @charset directive; we assume the text is already in the port's encoding.  We may support it in future versions. CSSを与えられたポートから読み、SxCSSを返します。IPORTのデフォルトは現在の入力ポートです。

     パーズできないCSS (不正なCSSか、サポートされていない構文) に出会った場合、 warningメッセージを出力してその箇所を飛ばし、次にパーズできるところから処理を続けます。

     註：今のところ、@charsetディレクティブは無視され、入力テキストはポートのエンコーディングであると仮定されます。将来は対応するかもしれません。

 -- Function: parse-css-file file :key encoding
     Read the CSS text from the given file and parse it using parse-css.  Again, we don't handle @charset directive yet, and you have to pass encoding argument if the CSS text isn't in the Gauche's native character encoding. 与えられたファイルからCSSを読み、parse-cssを使ってパーズして結果をSxCSSで返します。@charsetディレクティブはまだ認識されないので、 CSSファイルがGaucheのネイティブエンコーディングと異なるエンコーディングで書かれている場合は、ENCODINGにエンコーディング名を渡してください。

 -- Function: parse-css-selector-string str
     This parses the selector part of the CSS. CSSのセレクター部分をパーズするユーティリティです。

          (parse-css-selector-string "ul li.item span#foo")
            => (ul (li (class item)) (span (id foo)))

          (parse-css-selector-string "h1,h2")
            => (:or h1 h2)

CSS in S-expression
-------------------

S式CSS
-----

The following is the complete rules of SxCSS syntax. 完全なSxCSSの構文規則を以下に示します。

     <sxcss>      : ({<style-rule> | <at-rule>} ...)

     <style-rule> : (style-rule <pattern> <declaration> ...)
                  | (style-decls <declaration> ...)

     <pattern>   : <selector> | (:or <selector> ...)
     <selector>  : <simple-selector>
                 | <chained-selector>
     <chained-selector> : (<simple-selector> . (<op>? . <chained-selector>))
     <op>        : > | + | ~
     <simple-selector> : <element-name>
                 | (<element-name> <option> ...)
     <option>    : (id <name>)                           ; E#id
                 | (class <ident>)                       ; E.class
                 | (has <ident>)                         ; E[attrib]
                 | (= <ident> <attrib-value>)            ; E[attrib=val]
                 | (~= <ident> <attrib-value>)           ; E[attrib~=val]
                 | (:= <ident> <attrib-value>)           ; E[attrib|=val]
                 | (*= <ident> <attrib-value>)           ; E[attrib*=val]
                 | (^= <ident> <attrib-value>)           ; E[attrib^=val]
                 | ($= <ident> <attrib-value>)           ; E[attrib$=val]
                 | (:not <negation-arg>)                 ; E:not(s)
                 | (: <ident>)                           ; E:pseudo-class
                 | (: (<fn> <ident> ...))                ; E:pseudo-class(arg)
                 | (:: <ident>)                          ; E::pseudo-element
     <element-name> : <ident> | *
     <attrib-value> : <ident> | <string>
     <negation-arg> | <element-name> | * | <option>  ; except <negation-arg>

     <declaration>  : (<ident> <expr> <expr2> ... <important>?)
     <important> : !important
     <expr>      : <term>
                 | (/ <term> <term> ...)
                 | (:or <term> <term> ...)
                 | #(<term> <term> ...)             ; juxtaposition
     <term>      : <quantity> | (- <quantity>) | (+ <quantity>)
                 | <string> | <ident> | <url> | <hexcolor> | <function>
     <quantity>  : <number>
                 | (<number> %)
                 | (<number> <ident>)
     <url>       | (url <string>)
     <hexcolor>  | (color <string>)  ; <string> must be hexdigits
     <function>  | (<fn> <arg> ...)
     <arg>       | <term> | #(<term> ...) | (/ <term> <term> ...)

     <at-rule>    : <at-media-rule> | <at-import-rule>
                        ; NB: Other at-rules are not supported yet
     <at-media-rule>  : (@media (<symbol> ...) <style-rule> ...)
     <at-import-rule> : (@import <string> (<symbol> ...))

NB: Negation op is :not instead of not, since (not <negation-arg>) would be ambiguous from the simple node named "not" with one option. 註: 否定オペレータはnotではなく:notです。というのは、(not <negation-arg>)だと ``not'' と言う名前を持ち一つのオプションを持つノードと区別できないからです。

NB: style-decls selector rule is currently won't appear in the parse-css output; it can be used in SxCSS to make construct-css render declarations only, which can be used in the style attribute of the document, for example. 註: style-declsセレクタルールはparse-cssの出力には現れません。ドキュメントのstyle属性に渡すCSS断片を生成したい場合に、 (style-decls <declaration> ...)をconstruct-cssに渡します。

     (with-output-to-string
      (cut construct-css
           '((style-decls (width (50 %))
                          (padding #(0 (10 pt) 0 (10 pt)))))))
       => "width:50%;padding:0 10pt 0 10pt"