Core library
************

Types and classes
=================

Scheme is a dynamically and strongly typed language.  That is, every value knows its type at run-time, and the type determines what kind of operations can be applied on the value. Schemeは動的な強い型付けの言語です。つまり、全ての値は実行時に自分の型を知っていて、その型が値に適用できる操作を決定します。

In Gauche, classes are used to describe types. A class is also an object you can handle at runtime. You can also create a new class in order to have objects with distinct types. Gaucheでは、クラスによって型を記述します。クラス自身もオブジェクトであり、実行時に取り扱うことができます。新たなクラスを作成することで、既存の型とは異なるユーザ定義型を使うことができます。

Since R6RS, Scheme got a standard way to define a new type, through define-record-type.  You can use record types in Gauche as well, via gauche.record module. See Record types.  Internally a record type is implemented as a class. R6RSから、Schemeにも新しい型を定義する機能が標準で備わりました。 define-record-typeを使います。Gaucheでも、 gauche.recordモジュールを使うことでレコード型を定義できます。 Record typesを参照してください。内部的にはレコード型はクラスで実装されています。

In this section we introduce the most basic interface to the Gauche's type system. See Object system, for the details of how to define your own classes and creates values (instances). この節ではもっとも基本的な型システムへのインタフェースを説明します。新たなクラスを定義し、そのインスタンスを作る方法については Object systemを参照してください。

Predefined classes are bound to a global variable; Gauche's convention is to name the variable that holds a class with brackets < and >, e.g. <string>. (It's nothing syntactically special with these brackets; they're valid characters to consist of variable names). We'll introduce classes for each built-in type as we go through this chapter.  Here are a few basic classes to start with: あらかじめ定義されているクラスはグローバル変数に束縛されています。Gaucheでの慣習として、クラスを格納している変数は<string>のように <と>で囲まれた名前を持ちます。 (この<や>は文法的には何ら特別な意味を持ちません。普通に変数名として使える文字です)。組み込みの型に対応するクラスについては、この章の中で順に紹介してゆきます。まずは次のいくつかのクラスから始めましょう。

 -- Builtin Class: <top>
     This class represents the supertype of all the types in Gauche. That is, for any class X, (subtype? X <top>) is #t, and for any object x, (is-a? x <top>) is #t. 全ての型のスーパータイプを表現するクラスです。つまり、どんなクラスXに対しても(subtype? X <top>)は#tであり、どんなオブジェクトxに対しても(is-a? x <top>)は#tです。

 -- Builtin Class: <bottom>
     This class represents the subtype of all the types in Gauche. For any class X, (subtype? <bottom> X) is #t, and for any object x, (is-a? x <bottom>) is #f. 全ての型のサブタイプを表現するクラスです。どんなクラスXに対しても(subtype? <bottom> X)は#tであり、どんなオブジェクトxに対しても(is-a? x <bottom>)は#fです。

     There's no instance of <bottom>. <bottom>型のインスタンスは存在しません。

     Note: Although <bottom> is subtype of other types, the class precedence list (CPL) of <bottom> only contains <bottom> and <top>.  It's because it isn't always possible to calculate a linear list of all the types. Even if it is possible, it would be expensive to check and update the CPL of <bottom> every time a new class is defined or an existing class is redefined.   Procedures subtype? and is-a? treat <bottom> specially.

     One of use case of <bottom> is applicable? procedure. See Procedure class and applicability. 註: <bottom>は全ての型のサブタイプですが、そのクラス順位リスト (class precedence list, CPL)には<bottom>と<top> 以外のクラスは含まれていません。全ての型を線形に並べることは常に可能であるとは限らず、まだそうであったとしても新たなクラスの定義や既存のクラスの再定義のたびに<bottom>のCPLを検査してアップデートすることは高くつくでしょう。subtype?やis-a?といった手続きは <bottom>を特別扱いしています。

     <bottom>の使いどころのひとつは、applicable?手続きです。 Procedure class and applicabilityを参照のこと。

 -- Builtin Class: <object>
     This class represents a supertype of all user-defined classes. このクラスは、ユーザ定義されたクラスのスーパータイプを表現するクラスです。

 -- Function: class-of obj
     Returns a class metaobject of OBJ. OBJのクラスを返します。

          (class-of 3)         => #<class <integer>>
          (class-of "foo")     => #<class <string>>
          (class-of <integer>) => #<class <class>>

     Note: In Gauche, you can redefine existing user-defined classes. If the new definition has different configuration of the instance, class-of on existing instance triggers instance updates; see Class redefinition for the details.  Using current-class-of suppresses instance updates (see Accessing instance). 註: Gaucheでは、ユーザ定義クラスを再定義することができます。新たな定義でインスタンスの構造が変更された場合、以前のクラスから作られたインスタンスにclass-ofを適用すると、インスタンスが新しいクラスに適合するようにアップデートされます。詳しくはClass redefinitionを参照してください。インスタンスアップデートを避けるにはcurrent-class-ofを使います(Accessing instance参照)。

 -- Function: is-a? obj class
     Returns true if OBJ is an instance of CLASS or an instance of descendants of CLASS. OBJがCLASSのインスタンスであるか、CLASSのサブクラスのインスタンスである場合に、真を返します。

          (is-a? 3 <integer>)   => #t
          (is-a? 3 <real>)      => #t
          (is-a? 5+3i <real>)   => #f
          (is-a? :foo <symbol>) => #f

     Note: If OBJ's class has been redefined, is-a? also triggers instance update. See Class redefinition for the details. 註：OBJのクラスが再定義されていた場合、is-a?はインスタンスアップデートをトリガします。Class redefinitionを参照してください。

 -- Function: subtype? sub super
     Returns #t if a class SUB is a subclass of a class SUPER (includes the case that SUB is SUPER). Otherwise, returns #f.

     (The name subtype? is taken from Common Lisp's procedure subtypep.) クラスSUBがクラスSUPERのサブクラスであれば(SUBとSUPERが同じである場合も含め)#tを、そうでなければ#fを返します。

     (subtype?という名前はCommon Lispのsubtypepから来ています)。

Equality and comparison
=======================

Comparing two objects seems trivial, but if you look into deeper, there are lots of subtleties hidden in the corners.  What should it mean if two procedures are equal to each other?  How to order two complex numbers?  It all depends on your purpose; there's no single generic answer.  So Scheme (and Gauche) provides several options, as well as the way to make your own. ふたつのオブジェクトを比較するというのは簡単な話のように思えるかもしれません。しかし詳しく見てゆくと、一筋縄ではいかない特別なケースが出てきます。ふたつの手続きが等しいとはどういうことでしょうか。複素数を何らかの基準で順番に並べるにはどうすばいいでしょう。一般的な回答は無く、目的によるとしか言えません。そこで、Schemeでは(Gaucheも)、いくつかの選択肢を用意しておき、さらに必要ならばユーザが独自の定義を与えることもできるようにしています。

Equality
--------

Scheme has three different general equality test predicates. Other than these, some types have their own comparison predicates. Schemeには等価性を判定する汎用的な述語が3つあります。また、これらの他に、いくつかの型はその型同士で使える比較手続きを持っています。

 -- Function: eq? obj1 obj2
     [R7RS base] This is the fastest and finest predicate. Returns #t if OBJ1 and OBJ2 are identical objects---that is, if they represents the same object on memory or in a register.  Notably, you can compare two symbols or two keywords with eq? to check if they are the same or not. You can think eq? as a pointer comparison for any heap-allocated objects.

     Booleans can be compared with eq?, but you can't compare characters and numbers reliably---objects with the same numerical value may or may not eq? to each other. If you identity comparison needs to include those objects, use eqv? below. 最も高速で、細かい区別ができる述語です。 OBJ1とOBJ2が同一(identical)のオブジェクト、すなわち、メモリ上の同じオブジェクトを表している場合に#tを返します。特に、二つのシンボルもしくは二つのキーワードが同一かどうかを比較するのにeq?が使えます。ヒープアロケートされるオブジェクトに対しては、ポインタ比較と考えても良いでしょう。

     真偽値もeq?で比較できますが、文字と数値はたとえ値が同じオブジェクトであっても互いにeq?になるかどうかはわかりません。同一性比較で文字や数値も扱う必要がある場合は、下のeqv?を使いましょう。

          (eq? #t #t)               => #t
          (eq? #t #f)               => #f
          (eq? 'a 'a)               => #t
          (eq? 'a 'b)               => #f
          (eq? (list 'a) (list 'a)) => #f
          (let ((x (list 'a)))
            (eq? x x))              => #t

 -- Function: eqv? obj1 obj2
     [R7RS base] When OBJ1 and OBJ2 are both exact or both inexact numbers (except NaN), eqv? returns #t iff (= OBJ1 OBJ2) is true. When OBJ1 and OBJ2 are both characters, eqv? returns #t iff (char=? OBJ1 OBJ2) is true. Otherwise, eqv? is the same as eq? on Gauche. OBJ1とOBJ2がともに正確な数値、もしくはともに(NaN以外の)不正確な数値である場合、 (= OBJ1 OBJ2)が真であれば#tが、偽であれば#fが返されます。 OBJ1とOBJ2がともに文字である場合、 (char=? OBJ1 OBJ2)が真であれば#tが、偽であれば#fが返されます。それ以外の場合は、Gaucheではeqv?はeq?と同じです。

          (eqv? #\a #\a)             => #t
          (eqv? #\a #\b)             => #f
          (eqv? 1.0 1.0)             => #t
          (eqv? 1 1)                 => #t
          (eqv? 1 1.0)               => #f
          (eqv? (list 'a) (list 'a)) => #f
          (let ((x (list 'a)))
            (eqv? x x))              => #t

     Note that comparison of NaNs has some peculiarity. Any numeric comparison fails if there's at least one NaN in its argument. Therefore, (= +nan.0 +nan.0) is always #f.   However, Gauche may return #t for (eq? +nan.0 +nan.0) or (eqv? +nan.0 +nan.0). NaNの比較には少々奇妙なところがあります。数値比較は、引数に一つでもNaNが含まれていれば失敗します。したがって(= +nan.0 +nan.0)は常に#fとなります。けれども、(eq? +nan.0 +nan.0) や (eqv? +nan.0 +nan.0)は#tを返すことがあるかもしれません。

 -- Function: equal? obj1 obj2
     [R7RS+] If OBJ1 and OBJ2 are both aggregate types, equal? compares its elements recursively. Otherwise, equal? behaves the same as eqv?.

     If OBJ1 and OBJ2 are not eqv? to each other, not of builtin types, and the class of both objects are the same, equal? calls the generic function object-equal?. By defining the method, users can extend the behavior of equal? for user-defined classes. OBJ1とOBJ2がリストやベクタなどの複合型である場合、 equal?は再帰的に対応する要素同士をequal?で比較してゆきます。そうでなければ、equal?はeqv?と同じようにふるまいます。

     もしobj1とOBJ2が互いにeqv?でなく、組み込み型でもなく、かつ両者のクラスが等しい場合、equal?はジェネリックファンクションobject-equal?を呼びます。 object-equal?にメソッドを定義することにより、ユーザ定義のデータ型に対するequal?の振るまいを拡張することができます。

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

     Note: This procedure correctly handles the case when both OBJ1 and OBJ2 have cycles through pairs and vectors, as required by R6RS and R7RS.  However, if the cycle involves user-defined classes, equal? may fail to terminate. 註: この手続きは、OBJ1とOBJ2がともにペアやベクタを介した循環構造を持っている場合もR6RSやR7RSに規定されるように値を返します。ただし、循環構造がユーザ定義データ型を間に挟んでいる場合は終了しない可能性があります。

 -- Generic Function: object-equal? obj1 obj2
     This generic function is called when equal? is called on the objects it doesn't know about.  You can define this method on your class so that equal? can check equivalence.   This method is supposed to return #t if OBJ1 is equal to OBJ2, #f otherwise.  If you want to check equivalence of elements recursively, do not call object-equal? directly; call equal? on each element. equal?が未知のオブジェクトに対して呼ばれた場合、このジェネリックファンクションが呼ばれます。自分で定義したクラスに対してこのメソッドを定義することにより、equal?で等価判定が行えるようになります。メソッドは、OBJ1とOBJ2が等価ならば#tを、そうでなければ#fを返さねばなりません。オブジェクトの各要素に対して再帰的に等価判定を行いたい場合は、 object-equal?を直接呼ぶのではなく、equal?を各要素に対して呼ぶようにして下さい。

          (define-class <foo> ()
            ((x :init-keyword :x)
             (y :init-keyword :y)))

          (define-method object-equal? ((a <foo>) (b <foo>))
            (and (equal? (slot-ref a 'x) (slot-ref b 'x))
                 (equal? (slot-ref a 'y) (slot-ref b 'y))))

          (equal? (make <foo> :x 1 :y (list 'a 'b))
                  (make <foo> :x 1 :y (list 'a 'b)))
            => #t

          (equal? (make <foo> :x 1 :y (make <foo> :x 3 :y 4))
                  (make <foo> :x 1 :y (make <foo> :x 3 :y 4)))
            => #t

 -- Method: object-equal? (obj1 <top>) (obj2 <top>)
     This method catches equal? between two objects of a user-defined class, in case the user doesn't define a specialized method for the class.

     When called, it scans the registered default comparators that can handle both OBJ1 and OBJ2, and if it finds one, use the comparator's equality predicate to see if two arguments are equal to each other.  When no matching comparators are found, it just returns #f. See Predefined comparators, about the default comparators: Look for the entries of default-comparator and comparator-register-default!.

     Note: If you define object-equal? with exactly the same specializers of this method, you'll replace it and that breaks default-comparator operation.  Future versions of Gauche will prohibit such redefinition.  For now, be careful not to redefine it accidentally. このメソッドは、ユーザ定義クラスの2つのインスタンスがequal?であるかを調べる際に、そのクラスに特殊化したメソッドが無かった場合を捕まえるものです。

     このメソッドが呼ばれると、まず登録されたデフォルト比較器の中にOBJ1と OBJ2を共に処理できるものがあるかどうかを調べ、あればその比較器の等価述語を使って比較します。デフォルト比較器が引数を処理できなければ #fを返します。デフォルト比較器については Predefined comparatorsを参照してください。特に default-comparatorとcomparator-register-default!の項目を見てください。

     註: もし、このメソッドと全く同じスペシャライザを指定してobject-equal?メソッドを定義すると、それはこのメソッドを置き換えることになり、default-comparatorの動作が壊れることになります。将来のGaucheのバージョンではそのような再定義は禁止される予定です。うっかりそういう再定義を行わないように気をつけてください。

Sometimes you want to test if two aggregate structures are topologically equal, i.e., if one has a shared substructure, the other has a shared substructure in the same way. Equal? can't handle it; module util.isomorph provides a procedure isomorphic? which does the job (see Determine isomorphism). しばしば、ふたつの複合型オブジェクトに関して、両者がトポロジー的に等しいこと、すなわち一方が共有する部分構造を持っている場合にもう一方も同じように部分構造を共有しているかどうかを調べたいことがあります。equal?はその目的には使えません。モジュールutil.isomorphの提供するisomorphic?がその目的に使えます。(Determine isomorphism参照)。

Comparison
----------

Equality only concern about whether two objects are equivalent or not. However, sometimes we want to see the order among objects.  Again, there's no single ``universal order''.  It doesn't make mathematical sense to ask if one complex number is greater than another, but having some artificial order is useful when you want a consistent result of sorting a list of objects including numbers. 等価性はオブジェクトが等しいかどうかしか判断しませんが、しばしばオブジェクトの順序関係を調べたい場合もあります。ここでも、唯一の「万能順序」があるわけではありません。例えばある複素数が別の複素数より大きいか小さいかというのは数学的には意味をなしませんが、数値を含むオブジェクトのリストをソートして一貫性のある結果を得たい場合は何らかの適当な順序づけを決めておくことは役に立ちます。

 -- Function: compare obj1 obj2
     A general comparison procedure.  Returns -1 if OBJ1 is less than OBJ2, 0 if OBJ1 is equal to OBJ2, and 1 if OBJ1 is greater than OBJ2. 一般的な比較手続きです。OBJ1がOBJ2より小さければ-1を、等しければ0を、大きければ1を返します。

     If OBJ1 and OBJ2 are incomparable, an error is signalled. However, compare defines total order between most Scheme objects, so that you can use it on wide variety of objects.  The definition is upper-compatible to the order defined in srfi-114. OBJ1とOBJ2が比較できない場合はエラーとなりますが、 compareは多くのSchemeオブジェクト間に全順序を定義しているので、様々なオブジェクトの比較に使うことができます。この全順序は、 srfi-114で定義されているものの上位互換です。

     Some built-in types are handled by this procedure reflecting ``natural'' order of comparison if any (e.g. real numbers are compared by numeric values, characters are compared by char< etc.) For convenience, it also defines superficial order between objects that doesn't have natural order; complex numbers are ordered first by their real part, then their imaginary part, for example.  That is, 1+i comes before 2-i, which comes before 2, which comes before 2+i. 組み込みオブジェクトのうち、自然な順序が定義されているものはそれに従って順序づけられます (例えば実数はその数値の大小で、文字はchar<等を使って比較されます)。また便宜上、通常の意味で大小が定義されないオブジェクトについてもある程度表面的な順序が定義されます。例えば複素数は、まず実部の大小によって順序づけられ、次に虚部の大小によって順序づけられます。すなわち、1+i、2-i、2、2+iはこの順番に並びます。

     Boolean false comes before boolean true. #fは#tより前に来ます。

     Lists are ordered by dictionary order: Take the common prefix. If either one is () and the other is not, () comes first. If both tails are not empty, compare the heads of the tails. (This makes empty list the ``smallest'' of all lists). リストは辞書順で比較されます。すなわち、まず共通のプリフィクスを除きます。一方が()でもう一方がそうでなければ、()である方が先にきます。どちらの尾部も空でなければ、尾部の先頭要素同士を比べます。 (この定義により、空リストは全てのリストの「最小」のものになります)。

     Vectors (including uniform vectors) are compared first by their lengths, and if they are the same, elements are compared from left to right. Note that it's different from lists and strings. (ユニフォームベクタを含む)ベクタは、まず長さで比較され、長さが同じ場合は要素同士が左から比較されます。リストや文字列とは異なることに注意。

          (compare '(1 2 3) '(1 3))
            => -1  ; (1 2 3) is smaller
          (compare '#(1 2 3) '#(1 3))
            => 1   ; #(1 3) is smaller
          (compare "123" "13")
            => -1  ; "123" is smaller

     If two objects are of subclasses of <object>, a generic function object-compare is called. 二つのオブジェクトがともに<object>のサブクラスであれば、ジェネリックファンクションobject-compareが呼ばれます。

     If two objects are of different types and at least one of them isn't <object>, then they are ordered by their types. Srfi-114 defines the order of builtin types as follows: 二つのオブジェクトが異なる型で、少なくとも一方が<object>でない時は、両者の型により順序が決まります。srfi-114は組み込み型について次の順序を定めています。

      1. Empty list.

      2. Pairs.

      3. Booleans.

      4. Characters.

      5. Strings.

      6. Symbols.

      7. Numbers.

      8. Vectors.

      9. Uniform vectors (u8 < s8 < u16 < s16 < u32 < s32 < u64 < s64 < f16 < f32 < f64)

      10. All other objects. 他のオブジェクトすべて

 -- Generic Function: object-compare obj1 obj2
     Specializing this generic function extends compare procedure for user-defined classes.

     This method must return either -1 (OBJ1 precedes OBJ2), 0 (OBJ1 equals to OBJ2), 1 (OBJ1 succeeds OBJ2), or #f (OBJ1 and OBJ2 cannot be ordered). このジェネリックファンクションを特殊化することで compare手続きをユーザ定義クラスに対して動作するように拡張できます。

     このメソッドは以下のいずれかの値を返さねばなりません。 -1 (OBJ1はOBJ2より前)、 0 (OBJ1とOBJ2は等しい)、 1 (OBJ1はOBJ2より後)、 #f (OBJ1とOBJ2は順序づけできない)。

 -- Method: object-compare (obj1 <top>) (obj2 <top>)
     This method catches compare between two objects of a user-defined class, in case the user doesn't define a specialized method for the class.

     When called, it scans the registered default comparators that can handle both OBJ1 and OBJ2, and if it finds one, use the comparator's compare procedure to determine the order of OBJ1 and OBJ2. When no matching comparators are found, it returns #f, meaning two objects can't be ordered. See Predefined comparators, about the default comparators: Look for the entries of default-comparator and comparator-register-default!.

     Note: If you define object-compare with exactly the same specializers of this method, you'll replace it and that breaks default-comparator operation.  Future versions of Gauche will prohibit such redefinition.  For now, be careful not to redefine it accidentally. このメソッドは、ユーザ定義クラスの2つのインスタンスをcompareする際に、そのクラスに特殊化したメソッドが無かった場合を捕まえるものです。

     このメソッドが呼ばれると、まず登録されたデフォルト比較器の中にOBJ1と OBJ2を共に処理できるものがあるかどうかを調べ、あればその比較器の比較手続きを使って両者の順序を判定します。デフォルト比較器が引数を処理できなければ #f(「比較できない」)を返します。デフォルト比較器については Predefined comparatorsを参照してください。特に default-comparatorとcomparator-register-default!の項目を見てください。

     註: もし、このメソッドと全く同じスペシャライザを指定してobject-compareメソッドを定義すると、それはこのメソッドを置き換えることになり、default-comparatorの動作が壊れることになります。将来のGaucheのバージョンではそのような再定義は禁止される予定です。うっかりそういう再定義を行わないように気をつけてください。

 -- Function: eq-compare obj1 obj2
     Returns -1 (less than), 0 (equal to) or 1 (greater than) according to a certain total ordering of OBJ1 and OBJ2.   Both arguments can be any Scheme objects, and can be different type of objects. The following properties are guaranteed.

       * (eq-compare x y) is 0 iff (eq? x y) is #t.

       * The result is consistent within a single run of the process (but may differ between runs).

     Other than these, no actual semantics are given to the ordering.

     This procedure is useful when you need to order arbitrary Scheme objects, but you don't care the actual order as far as it's consistent. とある全順序に従ってOBJ1とOBJ2を比較し、前者が小さければ-1、等しければ0、前者が大きければ1を返します。OBJ1とOBJ2はどんなSchemeオブジェクトでも良く、また型が違っていても構いません。次の二つの性質が保証されます。

       * (eq? x y)が#tなら、そしてその時に限り、 (eq-compare x y)は0。

       * 結果は、一回のプロセスの実行中で一貫している (ただし、別のプロセスの実行では異なる結果を返すかもしれない)。

     これらの性質以外には、順序についていかなる意味もありません。

     この手続きは、任意のSchemeオブジェクトをとにかく順序づけたい (一貫してさえいれば、実際の順序は何でも良い)、という場合に使います。

Hashing
-------

Hash functions have close relationship with equality predicate, so we list them here.

ハッシュ関数は等価判定述語と関係が深いので、ここで説明します。

 -- Function: eq-hash obj
 -- Function: eqv-hash obj
     These are hash functions suitable to be used with eq? and eqv?, respectively. The returned hash value is system- and process-dependent, and can't be carried over the boundary of the running process.

     Note: don't hash numbers by eq-hash.  Two numbers are not guaranteed to be eq? even if they are numerically equal. この2つはそれぞれeq?および eqv?と一緒に使うのに適したハッシュ関数です。返り値のハッシュ値は、システムおよびプロセスに依存する値です。動作しているプロセスの境界を超えてもちまわることはできません。

     注意: eq-hash をつかって、数をハッシュしてはいけません。 2つの数はたとえその値が等しくても eq? であることは保証されていません。

 -- Function: default-hash obj
     [R7RS+] This is a hash function suitable to be used with equal?. In R7RS, this is defined in scheme.comparator (originally in srfi-128).

     If OBJ is either a number, a boolean, a character, a symbol, a keyword, a string, a list, a vector or a uniform vector, internal hash function is used to calculate the hash value. If OBJ is other than that, a generic function object-hash is called to calculate the hash value (see below).

     The hash value also depends on hash-salt, which differs for every run of the process. equal?と一緒に使うのに適したハッシュ関数です。 R7RSでは、scheme.comparatorライブラリで定義されています (元はsrfi-128)。

     OBJ が、数値、真理値、文字、シンボル、キーワード、文字列、リスト、ベクタ、ユニフォームベクタのいずれかならば、そのハッシュ値を求めるのには内部ハッシュ関数を使います。 OBJ が、それ以外であれば、 hash は総称関数 object-hash を呼んで、そのハッシュ値を計算します。

     返されるハッシュ値はhash-saltの値にも依存します。hash-salt はプロセスが走る度に異なる値をとります。

 -- Function: portable-hash obj salt
     Sometimes you need to calculate a hash value that's ``portable'', in a sense that the value won't change across multiple runs of the process, nor between different platforms.  Such hash value can be used with storing objects externally to share among processes.

     This procedure calculates a hash value of OBJ with such characteristics; the hash value is the same for the same object and the same salt value. Here ``same object'' roughly means having the same external representation.  Objects equal? to each other are same.  If you write out an object with write, and read it back, they are also the same objects in this sense.

     This means objects without read/write invariance, such as ports, can't be handled with portable-hash.  It is caller's responsibility that OBJ won't contain such objects.

     The SALT argument is a nonnegative fixnum and gives variations in the hash function.  You have to use the same salt to get consistent results.

     If OBJ is other than a number, a boolean, a character, a symbol, a keyword, a string, a list, a vector, or a uniform vector, this procedure calls a generic function object-hash is called to calculate the hash value (see below). 時に、「ポータブル」なハッシュ値が必要になることがあります。ここでポータブルとは、プロセスを何度実行しても、また異なるプラットフォームで実行しても、同じオブジェクトに対して常に同じ値となることです。そのようなハッシュ値は、プロセスの外に保存したり他のプロセスと共有するオブジェクトと一緒に使えます。

     この手続きはOBJについてその性質を持つハッシュ値を計算して返します。つまり、同じオブジェクトと同じソルト値が渡されれば同じハッシュ値となる、ということです。ここで、「同じオブジェクト」とは、だいたい外部表現が同じになるものと考えて構いません。equal?であるもの同士は同じです。また、オブジェクトをwriteで書き出してreadで読み込んだものは元のオブジェクトと同じになります。

     このことから、read/write不変性をもたないオブジェクトはportable-hash では扱えません。OBJがそのようなオブジェクトを含まないことは呼び出し側で保証する必要があります。

     SALTは非負のfixnumで、ハッシュ関数に変化をつけます。一貫した結果を得るには同じソルト値を使わなければなりません。

     OBJが数値、真理値、文字、シンボル、キーワード、文字列、リスト、ベクタ、ユニフォームベクタのいずれでもない場合、ハッシュ値を計算するのに総称関数 object-hashが呼ばれます。

 -- Function: legacy-hash obj
     Up to 0.9.4, Gauche had a hash function called hash that was used in both equal?-hashtable and for the portable hash function.  It had a problem, though. バージョン0.9.4まで、Gaucheではhashと呼ばれるハッシュ関数が equal?ハッシュテーブル用のハッシュ計算とポータブルなハッシュ値の計算の両方を兼ねていました。しかしそれには問題がありました。

      1. There was no way to salt the hash function, which makes the hashtables storing externally provided data vulnerable to collision attack. ハッシュ関数にソルトを与えることができなかったため、外部からのデータによる衝突攻撃が可能だった

      2. The hash function behaves poorly, especially on flonums. ハッシュ関数自体があまり良くなかった(特に浮動小数点数)

      3. There are bugs in bignum and flonum hashing code that have produced different results on different architectures. 多倍長整数と浮動小数点数のハッシュ値計算で、異なるアーキテクチャで異なる値を返してしまうバグがあった。

     Since there are existing hash values calculated with the old hash function, we preserve the behavior of the original hash function as legacy-hash. Use this when you need to access old data. (The hash function also behaves as legacy-hash by default, but it has tweaks; see below.) 既にhashで計算されたハッシュ値を利用しているデータがあるため、以前のhashで提供していたハッシュ関数をlegacy-hashとして保存することにしました。古いデータにアクセスする場合に使ってください。 (hash関数自体もデフォルトでは legacy-hashと同様に振る舞いますが、ちょっとした仕掛けがあります。下の説明を参照)。

     The new code that needs portable hash value should use portable-hash instead. 新たに書くコードでポータブルなハッシュ値が必要なら portable-hashを使ってください。

 -- Generic Function: object-hash obj rec-hash
     By defining a method for this generic function, objects of user-defined types can have a hash value and can be used in a equal? hash table.

     The method has to return an exact non-negative integer, and must return the same value for two object which are equal?. Furthermore, the returned value must not rely on the platform or state of the process, if OBJ is a portable object (see portable-hash above for what is portable.)

     If the method needs to get hash value of OBJ's elements, it has to call REC-HASH on them.  It guarantees that the proper hash function is called recursively.  So you can count on REC-HASH to calculate a portable hash value when object-hash itself is called from portable-hash.

     If OBJ has several elements, you can call combine-hash-value on the elements' hash values. この総称関数に対するメソッドを定義することにより、ユーザ定義された型のオブジェクトはハッシュ値を持つことができ、equal?型のハッシュテーブルで利用できるようになります。

     メソッドは正確な非負整数を返さなければなりません。また、互いにequal?であるオブジェクト同士に対しては同じハッシュ値を返さなければなりません。さらに、OBJがポータブル(「ポータブル」の意味については上のportable-hashの説明を参照)の場合には、ハッシュ値は実行中のプラットフォームやプロセスの状態に依存してはなりません。

     メソッドが OBJ の要素のハッシュ値を必要とする場合には、それらに対して、REC-HASHを呼び出してください。そうすれば適切なハッシュ関数が再帰的に呼び出されます。例えばobject-hashが portable-hash経由で呼び出されている場合、 REC-HASHを呼べば同じソルト値でポータブルなハッシュ値が計算されます。

     OBJがいくつかの要素を持っている場合、各要素のハッシュ値をまとめるにはcombine-hash-valueを呼びます。

          (define-class <myclass> () (x y))

          ;; user-defined equality function
          (define-method object-equal? ((a <myclass>) (b <myclass>))
            (and (equal? (ref a 'x) (ref b 'x))
                 (= (abs (ref a 'y)) (abs (ref b 'y)))))

          ;; user-defined hash function
          (define-method object-hash ((a <myclass>) rec-hash)
            (combine-hash-value (rec-hash (ref a 'x))
                                (rec-hash (abs (ref a 'y)))))

     Note: The base method of object-hash hashes any object to a single hash value (the actual value depends on hash-salt if object-hash is called from default-hash, and a fixed constant value otherwise. It's because object's equality semantics can be customized separately, and we can't compute a non-constant hash value without knowing the equality semantics.

     This behavior is the last ``safety net''; in general, you should define object-hash method on your class if the instances of your class can ever be hashed. 註: object-hashのベースメソッドは、どんな引数に対しても単一の値を返します (具体的な値は、object-hashが default-hashから呼ばれた場合はhash-saltに依存します。それ以外の場合は固定値です)。これは、オブジェクトの等価性が自由に設定できるからで、等価性を知らずに意味のあるハッシュ値を計算できないあらです。

     この振る舞いは最後の安全ネットと考えるべきで、一般には自分で定義したクラスのインスタンスがハッシュされる可能性があるなら、必ずobject-hashメソッドを定義するようにしてください。

 -- Method: object-hash (obj <top>) rec-hash
 -- Method: object-hash (obj <top>)
     These two methods are defined by the system and ensures the backward compatibility and the behavior of default-comparator. Be careful not to replace these methods by defining the exactly same specializers.  In future versions of Gauche, attempts to replace these methods will raise an error. これら二つのメソッドはシステムで定義されており、後方互換性およびdefault-comparatorの正しい振る舞いを保証しています。全く同じスペシャライザを持つメソッドを定義することでこれらを置き換えてしまわないように注意してください。将来のバージョンでは、これらのメソッドを置き換えるのはエラーになる予定です。

 -- Function: combine-hash-value ha hb
     Returns a hash value which is a combination of two hash values, HA and HB.  The guaranteed invariance is that if (= ha1 ha2) and (= hb1 hb2) then (= (combine-hash-value ha1 hb1) (combine-hash-value ha2 hb2)). This is useful to write user-defined object-hash method. 二つのハッシュ値HAとHBを組み合わせたハッシュ値を返します。次の性質が保証されます：(= ha1 ha2) かつ (= hb1 hb2) ならば (= (combine-hash-value ha1 hb1) (combine-hash-value ha2 hb2))。これはユーザ定義のobject-hashメソッドを書くのに便利です。

 -- Function: hash obj
     This function is deprecated.

     Calculate a hash value of OBJ suitable for equal? hash. By default, it returns the same value as legacy-hash.  However, if this is called from default-hash or portable-hash (via object-hash method), it recurses to the calling hash function.

     The behavior is to keep the legacy code work.  Until 0.9.5, hash is the only hash function to be used for both portable hash and equal?-hash, and object-hash method takes single argument (an object to hash) and calls hash recursively whenever it needs to get a hash value of other objects pointed from the argument.

     As of 0.9.5 we have more than one hash functions that calls object-hash, so the method takes the hash function as the second argument to recurse.  However, we can't just break the legacy code; so there's a default method defined in object-hash which is invoked when no two-arg method is defined for the given object, and dispatches to one-arg method. As far as the legacy object-hash code calls hash, it calls proper function. The new code shouldn't rely on this behavior, and must use the second argument of object-hash instead. この関数は非推奨となりました。

     equal?ハッシュとして使える、OBJのハッシュ値を返します。デフォルトでは、この関数はlegacy-hashと同じ値を返します。しかし、この関数がdefault-hashかportable-hashから (object-hashを経由して)呼ばれた場合は、呼び出したハッシュ関数へと再帰します。

     この振る舞いは既存のコードを動かすためのものです。0.9.5より前は、 hashが、ポータブルなハッシュ値にもequal?ハッシュテーブルにも使えるハッシュ値を計算する唯一の関数でした。object-hashメソッドはハッシュ値を計算したいオブジェクトだけを引数に取り、もしそのオブジェクトが指す他のオブジェクトのハッシュ値が欲しいなら、hashを再帰呼び出ししていました。

     0.9.5から、object-hashはいくつかのハッシュ関数から呼び出されるようになり、第2引数に再帰すべきハッシュ関数を取るようになりました。けれども既存のコードを動かなくしてしまうわけにはいきません。そこで、 object-hashのデフォルトメソッド(2引数でマッチするメソッドが無い場合に呼ばれるもの)が、1引数のobject-hashを呼び出すように定義されています。既存のobject-hashがhashを呼び出していれば、正しいハッシュ関数へと再帰するというわけです。新たに書くコードはこの振る舞いに依存してはいけません。 2引数のobject-hashメソッドを定義してください。

 -- Function: boolean-hash bool
 -- Function: char-hash char
 -- Function: char-ci-hash char
 -- Function: string-hash str
 -- Function: string-ci-hash str
 -- Function: symbol-hash sym
 -- Function: number-hash num
     [R7RS comparator] These are hash functions for specific type of objects, defined in R7RS scheme.comparator. In Gauche, these procedures are just a wrapper of default-hash with type checks (and case folding when relevant).  These are mainly provided to conform scheme.comparator; in your code you might just want to use default-hash (or eq-hash/eqv-hash, depending on the equality predicate). これらは、R7RSのscheme.comparatorで定義された、特定の型のオブジェクト専用のハッシュ関数です。 Gaucheでは、これらの関数は単に引数の型チェックをして(必要なら大文字小文字の区別をなくした後)、組み込みのdefault-hashを呼び出しているだけです。これらはscheme.comparatorで定義されているために提供されていますが、特にポータビリティが必要でなければdefault-hash (あるいは、等価述語によってはeq-hashや eqv-hash)を呼んでしまう方が簡単だし高速です。

     The case-folding versions, char-ci-hash and string-ci-hash, calls char-foldcase and string-foldcase respectively, on the argument before passing it to hash. (see Characters, for char-foldcase. See Full string case conversion, for string-foldcase). 大文字小文字を区別しない、char-ci-hashおよびstring-ci-hashは、引数にそれぞれchar-foldcaseとstring-foldcaseを適用してから hashに渡します。 (char-foldcaseについてはCharactersを、 string-foldcaseについてはFull string case conversionを参照してください。)

 -- Function: hash-bound
 -- Function: hash-salt
     [R7RS comparator] Both evaluates to an exact nonnegative integers.  In R7RS, these are defined in scheme.comparator.

     (Note: scheme.comparator defines these as macros, in order to allow implementations optimize runtime overhead.  In Gauche we use procedures but the overhead is negligible.)

     User-defined hash functions can limit the range of the result between 0 and (hash-bound), respectively, without worrying to lose quality of hash function.  (User-defined hash functions don't need to honor (hash-bound) at all; hashtables takes modulo when necessary.)

     User-defined hash function can also take into account of the value (hash-salt) into hash calculation; the salt value may differ between runs of the Scheme processes, or even between hash table instances.  It is to avoid collision attack. Built-in hash functions already takes the salt value into account, so if your hash function is combining the hash values of primitive types, you don't need to worry about salt values. どちらも、正確な非負整数へと展開されます。R7RSでは、 scheme.comparatorライブラリで定義されています。

     (註: scheme.comparatorはこれらをマクロと定義しています。処理系がランタイムオーバヘッドを避けられるようにするためです。 Gaucheでは、呼び出しのオーバヘッドはそれほど問題にならないという立場から、どちらも手続きにしています。)

     ユーザ定義のハッシュ関数は、結果を0と(hash-bound)の間に限定してもハッシュの質を落とさないことが保証されます。(ユーザ定義のハッシュ関数は(hash-bound)を気にする必要はありません。ハッシュテーブルが必要な時にモジュロを取ります)。

     ユーザ定義のハッシュ関数はまた、(hash-salt)を計算に組み入れることができます。展開されるソルト値は、Schemeプロセスの実行ごとに異なる値を取ったり、ハッシュテーブルごとに異なる値を取るかもしれません。これは、コリジョン攻撃を回避するためのものです。組み込みのハッシュ関数は既にソルト値を考慮しているので、ユーザ定義ハッシュ関数がプリミティブ型のハッシュ値を組み合わせるだけの場合は、ソルト値を気にする必要はありません。

Basic comparators
-----------------

Equality and comparison procedures are parameters in various data structures.   A treemap needs to order its keys; a hashtable needs to see if the keys are the same or not, and it also need a hash function consistent with the equality predicate. 等価性判定と大小比較は色々なデータ構造のパラメータになっています。 treemapはキーの大小を比較します。ハッシュテーブルはキーが等しいかどうかを調べ、またハッシュ関数と等価性判定に一貫性が無ければなりません。

If we want to work on generic data structures, we need to abstract those variations of comparison schemes.  So here comes the comparator, a record that bundles closely-related comparison procedures together. ジェネリックなデータ構造を作りたければ、こういった比較についてのバリエーションを抽象化する必要があります。そのために導入されたのが比較器(comparator)です。これは、比較について関係の深いいくつかの手続きをまとめた構造体です。

There are two SRFIs that define comparators.  The one that was originally called srfi-128 has now become a part of R7RS large as scheme.comparator, and we recommend new code to use it. Gauche has all of scheme.comparator procedures built-in.  The older, and rather complex one is srfi-114; Gauche also supports it mainly for the backward compatibility. Importantly, Gauche's native <comparator> object is compatible to both scheme.comparator and srfi-114 comparators. 比較器を定義したSRFIは二つあります。srfi-128と呼ばれていた規格は R7RS largeに取り込まれ、scheme.comparatorになりました。新しいコードではそちらを使うべきです。 Gaucheはscheme.comparatorのAPIを全て組み込みで提供します。古く、より複雑なのがsrfi-114で、Gaucheはそちらは主に後方互換性のためにサポートしています。重要なのは、Gaucheの組み込みの<comparator>オブジェクトは scheme.comparatorの比較器としても srfi-114の比較器としても使えるということです。

Comparator class and constructors
.................................

 -- Builtin Class: <comparator>
     A comparator record that bundles the following procedures: 以下の手続きをひとまとめにするレコードです。

     Type test predicate
          Checks if an object can be compared with this comparator.

     Equality predicate
          See if given two objects are equal to each other; returns a boolean value.

     Ordering predicate
          Compare given two objects, and returns true iff the first one is strictly precedes the second one.  That is, this is a less-than predicate.

     Comparison procedure
          Compare given two objects, and returns either -1 (the first one is less than the second), 0 (they are equal), or 1 (the first one is greater than the second).

     Hash function
          Returns a hash value of the given object.

     型検査述語
          オブジェクトがこの比較器によって扱えるかどうかを調べます。

     等価述語
          二つのオブジェクトが等価かどうかを判定し、等価なら#tを、そうでなければ#f を返します。

     順序手続き
          二つのオブジェクトの大小関係を判定し、最初のオブジェクトが二つ目のオブジェクトより小さければ#tを、そうでなければ#fを返します。

     比較手続き
          二つのオブジェクトの大小関係を判定し、最初のオブジェクトの方が小さければ-1を、二つが等しければ0を、最初のオブジェクトの方が大きければ1を返します。

     ハッシュ関数
          オブジェクトのハッシュ値を返します。

     Scheme.comparator's comparators use the ordering predicate, while SRFI-114 comparators use the comparison procedure. Gauche's <comparator> supports both by automatically generating the missing one; that is, if you create a comparator with scheme.comparator interface, by giving an ordering predicate, Gauche automatically fills the comparison procedure, and if you create one with SRFI-114 interface by giving a comparison procedure, Gauche generates the ordering predicate. scheme.comparatorの比較器は順序手続きを使い、 SRFI-114の比較器は比較手続きを使います。 Gaucheの<comparator>は両方をサポートするために、自動的に欠けている手続きを補います。つまり、順序手続きを与えてscheme.comparatorのインタフェースで比較器を作った場合、Gaucheは自動的に比較手続きを生成しますし、比較手続きを与えてSRFI-114のインタフェースで比較器を作った場合は順序手続きが自動生成されます。

     A comparator may not have an ordering predicate / comparison procedure, and/or a hash function.  You can check if the comparator can be used for ordering or hashing by comparator-ordered? and comparator-hashable?, respectively. 比較器は、順序/比較手続き、ハッシュ関数、あるいはその両方を欠いていることもあります。比較器が順序づけやハッシュに使えるかどうかは、それぞれ comparator-ordered?と comparator-hashable?で調べることができます。

     Some built-in data types such as hashtables (see Hashtables) and treemaps (see Treemaps), take a comparator in their constructors. The sort and merge procedures also accept comparators (see Sorting and merging). Gauche組み込みのデータ型は、コンストラクタで比較器を取ることができます (例:ハッシュテーブル(Hashtables参照)、ツリーマップ(Treemaps参照))。また、ソートとマージの手続きも比較器を受け取ることができます (Sorting and merging参照。

 -- Function: make-comparator type-test equal order hash :optional name
     [R7RS comparator] Creates a new comparator form the given TYPE-TEST, EQUAL, ORDER and HASH functions, and returns it. In R7RS, this is defined in scheme.comparator

     See the description of <comparator> above for the role of those procedures. 与えられたTYPE-TEST、EQUAL、ORDER、HASHの各関数をまとめて、新たな比較器を作って返します。 R7RSではこの関数はscheme.comparatorで定義されています。

     各関数の役割については上の<comparator>の説明を参照してください。

     Note: Both scheme.comparator and srfi-114 defines make-comparator, but where scheme.comparator takes ORDER argument, srfi-114 takes COMPARE argument. Since scheme.comparator is preferable, we adopt it for the built-in interface, and give a different name (make-comparator/compare) for SRFI-114 constructor. 註: scheme.comparatorとsrfi-114は両方とも make-comparatorを定義していますが、 scheme.comparatorがORDER手続きを取るところで srfi-114はCOMPARE手続きを取ります。 scheme.comparatorの方が推奨されるので、 Gaucheでは組み込みのmake-comparatorをscheme.comparatorに合わせ、 SRFI-114の方はmake-comparator/compareという名前にしてあります。

     Actually, some arguments can be non-procedures, to use predefined procedures, for the convenience.  Even if non-procedure arguments are passed, the corresponding accessors (e.g. comparator-type-test-procedure for the type-test procedure) always return a procedure---either the given one or the predefined one. 各引数は、手続きでなく真偽値を取ることもできます。その場合、既に定義された手続きが使えるので便利です。但し、引数に真偽値を渡した場合でも、アクセサは補われた手続きの方を返します。 (例えばtype-test引数に対応するアクセサは comparator-type-test-procedureですが、これは常に手続きを返します。)

     The TYPE-TEST argument must be either #t or a predicate taking one argument to test suitability of the object for comparing by the resulting comparator. If it is #t, a procedure that always return #t is used. type-test引数は、#tもしくは1引数の手続きでなければなりません。手続きの場合、それは渡されたオブジェクトが比較器の他の手続きに渡せるかどうかを判定する述語です。#tの場合、どんなオブジェクトに対しても#tを返す手続きが補われます。

     The EQUAL argument must a predicate taking two arguments to test equality. EQUAL引数は二つの引数を取りその等価性を判定する述語でなければなりません。

     the ORDER argument must be either #f or a procedure taking two arguments and returning a boolean value. It must return #t iff the first argument strictly precedes the second one.  If #f is passed, the comparator can not be used for ordering. ORDER手続きは#fもしくは二つの引数を取り真偽値を返す手続きでなければなりません。手続きの場合、最初の引数が二番目の引数より厳密に手前にある場合にのみ#tを返します。#fが渡された場合は、作られる比較器は順序づけには使えません。

     The HASH argument must be either #f, or a procedure taking one argument and returning nonnegative exact integer.  If #f is given, it indicates the comparator can't hash objects; the predefined procedure just throws an error. HASH引数は#fか、一つの引数を取り非負の正確な整数をハッシュ値として返す手続きでなければなりません。 #fが渡された場合は、この比較器ではハッシュ値を取れないことを意味します。この場合、呼ばれたらエラーを投げる手続きが補われます。

     The fifth, optional argument NAME, is Gauche's extension. It can be any object but usually a symbol; it is only used when printing the comparator, to help debugging. 最後の、省略可能な引数NAMEはGaucheの拡張です。どんなオブジェクトでも構いませんが、通常はシンボルが渡されます。これは比較器を出力する時に使われるだけですが、デバッグには役に立ちます。

 -- Function: make-comparator/compare type-test equal compare hash :optional name
     This is SRFI-114 comparator constructor.  In SRFI-114, this is called make-comparator.  Avoiding name conflict, we renamed it. If you (use srfi-114) you get the original name make-comparator (and the built-in make-comparator is shadowed). This is provided for the backward compatibility, and new code should use built-in make-comparator above. これはSRFI-114比較器のコンストラクタです。SRFI-114ではこれが make-comparatorと呼ばれていますが、名前の衝突を避けるために別の名前を用意しました。 (use srfi-114)した場合は、SRFI-114のコンストラクタが元の名前で使えるようになります(組み込みのmake-comparatorがシャドウされます。) これは後方互換性のために提供されています。新たなコードは上に示した組み込みのmake-comparatorを使ってください。

     It's mostly the same as make-comparator above, except the following: 以下の点を除き、上のmake-comparatorとほぼ同じです。

       * The third argument (COMPARE) is a comparison procedure instead of an ordering predicate. It must be either #f, or a procedure taking two arguments and returning either -1, 0, or 1, depending on whether the first argument is less than, equal to, or greater than the second argument. If it is #f, it indicates the comparator can't order objects. 第3引数(COMPARE)には順序手続きのかわりに比較手続きを渡します。この引数は#fか、二つの引数を取りそれらの大小関係を判定する手続きでなければなりません。手続きの場合、引数の最初の方が小さいか、両者が等しいか、最初の方が大きいか、に応じて-1, 0, 1をそれぞれ返さなければなりません。#fの場合、対象とするオブジェクトの集合に全順序関係がつけられないことを表します。

       * You can pass #t to the EQUAL argument when you give a comparison procedure.  In that case, equality is determined by calling the comparison procedure and see if the result is 0. 比較手続きを与えた場合、EQUAL手続きに#tを渡すことができます。その場合、等価性の判定は比較手続きが0を返すかどうかで行われます。

Comparator predicates and accessors
...................................

 -- Function: comparator? obj
     [R7RS comparator] Returns true iff OBJ is a comparator. In R7RS, this is provided from scheme.comparator. OBJが比較器である場合に#tを、そうでなければ#fを返します。 R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Method: object-equal? (a <comparator>) (b <comparator>)
     Comparing two comparators by equal? compares their contents, via this method.  Even A and B are comparators created separately, they can be equal? if all of their slots are the same.

     This is Gauche's extension.  The standard says nothing about equality of comparators, but it is sometimes useful if you can compare two. 二つの比較器が等価かどうかをequal?で調べた場合、比較はこのメソッドを介して、各スロットが等価かどうかで判定されます。比較器AとBが別々に作られたものであっても、各スロットの内容が等価であればequal?とみなされます。

     これはGaucheの拡張です。標準は比較器同士の等価性については何も定義していません。けれども、時には等価判定が便利なことがあります。

          (equal? (make-comparator #t equal? #f hash 'foo)
                  (make-comparator #t equal? #f hash 'foo))
            => #t

          ;; The following may be #t or #f, depending on how the anonymous
          ;; procedure is allocated.
          ;; 次の式は、無名手続きがどのようにアロケートされるかによって、#tにも#fにも
          ;; なり得る。
          (equal? (make-comparator (^x x) eq? #f #f)
                  (make-comparator (^x x) eq? #f #f))

 -- Function: comparator-flavor cmpr
     Returns a symbol ordering if CMPR is created with scheme.comparator constructor, and returns comparison if CMPR is created with SRFI-114 constructor.

     Usually applications don't need to distinguish these two kinds of comparators, for either kind of comparators can behave just as another kind.  This procedure is for some particular cases when one wants to optimize for the underlying comparator implementation. CMPRがscheme.comparatorコンストラクタで作られた場合はシンボルorderingを、 srfi-114コンストラクタで作られた場合はシンボルcomparisonを返します。

     アプリケーションは通常両者を区別する必要はありません。一方の比較器はもう一方の比較器としても使うことができるからです。比較器の実装に特化した最適化をしたい場合にのみ、区別が必要です。

 -- Function: comparator-ordered? cmpr
 -- Function: comparator-hashable? cmpr
     [R7RS comparator] Returns true iff a comparator CMPR can be used to order objects, or to hash them, respectively. In R7RS, this is provided from scheme.comparator. 比較器CMPRが、オブジェクトの順序づけあるいはハッシュに使える場合にそれぞれ#tを返します。 R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: comparator-type-test-procedure cmpr
 -- Function: comparator-equality-predicate cmpr
 -- Function: comparator-ordering-predicate cmpr
 -- Function: comparator-hash-function cmpr
     [R7RS comparator] Returns type test procedure, equality predicate, ordering procedure and hash function of comparator CMPR, respectively. In R7RS, this is provided from scheme.comparator.

     These accessors always return procedures; if you give #f to the ORDER or HASH argument of the constructor, comparator-ordering-predicate and comparator-hash-function still return a procedure, which will just raise an error. 比較器の型検査述語、等価述語、順序手続きおよびハッシュ関数をそれぞれ返します。 R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

     これらの手続きは常に手続きを返します。make-comparatorで ORDERやHASHに#fを渡した場合でも、エラーを投げるだけの手続きが返されます。

 -- Function: comparator-comparison-procedure cmpr
     [SRFI-114] This is a SRFI-114 procedure, but sometimes handy with scheme.comparator comparators. Returns a procedure that takes two objects that satisfy the type predicates of CMPR.  The procedure returns either -1, 0 or 1, depending on whether the first object is less than, equal to, or greater than the second.  The comparator must be ordered, that is, it must have an ordering predicate (or a comparison procedure, if it is created by SRFI-114 constructor). これはSRFI-114の手続きですが、 scheme.comparator比較器でも時々便利なことがあります。 CMPRの型検査述語を満たす二つのオブジェクトを取り、-1、0、1のいずれかを返す手続きを返します。二つのオブジェクトのうち最初の方が小さければ-1が、等しければ0が、大きければ1が返されます。比較器は大小比較可能でなけばなりません(順序手続きが渡されるか、あるいはSRFI-114コンストラクタで比較手続きが渡されるか)。

 -- Function: comparator-test-type cmpr obj
 -- Function: comparator-check-type cmpr obj
     [R7RS comparator] Test whether OBJ can be handled by a comparator CMPR, by applying CMPR's type test predicate. The former (comparator-test-type) returns a boolean values, while the latter (comparator-check-type) signals an error when OBJ can't be handled.

     In R7RS, this is provided from scheme.comparator. OBJが比較器CMPRで扱えるオブジェクトかどうかを、 CMPRの型検査述語を適用して調べます。 comparator-test-typeは結果の真偽値を返します。 comparator-check-typeはOBJが扱えないオブジェクトである場合にエラーを投げます。

     R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: =? cmpr obj obj2 obj3 ...
 -- Function: <? cmpr obj obj2 obj3 ...
 -- Function: <=? cmpr obj obj2 obj3 ...
 -- Function: >? cmpr obj obj2 obj3 ...
 -- Function: >=? cmpr obj obj2 obj3 ...
     [R7RS comparator] Compare objects using a comparator CMPR.  All of OBJ, OBJ2, OBJ3 ... must satisfy the type predicate of CMPR.  When more than two objects are given, the order of comparison is undefined.

     In order to use <?, <=?, >? and >=?, comparator must be ordered.

     In R7RS, this is provided from scheme.comparator. 比較器CMPRを使ってオブジェクトを比較します。 OBJ, OBJ2, OBJ3 ...は全てcmprの型検査述語を満たさなければなりません。 3つ以上のオブジェクトが渡された場合、比較の順番は規定されていません。

     <?、<=?、>?、>=?を使うためには比較器は順序比較可能でなければなりません。

     R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: comparator-hash cmpr obj
     [R7RS comparator] Returns a hash value of OBJ with the hash function of a comparator CMPR.  The comparator must be hashable, and OBJ must satisfy comparator's type test predicate.

     In R7RS, this is provided from scheme.comparator. 比較器CMPRのハッシュ関数を使ってOBJのハッシュ値を計算して返します。比較器はハッシュ計算可能でなければなりません。また、OBJは比較器の型検査述語を満たさなければなりません。

     R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: comparator-compare cmpr a b
     [SRFI-114] Order two objects A and B using CMPR, and returns either one of -1 (A is less than B), 0 (A equals to B), or 1 (A is greater than B). Objects must satisfy CMPR's type test predicate.

     A simple comparison can be done by <? etc, but sometimes three-way comparison comes handy.  So we adopt this procedure from srfi-114. ふたつのオブジェクトAとBの順序を調べ、 Aが先 (小さい) なら -1を、等しければ0を、 Aが後 (大きい) なら 1を返します。 AとBはともにCMPRの型検査述語を満たさねばなりません。

     単純な比較なら<?等の手続きでできますが、時に3分岐の比較が便利なこともあります。そのため、srfi-114からこの手続きを採用しました。

Predefined comparators
......................

 -- Variable: default-comparator
     [SRFI-114] This variable bounds to a comparator that is used by default in many context.

     It can compare most of Scheme objects, even between objects with different types.  In fact, it is defined as follows: この変数は、様々な場所でオブジェクトを比較する際のデフォルトとして使われる比較器に束縛されています。

     デフォルト比較器は次のとおり定義されており、ほぼすべてのSchemeオブジェクト間の比較が出来ます。

          (define default-comparator
            (make-comparator/compare #t equal? compare default-hash
                                     'default-comparator))

     As you see in the definition, equality, ordering and hashing are handled by equal?, compare and default-hash, respectively.  They takes care of builtin objects, and also equal? and compare handle the case when two objects () are of different types. 定義からわかるように、等価述語、比較手続き、そしてハッシュ計算はそれぞれ equal?、compare、default-hashで処理されます。組み込みオブジェクト、及び二つの異なる型の間の比較についてはそれらが処理します。

     For objects of user-defined classes, those procedures call generic functions object-equal?, object-compare, and object-hash, respectively.   Defining methods for them automatically extended the domain of default-comparator. ユーザ定義クラスのオブジェクトについては、上記手続きがそれぞれジェネリック関数 object-equal?、object-compare、object-hashを呼び出します。これらのメソッドを定義することにより、 default-comparatorの定義域も自動的に拡張されます。

     Scheme.comparator defines another way to extend default-comparator. See comparator-register-default! below for the details. scheme.comparatorは、default-comparatorを拡張する別の方法を定義しています。下のcomparator-register-default!の項を参照してください。

 -- Function: comparator-register-default! comparator
     [R7RS comparator] In R7RS, this is provided from scheme.comparator. This is the scheme.comparator way for user programs to extend the behavior of the default-comparator (which is what make-default-comparator returns).

     Note that, in Gauche, you can also extend default comparator's behavior by defining specialized methods for object-equal?, object-compare and object-hash. See the description of default-comparator above, for the details. R7RSではこの手続きはscheme.comparatorライブラリで提供されます。これは、default-comparator(make-default-comparatorが返す比較器)の振る舞いをユーザプログラムが拡張できるようにする、 scheme.comparatorが定める方法です。

     Gaucheでは、object-equal?、object-compare、object-hashに特殊化したメソッドを定義することでも、デフォルト比較器を拡張できることに留意してください。詳しくは上のdefault-comparatorの説明を参照のこと。

     In fact, Gauche uses those generic functions to handle the registered comparators; methods specialized for <top> are defined for these generic functions, which catches the case when default-comparator is applied on object(s) of user-defined classes that don't have specialized methods defined for those generic functions. The catching method examines registered comparators to find one that can handle passed argument(s), and if it finds one, use it. 実際、Gaucheではこれらのジェネリックファンクションを使って、登録されたデフォルト比較器を処理しています。これらのジェネリックファンクションには、あらかじめ<top>に特殊化されたメソッドが定義されており、 default-comparatorがユーザ定義クラスのオブジェクトに使われ、かつそのクラスに特殊化されたメソッドが定義されていない場合を捕まえます。そして、登録された比較器から与えられた引数に適用可能なものを探し、見つかればそれを使います。

     You might frown at this procedure having a global side-effect. Well, scheme.comparator explicitly prohibits comparators registered by this procedure alters the behavior of the default comparator in the existing domain---it is only allowed to handle objects that aren't already handled by the system's original default comparator and other already registered comparators.  So, the only effect of adding new comparator should make the default comparator work on objects that had been previously raised an error. この手続きがグローバルな副作用を持つことに顔をしかめる人もいるかもしれません。 scheme.comparatorでは、デフォルトの比較器や登録された比較器が既にカバーしている定義域と重複する定義域を持つ比較器を登録することを禁じています。言い換えれば、comparator-register-default!で定義できるのは、デフォルトの比較器や既に登録された比較器が処理できないオブジェクトを扱う比較器だけです。従って、新たな比較器を登録することによる副作用は、それまでdefault-comparatorが扱えなかったオブジェクトを扱えるようになるというだけで、既に扱えていたオブジェクトに対する default-comparatorの動作が変わってしまうということはありません。

     In reality, it is impossible to enforce the condition.  If you register a comparator whose domain overlaps overlaps the domain the default comparator (and its extensions via Gauche's methods), the program becomes non-portable at that moment.  In the current version, the comparators registered by comparator-register-default! has the lowest precedence on the dispatch mechanism, but you shouldn't count on that. 尤も、現実にその条件を強制することは不可能です。もし、既にデフォルトの比較器の定義域(および、Gaucheのメソッドにより拡張された定義域) と重なるような定義域を持つ比較器を登録してしまったら、その時点でプログラムの移植性は損なわれます。現在のバージョンでは、comparator-register-default! で登録された比較器は最も低い優先度を持ちますが、その動作をあてにすべきではありません。

 -- Variable: eq-comparator
 -- Variable: eqv-comparator
 -- Variable: equal-comparator
     [SRFI-114] Built-in comparators that uses eq?, eqv? and equal? for the equality predicate, respectively.  They accept any kind of Scheme objects.  Each has corresponding hash functions (i.e. eq-hash for eq-comparator, eqv-hash for eqv-comparator and default-hash for equal-comparator). Only eq-comparator is ordered, using eq-compare to order the objects (see Comparison, for eq-compare). それぞれ、等価述語にeq?、eqv?、equal?を使う組み込みの比較器です。全てのSchemeオブジェクトを受け付けます。対応するハッシュ関数(eq-comparatorはeq-hash、 eqv-comparatorはeqv-hash、equal-comparatorは hash)を備えています。 eq-comparatorのみ、eq-compareを使った順序づけが可能です (eq-compareについてはComparison参照)。

     Note that eq-comparator and eqv-comparator are not equivalent from what make-eq-comparator and make-eqv-comparator return, respectively.  The latter two are defined in scheme.comparator and specified to use default-hash for the hash function.  It is heavier than eq-hash/eqv-hash, and it can't be used for circular objects, nor for the mutable objects with which you want to hash them by identity.  We provide eq-comparator and eqv-comparator in case you want to avoid limitations of default-hash. eq-comparatorとeqv-comparatorはそれぞれ、 make-eq-comparator and make-eqv-comparatorが返す比較器とは等価でないことに注意してください。後者の手続きはscheme.comparator で規定されていますが、ハッシュ関数にはdefault-hashを使うように指定されています。 default-hashはeq-hashやeqv-hashより重く、ループのある構造は扱えず、また変更可能なオブジェクトの同一性のみに基づいてハッシュ値を計算するのには使えません。こういったdefault-hashの制限を避けたい場合のために eq-comparatorとeqv-comparatorを用意しました。

 -- Variable: boolean-comparator
 -- Variable: char-comparator
 -- Variable: char-ci-comparator
 -- Variable: string-comparator
 -- Variable: string-ci-comparator
     [SRFI-114] Compare booleans, characters, and strings, respectively. The *-ci-* variants uses case-insensitive comparison. All have appropriate hash functions, too.

     The string case-insensitive comparison uses Unicode full-string case conversion (see Full string case conversion). それぞれ、真偽値、文字、文字列を比較する比較器です。 *-ci-*がついている手続きは大文字小文字の区別をしません。全て、適切なハッシュ関数も備えています。

     文字列の大文字小文字の区別をしない比較は、Unicodeのfull-string case conversion に従います (Full string case conversion参照)。

 -- Variable: exact-integer-comparator
 -- Variable: integer-comparator
 -- Variable: rational-comparator
 -- Variable: real-comparator
 -- Variable: complex-comparator
 -- Variable: number-comparator
     [SRFI-114] Compare exact integers, integers, rational numbers, real numbers, complex numbers and general numbers, respectively. In Gauche number-comparator is the same as complex-comparator.

     The equality are determined by =. For exact integer, integer, rational and real comparators, the order is the numerical order.  Two complex numbers are compared first by their real components, and then their imaginary components only if the real components are the same.

     Note that those comparator rejects NaN. You need make-inexact-real-comparator in srfi-114 module to compare NaNs with your own discretion. See Comparators, for the details. それぞれ、正確な整数、整数、有理数、実数、複素数、そして全ての数値を比較する比較器です。 Gaucheではnumber-comparatorはcomplex-comparatorと同じです。

     等価性は=により判定されます。正確な整数、整数、有理数および実数の比較器では、比較手続きは数値の大小に基づいて判定されます。複素数の比較においては、まず実部の大小が比べられ、実部が等しい場合に虚部の大小が比べられます。

     これらの比較器はNaNを扱いません。 NaNを扱いたい場合は、srfi-114モジュールのmake-inexact-real-comparator 手続きを使って、NaNの比較方法を指定する必要があります。詳しくはComparatorsを参照してください。

 -- Variable: pair-comparator
 -- Variable: list-comparator
 -- Variable: vector-comparator
 -- Variable: uvector-comparator
 -- Variable: bytevector-comparator
     [SRFI-114] The default comparators to compare pairs, lists, vectors, uniform vectors and bytevectors (which is synonym to u8vector). Their respective elements are compared with the default comparators.

     Note that lists are compared by dictionary order ((1 2 3) comes before (1 3)), while in vector-families shorter ones are ordered first ( #(1 3) comes before #(1 2 3)). ペア、リスト、ベクタ、ユニフォームベクタ、バイトベクタ(u8vectorの別名)をそれぞれ比較するための比較器です。各データ型の要素についてはデフォルトの比較器(default-comparator)が使われます。

     リストは辞書順で比較されますが(例:(1 2 3)は(1 3)より前)、ベクタの仲間はまず長さが短いものが先に来て、それから内容で比較されることに注意してください (#(1 3)は#(1 2 3)より前)。

Combining comparators
.....................

 -- Function: make-default-comparator
     [R7RS comparator] Returns a default comparator.  In Gauche, this returns the default-comparator object. In R7RS, this is provided from scheme.comparator. デフォルト比較器を返します。Gaucheでは常に唯一のdefault-comparatorが返されます。 R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: make-eq-comparator
 -- Function: make-eqv-comparator
     [R7RS comparator] Returns comparators that use eq? and eqv? for its equality predicate, respectively.  Note that they use default-hash for hash functions, as specified by scheme.comparator, which has a few drawbacks: You can't use it if you want to hash based on identity of mutable objects, it diverges on circular objects, and it is slow if applied on a large structures.  We recommend to use eq-comparator or eqv-comparator if possible (see Predefined comparators).

     In R7RS, this is provided from scheme.comparator. eq?およびeqv?を等価述語に使う比較器をそれぞれ返します。これらの関数が返す比較器のハッシュには、default-hashを使うことが scheme.comparatorで規定されていますが、それにはいくつか欠点があります。変更可能なオブジェクトの同一性に基づいたハッシュ関数が欲しい場合は使えませんし、循環するオブジェクトでは発散します。大きな構造をハッシュしようとすると遅くなります。可能ならば、eq-comparatorやeqv-comparatorを使うことを推奨します(Predefined comparators)参照。)

     R7RSではこの手続きはscheme.comparatorライブラリで提供されます。

 -- Function: make-reverse-comparator cmpr
     [SRFI-114] Returns a comparator with the same type test predicate, equality procedure, and hash function as the given comparator, but the comparison procedure is flipped. 与えられた比較器CMPRと同じ型検査述語、等価述語、ハッシュ関数を持ち、大小比較だけが逆になっているような比較器を返します。

 -- Function: make-key-comparator cmpr test key
     Suppose you have some kind of structure, but you only need to look at one part of it to compare them.

     Returns a new comparator that uses TEST as type test predicate. Its equality predicate, comparison procedure and hash function are constructed by applying KEY to the argument(s) then passing the result to the corresponding procedure of CMPR.  If CMPR lacks comparison procedure and/or hash function, so does the returned comparator. 何らかの構造体があって、その比較に際してはその中の一つの要素を見るだけで良い、という場合に使える手続きです。

     比較器を作って返します。型検査述語にはTESTが使われます。等価述語、比較手続き、ハッシュ関数については、それらの引数にKEYを適用して得られた値を、比較器CMPRの対応する手続きに渡すような手続きとなります。 CMPRが比較手続きやハッシュ関数を欠いている場合は、返される比較器も同様に比較手続きやハッシュ関数を欠いたものとなります。

     In the following example, the tree-map users compares the given user records only by the username slots: 次の例では、ツリーマップusersは userレコードのusernameスロットだけを見て比較を行います。

          (use gauche.record)

          (define-record-type user #t #t
            username      ; string
            password-hash ; string
            comment)      ; string

          (define users   ; table of users, managed by tree-map
            (make-tree-map
              (make-key-comparator string-comparator user? user-username)))

 -- Function: make-tuple-comparator cmpr1 cmpr2 ...
     Creates a comparator that compares lists of the form (x1 x2 ...), where each element is compared with the corresponding comparator. For example, (make-tuple-comparator c1 c2 c3) will compare three-element list, whose first elements are compared by C1, second elements by C2 and third elements by C3. リスト(x1 x2 ...)の各要素をそれぞれCMPR1 cmpr2 ... で比較するような比較器を返します。例えば(make-tuple-comparator c1 c2 c3)が返すのは、 3要素のリストを受け入れ、最初の要素がC1で、二番目の要素がC2で、最後の要素がC3で比較されるような比較器です。

Numbers
=======

Gauche supports the following types of numbers

multi-precision exact integer
     There's no limit of the size of number except the memory of the machine.

multi-precision exact non-integral rational numbers.
     Both denominator and numerator are represented by exact integers. There's no limit of the size of number except the memory of the machine.

inexact floating-point real numbers
     Using double-type of underlying C compiler, usually IEEE 64-bit floating point number.

inexact floating-point complex numbers
     Real part and imaginary part are represented by inexact floating-point real numbers.

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

多倍長の正確な整数
     メモリの許す限りの精度が扱えます。

多倍長の正確な非整数の有理数
     分母と分子は正確な整数で表現されます。メモリの許す限りの精度が扱えます。

浮動小数点の不正確な実数
     実装に使われるC言語のdouble型で表現されます。通常IEEE 64bit浮動小数点数です。

浮動小数点の不正確な複素数
     実部と虚部はそれぞれ浮動小数点の不正確な実数で表現されます。

Number classes
--------------

 -- Builtin Class: <number>
 -- Builtin Class: <complex>
 -- Builtin Class: <real>
 -- Builtin Class: <rational>
 -- Builtin Class: <integer>
     These classes consist a class hierarchy of number objects. <complex> inherits <number>, <real> inherits <complex>,<rational> inherits <real> and <integer> inherits <rational>.

     Note that these classes do not exactly correspond to the number hierarchy defined in R7RS.  Especially, only exact integers are the instances of the <integer> class.  That is, 数値オブジェクトのクラス階層を構成します。<complex>は <number>を継承し、<real>は<complex>を継承し、 <rational>は<real>を継承し、 <integer>は<rational>を継承します。

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

          (integer? 1)        => #t
          (is-a? 1 <integer>) => #t
          (is-a? 1 <real>)    => #t

          (integer? 1.0)        => #t
          (is-a? 1.0 <integer>) => #f
          (is-a? 1.0 <real>)    => #t

          (class-of (expt 2 100)) => #<class <integer>>
          (class-of (sqrt -3)) => #<class <complex>>

Numerical predicates
--------------------

 -- Function: number? obj
 -- Function: complex? obj
 -- Function: real? obj
 -- Function: rational? obj
 -- Function: integer? obj
     [R7RS base] Returns #t if OBJ is a number, a complex number, a real number, a rational number or an integer, respectively.   In Gauche, a set of numbers is the same as a set of complex numbers. A set of rational numbers is the same as a set of real numbers, except +inf.0, -inf.0 and +nan.0 (since we have only limited-precision floating numbers). OBJがそれぞれ数、複素数、実数、有理数、整数ならば#tを返します。 Gaucheでは、数の集合は複素数の集合と同一であり、有理数の集合は +inf.0, -inf.0, +nan.0を除いた実数の集合と同一 (浮動小数点数が有限精度であるため)です。

          (complex? 3+4i)   => #t
          (complex? 3)      => #t
          (real? 3)         => #t
          (real? -2.5+0.0i) => #t
          (real? #e1e10)    => #t
          (integer? 3+0i)   => #t
          (integer? 3.0)    => #t

          (real? +inf.0)     => #t
          (real? +nan.0)     => #t
          (rational? +inf.0) => #f
          (rational? +nan.0) => #f

     Note: R6RS adopts more strict definition on exactness, and notably, it defines a complex number with non-exact zero imaginary part is not a real number.   Currently Gauche doesn't have exact complex numbers, and automatically coerces complex numbers with zero imaginary part to a real number. Thus R6RS code that relies on the fact that (real? 1+0.0i) is #f won't work with Gauche. R6RSでは正確性についてより厳密な定義がなされ、特に非正確なゼロを虚数部に持つ複素数は実数ではないと規定されています。 Gaucheは今のところ正確な複素数を持たず、虚部がゼロの複素数は自動的に実数に変換されます。従ってR6RSのコードのうち、 (real? 1+0.0i)が#fであることを当てにしているものはうまく動かないでしょう。

 -- Function: real-valued? obj
 -- Function: rational-valued? obj
 -- Function: integer-valued? obj
     [R6RS] In Gauche these are just an alias of real?, rational? and integer?.  They are provided for R6RS compatibility.

     The difference of those and non -valued versions in R6RS is that these returns #t if OBJ is a complex number with nonexact zero imaginary part.   Since Gauche doesn't distinguish complex numbers with zero imaginary part and real numbers, we don't have the difference. Gaucheではこれらの手続きはそれぞれreal?、rational?、およびinteger?の別名となっています。これらはR6RSコードとの互換性のために提供されています。

     R6RSで規定されている、これらの手続きと-valuedがついていない手続きの違いは、これらの手続きは非正確なゼロの虚部を持つ複素数に対しても#tを返すということです。Gaucheではゼロの虚部を持つ複素数は実数とみなしているので、この違いは現れません。

 -- Function: exact? obj
 -- Function: inexact? obj
     [R7RS base] Returns #t if OBJ is an exact number and an inexact number, respectively. OBJがそれぞれ正確な数、不正確な数ならば#tを返します。

          (exact? 1)       => #t
          (exact? 1.0)     => #f
          (inexact? 1)     => #f
          (inexact? 1.0)   => #t

          (exact? (modulo 5 3)) => #t
          (inexact? (modulo 5 3.0)) => #f

 -- Function: exact-integer? obj
     [R7RS base] Same as (and (exact? obj) (integer? obj)), but more efficient. (and (exact? obj) (integer? obj))と等価ですが、より高速です。

 -- Function: zero? z
     [R7RS base] Returns #t if a number Z equals to zero. 数値Zがゼロに等しければ#tを返します。

          (zero? 1)        => #f
          (zero? 0)        => #t
          (zero? 0.0)      => #t
          (zero? 0.0+0.0i) => #t

 -- Function: positive? x
 -- Function: negative? x
     [R7RS base] Returns #t if a real number X is positive and negative, respectively.  It is an error to pass a non-real number. 実数Xがそれぞれ正または負なら#tを返します。非実数を渡すとエラーになります。

 -- Function: finite? z
 -- Function: infinite? z
 -- Function: nan? z
     [R7RS inexact] For real numbers, returns #f iff the given number is finite, infinite, or NaN, respectively.

     For non-real complex numbers, finite? returns #t iff both real and imaginary components are finite, infinite? returns #t if at least either real or imaginary component is infinite, and nan? returns #t if at least either real or imaginary component is NaN.  (Note: It is incompatible to R6RS, in which these procedures must raise an error if the given argument is non-real number.)

     In R7RS, these procedures are in (scheme inexact) library. 実数に対して、それが有限、無限、NaNであればそれぞれ#tを返します。

     非実数の複素数に対しては、finite?は実数部と仮数部がともに有限なら#tを、infinite?は実数部と仮数部の少なくともどちらかが無限なら#tを、nan?は実数部と仮数部の少なくともどちらかが NaNなら#tを返します。(これはR6RSとは非互換です。R6RSではこれらの手続きは引数に非実数の数が与えられた場合はエラーを通知しなければならないからです。)

     R7RSではこれらの手続きは(scheme inexact)ライブラリにあります。

 -- Function: odd? n
 -- Function: even? n
     [R7RS base] Returns #t if an integer N is odd and even, respectively.  It is an error to pass a non-integral number. 整数Nがそれぞれ奇数または偶数なら#tを返します。非整数を渡すとエラーになります。

          (odd? 3)     => #t
          (even? 3)    => #f
          (odd? 3.0)   => #t

 -- Function: fixnum? n
 -- Function: bignum? n
     [R7RS fixnum] Returns #t iff N is an exact integer whose internal representation is fixnum and bignum, respectively. R7RS-large defines fixnum? in scheme.fixnum library; bignum? is Gauche's extension. Portable Scheme programs don't need to care about the internal representation of integer.   These are for certain low-level routines that does particular optimization.

     See R7RS fixnum, for the comprehensive fixnum library. Nが正確な整数で、かつ内部的にそれぞれfixnumもしくはbignum で表現されているときに#tを返します。R7RS-largeは scheme.fixnumライブラリでfixnum?を定義しています。 bignum?はGauche拡張です。通常のSchemeプログラムは整数の内部表現を気にする必要はありません。これらの手続きは、ある種の最適化を行う低レベル手続きのために用意されています。

     fixnumを扱う包括的なライブラリはR7RS fixnumを参照してください。

 -- Function: flonum? x
     [R7RS flonum] Returns #t if X is a number represented by a floating-point number, #f otherwise.  In Gauche, inexact real numbers are flonums.

     See R7RS flonum, for comprehensive flonum library. Xが浮動小数点数で表現される数値の場合に#tを、それ以外の場合に #fを返します。Gaucheでは、不正確な実数がflonumです。

     flonumを扱う包括的なライブラリはR7RS flonumを参照してください。

Numerical comparison
--------------------

 -- Function: = z1 z2 z3 ...
     [R7RS base] If all the numbers Z are equal, returns #t. 与えられた全ての数値Zが等しければ#tを返します。

          (= 2 2)          => #t
          (= 2 3)          => #f
          (= 2 2.0)        => #t
          (= 2 2.0 2.0+0i) => #t
          (= 2/4 1/2)      => #t

 -- Function: < x1 x2 x3 ...
 -- Function: <= x1 x2 x3 ...
 -- Function: > x1 x2 x3 ...
 -- Function: >= x1 x2 x3 ...
     [R7RS base] Returns #t If all the real numbers X are monotonically increasing, monotonically nondecreasing, monotonically decreasing, or monotonically nonincreasing, respectively. 与えられた全ての実数Xがそれぞれ単調増加、単調非減少、単調減少、単調非増加している場合に#tを返します。

 -- Function: max x1 x2 ...
 -- Function: min x1 x2 ...
     [R7RS base] Returns a maximum or minimum number in the given real numbers, respectively. If any of the arguments are NaN, NaN is returned. 与えられた実数のうち、それぞれ最大と最小のものを返します。引数にNaNが含まれていた場合は、NaNが返されます。

     See also find-min and find-max in Selection and searching in collection. Selection and searching in collectionの find-minとfind-maxも参照。

 -- Function: min&max x1 x2 ...
     Returns a maximum and minimum number in the given real numbers. 与えられた実数から、最大値と最小値の二つの値を返します。

     See also find-min&max in Selection and searching in collection. Selection and searching in collectionの find-min&maxも参照。

 -- Function: approx=? x y :optional relative-tolerance absolute-tolerance
     Returns #t iff two numbers are approximately equal within the given error tolerance.

       * If at least one of X or Y is NaN, returns #f.

       * If either one is infinity, returns #t iff the other one is also infinity of the same sign.

       * Otherwise, return a boolean value computed as follows:

               (<= (abs (- x y))
                   (max (* (max (abs x) (abs y)) relative-tolerance)
                        absolute-tolerance))

     If at least one of X or Y are non-real complex number, magnitude is used in place of abs.

     When omitted, RELATIVE-TOLERANCE is assumed to be (flonum-epsilon), and ABSOLUTE-TOLERANCE is (flonum-min-denormalized). That is, by default, approx=? tolerates 1 ULP (unit in the last place) error.

     The ABSOLUTE-TOLERANCE argument is useful when arguments are close to zero, in which case relative tolerance becomes too small. 二つの数値が与えられたエラー許容範囲内で等しいとみなせる場合に#tを、そうでなければ#fを返します。

       * XとYの少なくとも一方がNaNであれば、常に#fを返します。

       * 一方が無限大である場合、もう一方も同じ符号の無限大である場合のみ#tを、そうでなければ#fを返します。

       * そうでない場合、次の式により一致が判定されます。

               (<= (abs (- x y))
                   (max (* (max (abs x) (abs y)) relative-tolerance)
                        absolute-tolerance))

     XかYの少なくとも一方が非実数の複素数である場合は、 absのかわりにmagnitudeが使われます。

     省略された場合、relative-toleranceには (flonum-epsilon)の値が、ABSOLUTE-TOLERANCEには (flonum-min-denormalized)の値が使われます。すなわち、デフォルトではapprox=?は 1 ULP (unit in the last place)のエラーを許容するということです。

     ABSOLUTE-TOLERANCE引数は、引数がともにゼロに近く、相対許容範囲が小さくなりすぎる場合に便利です。

 -- Function: flonum-epsilon
 -- Function: flonum-min-normalized
 -- Function: flonum-min-denormalized
     Returns flonums with the following characteristics, respectively:

     flonum-epsilon
          Returns the least positive flonum e such that, for a normalized flonum x, x and (* x (+ 1.0 e)) are distinguishable.

     flonum-min-normalized
          Returns the least positive flonum representable as normalized floating-point number.

     flonum-min-denormalized
          Returns the least positive flonum representable as denormalized floating-point number.  If the platform doesn't support denormalized flonum, it returns the least positive normalized floating number.

     それぞれ次の性質を持つ浮動小数点数を返します:

     flonum-epsilon
          正規化浮動小数点数xに対し、xと(* x (+ 1.0 e))が異なる値となるような最小の正の浮動小数点数。

     flonum-min-normalized
          最小の正の正規化浮動小数点数。

     flonum-min-denormalized
          最小の正の非正規化浮動小数点数。但しプラットフォームが非正規化浮動小数点数をサポートしない場合は、最小の正の正規化浮動小数点数。

Arithmetics
-----------

 -- Function: + z ...
 -- Function: * z ...
     [R7RS base] Returns the sum or the product of given numbers, respectively. If no argument is given, (+) yields 0 and (*) yields 1. 与えられた数の和と積をそれぞれ返します。引数が与えられない場合、 (+) は 0、 (*) は 1 となります。

 -- Function: - z1 z2 ...
 -- Function: / z1 z2 ...
     [R7RS base] If only one number Z1 is given, returns its negation and reciprocal, respectively.

     If more than one number are given, returns:

          Z1 - Z2 - Z3 ...
          Z1 / Z2 / Z3 ...

     respectively. 一つだけ数値が与えられた場合、それぞれnegationと逆数を返します。

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

          Z1 - Z2 - Z3 ...
          Z1 / Z2 / Z3 ...

          (- 3)       => -3
          (- -3.0)    => 3.0
          (- 5+2i)    => -5.0-2.0i
          (/ 3)       => 1/3
          (/ 5+2i)    => 0.172413793103448-0.0689655172413793i

          (- 5 2 1)     => 2
          (- 5 2.0 1)   => 2.0
          (- 5+3i -i)   => 5.0+2.0i
          (/ 14 6)      => 7/3
          (/ 6+2i 2)    => 3.0+1.0i

     Note: Gauche didn't have exact rational number support until 0.8.8; before that, / coerced the result to inexact even if both divisor and dividend were exact numbers, when the result wasn't a whole number.  It is not the case anymore.

     If the existing code relies on the old behavior, it runs very slowly on the newer versions of Gauche, since the calculation proceeds with exact rational arithmetics that is much slower than floating point arithmetics.  You want to use /. below to use fast inexact arithmetics (unless you need exact results). 註：0.8.8までGaucheは正確な有理数をサポートしておらず、それ以前は除数と被除数がともに正確な数であっても商が整数にならなければ結果は非正確な数へと変換されていました。今のGaucheはそうではありません。

     既存のコードが以前のGaucheのふるまいを当てにしていた場合、速度が大きく低下する可能性があります。正確な有理数の演算は浮動小数点数の演算よりはるかに遅いからです。 (正確な結果を得たいのでない場合は)下に述べる/.を使うと良いでしょう。

 -- Function: +. z ...
 -- Function: *. z ...
 -- Function: -. z1 z2 ...
 -- Function: /. z1 z2 ...
     Like +, *, -, and /, but the arguments are coerced to inexact number.  So they always return inexact number. These are useful when you know you don't need exact calculation and want to avoid accidental overhead of bignums and/or exact rational numbers. +、*、-、/と同様ですが、引数は不正確な数へと変換され、結果も常に不正確な数となります。正確数による計算が不要で、bignumや正確な有理数をうっかり使ってしまうことによるオーバヘッドを避けたい時に便利です。

 -- Function: abs z
     [R7RS+] For real number Z, returns an absolute value of it. For complex number Z, returns the magnitude of the number. The complex part is Gauche extension. 実数のZに対しては、その絶対値を返します。複素数のZに対しては、そのmagnitudeを返します。複素数を扱うのはGaucheの拡張です。

          (abs -1)   => 1
          (abs -1.0) => 1.0
          (abs 1+i)  => 1.4142135623731

 -- Function: quotient n1 n2
 -- Function: remainder n1 n2
 -- Function: modulo n1 n2
     [R7RS base] Returns the quotient, remainder and modulo of dividing an integer N1 by an integer N2.   The result is an exact number only if both N1 and N2 are exact numbers.

     Remainder and modulo differ when either one of the arguments is negative. Remainder R and quotient Q have the following relationship.

            N1 = Q * N2 + R

     where abs(Q) = floor(abs(N1)/abs(N2)). Consequently, R's sign is always the same as N1's.

     On the other hand, modulo works as expected for positive N2, regardless of the sign of N1 (e.g. (modulo -1 N2) == N2 - 1). If N2 is negative, it is mapped to the positive case by the following relationship.

            modulo(N1, N2) = -modulo(-N1, -N2)

     Consequently, MODULO's sign is always the same as N2's. 整数N1を整数N2で割った商(quotient)および余り(remainder, modulo) を返します。  N1とN2の両方が正確な数値の時のみ、戻り値は正確な数値になります。

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

            N1 = Q * N2 + R

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

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

            modulo(N1, N2) = -modulo(-N1, -N2)

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

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

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

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

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

 -- Function: quotient&remainder n1 n2
     Calculates the quotient and the remainder of dividing integer N1 by integer N2 simultaneously, and returns them as two values. 整数N1を整数N2で割った商(quotient)および余り(remainder) を同時に計算し、2つの値として返します。

 -- Function: div x y
 -- Function: mod x y
 -- Function: div-and-mod x y
 -- Function: div0 x y
 -- Function: mod0 x y
 -- Function: div0-and-mod0 x y
     [R6RS] These are integer division procedures introduced in R6RS. Unlike quotient, modulo and remainder, these procedures can take non-integral values. The dividend X can be an arbitrary real number, and the divisor Y can be non-zero real number. これらはR6RSで導入された整数除算手続きです。 quotient, modulo, remainderと違い、これらの手続きは整数でない値を取ることもできます。被除数Xには任意の実数、除数Yにはゼロ以外の実数が許されます。

     div returns an integer N, and mod returns a real number M, such that:

       * X = N Y + M, and

       * 0 <= M < |Y|.

     Examples: divは整数Nを、modは実数Mを返し、それらは以下の関係を満たします。

       * X = N Y + M

       * 0 <= M < |Y|

     例:

          (div 123 10)     => 12
          (mod 123 10)     => 3

          (div 123 -10)    => -12
          (mod 123 -10)    => 3

          (div -123 10)    => -13
          (mod -123 10)    => 7

          (div -123 -10)   => 13
          (mod -123 -10)   => 7

          (div 123/7 10/9) => 15
          (mod 123/7 10/9) => 19/21
          ;; 123/7 = 10/9 * 15 + 19/21

          (div 14.625 3.75) => 3.0
          (mod 14.625 3.75) => 3.375
          ;; 14.625 = 3.75 * 3.0 + 3.375

     For a nonnegative integer X and an integer Y, The results of div and mod matches those of quotient and remainder.  If X is negative, they differ, though. Xが非負の整数、Yが整数である場合は、 divとmodの結果はquotientとremainder の結果に一致します。しかしXが負になると結果は異なります。

     div-and-mod calculates both div and mod and returns their results in two values. div-and-modはdivとmodを同時に計算し、結果を二つの値で返します。

     DIV0 and MOD0 are similar, except the range of M: DIV0とMOD0は、mの値域が異なる以外は同じです。

       * X = N Y + M

       * -|Y|/2 <= M < |Y|/2

          (div0 123 10)   => 12
          (mod0 123 10)   => 3

          (div0 127 10)   => 13
          (mod0 127 10)   => -3

          (div0 127 -10)  => -13
          (mod0 127 -10)  => -3

          (div0 -127 10)  => -13
          (mod0 -127 10)  => 3

          (div0 -127 -10) => 13
          (mod0 -127 -10) => 3

     div0-and-mod0 calculates both div0 and mod0 and returns their results in two values. div0-and-mod0はdiv0とmod0を同時に計算し、結果を二つの値で返します。

     Here's a visualization of R6RS and R7RS division and modulo operations: http://blog.practical-scheme.net/gauche/20100618-integer-divisions It might help to grasp how they works. R6RSとR7RSの除算・剰余操作を可視化したものが http://blog.practical-scheme.net/gauche/20100618-integer-divisions にあります。

 -- Function: floor-quotient n d
 -- Function: floor-remainder n d
 -- Function: floor/ n d
 -- Function: truncate-quotient n d
 -- Function: truncate-remainder n d
 -- Function: truncate/ n d
     [R7RS base] These are integer division operators introduced in R7RS.  The names explicitly indicate how they behave when numerator and/or denominator is/are negative.

     The arguments N and D must be an integer.  If any of them are inexact, the result is inexact.  If all of them are exact, the result is exact.  Also, D must not be zero.

     Given numerator N, denominator D, quotient Q and remainder R, the following relations are always kept.

          r = n - dq
          abs(r) < abs(d)

     Now, (floor-quotient n d) and (truncate-quotient n d) are the same as (floor (/ n d)) and (truncate (/ n d)), respectively. The *-remainder counterparts are derived from the above relation.

     The /-suffixed version, floor/ and truncate/, returns corresponding quotient and remainder as two values. R7RSで導入された整数除算オペレータです。除数や被除数が負の場合の振る舞いが、名前によって明示されています。

     引数NとDは整数でなけばなりません。両方とも正確数であれば結果は正確数に、一方でも不正確数であれば結果は不正確数になります。また、Dはゼロであってはなりません。

     被除数N、除数D、商Q、剰余Rには常に以下の関係が成り立ちます。

          r = n - dq
          abs(r) < abs(d)

     (floor-quotient n d)と (truncate-quotient n d)はそれぞれ (floor (/ n d))と(truncate (/ n d))と同じです。対応する*-remainderは、上記の関係から導かれます。

     floor/ と truncate/は、対応する商と剰余を二つの値として返します。

          (floor-quotient 10 -3)     => -4
          (floor-remainder 10 -3)    => -2
          (truncate-quotient 10 -3)  => -3
          (truncate-remainder 10 -3) => 1

     R7RS division library (scheme.division) introduces other variation of integer divisions (see R7RS integer division). R7RS除算ライブラリ(scheme.division)では、他の整数除算のバリエーションが定義されています。 (R7RS integer division参照)。

 -- Function: gcd n ...
 -- Function: lcm n ...
     [R7RS base] Returns the greatest common divisor or the least common multiplier of the given integers, respectively 与えられた整数の、最大公約数と最小公倍数をそれぞれ返します。

     Arguments must be integers, but doesn't need to be exact. If any of arguments is inexact, the result is inexact. 引数は整数でなければなりませんが、正確数である必要はありません。引数が一つでも非正確なら、結果は非正確数になります。

 -- Function: continued-fraction x
     Returns a lazy sequence of regular continued fraction expansion of finite real number X.  An error is raised if X is infinite or NaN, or not a real number. The returned sequence is lazy, so the terms are calculated as needed. 有限の実数Xの正規連分数展開を、遅延シーケンスで返します。 Xが無限大、NaN、または非実数の場合はエラーが報告されます。返り値は遅延シーケンスなので、係数は必要になる度に計算されます。

          (continued-fraction 13579/2468)
            => (5 1 1 122 1 9)

          (+ 5 (/ (+ 1 (/ (+ 1 (/ (+ 122 (/ (+ 1 (/ 9))))))))))
            => 13579/2468

          (continued-fraction (exact 3.141592653589793))
            => (3 7 15 1 292 1 1 1 2 1 3 1 14 3 3 2 1 3 3 7 2 1 1 3 2 42 2)

          (continued-fraction 1.5625)
            => (1.0 1.0 1.0 3.0 2.0)

 -- Function: numerator q
 -- Function: denominator q
     [R7RS base] Returns the numerator and denominator of a rational number Q. 有理数Qの分子と分母をそれぞれ返します。

 -- Function: rationalize x ebound
     [R7RS base] Returns the simplest rational approximation Q of a real number X, such that the difference between X and Q is no more than the error bound EBOUND.

     Note that Gauche doesn't have inexact rational number, so if X and/or EBOUND is inexact, the result is coerced to floating point representation.  If you want an exact result, coerce the arguments to exact number first. 実数Xを、誤差EBOUND以内で近似した最も単純な有理数Qを返します。

     Gaucheは不正確な有理数をサポートしないので、引数の少なくとも一方が不正確数だと結果の有理数が浮動小数点数へと変換され不正確数として返されることに注意してください。結果を正確数で得たい場合は、引数を正確数で渡してください。

          (rationalize 1234/5678 1/1000) => 5/23

          (rationalize 3.141592653589793 1/10000)
            => 3.141509433962264
          (rationalize (exact 3.141592653589793) 1/10000)
            => 333/106
          (rationalize (exact 3.141592653589793) 1/10000000)
            => 75948/24175

          ;; Some edge cases
          (rationalize 2 +inf.0) => 0
          (rationalize +inf.0 0) => +inf.0
          (rationalize +inf.0 +inf.0) => +nan.0

 -- Function: floor x
 -- Function: ceiling x
 -- Function: truncate x
 -- Function: round x
     [R7RS base] The argument X must be a real number. Floor and ceiling return a maximum integer that isn't greater than X and a minimum integer that isn't less than X, respectively. Truncate returns an integer that truncates X towards zero.  Round returns an integer that is closest to X.  If fractional part of X is exactly 0.5, round returns the closest even integer. 引数Xは実数でなければなりません。floorとceilingはそれぞれ Xを越えない最大の整数と、Xを下回らない最小の整数を返します。 truncateはXの小数部をゼロの方向に向かって切捨てた整数を返します。 roundはXに最も近い整数を返します。Xの小数部が0.5ぴったりだった場合はroundは最も近い偶数を返します。

     Following Scheme's general rule, the result is inexact if X is an inexact number; e.g. (round 2.3) is 2.0.  If you need an exact integer by rounding an inexact number, you have to use exact on the result, or use one of the following procedure ((floor->exact etc). Schemeの一般的な規則に従い、Xが不正確数であれば結果も不正確となります。例えば(round 2.3)の結果は2.0です。もし、不正確な数を丸めて正確な整数を得たいのであれば、結果にexactを適用するか、以下に示すfloor->exactなどの手続きを使ってください。

 -- Function: floor->exact x
 -- Function: ceiling->exact x
 -- Function: truncate->exact x
 -- Function: round->exact x
     These are convenience procedures of the popular phrase (exact (floor x)) etc. これらは、頻出する(exact (floor x)) 等を簡潔に書くための手続きです。

 -- Function: clamp x :optional min max
     Returns

           MIN if X < MIN
           X   if MIN <= X <= MAX
           MAX if MAX < X

     If MIN or MAX is omitted or #f, it is regarded as -inf.0 or +inf.0, respectively. Returns an exact integer only if all the given numbers are exact integers.

           MIN if X < MIN
           X   if MIN <= X <= MAX
           MAX if MAX < X

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

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

 -- Function: exp z
 -- Function: log z
 -- Function: log z1 z2
 -- Function: sin z
 -- Function: cos z
 -- Function: tan z
 -- Function: asin z
 -- Function: acos z
 -- Function: atan z
 -- Function: atan y x
     [R7RS inexact] Transcendental functions.  Work for complex numbers as well. In R7RS, these procedures are in the (scheme inexact) module. 超越関数です。複素数も扱えます。 R7RSではこれらの手続きは(scheme inexact)モジュールにあります。

     The two-argument version of log is added in R6RS, and returns base-Z2 logarithm of Z1. 2引数のlogはR6RSで追加されたもので、Z2を底としたZ1の対数を返します。

     The two-argument version of atan returns (angle (make-rectangular x y)) for the real numbers x and y. 2引数のatanは実数XとYに対して (angle (make-rectangular x y))を返します。

 -- Function: sinh z
 -- Function: cosh z
 -- Function: tanh z
 -- Function: asinh z
 -- Function: acosh z
 -- Function: atanh z
     Hyperbolic trigonometric functions.  Work for complex numbers as well. 双曲線関数です。複素数も扱えます。

 -- Function: sqrt z
     [R7RS inexact] Returns a square root of a complex number Z. The branch cut scheme is the same as Common Lisp. For real numbers, it returns a positive root.

     If Z is the square of an exact real number, the return value is also an exact number. 複素数Zの平方根のひとつを返します。枝刈りの定義はCommon Lispと同じです。実数に対しては正の平方根を返します。

     Zが正確な実数の平方である場合、戻り値は正確数となります。

          (sqrt 2)      => 1.4142135623730951
          (sqrt -2)     => 0.0+1.4142135623730951i
          (sqrt 256)    => 16
          (sqrt 256.0)  => 16.0
          (sqrt 81/169) => 9/13

 -- Function: exact-integer-sqrt k
     [R7RS base] Given an exact nonnegative integer K, returns two exact nonnegative integer S and R that satisfy the following equations: 非負の正確な整数Kに対し、次の式を満たす非負の正確な整数SとRを返します。

          K = (+ (* S S) R)
          K < (* (+ S 1) (+ S 1))

          (exact-integer-sqrt 782763574)
            => 27977 and 51045

 -- Function: square z
     [R7RS base] Returns (* z z). (* z z)を返します。

 -- Function: expt z1 z2
     [R7RS base] Returns Z1^Z2 (Z1 powered by Z2), where Z1 and Z2 are complex numbers. 複素数Z1, Z2に対して、 Z1^Z2 (Z1のZ2乗)を返します。

     Scheme standard defines (expt 0 0) as 1 for convenience. Scheme標準では便宜上(expt 0 0)は1と定めています。

 -- Function: expt-mod base exponent mod
     Calculates (modulo (expt base exponent) mod) efficiently.

     The next example shows the last 10 digits of a mersenne prime M_74207281 (2^74207281 - 1) (modulo (expt base exponent) mod) を効率よく計算します。

     次の例は、メルセンヌ素数M_74207281 (2^74207281 - 1) の最後の10桁を求めます。

          (- (expt-mod 2 74207281 #e1e10) 1)
           => 1086436351

 -- Function: gamma x
 -- Function: lgamma x
     Gamma function and natural logarithmic of absolute value of Gamma function.

     NB: Mathematically these functions are defined in complex domain, but currently we only support real number argument. ガンマ関数と、ガンマ関数の絶対値の自然対数です。

     註：数学的にはこれらの関数は複素領域で定義されますが、現在の実装は実数引数だけをサポートします。

 -- Function: fixnum-width
 -- Function: greatest-fixnum
 -- Function: least-fixnum
     [R6RS] These procedures return the width of fixnum (W), the greatest integer representable by fixnum (2^(W-1) - 1), and the least integer representable by fixnum (- 2^(W-1)), respectively.  You might want to care the fixnum range when you are writing a performance-critical section.

     These names are defined in R6RS.  Common Lisp and ChezScheme have most-positive-fixnum and most-negative-fixnum. これらの手続きは、fixnumで表現できる数値の幅 (Wとします)、 fixnumで表現できる最大の整数値 (2^(W-1) - 1)、および fixnumで表現できる最小の整数値 (- 2^(W-1)) をそれぞれ返します。性能が重要になる部分では数値がfixnumの範囲に収まるかどうかを気にかける必要があります。

     これらの名前はR6RSで定義されました。Common LispとChezSchemeには most-positive-fixnumおよびmost-negative-fixnumがあります。

     NB: Before 0.9.5, fixnum-width had a bug to return one smaller than the supposed value. 註: 0.9.5以前のfixnum-widthには本来より1小さい値を返すバグがありました。

Numerical conversions
---------------------

 -- Function: make-rectangular x1 x2
 -- Function: make-polar x1 x2
     [R7RS complex] Creates a complex number from two real numbers, X1 and X2. make-rectangular returns X1 + iX2. make-polar returns X1e^(iX2).

     In R7RS, these procedures are in the (scheme complex) library. 二つの実数X1とX2から複素数を作ります。 make-rectangular は X1 + iX2 を返します。 make-polar は X1e^(iX2) を返します。

     R7RSではこれらの手続きは(scheme complex)ライブラリにあります。

 -- Function: real-part z
 -- Function: imag-part z
 -- Function: magnitude z
 -- Function: angle z
     [R7RS complex] Decompose a complex number Z and returns a real number. real-part and imag-part return Z's real and imaginary part, respectively.  magnitude and angle return Z's magnitude and angle, respectively.

     In R7RS, these procedures are in the (scheme complex) library. 複素数Zを取り、実数を返します。 real-partとimag-partはZの実数部と虚数部をそれぞれ返し、 magnitudeとangleはZの絶対値と偏角をそれぞれ返します。

     R7RSではこれらの手続きは(scheme complex)ライブラリにあります。

 -- Function: decode-float x
     For a given finite floating-point number, returns a vector of three exact integers, #(M, E, SIGN), where

            X = (* SIGN M (expt 2.0 E))
            SIGN is either 1, 0 or -1.

     If X is +inf.0 or -inf.0, M is #t. If X is +nan.0, M is #f.

     The API is taken from ChezScheme. 与えられた有限の浮動小数点数Xに対して、 3つの正確な整数からなるベクタ #(M, E, SIGN) を返します。ここで、

            X = (* SIGN M (expt 2.0 E))
            SIGN は 1, 0 または -1.

     です。

     特例として、Xが+inf.0もしくは-inf.0の時は Mが#tに、 Xが+nan.0の時はMが#fになります。

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

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

          (decode-float +nan.0)
           => #(#f 0 -1)

 -- Function: encode-float vector
     This is an inverse of decode-float.  VECTOR must be a three-element vector as returned from decode-float. これはdecode-floatの逆関数です。VECTORは decode-floatが返す形式の3要素のベクタでなければなりません。

          (encode-float '#(7074237631354954 -51 1))
           => 3.1415926

          (encode-float '#(#t 0 1))
           => +inf.0

 -- Function: fmod x y
 -- Function: modf x
 -- Function: frexp x
 -- Function: ldexp x n
     [POSIX] These procedures can be used to compose and decompose floating point numbers.  Fmod computes the remainder of dividing X by Y, that is, it returns X-N*Y where N is the quotient of X/Y rounded towards zero to an integer.   Modf returns two values; a fractional part of X and an integral part of X.   Frexp returns two values, FRACTION and EXPONENT of X, where X = FRACTION * 2^EXPONENT, and 0.5 <= |FRACTION| < 1.0, unless X is zero. (When X is zero, both FRACTION and EXPONENT are zero). LDEXP is a reverse operation of frexp; it returns a real number X * 2^N. これらの手続きは、浮動小数点数を分解したり合成するのに使えます。 fmodは実数Xを実数Yで割った余りを返します。すなわち、 X/Yを0に近いほうの整数に丸めた値をNとするとき、 X-N*Yを返します。 modfはXの少数部と整数部を返します。 frexpは実数Xを、仮数部と指数部に分解して返します。すなわち、 Xが0でない限り、 X = FRACTION * 2^EXPONENT かつ 0.5 <= |FRACTION| < 1.0 であるところのFRACTIONとEXPONENTを返します。 (Xが0であれば、FRACTIONとEXPONENTはともに0となります。) ldexpはfrexpの逆関数で、X * 2^N を返します。

          (fmod 32.1 10.0)  => 2.1
          (fmod 1.5 1.4)    => 0.1
          (modf 12.5)       => 0.5 and 12.0
          (frexp 3.14)      => 0.785 and 2
          (ldexp 0.785 2)   => 3.14

 -- Function: exact z
 -- Function: inexact z
     [R7RS base] Returns an exact or an inexact representation of the given number Z, respectively.  Passing an exact number to exact, and an inexact number to inexact, are no-op.

     Gauche doesn't have exact complex number with non-zero imaginary part, nor exact infinites and NaNs, so passing those to exact raises an error. それぞれ数Zの正確な表現および不正確な表現を返します。正確数をexactに渡した場合や、不正確数をinexactに渡した場合は渡した値がそのまま返されます。

     Gaucheは、虚部がゼロでない正確な複素数や、正確な無限大/NaNをサポートしないので、これらの数がexactに渡された場合はエラーとなります。

          (inexact 1)    => 1.0
          (inexact 1/10) => 0.1

     If an inexact finite real number is passed to exact, the simplest exact rational number within the precision of the floating point representation is returned. 不正確で有限な実数がexactに渡された場合は、浮動小数点数演算の精度の中で最も簡単な表現となる正確な有理数が返されます。

          (exact 1.0)     => 1
          (exact 0.1)     => 1/10
          (exact (/ 3.0)) => 1/3

     For all finite inexact real number X, (inexact (exact X)) is always eqv? to the original number X. あらゆる有限の不正確な実数Xについて、 (inexact (exact X)) は常に元の数Xと eqv?になります。

     (Note that the inverse doesn't hold, that is, an exact number N and (exact (inexact N)) aren't necessarily the same. It's because many (actually, infinite number of) exact numbers can be mapped to one inexact number.) (その逆、つまり正確数 N と (exact (inexact N)) は必ずしも等しくならないことに注意してください。ある不正確数へと写像される正確数は無数にあり得るためです。)

     To specify the error tolerance when converting inexact real numbers to exact rational numbers, use rationalize or real->rational. 誤差の許容範囲を指定して非正確な実数を正確な有理数に直したい場合は、 rationalizeおよびreal->rationalを参照してください。

 -- Function: exact->inexact z
 -- Function: inexact->exact z
     [R5RS] Converts exact number to inexact one, and vice versa.

     In fact, exact->inexact returns the argument as is if an inexact number is passed, and inexact->exact returns the argument if an exact number is passed, so in Gauche they are equivalent to inexact and exact, respectively.  Note that other R5RS implementation may raise an error if passing an inexact number to exact->inexact, for example.

     Generally exact and inexact are preferred, for they are more concise, and you don't need to care whether the argument is exact or inexact numbers. These procedures are for compatibility with R5RS programs. それぞれ、正確数を非正確に変換、あるいはその逆を行います。

     不正確な数をexact->inexactに渡したり、または正確な数を inexact->exactに渡した場合、Gaucheではそれをエラーにせず引数をそのまま返します。従ってこれらはGaucheでは上のinexactおよびexactとそれぞれ等価です。 R5RS実装の中には、非正確数をexact->inexactに渡したりするとエラーになるものもあり得るので、ポータブルなコードを書く場合は注意してください。

     一般的には、exactおよびinexactを使う方が簡潔で良いでしょう。こちらの手続きはR5RSプログラムとの互換性のために用意されています。

 -- Function: real->rational x :optional hi lo open?
     Find the simplest rational representation of a finite real number X within the specified error bounds.  This is the low-level routine called by rationalize and exact. Typically you want to use rationalize (see Arithmetics) for this purpose.  Use real->rational only when you need finer control of error bounds. 指定されたエラー範囲の中で、有限な実数Xの正確な有理数表現のうち最も簡単なものを返します。rationalizeやexactはこの手続きを下請けとして呼び出しています。通常はrationalize (Arithmetics参照) を使い、real->rationalは誤差許容値をより細かく制御したい時のみ使うのが良いでしょう。

     The result rational value R satisfies the following condition: 返される有理数は次の条件を満たします。

          (<= (- x lo) r (+ x hi))   ; when open? is #f
          (<  (- x lo) r (+ x hi))   ; otherwise

     Note that both HI and LO must be nonnegative.

     If HI and/or LO is omitted, it is determined by X: if X is exact, HI and LO are defaulted to zero; if X is inexact, HI and LO depend on the precision of the floating point representation of X. In the latter case, the OPEN? also depends on X---it is true if the mantissa of X is odd, and false otherwise, reflecting the round-to-even rule.   So, if you call real->rational with one finite number, you'll get the same result as exact: HIとLOは非負でなければなりません。

     HIとLOの両方、もしくは一方が省略された場合、それはXの値に応じて決定されます。Xが正確数の場合、省略されたHI/LOはゼロとみなされます。 Xが非正確数の場合は、Xの浮動小数点数表現の精度に基づいて HI/LOが決定されます。後者の場合、OPEN?の値もまた、 Xの値で決まります。浮動小数点数の「偶数丸め」規則に対応して、 Xの仮数部が奇数であればOPEN?は真、そうでなければ偽となります。従って、real->rationalにひとつの有限の数値だけを渡した場合、その動作はexactと同じになります。

          (real->rational 0.1) => 1/10

     Passing zeros to the error bounds makes it return the exact conversion of the floating number itself (that is, the exact calculation of (* sign mantissa (expt 2 exponent))). エラー範囲にゼロを渡すと、引数の浮動小数点数の正確な数値表現 (つまり、(* sign mantissa (expt 2 exponent))を正確値で計算した結果) が返されます。

          (real->rational 0.1 0 0) => 3602879701896397/36028797018963968

     (If you give both HI and LO, but omit OPEN?, we assume closed range.) (HIとLO引数を与えて OPEN?を省略した場合は、閉じた範囲と考えます。)

 -- Function: number->string z :optional radix use-upper?
 -- Function: string->number string :optional radix default-exactness
     [R7RS+] These procedures convert a number and its string representation in radix RADIX system. RADIX must be between 2 and 36 inclusive. If RADIX is omitted, 10 is assumed.

     Number->string takes a number Z and returns a string. If Z is not an exact integer, RADIX must be 10. For the numbers with radix more than 10, lower case alphabet character is used for digits, unless the optional argument USE-UPPER? is true, in that case upper case characters are used. The argument USE-UPPER? is Gauche's extension.

     String->number takes a string STRING and parses it as a number in radix RADIX system.  If the number contains a decimal point, only radix 10 is allowed.  If the given string can't be a number, #f is returned.

     The DEFAULT-EXACTNESS optional argument of string->number is Gauche's extension, and it must be either #f (default), a symbol exact, or a symbol inexact. If it is either symbol, it sets the exactness of the number if no exactness prefix (#e or #i) is given. これらの手続きは数値とそれをRADIX進数で表現する文字列とを変換します。 RADIXは2から36の間でなければなりません。省略された場合は10進数とみなされます。

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

     string->numberは文字列STRINGを取り数値を返します。入力が小数点を含んでいる場合は10進数表記しか認識されません。与えられた文字列が数値を構成しない場合は#fが返されます。

     string->numberの省略可能引数DEFAULT-EXACTNESSはGaucheの拡張で、 #f (デフォルト)あるいはシンボルexactまたはinexactのいずれかでなければなりません。シンボルが与えられた場合は、正確数か不正確数かがプレフィクス(#eもしくは#i) で明示されていない場合の正確性の解釈を指定します。

          (string->number "2.718281828459045" 10 'exact)
            => 543656365691809/200000000000000
          (string->number "#i2.718281828459045" 10 'exact)
            => 2.718281828459045
          (string->number "1/3" 10 'inexact)
            => 0.3333333333333333
          (string->number "#e1/3" 10 'inexact)
            => 1/3

 -- Generic Function: x->number obj
 -- Generic Function: x->integer obj
     Generic coercion functions.  Returns `natural' interpretation of OBJ as a number or an exact integer, respectively. The default methods are defined for numbers and strings; a string is interpreted by string->number, and if the string can't be interpreted as a number, 0 is returned. Other OBJ is simply converted to 0. If OBJ is naturally interpreted as a number that is not an exact integer, x->integer uses round and inexact->exact to obtain an integer.

     Other class may provide a method to customize the behavior. 数値への強制型変換手続きです。 OBJをそれぞれ数値もしくは正確な整数と解釈して返します。数値と文字列に対してのメソッドは定義されています (文字列はstring->numberを使って変換されます。数値として解釈できない文字列に関しては0が返されます)。その他のOBJについては単に0が返されます。 x->integerは、OBJが数値として表現できるけれど正確な整数ではない場合、roundとinexact->exactによって正確な整数に変換します。

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

Basic bitwise operations
------------------------

These procedures treat integers as half-open bit vectors. If an integer is positive, it is regarded as if infinite number of zeros are padded to the left.  If an integer is negative, it is regarded in 2's complement form, and infinite number of 1's are padded to the left. これらの手続きは整数を半無限のビットベクタとして扱います。正の整数の場合、数値の左側に無限に0が続いていると見倣されます。負の整数の場合、数値は2の補数で表現され、左側に無限に1が続いていると見倣されます。

In regard to the names of those operations, there are two groups in the Scheme world; Gauche follows the names of the original SLIB's ``logical'' module, which was rooted in CL. Another group uses a bit long but descriptive name such as arithmetic-shift. これらの操作の名前に関しては、Scheme界には大きく二つの流儀があります。 GaucheはSLIBの元々の``logical''モジュールに合わせました。その起源はCommon Lispです。もう一つの流儀では、arithmetic-shiftといった、より長く記述的な名前を使います。

R7RS bitwise library (see R7RS bitwise operations) provides additional bitwise operations. R7RSビット演算ライブラリ(see R7RS bitwise operations) は追加のビット演算を提供しています。

 -- Function: ash n count
     [SRFI-60] Shifts integer N left with COUNT bits. If COUNT is negative, ash shifts N right with -COUNT bits. 整数Nを左に整数COUNTビットだけシフトします。 COUNTが負であれば、-COUNTだけNを右にシフトします。

          ; Note: 6  == [...00110], and
          ;       -6 == [...11010]
          (ash 6 2)   => 24  ;[...0011000]
          (ash 6 -2)  => 1   ;[...0000001]
          (ash -6 2)  => -24 ;[...1101000]
          (ash -6 -2) => -2  ;[...1111110]

 -- Function: logand n1 ...
 -- Function: logior n1 ...
 -- Function: logxor n1 ...
     [SRFI-60] Returns bitwise and, bitwise inclusive or and bitwise exclusive or of integers N1 ....   If no arguments are given, logand returns -1, and logior and logxor returns 0. 整数N1 ...の、それぞれビット論理積、ビット論理和、ビット排他的論理積を返します。ゼロ個の引数が与えられた場合は、logandは-1を、 logiorとlogxorは0を返します。

 -- Function: lognot n
     [SRFI-60] Returns bitwise not of an integer N. 整数Nのビット否定を返します。

 -- Function: logtest n1 n2 ...
     [SRFI-60] == (not (zero? (logand N1 N2 ...)))

 -- Function: logbit? index n
     [SRFI-60] Returns #t if INDEX-th bit of integer N is 1, #f otherwise. 整数NのINDEX目のビットが1ならば#tを、0ならば#fを返します。

 -- Function: bit-field n start end
     [R7RS bitwise] Extracts START-th bit (inclusive) to END-th bit (exclusive) from an exact integer N, where START < END. 整数NのSTARTビット目(含む)からENDビット目(含まない)までを取り出した数値を返します。START < END でなければなりません。

 -- Function: copy-bit index n bit
     [R7RS bitwise] If BIT is true, sets INDEX-th bit of an exact integer N. If BIT is false, resets INDEX-th bit of an exact integer N. BITが真の値なら、整数NのINDEXビット目をセットした数値を返します。 BITが偽の値なら、整数NのINDEXビット目をリセットした数値を返します。

 -- Function: copy-bit-field n from start end
     [SRFI-60] Returns an exact integer, each bit of which is the same as N except the START-th bit (inclusive) to END-th bit (exclusive), which is a copy of the lower (END-START)-th bits of an exact integer FROM. 正確な整数を返します。この整数の各ビットはSTART番目のビット(このビットを含む)からEND番目のビット(このビットは含まない)の部分以外はNと同じで、この区間のビットは、正確な数FROMの下位 (END-START)ビットのコピーです。

          (number->string (copy-bit-field #b10000000 -1 1 5) 2)
            => "10011110"

          (number->string (copy-bit-field #b10000000 #b010101010 1 7) 2)
            => "11010100"

     Note: The API of this procedure was originally taken from SLIB, and at that time, the argument order was (copy-bit-field n start end from). During the discussion of SRFI-60 the argument order was changed for the consistency, and the new versions of SLIB followed it. We didn't realize the change until recently - before 0.9.4, this procedure had the old argument order.  Code that is using this procedure needs to be fixed.  If you need your code to work with both versions of Gauche, have the following definition in your code. 註：この手続きのAPIはSLIBから採られましたが、採用当時の引数の順序は (copy-bit-field n start end from) でした。SRFI-60の議論中に、一貫性のために引数順が変更され、SLIBの新しいバージョンもそれに追従しています。Gaucheではこの引数順の変更に最近まで気づいていなかったため、 0.9.4以前のバージョンではcopy-bit-fieldが古い引数順で定義されています。この手続きを使っていたコードは0.9.4以降のGaucheで使う際に修正しなければなりません。もしどちらのバージョンのGaucheでも動かす必要がある場合は、回避策としてcopy-bit-fieldの定義を自前で持つのが良いでしょう。

          (define (copy-bit-field to from start end)
            (if (< start end)
              (let1 mask (- (ash 1 (- end start)) 1)
                (logior (logand to (lognot (ash mask start)))
                        (ash (logand from mask) start)))
              from))

 -- Function: logcount n
     [SRFI-60] If N is positive, returns the number of 1's in the bits of N.  If N is negative, returns the number of 0's in the bits of 2's complement representation of N. Nが正なら、Nのビットのうち1の個数を返します。N が負なら、Nの2に関する補数のビットのうち0の個数を返します。

          (logcount 0)      => 0
          (logcount #b0010) => 1
          (logcount #b0110) => 2
          (logcount #b1111) => 4

          (logcount #b-0001) => 0  ;; 2's complement:  ....111111
          (logcount #b-0010) => 1  ;; 2's complement:  ....111110
          (logcount #b-0011) => 1  ;; 2's complement:  ....111101
          (logcount #b-0100) => 2  ;; 2's complement:  ....111100

          (logcount 0)      => 0
          (logcount #b0010) => 1
          (logcount #b0110) => 2
          (logcount #b1111) => 4

          (logcount #b-0001) => 0  ;; 2の補数:  ....111111
          (logcount #b-0010) => 1  ;; 2の補数:  ....111110
          (logcount #b-0011) => 1  ;; 2の補数:  ....111101
          (logcount #b-0100) => 2  ;; 2の補数:  ....111100

 -- Function: integer-length n
     [R7RS bitwise] Returns the minimum number of bits required to represent an exact integer N.  Negative integer is assumed to be in 2's complement form.  A sign bit is not considered. 正確な整数Nを表現するのに必要な最小ビット数を返します。負の数は2 の補数で表現されるものと仮定しています。符号用のビットは考慮しません。

          (integer-length 255)  => 8
          (integer-length 256)  => 9

          (integer-length -256)  => 8
          (integer-length -257)  => 9

 -- Function: twos-exponent n
     If N is a power of two, that is, (expt 2 k) and k >= 0, then returns k.  Returns #f if N is not a power of two. Nが2の冪乗(expt 2 k) (k >= 0) ならその冪 k を、そうでなければ#fを返します。

 -- Function: twos-exponent-factor n
     Returns maximum K such that (expt 2 k) is a factor of N. In other words, returns the number of consecutive zero bits from LSB of N.  When N is zero, we return -1 for the consistency of the following equivalent expression. (expt 2 k)がNの約数であるような最大のKを返します。言い換えれば、NのLSBから連続するゼロビットの数を返します。ただしNがゼロの場合は、下の等価式との一貫性から-1が返されます。

     This can be calculated by the following expression; this procedure is for speed to save creating intermediate numbers when N is bignum. これは次の式でも計算できますが、この手続きはNがbignumの場合にも中間結果を作らないので若干速いです。

          (- (integer-length (logxor n (- n 1))) 1)

     This procedure is also equivalent to srfi-60's log2-binary-factors and first-set-bit (see Integers as bits). この手続きはまた、srfi-60のlog2-binary-factorsおよび first-set-bitと等価です(Integers as bits参照)。

Endianness
----------

In the Scheme world you rarely need to know about how the numbers are represented inside the machine.  However, it matters when you have to exchange data to/from the outer world in binary representation. Schemeの世界では、数値がマシン上でどのように表現されているかを気にする必要はほとんどありません。しかし、外の世界とバイナリ表現でデータをやりとりする場合はそれが問題になります。

Gauche's binary I/O procedures, such as in the binary.io module (see Binary I/O) and write-uvector/read-uvector! (see Uniform vectors), take optional ENDIAN argument to specify the endianness. binary.ioモジュール(Binary I/O参照)や write-uvector/read-uvector!(Uniform vectors参照) 等、Gaucheのバイナリ入出力手続きはバイトオーダーを指定する省略可能なENDIAN引数を取ります。

Currently Gauche recognizes the following endiannesses. エンディアンの指定には次のシンボルを使います。

big-endian
big
     Big-endian.  With this endianness, a 32-bit integer #x12345678 will be written out as an octet sequence #x12 #x34 #x56 #x78.

     Gauche has been using big-endian, but scheme.bytevector incorporated in R7RS uses big, so we recognize both. ビッグエンディアン。32ビット整数値#x12345678は#x12 #x34 #x56 #x78 のようなバイトシーケンスとして出力されます。

     Gaucheはずっとbig-endianを使ってきましたが、 R7RS-largeに取り入れられたscheme.bytevectorがbigを使うので、両方認識するようになっています。

little-endian
little
     Little-endian.  With this endianness, a 32-bit integer #x12345678 is written out as an octet sequence #x78 #x56 #x34 #x12.

     Gauche has been using little-endian, but scheme.bytevector incorporated in R7RS uses little, so we recognize both. リトルエンディアン。32ビット整数値#x12345678は#x78 #x56 #x34 #x12 のようなバイトシーケンスとして出力されます。

     Gaucheはずっとlittle-endianを使ってきましたが、 R7RS-largeに取り入れられたscheme.bytevectorがlittleを使うので、両方認識するようになっています。

arm-little-endian
     This is a variation of little-endian, and used in ARM processors in some specific modes.  It works just like little-endian, except reading/writing double-precision floating point number (f64), which is written as two little-endian 32bit words ordered by big-endian (e.g. If machine register's representation is #x0102030405060708, it is written as #x04 #x03 #x02 #x01 #x08 #x07 #x06 #x05. これはlittle-endianのバリエーションで、ARMプロセッサの特定のモードで使われるものです。倍精度浮動小数点数以外はlittle-endian と同様に動作します。倍精度浮動小数点数については、ふたつのリトルエンディアンワードがビッグエンディアンの順で書き出されます (例えばマシンレジスタ上でのビットパターンが #x0102030405060708の場合、出力は #x04 #x03 #x02 #x01 #x08 #x07 #x06 #x05となります)。

When the ENDIAN argument is omitted, those procedures use the parameter default-endian: ENDIAN引数が省略された場合は、これらの手続きはパラメータdefault-endianの値を使います。

 -- Parameter: default-endian
     This is a dynamic parameter (see Parameters) to specify the endianness the binary I/O routines use when its ENDIAN argument is omitted.  The initial value of this parameter is the system's native endianness. これは、バイナリ入出力ルーチンでENDIAN指定が省略された場合に共通して使われるエンディアンを指定する動的パラメータです (Parameters参照)。このパラメータの初期値はシステムのネイティブエンディアンです。

The system's native endianness can be queried with the following procedure: システムのネイティブエンディアンは次の手続きで得られます。

 -- Function: native-endian
     Returns a symbol representing the system's endianness. システムのエンディアンを示すシンボルを返します。

Booleans
========

 -- Builtin Class: <boolean>
     A boolean class.  Only #t and #f belong to this class. 論理値のクラスです。#tと#fのみがこのクラスのインスタンスです。

 -- Function: not obj
     [R7RS base] Returns #t if and only if OBJ is #f, and returns #f otherwise. OBJが#fの時のみ#tを返し、それ以外の場合は#fを返します。

 -- Function: boolean? obj
     [R7RS base] Returns #t if OBJ is a boolean value. OBJが論理値である場合に#tを返します。

 -- Function: boolean obj
     Returns #f iff OBJ is #f, and returns #t otherwise.  Convenient to coerce a value to boolean. OBJが#fであるとき#fを返し、それ以外の場合は#tを返します。値を論理値に変換したい場合に便利です。

 -- Function: boolean=? a b c ...
     [R7RS base] Every argument must be a boolean value.  Returns #t iff all values are the same, #f otherwise. 全ての引数は論理値でなければなりません。全ての引数が等しい場合に #tが、そうでなければ#fが返ります。

Undefined values
================

While working with Gauche, sometimes you encounter a value printed as #<undef>, an undefined value. Gaucheで作業していると、しばしば未定義値 #<undef> に出会うことがあるでしょう。

     gosh> (if #f #t)
     #<undef>

It is a value used as a filler where the actual value doesn't matter, or there's no other suitable value, or the binding hasn't been calculated. この値は、値そのものに意味が無いこと、ほかにふさわしい値が無いこと、あるいは束縛する値がまだ計算されていないことを示します。

Do not confuse undefined values with unbound variables; A variable can be bound to #<undef>, for it is just an ordinary first-class value.  On the other hand, an unbound variable means there's no value associated with the variable. 未定義値と未束縛の変数を混同しないようにしてください。 #<undef>は通常の第一級の値であり、変数に束縛しておくこともできます。未束縛の変数は文字通り、変数が束縛されていない、すなわち値を持たないことを意味します。

However, #<undef> may be used in certain occasions to indicate that a value is not provided for the variable.  For example, the toplevel variable can be bound to #<undef> if it is defined by (define variable) form (see Definitions). An optional procedure parameter without default value is bound to #<undef> if an actual argument is not given (see Making procedures).

Note that it cannot be distinguished from the case a value is actually provided, and the value just happens to be #<undef>.  If you get an #<undef>, you can say at most is that the value doesn't matter. You shouldn't let it carry too much meanings. しかし、場合によっては、変数に特定の値が提供されていないことを示すのに#<undef>が使われることもあります。例えば、トップレベル変数は、(define variable)の形式で定義された場合に #<undef>に束縛されます(Definitions参照)。また、既定値をもたない省略可能引数に実引数が提供されなかった場合、引数の値は#<undef>となります (Making procedures参照)。

これは実際に#<undef>が初期値として、あるいは引数として渡された場合と区別がつかないことに注意してください。#<undef>を受け取ってわかることは、せいぜいその値にたいした意味がないということくらいです。 #<undef>に大きな意味を持たせすぎないようにしましょう。

The #<undef> value is counted as true value in generalized boolean context, since it is not #f.  However, branching based on #<undef> is dangerous---a procedure that is defined to return unspecified value may merely returning #<undef> as a provisional value; it will change the return value in future.  Since the return value isn't specified, no one should be using it.  The code that tests such result value as a generalized boolean may break if the procedure changes the return value.

In fact, we've found that there are quite a few code that accidentally tests #<undef> return value in conditionals.  They can be seeds for future bugs, so we added a feature to warn when #<undef> value is used in the test of branches.  You can turn it on with setting the environment variable GAUCHE_CHECK_UNDEFINED_TEST. In future, we may turn it on while testing.

One typical case of such accidental use of #<undef> branching is in and-let*; the following code assumes print always return #<undef>, which is counted as a true value, and expects the control to proceeed to the next clause.  It'll break if print ever changes so that it may return #f in some cases. #<undef>は一般化された真偽値としては真の値とみなされます (偽になるのは#fのみですから)。しかし、#<undef>の値を見て分岐するコードは危険です。というのも、戻り値が規定されていない手続きが暫定的に#<undef>を返している場合が良くあるからです。でも、それは将来変更されるかもしれません。戻り値が規定されていない以上、戻り値に依存するコードは無いはずだからです。もしうっかり、その戻り値に基づいて分岐しているコードがあると、変更があったときに壊れてしまいます。

実のところ、#<undef>に依存して分岐しているコードが結構多いことがわかりました。これは将来のバグの芽となるので、#<undef>が分岐テストに現れた時に警告する機能がつけてあります。環境変数GAUCHE_CHECK_UNDEFINED_TEST をセットすることでその機能をオンにできます。将来、テストの際にこの機能をオンにするかもしれません。

#<undef>をうっかり分岐テストに使ってしまう良くあるパターンは、 and-let*です。次のコードでは、printがテスト節に現れていますが、このコードはprintが常に#<undef>を返しそれが真の値であることから次のテスト節に進むことを期待しています。けれども、printが場合によっては#fを返すように変更されたら、このコードは壊れてしまいます。

     (and-let* ([var (foo x y z)]
                [ (print var) ]    ;; branch on #<undef>
                [baz (bar var)])
       ...)

Being said that, there are a couple of procedures to deal with undefined values. 以上の注意を念頭においた上で、未定義値を扱うには次の手続きが利用できます。

 -- Function: undefined? obj
     Returns #t iff OBJ is an undefined value. OBJが未定義値である場合に限り#tを返します。

 -- Function: undefined
     Returns an undefined value. 未定義値を返します。

Pairs and lists
===============

Pairs and lists are one of the most fundamental data structure in Scheme. Gauche core provides all standard list procedures, plus some useful procedures that are commonly supported in lots of implementations. If they are not enough, you can find more procedures in the modules described in R7RS lists and Combination library. See also Collection framework and Sequence framework for generic collection/sequence operations. ペアとリストはSchemeにおける最も基本的なデータ構造のひとつです。 Gaucheのコアは全ての標準のリスト手続きと、多くのScheme実装に見られる便利な手続きのいくつかを提供します。それらで足りない場合はさらに多くの手続きがR7RS lists、 Combination library といったモジュールで提供されています。また、リストに限らないジェネリックなシーケンス/コレクションの操作が Collection frameworkと Sequence frameworkで提供されています。

Pair and null class
-------------------

 -- Builtin Class: <list>
     An abstract class represents lists.   A parent class of <null>
     and <pair>.   Inherits <sequence>.

     Note that a circular list is also an instance of the <list> class, while list? returns false on the circular lists and dotted lists. リストを表す抽象クラスで、クラス<null>とクラス<pair>の親クラスです。クラス<sequence>を継承します。

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

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

 -- Builtin Class: <null>
     A class of empty list.  () is the only instance. 空リストのクラスです。()がこのクラスの唯一のインスタンスです。

 -- Builtin Class: <pair>
     A class of pairs. ペアのクラスです。

Mutable and immutable pairs
---------------------------

A pair may be either mutable or immutable.  You can desctructively modify mutable pairs with set-car!, set-cdr!, or other destructive procedures (usually they have ! at the end). An error is signaled when you try to modify an immutable pair. ペアには変更可能なものと変更不可なものがあります。変更可能なペアは、set-car!やset-cdr!等の破壊的変更手続き (通常、名前の最後に!がついています)で変更することが可能です。変更不可なペアを変更しようとするとエラーが報告されます。

In Gauche, both type of pairs can be treated the same unless you try to modify them.  Both satisfies the predicate pair?.  If you need to test specifically if a pair is immutable, use ipair? (see List predicates). The traditional constructor cons creates a mutable pair; you can create an immutable pair with ipair (see List constructors). More procedures that use immutable pairs are defined in R7RS-large scheme.ilist module (see R7RS immutable lists). Gaucheでは、変更しようとしない限り、どちらのペアも全く同じように振る舞います。 pair?にはどちらも真を返します。ペアが変更不可であることを調べたければ ipair?が使えます(List predicates参照)。伝統的なコンストラクタconsは変更可能なペアを作ります。変更不可なペアを作るにはipairを使ってください (List constructors参照)。変更不可なペアを特に扱う手続きは、R7RS-largeのscheme.ilistモジュールに定義されています (R7RS immutable lists参照)。

Note that quoted literals are immutable. Old versions of Gauche wasn't supported immutable pairs and quoted literal lists were mutable.  If your code accidentally mutate such pairs, you'll get an error.  If you need to run such code without tracking down the error, you can define the environment variable GAUCHE_MUTABLE_LITERALS. クオートされたリテラルは変更不可です。ただ、古いバージョンのGaucheは変更不可なペアを持っておらず、クオートされたリテラルリストも変更可能でした。その頃に書かれたコードでうっかりリテラルを変更していたら、現在のGaucheではエラーになってしまうでしょう。問題を修正せずにどうしても古いコードのまま走らせたい場合は、環境変数 GAUCHE_MUTABLE_LITERALSを定義してください。

List predicates
---------------

 -- Function: pair? obj
     [R7RS base] Returns #t if OBJ is a pair, #f otherwise. OBJがペアなら#tを、そうでなければ#fを返します。

 -- Function: ipair? obj
     [R7RS ilist] Returns #t iff OBJ is an immutable pair, #f otherwise.

     An immutable pair is indistinguishable from a mutable pair except using this predicate, or when you attempt to modify it. See Mutable and immutable pairs. OBJが変更不可なペアなら#tを、そうでなければ#fを返します。

     変更不可なペアは、この述語を使うか、あるいはそのペアを変更しようとした場合を除いては、変更可能なペアと全く同じように動作します。詳しくはMutable and immutable pairs参照。

 -- Function: null? obj
     [R7RS base] Returns #t if OBJ is an empty list, #f otherwise. OBJが空リストなら#tを、そうでなければ#fを返します。

 -- Function: null-list? obj
     [R7RS list] Returns #t if OBJ is an empty list, #f if OBJ is a pair.  If OBJ is neither a pair nor an empty list, an error is signaled.

     This can be used instead of null? to check the end-of-list condition when you want to be more picky about non-proper lists. OBJ が空リストなら#tを、ペアなら#fを返し、それ以外のときはエラーを報告します。

     リスト終了条件を検査する時に、正しいリスト以外を除外したい場合に null?の代わりに使えます。

 -- Function: list? obj
     [R7RS base] Returns #t if OBJ is a proper list, #f otherwise. This function returns #f if OBJ is a dotted or circular list.

     See also proper-list?, circular-list? and dotted-list? below. OBJが正しいリストなら#tを、そうでなければ#fを返します。この手続きはOBJがドットリストや循環リストなら#fを返します。

     下に説明する、 proper-list?、circular-list?、dotted-list? といった手続きも参照してください。

 -- Function: proper-list? x
     [R7RS list] Returns #t fif x is a proper list, that is, a finite list terminated by (). X が真性リスト、つまり()で終端された有限のリストであれば #t を、そうでなければ#fを返します。

 -- Function: circular-list? x
     [R7RS list] Returns #t if x is a circular list.  A list is circular if you follow cdr of the pairs you'll eventually get to a pair you already visited.  It doesn't necessary that the head of the list X is a part of the circle.  A list isn't circular by the cycle that involves CAR of the paris. X が循環リストであれば #t を返します。リストをcdr方向に辿って行って、既に訪れたペアに出会ったら、それは循環リストです。リストの頭 (x) が循環に含まれている必要はありません。また、car方向への循環があってもそれだけでは循環リストとはみなされません。

 -- Function: dotted-list? x
     [R7RS list] Returns #t if x is a finite, non-nil-terminated list. This includes non-pair, non-() values (e.g. symbols, numbers), which are considered to be dotted lists of length 0. X が有限の大きさで、空リストで終端していないリストなら #t を返します。これには、ペアではなく、空リストもない値(たとえばシンボルや数値)のような長さ0のドットリストと考えられるものを含みます。

List constructors
-----------------

 -- Function: cons obj1 obj2
     [R7RS base] Constructs a mutable pair of OBJ1 and OBJ2 and returns it. OBJ1とOBJ2の変更可能なペアを作成して返します。

          (cons 'a 'b) => (a . b)

 -- Function: ipair obj1 obj2
     [R7RS ilist] Constructs an immutable pair of OBJ1 and OBJ2 and returns it. OBJ1とOBJ2の変更不可なペアを作成して返します。

          (ipair 'a 'b) => (a . b)

 -- Function: make-list len :optional fill
     [R7RS base] Makes a proper list of length LEN.  If optional argument FILL is provided, each element is initialized by it.  Otherwise each element is undefined. 長さLENの正規のリストを返します。引数FILLが与えられていれば、各要素は FILLになります。そうでなければ各要素の値は不定です。

          (make-list 5 #t) => (#t #t #t #t #t)

 -- Function: list obj ...
     [R7RS base] Makes a list, whose elements are OBJ .... 要素がOBJ ...であるリストを作成します。

          (list 1 2 3) => (1 2 3)
          (list) => ()

 -- Function: ilist obj ...
     [R7RS ilist] Makes a list, whose elements are OBJ ..., and which consists of immutable pairs. 要素がOBJ ...であり、変更不可なペアで作られたリストを作成します。

          (ilist 1 2 3) => (1 2 3)
          (ilist) => ()

          (list-set! (ilist 1 2 3) 1 'a)
            => ERROR: Attempt to modify an immutable pair: (2 3)

 -- Function: list* obj1 obj2 ...
 -- Function: cons* obj1 obj2 ...
     [R7RS list] Like list, but the last argument becomes cdr of the last pair. Two procedures are exactly the same.  Gauche originally had list*, and SRFI-1 (R7RS (scheme list))defines cons*. listとほぼ同じですが、最後の引数が作成されるリストの最後のペアのcdrになります。二つの手続きは全く同じです。Gaucheはもともとlist*を持っていましたが、 SRFI-1 (R7RS (scheme list)) がcons*という名前を定義しました。

          (list* 1 2 3) => (1 2 . 3)
          (list* 1) => 1

 -- Function: list-copy list
     [R7RS base] Shallow copies LIST. If LIST is circular, an error is thrown. (Detecting circular list is Gauche's extension; R7RS allows the procedure to diverge.) LISTの浅いコピーを行います。 LISTが循環リストの場合、エラーが投げられます。 (循環リストを検出するのはGaucheの拡張です。 R7RSではこの手続きは停止しなくても良いことになっています。)

 -- Function: iota count :optional (start 0) (step 1)
     [R7RS list] Returns a list of COUNT numbers, starting from START, increasing by STEP.   COUNT must be a nonnegative integer.  If both START and STEP are exact, the result is a list of exact numbers; otherwise, it is a list of inexact numbers. STARTから始まり、STEPずつ増加する、 COUNT 個の要素からなる数値のリストを返します。COUNTは非負の整数でなければなりません。STARTとSTEPがともに正確数であれば、結果は正確数のリストになります。そうでなければ結果は非正確数のリストです。

          (iota 5)        => (0 1 2 3 4)
          (iota 5 1 3/7)  => (1 10/7 13/7 16/7 19/7)
          (iota 5 0 -0.1) => (0 -0.1 -0.2 -0.3 -0.4)

     This creates a list eagerly.  If the list is short it is fast enough, but if you want to count tens of thousands of numbers, you may want to do so lazily.  See liota (see Lazy sequences). この手続きはリストを最後まで作って返します。リストが短ければ十分速いですが、何万という数をリストにしたければ、遅延リストを使った方が良いかもしれません。liotaを見てください(Lazy sequences参照)。

 -- Macro: cond-list clause ...
     Construct a list by conditionally adding entries. Each CLAUSE has a test and expressions.  When its test yields true, the result of associated expression is used to construct the resulting list.  When the test yields false, nothing is inserted. 条件によりエントリを追加することによりリストを構築します。それぞれのCLAUSEは条件と式を持ちます。条件が真であれば、関連する式の結果が結果のリストの構築に使われます。条件が偽であれば、何も挿入されません。

     CLAUSE must be either one of the following form:

     (TEST EXPR ...)
          TEST is evaluated, and when it is true, EXPR ... are evaluated, and the return value becomes a part of the result.  If no EXPR is given, the result of TEST is used if it is not false.

     (TEST => PROC)
          TEST is evaluated, and when it is true, PROC is called with the value, and the return value is used to construct the result.

     (TEST @ EXPR ...)
          Like (test expr ...), except that the result of the last EXPR must be a list, and it is spliced into the resulting list, like unquote-splicing.

     (TEST => @ PROC)
          Like (test => proc), except that the result of PROC must be a list, and and it is spliced into the resulting list, like unquote-splicing.

     CLAUSEは、以下のフォームのうちの1つでなければなりません。

     (TEST EXPR ...)
          TESTが評価され、それが真ならばEXPR ...が評価され、戻り値が結果の一部となります。EXPRが与えられなければ、 TESTの結果が偽でなければその結果が使われます。

     (TEST => PROC)
          TESTが評価され、それが真ならばPROCがその値とともに呼ばれ、その戻り値が結果を構築するために使われます。

     (TEST @ EXPR ...)
          (test expr ...)のように動作しますが、最後のEXPRの値はリストでなければならず、それは結果のリストに(unquote-splicingのように) スプライスされます。

     (TEST => @ PROC)
          (test => proc)のように動作しますが、PROCの戻り値はリストでなければならず、それは結果のリストに(unquote-splicingのように) スプライスされます。

          (let ((alist '((x 3) (y -1) (z 6))))
           (cond-list ((assoc 'x alist) 'have-x)
                      ((assoc 'w alist) 'have-w)
                      ((assoc 'z alist) => cadr)))
            => (have-x 6)

          (let ((x 2) (y #f) (z 5))
            (cond-list (x @ `(:x ,x))
                       (y @ `(:y ,y))
                       (z @ `(:z ,z))))
            => (:x 2 :z 5)

List accessors and modifiers
----------------------------

 -- Function: car pair
 -- Function: cdr pair
     [R7RS base] Returns car and cdr of PAIR, respectively. それぞれPAIRのcarとcdrを返します。

 -- Function: set-car! pair obj
 -- Function: set-cdr! pair obj
     [R7RS base] Modifies car and cdr of PAIR, by OBJ, respectively.

     Note: (setter car) == set-car!, and (setter cdr) == set-cdr!. PAIRのcarもしくはcdrをOBJで置き換えます。

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

 -- Function: caar pair
 -- Function: cadr pair
     ...

 -- Function: cdddar pair
 -- Function: cddddr pair
     [R7RS base][R7RS cxr] caar == (car (car x)), cadr == (car (cdr x)), and so on.

     In R7RS, more than two-level of accessors are defined in the (scheme cxr) library.

     The corresponding setters are also defined. caar == (car (car x)), cadr == (car (cdr x)), 等々。

     R7RSでは、2レベルよりも深いアクセサは(scheme cxr)ライブラリに含まれます。

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

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

 -- Function: length list
     [R7RS base] Returns the length of a proper list LIST. If LIST is a dotted list, an error is signaled. If LIST is a circular list, this function diverges. 正規のリストLISTの長さを返します。 LISTがドットリストならばエラーが起きます。 LISTが循環リストの場合、この関数は無限ループします。

 -- Function: length+ x
     [R7RS list] If X is a proper list, returns its length. For all other X, including a circular list, it returns #f. X が真性リストなら、その長さを返します。 X がそうでなければ(たとえ循環リストであっても) #f を返します。

 -- Function: length=? x k
 -- Function: length<? x k
 -- Function: length<=? x k
 -- Function: length>? x k
 -- Function: length>=? x k
     Returns #t iff X is a (possibly improper) list whose length is equal to, less than, less than or equal to, greater than, or greater than or equal to an exact integer K, respectively. This procedure only follows the list up to the K items, so it doesn't realize elements of lazy sequence more than needed (see Lazy sequences, for the lazy sequences).

     Dotted lists and circular lists are allowed.  For the dotted list, the cdr of the last pair isn't counted; that is, a non-pair object has length 0, and (a . b) has length 1. A circular list is treated as if it has infinite length. それぞれ、リストXの長さが正確な整数kと等しいか、k未満か、k以下か、kより大きいか、 k以上かの場合に#tを、そうでなければ#fを返します。この関数はK要素までしかリストを辿らないので、特にXが遅延シーケンス (Lazy sequences参照)である場合に、必要以上にリストを実体化しなくて済みます。

     Xはドットリストや循環リストでも構いません。ドットリストの長さを数える際には最後のペアのcdrは無視します。つまり、ペアでないオブジェクトの長さは0で、(a . b)の長さは1になります。循環リストは無限の長さを持つとみなします。

          (length<=? '(a b) 2)  => #t
          (length<=? '(a b) 1)  => #f
          (length<=? '()    0)  => #t

          ;; dotted list cases
          (length<=? 'a       0)  => #t
          (length<=? '(a . b) 0)  => #f
          (length<=? '(a . b) 1)  => #t

     NB: The name of these procedures might be misleading, for other procedures with the name something<=? etc. usually takes objects of the same type. We don't have any better idea now, unfortunately. 註: これらの手続きの名前は混乱を招きやすいかもしれません。something<=?等の名前は通常、同じ型のオブジェクト同士の比較に使われるからです。残念ながら、今のところより良い名前を思いつけていません。

 -- Function: take x i
 -- Function: drop x i
     [R7RS list] take returns the first i elements of list x. drop returns all but the first i elements of list x. take はリスト X の最初のi個の要素を返します。 drop はリスト X の最初のi個の要素を除いたリストを返します。

          (take '(a b c d e) 2) => (a b)
          (drop '(a b c d e) 2) => (c d e)

     X may be any value: X はあらゆる値をとりえます。

          (take '(1 2 3 . d) 2) => (1 2)
          (drop '(1 2 3 . d) 2) => (3 . d)
          (drop '(1 2 3 . d) 3) => d

     drop is exactly equivalent to performing I cdr operations on X.  The returned value shares a common tail with X. On the other hand, take always allocates a new list for result if the argument is a list of non-zero length.

     An error is signaled if I is past the end of list X. See take* and drop* below for more tolerant version.

     For generic subsequence extraction from any sequence, see subseq in Slicing sequence. drop は X に I 回 cdr 操作をおこなうのと全く同じです。返される値は、X と共通の末尾を共有します。一方、 take は、引数のリストが長さ0でないリストなら必ず新しいリストの領域を確保します。

     I がリスト X の終端を超えたらエラーが発生します。より寛容な手続きについては、下のtake*とdrop*を見てください。

     あらゆる並びからの部分並びを抽出する汎用的な方法に関しては、 Slicing sequence にある subseq を参照してください。

 -- Function: take* list k :optional (fill? #f) (padding #f)
 -- Function: drop* list k
     More tolerant version of take and drop. They won't raise an error even if K is larger than the size of the given list.

     If the list is shorter than K elements, take* returns a copy of LIST by default.   If FILL? is true, PADDING is added to the result to make its length K.

     On the other hand, drop* just returns an empty list when the input list is shorter than K elements. takeとdropのより寛容なバージョンです。これらの手続きは、リストがkより短くてもエラーを通知しません。

     その場合、take*はデフォルトではLISTのコピーを返します。もしFILL?が真であれば、足りない要素の部分に PADDINGを追加してK要素にしたリストを返します。

     一方、drop*はリストの長さが不足する場合は単に空リストを返します。

          (take* '(a b c d) 3)       => (a b c)
          (take* '(a b c d) 6)       => (a b c d)
          (take* '(a b c d) 6 #t)    => (a b c d #f #f)
          (take* '(a b c d) 6 #t 'z) => (a b c d z z)
          (drop* '(a b c d) 3)       => (d)
          (drop* '(a b c d) 5)       => ()

     Note: For generic subsequence extraction from any sequence, see subseq in Slicing sequence. 注意: 一般的な、いかなるシーケンスからのサブシーケンスの抽出については、 Slicing sequenceのsubseqを見て下さい。

 -- Function: take-right lis k
 -- Function: drop-right lis k
     [R7RS list] take-right returns the last K elements of LIS. drop-right returns all but the last K elements of LIS. take-right は LIS の最後の K個の要素からなるリストを返します。 drop-right は LIS の最後の K個の要素を除いたリスト返します。

          (take-right '(a b c d e) 2) => (d e)
          (drop-right '(a b c d e) 2) => (a b c)

     LIS may be any finite list. LIS は有限リストであればOKです。

          (take-right '(1 2 3 . d) 2) => (2 3 . d)
          (drop-right '(1 2 3 . d) 2) => (1)
          (take-right '(1 2 3 . d) 0) => d
          (drop-right '(1 2 3 . d) 0) => (1 2 3)

     take-right's return value always shares a common tail with LIS. drop-right always allocates a new list if the argument is a list of non-zero length.

     An error is signaled if K is larger than the length of LIS. See take-right* and drop-right* below, for more tolerant version. take-right の返す値はいつでも LIS の共通の末尾を共有します。 drop-right は、引数が長さが0でないリストなら、必ず新しいリストの領域を確保します。

     K がリスト LIS の長さより大きければエラーが発生します。より寛容なバージョンについては下のtake-right*, drop-right*を参照してください。

 -- Function: take-right* list k :optional (fill? #f) (padding #f)
 -- Function: drop-right* list k
     Like take* and drop*, but counts from right of LIST. If LIST is shorter than K elements, they won't raise an error.  Instead, drop-right* just returns an empty list, and take-right* returns LIST itself by default. If FILL? is true for take-right*, PADDING is added on the left of the result to make its length K. The result still shares the LIST. take*及びdrop*と同じですが、LISTの右端からカウントします。これらはLISTがK要素より短い場合にもエラーを通知しません。 drop-right*はその場合は単に空リストを返します。 take-right*はその場合はデフォルトでLISTそのものを返しますが、FILL?が真であればLISTの右側に足りない分だけPADDINGを足したものを返します。その場合でも結果の尾部はLISTと共有されます。

 -- Function: take! lis k
 -- Function: drop-right! lis k
     [R7RS list] Linear update variants of take and drop-right. Those procedures may destructively modifies LIS.

     If LIS is circular, take! may return a list shorter than expected. take および drop-right のその場で更新されるバージョンです。これらの手続きは LIS を破壊的に変更するかもしれません。

     LIS が循環リストなら、take! は期待されるものより短いリストを返す可能性があります。

 -- Function: list-tail list k :optional fallback
     [R7RS base] Returns K-th cdr of LIST. LIST can be a proper, dotted or circular list. (If LIST is a dotted list, its last cdr is simply ignored).

     If K is negative or larger than the length of LIST, the behavior depends on whether the optional FALLBACK argument is given or not.  If FALLBACK is given, it is returned. Otherwise, an error is signaled. LISTのK番目のcdrを返します。LISTは正規のリストでもドットリストでも循環リストでも構いません。 (LISTがドットリストの場合、最後のcdrは無視されます)。

     Kの値が負であったりLISTの長さ以上の場合、 FALLBACK引数が与えられていればそれが返され、そうでなければエラーが報告されます。

 -- Function: list-ref list k :optional fallback
     [R7RS+] Returns K-th element of LIST. LIST can be a proper, dotted or circular list.

     By default, list-ref signals an error if K is negative, or greater than or equal to the length of LIST. However, if an optional argument FALLBACK is given, it is returned for such case.  This is an extension of Gauche. LISTのK番目の要素を返します。LISTは正規のリストでもドットリストでも循環リストでも構いません。

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

 -- Function: list-set! list k v
     [R7RS base] Modifies the K-th element of a LIST by V. It is an error unless K is an exact integer between 0 and one minus the length of K.  If LIST is immutable, no error is signalled but the behavior is undefined. リストLISTのK番目の要素をVへと変更します。 Kが0から(- リストの長さ 1)の範囲の正確な整数でない場合はエラーが報告されます。LISTが変更不可なリストであった場合、エラーは報告されませんが、その後の振る舞いは不定となります。

 -- Function: last-pair list
     [R7RS list] Returns the last pair of LIST. LIST can be a proper or dotted list. LISTの最後のペアを返します。LISTは正規のリストかドットリストです。

          (last-pair '(1 2 3))   => (3)
          (last-pair '(1 2 . 3)) => (2 . 3)
          (last-pair 1)          => error

 -- Function: last pair
     [R7RS list] Returns the last element of the non-empty, finite list PAIR. It is equivalent to (car (last-pair pair)). 空ではない有限リスト PAIR の最後の要素を返します。これは、(car (last-pair pair)) と同等です。

          (last '(1 2 3))   => 3
          (last '(1 2 . 3)) => 2

 -- Function: split-at x i
 -- Function: split-at! x i
     [R7RS list] split-at splits the list X at index I, returning a list of the first I elements, and the remaining tail. split-at はリスト X をインデックス I の位置で分割し、最初の I 個の要素からなるリストと、残りの末尾とを返します。

          (split-at '(a b c d e) 2) => (a b) (c d e)

     split-at! is the linear-update variant. It may destructively modifies X to produce the result. split-at! はその場で更新されるバージョンです。これは X を破壊的に更新するかもしれません。

 -- Function: split-at* list k :optional (fill? #f) (padding #f)
     More tolerant version of split-at. Returns the results of take* and drop*. SRFI-1 (R7RS (scheme list))のsplit-atの寛容なバージョンです。 take*とdrop*の結果を返します。

          (split-at* '(a b c d) 6 #t 'z)
            => (a b c d z z) and ()

 -- Function: slices list k :optional fill? padding
     Splits LIST into the sublists (slices) where the length of each slice is K. If the length of LIST is not a multiple of K, the last slice is dealt in the same way as take*; that is, it is shorter than K by default, or added PADDING if FILL? is true. LISTを、それぞれの長さがKであるようなサブリスト(スライス)に分割します。 LISTの長さがKの整数倍でない場合は、最後のスライスは take*と同じ方法で扱われます。つまり、デフォルトではKより短いもの、あるいはFILL?が真ならばPADDINGが追加されます。

          (slices '(a b c d e f g) 3)
            => ((a b c) (d e f) (g))
          (slices '(a b c d e f g) 3 #t 'z)
            => ((a b c) (d e f) (g z z))

 -- Function: intersperse item list
     Inserts ITEM between elements in the LIST. (The order of arguments is taken from Haskell's intersperse). LISTの要素の間にITEMを挿入します。 (引数の順番は、Haskellのintersperseと同じです。)

          (intersperse '+ '(1 2 3))  => (1 + 2 + 3)
          (intersperse '+ '(1))      => (1)
          (intersperse '+ '())       => ()

Walking over lists
------------------

 -- Function: map proc list1 list2 ...
     [R7RS+] Applies PROC for each element(s) of given list(s), and returns a list of the results.  R7RS doesn't specify the application order of map, but Gauche guarantees PROC is always applied in order of the list(s). Gauche's map also terminates as soon as one of the list is exhausted. 与えられたリストの各要素に対してPROCを適用し、その結果をリストにして返します。R7RSではPROCの適用順序が定められていませんが、Gaucheでは常にPROCはリスト内の順番で呼ばれます。複数のリストが与えられた場合、最も短いリストが終了した時点でPROCの適用を打ち切ります。

          (map car '((a b) (c d) (e f))) => (a c e)

          (map cons '(a b c) '(d e f))
            => ((a . d) (b . e) (c . f))

     Note that the gauche.collection module (see Collection framework) extends map to work on any type of collection. gauche.collectionモジュール(Collection framework参照) を使うと、mapがリスト以外のコレクション型に対しても動作するようになります。

 -- Function: append-map f clist1 clist2 ...
 -- Function: append-map! f clist1 clist2 ...
     [R7RS list] Functionally equivalent to the followings, though a bit more efficient: 機能的には以下と同等ですが、若干効率が良いです:

            (apply append (map F CLIST1 CLIST2 ...))
            (apply append! (map F CLIST1 CLIST2 ...))

     At least one of the list arguments must be finite. 引数のリストのうち少くともひとつは有限でなければなりません。

 -- Function: map* proc tail-proc list1 list2 ...
     Like map, except that TAIL-PROC is applied to the cdr of the last pair in the argument(s) to get the cdr of the last pair of the result list.  This procedure allows improper list to appear in the arguments.   If a single list is given, TAIL-PROC always receives a non-pair object. mapとほぼ同じですが、引数の最後のペアのcdrにTAIL-PROCが適用され、その返り値が結果のリストの最後のペアのcdrになります。この手続きは正規でないリストを引数に取ることができます。引数のリストがひとつだけの場合、TAIL-PROCの引数は必ずペアでないオブジェクトです。

          (map* - / '(1 2 3 . 4)) => (-1 -2 -3 . 1/4)

          (define (proper lis)
            (map* values
                  (lambda (p) (if (null? p) '() (list p)))
                  lis))

          (proper '(1 2 3))     => (1 2 3)
          (proper '(1 2 3 . 4)) => (1 2 3 4)

     If more than one list are given, the shortest one determines how TAIL-PROC is called.  When map* reaches the last pair of the shortest list, TAIL-PROC is called with cdrs of the current pairs. 二つ以上のリストが与えられた場合は、最も短いリストがTAIL-PROCの呼び出しを決めます。map*が最も短いリストの最後のペアに達した時点で、その時のそれぞれのペアのcdrがTAIL-PROCへと渡されます。

          (map* + vector '(1 2 3 4) '(1 2 . 3))
            => (2 4 . #((3 4) 3))

     Note: The name map* is along the line of list*/cons* that can produce improper list (see List constructors, see R7RS lists). 註: map*という名前は、正規でないリストを作り得るlist*/cons*からの連想でつけられました (List constructors、R7RS lists参照)。

 -- Function: for-each proc list1 list2 ...
     [R7RS base] Applies PROC for each element(s) of given list(s) in order. The results of PROC are discarded.  The return value of for-each is undefined.  When more than one list is given, for-each terminates as soon as one of the list is exhausted. 手続きPROCをリストの各エレメントに対して順に適用します。 PROCの結果は捨てられます。for-eachの戻り値は定義されていません。複数のリストが与えられた場合、一番短いリストが終了した時点でfor-eachは終了します。

     Note that the gauche.collection module (see Collection framework) extends for-each to work on any type of collection. gauche.collectionモジュール(Collection framework参照) を使うと、for-eachがリスト以外のコレクション型に対しても動作するようになります。

 -- Function: fold kons knil clist1 clist2 ...
     [R7RS list] The fundamental list iterator. When it is given a single list CLIST1 = (E1 E2 ... EN), then this procedure returns 基本的なリスト反復演算子です。単一のリスト CLIST1 = (E1 E2 ... EN) を与えられたときには、以下を返します。

          (KONS EN ... (KONS E2 (KONS E1 KNIL)) ... )

     If N list arguments are provided, then the KONS function must take N+1 parameters: one element from each list, and the "seed" or fold state, which is initially KNIL. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

     Examples: N 本のリストが与えられた場合には、KONS 関数は N+1 個の引数をとる関数でなければなりません。それぞれのリストから要素をひとつずつと、初期値 KNIL である「種」あるいは畳み込み状態とよばれるものです。この畳み込み演算は、もっとも短いリストの要素がなくなったところで終了します。与えられるリストの少くともひとつは有限でなければなりません。

     例:

          (fold + 0 '(3 1 4 1 5 9)) => 23 ;sum up the elements
          (fold cons '() '(a b c d e)) => (e d c b a) ;reverse
          (fold cons* '() '(a b c) '(1 2 3 4 5))
              => (c 3 b 2 a 1) ;n-ary case

 -- Function: fold-right kons knil clist1 clist2 ...
     [R7RS list] The fundamental list recursion operator. When it is given a single list CLIST1 = (E1 E2 ... EN), then this procedure returns 基本的な再帰演算子です。単一のリスト CLIST1 = (E1 E2 ... EN) を与えられたときには、以下を返します。

          (KONS E1 (KONS E2 ... (KONS EN KNIL)))

     If N list arguments are provided, then the KONS function must take N+1 parameters: one element from each list, and the "seed" or fold state, which is initially KNIL. The fold operation terminates when the shortest list runs out of values. At least one of the list arguments must be finite.

     Examples: N 本のリストが与えられた場合には、KONS 関数は N+1 個の引数をとる関数でなければなりません。それぞれのリストから要素をひとつずつと、初期値 KNIL である「種」あるいは畳み込み状態とよばれものです。この畳み込み演算は、もっとも短いリストの要素がなくなったところで終了します。与えられるリストの少くともひとつは有限でなければなりません。

     例:

          (fold-right cons '() '(a b c d e))
             => (a b c d e) ;copy list
          (fold-right cons* '() '(a b c) '(1 2 3 4 5))
             => (a 1 b 2 c 3) ;n-ary case

 -- Function: fold-left snok knil clist1 clist2 ...
     [R6RS] This is another variation of left-associative folding. When it is given a single list CLIST1 = (E1 E2 ... EN), then this procedure returns: これは左結合のfoldの別バージョンです。一つのリスト CLIST1 = (E1 E2 ... EN) が与えられた場合、次の値を返します。

          (SNOK (... (SNOK (SNOK KNIL E1) E2) ...) EN)

     Compare this with fold above; association is the same, but the order of arguments passed to the procedure SNOK is reversed from the way arguments are passed to KONS in fold.   If SNOK is commutative, fold and fold-left produces the same result. 上のfoldと見比べてみてください。結合の順序は同じですが、 SNOKに渡される引数の順序が、foldにおいてKONSに渡される引数の順序とは逆になっています。snokが可換な演算であれば、 foldとfold-leftの結果は同じになります。

          (fold-left + 0 '(1 2 3 4 5) => 15

          (fold-left cons 'z '(a b c d))
            => ((((z . a) . b) . c) . d)

          (fold-left (^[a b] (cons b a)) 'z '(a b c d))
            => (a b c d z)

     If more than one lists are given, SNOK is called with the current seed value KNIL and each corresponding element of the input lists clist1 clist2 .... 二つ以上のリストが渡された場合、SNOKは現在のKNIL値および入力リストclist1 clist2 ... の対応する要素を引数として呼び出されます。

          (fold-left list 'z '(a b c) '(A B C))
            => (((z a A) b B) c C)

     Note: Most functional languages have left- and right- associative fold operations, which correspond to fold-left and fold-right, respectively. (e.g. Haskell's foldl and foldr).  In Scheme, SRFI-1 first introduced fold and fold-right.  R6RS introduced fold-left.  (However, in R6RS the behavior is undefined if the lengths of clist1 clist2 ... aren't the same, while in Gauche fold-left terminates as soon as any one of the lists terminates.) 註：多くの関数型言語で左結合および右結合の畳み込み操作が定義されていますが、それはfold-leftとfold-rightに相当します。 (例: Haskellのfoldlとfoldr。) Schemeでは、まずSRFI-1によってfoldとfold-rightが左/右結合の畳み込み演算として導入され、R6RSでfold-leftが定義されました。 (但し、R6RSのfold-leftではclist1 clist2 ...の長さがすべて同じでない場合の動作は未定義ですが、Gaucheでは最短のリストが終了した時点でそれまでの結果が返されます。)

 -- Function: reduce f ridentity list
 -- Function: reduce-right f ridentity list
     [R7RS list] Variant of fold and fold-right.   F must be a binary operator, and RIDENTITY is the value such that for any value X that is valid as F's input, fold および fold-right の変形バージョンです。 F は二項演算子でなければなりません。また、RIDENTITY は F の入力として許されるあらゆる値 X について以下を満していなければなりません。

           (f x ridentity) == x

     These functions effectively do the same thing as fold or fold-right, respectively, but omit the first application of F to RIDENTITY, using the above nature. So RIDENTITY is used only when LIST is empty. これらの関数は実質的に fold や fold-right と同じことを行いますが、RIDENTITYには上記の性質があるため、 FはRIDENTITYには適用されません。 RIDENTITYが使われるのはLISTが空の場合だけです。

 -- Function: filter pred list
 -- Function: filter! pred list
     [R7RS list] A procedure PRED is applied on each element of LIST, and a list of elements that PRED returned true on it is returned. 手続き PRED が LIST の各要素に適用され、 PRED が真を返す要素のリストが返されます。

          (filter odd? '(3 1 4 5 9 2 6)) => (3 1 5 9)

     filter! is the linear-update variant.  It may destructively modifies LIST to produce the result. filter! はその場で更新されるバージョンです。結果を生成するために LIST を破壊的に変更するかもしれません。

 -- Function: filter-map f clist1 clist2 ...
     [R7RS list] Like map, but only true values are saved. At least one of the list arguments must be finite. map と似ていますが、真になる場合の値のみが保存されます。引数として与えられるリストの少くともひとつは有限でなければなりません。

          (filter-map (lambda (x) (and (number? x) (* x x)))
                      '(a 1 b 3 c 7))
            => (1 9 49)

 -- Function: remove pred list
 -- Function: remove! pred list
     [R7RS list] A procedure PRED is applied on each element of LIST, and a list of elements that PRED returned false on it is returned. 手続き PRED が LIST の各要素に適用され、 PRED が偽を返す要素のリストが返されます。

          (remove odd? '(3 1 4 5 9 2 6)) => (4 2 6)

     remove! is the linear-update variant.  It may destructively modifies LIST to produce the result. remove! はその場で更新されるバージョンです。結果を生成するために LIST を破壊的に更新するかもしれません。

 -- Function: find pred clist
     [R7RS list] Applies PRED for each element of CLIST, from left to right, and returns the first element that PRED returns true on.  If no element satisfies PRED, #f is returned. CLIST の各要素に対して左から右に PRED を適用し、 PRED が真を返す最初の要素を返します。PREDを満たす要素が無い場合は#fを返します。

 -- Function: find-tail pred clist
     [R7RS list] Applies PRED for each element of CLIST, from left to right, and when PRED returns a true value, returns the pair whose car is the element.  If no element satisfies PRED, #f is returned. CLIST の各要素に対して左から右に PRED を適用し、PRED が真を返す場合、その car がその要素であるペアを返します。 PREDを満たす要素が無い場合は#fを返します。

 -- Function: any pred clist1 clist2 ...
     [R7RS list] Applies PRED across each element of CLISTs, and returns as soon as PRED returns a non-false value. The return value of any is the non-false value PRED returned. If CLISTs are exhausted before PRED returns a non-false value, #f is returned. CLIST の各要素に PRED を適用し、PREDが偽でない値を返したら直ちにその値を返します。 PREDが偽でない値を返す前にリストの要素を使いきってしまったら #fが返ります。

 -- Function: every pred clist1 clist2 ...
     [R7RS list] Applies PRED across each element of CLISTs, and returns #f as soon as PRED returns #f. If all application of PRED return a non-false value, every returns the last result of the applications. CLIST の各要素に PRED を順に適用し、PREDが偽を返した場合、直ちに偽を返します。全てのPREDの適用が偽でない値を返した場合は、最後に返された値が返されます。

 -- Function: count pred clist1 clist2 ...
     [R7RS list] A procedure PRED is applied to the N-th element of given lists, from N is zero to the length of the the shortest finite list in the given lists, and the count of times PRED returned true is returned. N をゼロから与えられたリストのうち最も短いリストの長さまでとして、PRED 手続きを与えられたリストの N 番目の要素にそれぞれ適用します。 PRED が真を返した数が返ります。

          (count even? '(3 1 4 1 5 9 2 5 6)) => 3
          (count < '(1 2 4 8) '(2 4 6 8 10 12 14 16)) => 3

     At least one of the argument lists must be finite: 引数で与えられるリストの少くともひとつは有限でなければなりません。

          (count < '(3 1 4 1) (circular-list 1 10)) => 2

 -- Function: delete x list :optional elt=
 -- Function: delete! x list :optional elt=
     [R7RS list] Equivalent to 以下と同等です。

            (remove (lambda (y) (elt= x y)) list)
            (remove! (lambda (y) (elt= x y)) list)

     The comparison procedure, ELT=, defaults to equal?. 比較手続き ELT= はデフォルトでは equal? です。

 -- Function: delete-duplicates list :optional elt=
 -- Function: delete-duplicates! list :optional elt=
     [R7RS list] Removes duplicate elements from LIST. If there are multiple equal elements in LIST, the result list only contains the first or leftmost of these elements in the result. The order of these surviving elements is the same as in the original list. The comparison procedure, ELT=, defaults to equal?. LIST から重複した要素を取り除きます。LIST 中に等しい要素が複数ある場合、一番左がわにある最初のものだけが残ります。これらの生き残った要素間の順番は最初のリストの順番が保存されます。比較手続き ELT= のデフォルト値は、equal? です。

Other list procedures
---------------------

 -- Function: append list ...
     [R7RS base] Returns a list consisting of the elements of the first LIST followed by the elements of the other lists.  The resulting list is always newly allocated, except that it shares structure with the last list argument. The last argument may actually be any object; an improper list results if the last argument is not a proper list. 渡されたリストの要素を繋げたリストを返します。最後の引数の部分以外は新しいセルがアロケートされて使われます。最後の引数は正規のリストである必要がありません。その場合、結果は正規でないリストとなります。

 -- Function: append! list ...
     [R7RS list] Returns a list consisting of the elements of the first LIST followed by the elements of the other lists.  The cells in the lists except the last one may be reused to construct the result.   The last argument may be any object. 渡されたリストの要素を繋げたリストを返します。最後の引数以外のリストのセルは、結果を作成するために再利用されるかもしれません。最後の引数は正規のリストである必要はありません。

 -- Function: concatenate list-of-lists
 -- Function: concatenate! list-of-lists!
     [R7RS list] Equivalent to (apply append LIST-OF-LISTS) and (apply append! LIST-OF-LISTS), respectively, but this can be a bit efficient by skipping overhead of apply. それぞれ、(apply append LIST-OF-LISTS) および (apply append! LIST-OF-LISTS) と同等ですが、 applyのオーバヘッドが無い分、わずかに効率的です。

 -- Function: reverse list :optional (tail '())
 -- Function: reverse! list :optional (tail '())
     [R7RS+] Returns a list consisting of the elements of LIST in the reverse order. While reverse always returns a newly allocated list, reverse! may reuse the cells of LIST.  Even LIST is destructively modified by reverse!, you should use its return value, for the first cell of LIST may not be the first cell of the returned list.

     If an optional argument TAIL is given, it becomes the tail of the returned list (TAIL isn't copied). It is useful in the idiom to prepend the processed results on top of already existing results. LISTの要素を逆順に並べたリストを返します。 reverseは常に新たにリストをアロケートしますが、 reverse!は結果を作るためにLISTのセルを再利用するかもしれません。但し、LISTの先頭のセルがreverse!の結果でも先頭になるとは限らないので、LISTが変更されることを当てにするのではなく、 reverse!の戻り値を利用する必要があります。

     省略可能引数TAILが与えられた場合、それは結果のリストの末尾に付け足されます (TAIL部分はコピーされません)。これは、既にある結果のリストに新たに作った結果を付け足すイディオムで便利です。

          (reverse '(1 2 3 4 5)) => (5 4 3 2 1)
          (reverse '(1 2 3) '(a b)) => (3 2 1 a b)

     The TAIL argument is Gauche's extension, and it isn't in the traditional Scheme's reverse. The rationale is the following correspondence: TAIL引数はGauche独自の拡張で、伝統的なSchemeのreverseにはありませんが、次の対応を考えると、そう不自然なことではありません。

          (reverse xs)      == (fold cons xs '())
          (reverse xs tail) == (fold cons xs tail)

 -- Function: append-reverse rev-head tail
 -- Function: append-reverse! rev-head tail
     [R7RS list] Equivalent to the two-argument reverse and reverse!. Provided for srfi-1 (R7RS (scheme list)) compatibility. 2引数のreverseおよびreverse!と同等です。 srfi-1 (R7RS (scheme list)) との互換のために用意されています。

 -- Function: memq obj list
 -- Function: memv obj list
 -- Function: member obj list :optional obj=
     [R7RS base] Searches OBJ in the LIST.  If n-th element of LIST equals to OBJ (in the sense of eq? for memq, eqv? for memv, and equal? for member), (list-tail LIST N) is returned. Otherwise, #f is returned. LISTからOBJを探します。もしLISTのN番目の要素が OBJと同一ならば、(list-tail LIST N)を返します。 memqは同一性の判定にeq?を、memvはeqv?を、 memberはequal?を使います。 OBJがLIST中に見つからなければ#fが返されます。

     If the optional OBJ= argument of member is given, it is used as a equivalence predicate instead of equal?. memberに省略可能引数OBJ=が与えられた場合は、その手続きがequal?のかわりにOBJと要素を比較するのに使われます。

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

Association lists
-----------------

 -- Function: acons obj1 obj2 obj3
     Returns (cons (cons OBJ1 OBJ2) OBJ3). Useful to put an entry at the head of an associative list.

     (This procedure is defined in SRFI-1 (R7RS (scheme list)) as alist-cons; see R7RS lists). (cons (cons OBJ1 OBJ2) OBJ3) を返します。連想リストの先頭に新しいエントリを加えるのに便利です。

     (この手続きはSRFI-1 (R7RS (scheme list))ではalist-consという名前で定義されています。 R7RS lists参照)。

          (acons 'a 'b '((c . d))) => ((a . b) (c . d))

 -- Function: alist-copy alist
     [R7RS list] Returns a fresh copy of ALIST. The spine of ALIST and each cell that points a key and a value is copied. ALIST の新しい複製を返します。ALIST の背骨の部分、およびキーと値を指す各セルは複製されます。

          (define a (list (cons 'a 'b) (cons 'c 'd)))
          a => ((a . b) (c . d))

          (define b (alist-copy a))
          b => ((a . b) (c . d))

          (set-cdr! (car a) 'z)
          a => ((a . z) (c . d))
          b => ((a . b) (c . d))

 -- Function: assq obj list
 -- Function: assv obj list
 -- Function: assoc obj list :optional key=
     [R7RS base] Each element in LIST should be a pair (Gauche ignores non-pair element in LIST, but other R7RS implementation may raise an error, so be aware of it when you're writing a portable code). These procedures search a pair whose car matches OBJ (in the sense of eq? for assq, eqv? for assv, and equal? for assoc) from left to right, and return the leftmost matched pair if any. If no pair matches, these return #f. LISTの各要素はペアでなければなりません (GaucheはLIST中のペアでない要素を単に無視しますが、他のR7RS処理系はエラーを投げるかもしれないので、ポータブルなコードを書いている時は注意してください)。これらの手続きは、LISTの要素であるペアのうち、そのcarが OBJと一致するペアを左から探して行きます。もし見付かればそのペアが、見付からなければ#fが返されます。 assqは比較関数にeq?を、assvはeqv?を、 assocはequal?をそれぞれ用います。

     If the optional argument of assoc is given, it is called instead of equal? to check the equivalence of OBJ and each key. assocの省略可能引数が与えられた場合は、その手続きがequal?のかわりに、 OBJと各キーとの同一性判定に使われます。

 -- Function: alist-delete key alist :optional key=
 -- Function: alist-delete! key alist :optional key=
     [R7RS list] Deletes all cells in ALIST whose key is the same as KEY. Comparison is done by a procedure KEY=.  The default is eqv?.

     The linear-update version alist-delete! may or may not modify ALIST. ALIST から KEYと同じキーをもつすべてのセルを削除します。比較は KEY= で行います。これのデフォルト値は eqv? です。

     その場で更新を行うバージョン alist-delete! は元の ALIST を変更してしまうことがあります。

 -- Function: rassoc key alist :optional eq-fn
 -- Function: rassq key alist
 -- Function: rassv key alist
     Reverse associations---given KEY is matched to the cdr of each element in ALIST, instead of the car. Handy to realize bidirectional associative list. Rassoc takes an optional comparison function, whose default is equal?.  Rassq and rassv uses eq? and eqv?. 与えられるKEYがALISTのそれぞれの要素で、carの代わりに cdrにマッチするような逆になった連想リストです。両方向の連想リストと理解すると簡単です。 rassocは、そのデフォルトがequal?である、オプションの比較関数を取ります。rassqはeq?、rassvはeqv?を使います。

 -- Function: assoc-ref alist key :optional default eq-fn
 -- Function: assq-ref alist key :optional default
 -- Function: assv-ref alist key :optional default
     These procedures provide the access to the assoc list symmetric with other *-ref procedures. (Note that the argument order is different from assoc, assq and assv -- *-ref procedures take a container first, and an item second.)

     This captures the common pattern of alist access: これらの手続きは、他の*-ref手続きと対称的な連想リストへのアクセスを提供します。(assoc, assq, assvと引数の順序が逆であることに注意しえください。*-ref手続きは、コンテナを最初に、要素を次に取ります)。

     これは、一般的な連想リストアクセスのパターンを提供します。

          (assoc-ref alist key default eq-fn)
           ==
            (cond [(assoc key alist eq-fn) => cdr]
                  [else default])))

     If DEFAULT is omitted, #f is used.

     Assoc-ref takes an optional comparison function EQ-FN, whose default is equal?.  Assq-ref and assv-ref uses eq? and eqv?, respectively. DEFAULTが省略されると、#fが使われます。

     assoc-refは、そのデフォルトがequal?である、オプションの比較関数EQ-FNを取ります。assq-refはeq?を、 assv-refはeqv?をそれぞれ使います。

 -- Function: rassoc-ref alist key :optional default eq-fn
 -- Function: rassq-ref alist key :optional default
 -- Function: rassv-ref alist key :optional default
     Reverse association version of assoc-ref. assoc-refの逆連想リストバージョンです。

          (rassoc-ref alist key default eq-fn)
           ==
            (cond ((rassoc key alist eq-fn) => car)
                  (else default))))

     The meanings of optional arguments are the same as assoc-ref. オプショナル引数の意味は、assoc-refと同じです。

 -- Function: assoc-set! alist key val :optional eq-fn
 -- Function: assq-set! alist key val
 -- Function: assv-set! alist key val
     Returns an alist who has (key . val) pair added to the alist. If alist already has an element with KEY, the element's cdr is destructively modified for VAL. If ALIST doesn't have an element with KEY, a new pair is created and appended in front of ALIST; so you should use the return value to guarantee KEY-VAL pair is added.

     Assoc-set! takes optional comparison function EQ-FN, whose default is equal?.  Assq-set! and assv-set! uses eq? and eqv?, respectively. alistに(key . val)のペアが追加された連想リストを返します。 alistがすでにKEYをキーとする要素を持っている場合、その要素のcdrは破壊的にVALに変更されます。 ALISTがKEYをキーとする要素を持っていない場合は、新しいペアが作成され、ALISTの一番前に追加されます。したがって、KEY-VALペアが追加されたことを保証するためにその戻り値を使うべきです。

     assoc-set!は、そのデフォルトがequal?である、オプションの比較関数EQ-FNを取ります。assq-set!はeq?を、 assv-set!はeqv?を、それぞれ使います。

 -- Function: assoc-adjoin alist key val :optional eq-fn
     If ALIST contains an entry with KEY, returns a new associative list where the value of the KEY is replaced for VAL. The order of entries in ALIST is preserved.  If ALIST doesn't contain the entry, it returns (acons KEY VAL ALIST).

     The original ALIST is left unmodified.  The returned associative list may share a part of its tail with the original ALIST, however.

     The optional EQ-FN argument is a procedure with two arguments to be used to compare the keys; the default is equal?.

     Note the order of arguments; we have ALIST first, just as assoc-ref and assoc-set!, and other -adjoin procedures. It is not the same as alist-delete and assoc, which takes the key first. ALISTがKEYをキーとするエントリを持っていた場合、その値をVALに変えた新たな連想リストを作って返します。ALIST中のエントリの順序は保存されます。もしALIST中にKEYをキーとするエントリが無い場合は、 (acons KEY VAL ALIST)が返されます。

     元のALISTは変更されません。但し、返された連想リストはALISTと末尾部分を共有するかもしれません。

     EQ-FN引数は2引数を取る手続きで、キーの比較に使われます。省略された場合はequal?が使われます。

     引数の順序に注意: assoc-refやassoc-set!、また他の-adjoin系関数と同じように、この手続きは連想リストを第一引数に取ります。一方、alist-deleteやassocはキーを第一引数に取ります。

 -- Function: assoc-update-in alist keys proc :optional default eq-fn
     This procedure allows to update a nested associative list. The ALIST argument is a (possibly nested) associative list, KEYS are a list of keys, and PROC is a procedure that takes one argument.  First, the keys are looked up recursively in ALIST; then its value is passed to PROC. The return value is a new (nested) associative list where the value pointed by KEYS is replaced with the return value of PROC. この手続きは、ネストした連想リストを更新するのに使えます。 ALISTはネストした連想リストです。 KEYSはキーのリストで、PROCは1引数を取る手続きです。まず、KEYSにあるキーを順に使って、ネストした連想リストから値が取り出され、PROCに渡されます。手続きの戻り値は新しいネストした連想リストで、該当するエントリの値が PROCの戻り値に置き換えられたものとなります。

          (assoc-update-in '((a (b . 1) (c . 2))) '(a c) (cut + <> 1))
            => ((a (b . 1) (c . 3))

     The order of entries are preserved.  The original ALIST is left unmodified, but the returned value may share a part of the structure with ALIST. エントリの順序は保存されます。元のALISTは変更を受けませんが、戻り値と部分構造を共有するかもしれません。

     If ALIST doesn't have the entry specified by KEYS, a new entry is added.  A new entry is added at the beginning of the sequence where specified key didn't exist. ALISTがKEYSで指定されるエントリを持たない場合は新たなエントリが追加されます。新たなエントリは、キーが存在しないシーケンスの先頭に付け加えられます。

          (assoc-update-in '((a (b . 1) (c . 2))) '(a d e) (^_ 99))
            => ((a (d (e . 99)) (b . 1) (c . 3)))

     The DEFAULT argument is passed to PROC when there's no entry with specified keys.  If omitted, #f is assumed. DEFAULT引数は、キーに対応するエントリが存在しなかった場合にPROCに渡されます。省略値は#fです。

     The optional EQ-FN argument is a procedure with two arguments to be used to compare the keys; the default is equal?.

     Note the order of arguments; we have ALIST first, just as assoc-ref and assoc-set!, and other -adjoin procedures. It is not the same as alist-delete and assoc, which takes the key first. EQ-FN引数は2引数を取る手続きで、キーの比較に使われます。省略された場合はequal?が使われます。

     引数の順序に注意: assoc-refやassoc-set!、また他の-adjoin系関数と同じように、この手続きは連想リストを第一引数に取ります。一方、alist-deleteやassocはキーを第一引数に取ります。

     Note: For destructively updating general nested aggregate structures, setter of ~ is handy (see Universal accessor).  You can modify an entry in a hashtable in a vector in a list, for example.  Associative list is a bit special, since you can't distinguish it from lists (thus ~ can't be used), and it is mostly used in functional way. So we added a special update procedure. 註: ネストした集合データ構造の一部を破壊的に更新するには、 ~のセッタが便利です(Universal accessor参照)。例えばハッシュテーブルのベクタのリスト、から一番奥のハッシュテーブルのエントリを更新することが出来ます。しかし連想リストはちょっと特殊で、リストと型的に区別できないため、~が使えません。連想リストはまた、関数的に使われることも多いため、専用の更新手続きを用意しました。

Symbols
=======

 -- Builtin Class: <symbol>
     A class for symbols. シンボルを表すクラスです。

 -- Reader Syntax: |name|
     [R7RS] Denotes a symbol that has weird name, including the characters that are not usually allowed in symbols.  It can also include hex-escaped characters. シンボルの定義では通常許されないような文字を使った妙な名前のシンボルを表記するのに使う構文です。16進数エスケープ表記を含めることもできます。

          ;; A symbol with spaces in its name
          ;; 空白を名前に含むシンボル
          '|this is a symbol| => |this is a symbol|

          ;; Unicode codepoint can be used following backslash-x escape,
          ;; and terminated by semicolon.
          ;; Unicodeコードポイントを、バックスラッシュとxからなるエスケープに続けて
          ;; 書くこともできます。セミコロンで終端します。
          '|\x3bb;| => λ

     If the interpreter is running in case-insensitive mode, this syntax can be used to include uppercase characters in a symbol (see Case-sensitivity). インタプリタが大文字小文字を区別しないモードで走っている場合は、大文字を含むシンボルを表記するときにも使えます (Case-sensitivity参照)。

 -- Reader Syntax: #:name
     Denotes uninterned symbol.  Uninterned symbols can be created by gensym or string->uninterned-symbol. 「インターンされていない」シンボルを表記します。インターンされていないシンボルは gensymかstring->uninterned-symbolで作ることができます。

     Uninterned symbols are mainly for legacy macros to avoid variable conflicts.   They are not registered in the internal dictionary, so such symbols with the same name can't be eq?. インターンされていないシンボルは、良く伝統的なマクロで変数衝突を避けるために使われます。インターンされていないシンボルは内部のシンボルのテーブルに登録されないため、同じ名前のシンボルでも eq?になりません。

          (eq? '#:foo '#:foo) => #f
          (eq? '#:foo 'foo) => #f

     When an S-expression including uninterned symbols are printed, the srfi-38 syntax is used to indicate which uninterned symbol is the same (eq?) to which. インターンされていないシンボルが含まれるS式を、シンボルの同一性を保って表記するには、srfi-38記法が使えます。

          (let1 s '#:foo (list s s))
            => prints (#0=#:foo #0#)

          (let ((s '#:foo) (t '#:foo)) (list s t s t))
            => prints (#0=#:foo #1=#:foo #0# #1#)

 -- Function: symbol? obj
     [R7RS base] Returns true if and only if OBJ is a symbol. OBJがシンボルなら#tを返します。

          (symbol? 'abc)     => #t
          (symbol? 0)        => #f
          (symbol? 'i)       => #t
          (symbol? '-i)      => #f
          (symbol? '|-i|)    => #t

 -- Function: symbol-interned? symbol
     Returns #t if SYMBOL is an interned symbol, #f if it is an uninterned symbol.   An error is signaled if SYMBOL is not a symbol. シンボルSYMBOLがインターンされていれば#tを、そうでなければ#fを返します。シンボルでないものが渡された場合はエラーとなります。

 -- Function: symbol=? a b c ...
     [R7RS base] Every argument must be a symbol.  Returns #t iff every pair of arguments are eq? to each other. 全ての引数はシンボルでなければなりません。引数のどの二つの組み合わせを取ってもそれがeq?である時に限り、#tが返ります。

 -- Function: symbol->string symbol
     [R7RS base] Returns the name of SYMBOL in a string.  Returned string is immutable. SYMBOLの名前を文字列で返します。返される文字列は変更不可です。

          (symbol->string 'foo) => foo

 -- Function: string->symbol string
     [R7RS base] Returns a symbol whose name is a string STRING. STRING may contain weird characters. 文字列STRINGを名前に持つシンボルを返します。

          (string->symbol "a") => a
          (string->symbol "A") => A
          (string->symbol "weird symbol name") => |weird symbol name|

 -- Function: string->uninterned-symbol string
     Like string->symbol, but the created symbol is uninterned. string->symbolと似ていますが、作られたシンボルはインターンされません。

          (string->uninterned-symbol "a") => #:a

 -- Function: gensym :optional prefix
     Returns a fresh, uninterned symbol.  The returned symbol can never be eq? to other symbol within the process. If PREFIX is given, which must be a string, it is used as a prefix of the name of the generated symbol.  It is mainly for the convenience of debugging. インターンされてない、新しいシンボルを作って返します。返されるシンボルは、他のシンボルとは決してeq?にならないことが保証されます。 PREFIXが与えられた場合は、それは文字列でなければならず、それが作られるシンボルのプレフィクスに使われます。これは主としてデバッグを容易にするためのものです。

 -- Function: symbol-sans-prefix symbol prefix
     Both SYMBOL and PREFIX must be symbols. If the name of PREFIX matches the beginning part of the name of SYMBOL, this procedure returns a symbol whose name is the name of SYMBOL without the matched prefix. Otherwise, it returns #f. SYMBOLとPREFIXは共にシンボルでなければなりません。 PREFIXがSYMBOLの先頭部分にマッチした場合、 SYMBOLからマッチ部分を取り除いた名前を持つシンボルを返します。マッチしない場合は#fを返します。

          (symbol-sans-prefix 'foo:bar 'foo:) => bar
          (symbol-sans-prefix 'foo:bar 'baz:) => #f

 -- Function: symbol-append interned? objs ...
 -- Function: symbol-append objs ...
     Returns a symbol with the name which is a concatenation of string representation of OBJS.

     If the first argument is a boolean, it is recognized as the first form; the first argument specifies whether the resulting symbol is interned or not.

     Each other argument is converted to a string as follows: If it is a keyword, its name (with the preceding :) is used. For all other objects, x->string is used.  (The special treatment of keyword is to keep the consistency before and after keyword-symbol integration.  See Keyword and symbol integration, for the details.)

     This is upper-compatible to Bigloo's same name procedure, which only allows symbols as the arguments and the result is always interned. OBJSの文字列表記をつなげた名前を持つシンボルを返します。

     最初の引数が真偽値の場合は、最初の形式と解釈されます。INTERNED?引数は結果のシンボルがインターンされているかどうかを指定します。

     それ以外の引数はそれぞれ次のとおり変換されます：キーワードであれば (先頭の:を含む)名前に、それ以外はx->stringを適用した結果に。 (キーワードを特別扱いするのは、キーワード-シンボル統合の後でも動作が変わらないようにするためです。詳しくはKeyword and symbol integrationを参照。)

     これは、Biglooにある同名の手続きの上位互換になっています。Bigloo版はシンボルのみを引数に許し、また結果は常にインターンされます。

          (symbol-append 'ab 'cd) => abcd
          (symbol-append 'ab ':c 30) => ab:c30
          (symbol-append #f 'g 100) => #:g100

Keywords
========

 -- Builtin Class: <keyword>
     Keywords are a subtype of symbols that are automatically bound to itself. It is extensively used in named arguments (keyword arguments), and keyword-value list.

     See Making procedures for how Gauche supports keyword arguments, and let-keywords macro (Optional argument parsing) for parsing keyword-value list manually.

     Keywords used to be a disjoint type from symbols. Since it isn't conformant to R7RS, in which symbols can begin with :, we've introduced two modes since 0.9.5; keywords can be a disjoint type of its own, or it can be a subtype of symbols.

     The behavior can be switched by environment variables.  If the environment variable GAUCHE_KEYWORD_DISJOINT is defined when gosh starts up, keywords and symbols are disjoint.  Otherwise, if the environment variable GAUCHE_KEYWORD_IS_SYMBOL is defined, keywords are a subtype of symbols.

     The default behavior when neither environment variables are defined has been switched since 0.9.8.  GAUCHE_KEYWORD_DISJOINT was assumed in 0.9.7 and before, while GAUCHE_KEYWORD_IS_SYMBOL is assumed in 0.9.8 and after.

     Most typical code run in either mode, but there can be some code that behaves differently.  See Keyword and symbol integration, for effect of the change.

     In future we'll stop supporting GAUCHE_KEYWORD_DISJOINT, so we recommend you to ensure applications to run on the current default mode. キーワードは、自動的に自分自身に束縛されるシンボルのサブタイプです。名前つき引数(キーワード引数)や、キーワード-値のリストで広く使われています。

     Gaucheにおけるキーワード引数のサポートについてはMaking proceduresを、また独自にキーワード-値リストをパーズする方法については let-keywords マクロ(Optional argument parsing) も参照して下さい。

     キーワードはかつてはシンボルと独立した型でしたが、それは :で始まる識別子もシンボルとして読まれるR7RSとは非互換でした。そこで、0.9.5からGaucheは二つのモードを持つようになりました。キーワードとシンボルが別の型になるモードと、キーワードがシンボルのサブタイプになるモードです。

     これらのモードは環境変数によって切り替えられます。環境変数GAUCHE_KEYWORD_DISJOINTがgosh起動時に定義されていたら、キーワードとシンボルは別の型になります。そうでなく、環境変数GAUCHE_KEYWORD_IS_SYMBOLが定義されていたら、キーワードはシンボルのサブタイプになります。

     どちらの環境変数も定義されていない場合のデフォルトの動作は、0.9.8で変更になりました。 0.9.7以前はGAUCHE_KEYWORD_DISJOINTの動作がデフォルトですが、 0.9.8以降はGAUCHE_KEYWORD_IS_SYMBOLがデフォルトになっています。

     ほとんどの典型的なコードはどちらのモードでも動きますが、異なる振る舞いをするコードもあります。二つのモードの違いについてはKeyword and symbol integrationを参照してください。

     将来的に、GAUCHE_KEYWORD_DISJOINTのサポートは無くなる予定です。今のうちに、現在のデフォルトモードでアプリケーションが走ることを確認しておくことをお勧めします。

 -- Reader Syntax: :NAME
     Read to a keyword whose name is :NAME. 名前が :NAME であるキーワードとして読み込まれます。

 -- Function: keyword? obj
     Returns #t if OBJ is a keyword. OBJ がキーワードであれば、#t を返します。

 -- Function: make-keyword name
     Returns a keyword whose name is NAME prepended by :. The NAME argument can be a string or a symbol. NAMEの前に:を付加した名前を持つキーワードを返します。 NAMEには文字列かシンボルが許されます。

          (make-keyword "foo")  => :foo

          (make-keyword 'foo)   => :foo

 -- Function: keyword->string keyword
     Returns the name (without the initial :) of the keyword KEYWORD, in a string. キーワード KEYWORD の(先頭の:を除いた)名前を文字列で返します。

          (keyword->string :foo) => "foo"

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

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

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

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

     This procedure is taken from STk. キー-値のリストから値を取り出すのに便利な手続きです。キー-値のリスト KV-LIST は偶数個の要素を持たなければなりません。 1つ目、3つ目、5つ目、... の要素はキーとして扱われ、 2つ目、4つ目、6つ目、... の要素は、その前の要素をキーとした値となります。

     この手続きは、キーの集合から KEY を探して、それが見つかれば、対応する値を返します。 2つ以上のキーにマッチしたら、最左のものとなります。マッチするキーがない場合、FALLBACK が与えられていればそれを返し、さもなければエラーを通知します。

     KV-LIST が正しい偶数個の要素を持つリストでない場合は、エラーになります。

     キーワード-値リストの `キーワード' と、KEY 引数は、実際にはキーワードである必要はありません。いかなる Scheme オブジェクトであっても良いです。キーの比較は、eq? によって行われます。

     この手続きは、STk から導入されました。

          (get-keyword :y '(:x 1 :y 2 :z 3))
            => 2
          (get-keyword 'z '(x 1 y 2 z 3))
            => 3

          (get-keyword :t '(:x 1 :y 2 :z 3))
            => #<error>
          (get-keyword :t '(:x 1 :y 2 :z 3) #f)
            => #f

 -- Macro: get-keyword* key kv-list :optional fallback
     Like get-keyword, but FALLBACK is evaluated only if KV-LIST does not have KEY. get-keyword と同様ですが、KV-LIST が KEY を含まない場合にのみ FALLBACK が評価されることだけが違います。

 -- Function: delete-keyword key kv-list
 -- Function: delete-keyword! key kv-list
     Removes all the keys and values from KV-LIST for keys that are eq? to KEY. KV-LIST から KEY に eq? であるキーをもつキーと値を削除します。

     delete-keyword doesn't change KV-LIST, but the returned list may share the common tail of it. delete-keyword は KV-LIST を変更しません。しかし、返されたリストは共通の末尾部分を共有します。

     delete-keyword! doesn't allocate, and may destructively changes KV-LIST.  You still have to use the returned value, for the original list may not be changed if its first key matches KEY. delete-keyword! は新しくアロケートされることはありません。そして、破壊的に KV-LIST を変更する可能性があります。最初のキーがマッチした場合元のリストは変更されないこともありえますが、返り値のリストを使わなければいけません。

     If there's no key that matches KEY, KV-LIST is returned. KEY にマッチするキーがない場合 KV-LIST が返ります。

          (delete-keyword :y '(:x 1 :y 2 :z 3 :y 4))
           => (:x 1 :z 3)

 -- Function: delete-keywords keys kv-list
 -- Function: delete-keywords! keys kv-list
     Similar to delete-keyword and delete-keyword!, but you can specify a list of objects in KEYS; when a key in KV-LIST matches any of KEYS, the key and the following value is removed from KV-LIST. delete-keywordやdelete-keyword!と似ていますが、 KEYSにオブジェクトのリストを指定できます。 KV-LIST中のキーがKEYSのうちのどれかに一致すれば、そのキーと続く値がKV-LISTから取り除かれます。

          (delete-keywords '(:x :y) '(:x 1 :y 2 :z 3 :y 4))
           => (:z 3)

Keyword and symbol integration
------------------------------

In older versions of Gauche, keywords are of disjoint type from symbols, and they are self-evaluating objects. To maintain the compatibility, the current Gauche makes symbols that begins with : automatically bound to itself.

On the surface it won't make much difference; you can write a keyword :key, which evaluates to itself; so you can pass and receive keyword arguments just as they used to be. If you use :key as variables, however, e.g. (define :key 3), the value of :key in your module changes (it won't affect other modules, which refer to the binding of :key in gauche.keyword module).

However, there are several subtle points that do make difference, that breaks compatibility of legacy code. We explain here how to change the code that works in both ways.

If you find a problem in new mode and want to get the old behavior until you change the code, you can set the environment variable GAUCHE_KEYWORD_DISJOINT. 以前のGaucheでは、キーワードはシンボルとは異なる型を持ち、自分自身に評価されるオブジェクトでした。互換性を保つため、現在のGaucheでは:で始まるシンボルは自動的に自分自身に束縛されるようになっています。

表面的にはこの変更はたいした違いをもたらさないでしょう。プログラム中に表記してあるキーワードはそれ自身に評価されるので、かつてと同じようにキーワード引数を渡すことができます。キーワードを変数として使い、例えば(define :key 3)のように新たな値に束縛することはできるますが、その変更はそうしているモジュールの中だけに留まります。 (他のモジュールはgauche.keywordモジュールにある:keyの束縛を参照するので影響を受けません。)

けれども、違いが現れるいくつかのわかりづらい場合が存在し、注意していないと古いコードの互換性を壊してしまうかもしれません。どちらのモードでも動くようにするコードの書き方をこれから説明します。

新しいモードで問題が出て、コードを直すまで以前の動作で使いたければ、環境変数GAUCHE_KEYWORD_DISJOINTをセットしてください。

(symbol? :key) used to return #f, now returns #t
................................................

(symbol? :key)は以前は#fを返したが、今は#tを返す
.................................

keyword? always returns #t on keywords, but if you need to switch behavior depending whether an object is a symbol or a keyword, you should test keyword-ness first. キーワードに対してkeyword?は常に#tを返しますが、シンボルかキーワードかで動作を変えるコードでは、キーワードの検査を先にするようにしてください。

     ;; behaved differently in 0.9.7 and before
     ;; 0.9.7以前は動作が異なる
     (cond
       [(symbol? x) (x-is-symbol)]
       [(keyword? x) (x-is-keyword)])

     ;; works on all versions
     ;; どのバージョンでも動く
     (cond
       [(keyword? x) (x-is-keyword)]
       [(symbol? x) (x-is-symbol)])

Literal keywords in pattern matching
....................................

パターンマッチ中のリテラルキーワード
..................

In the old versions, when keywords appear in a pattern of util.match or syntax-rules, they only matched to themselves. In the current version, such keywords in a pattern are treated as pattern variables, since they are symbols. 以前のバージョンでは、util.matchやsyntax-rulesのパターンにキーワードが現れた場合、それはキーワード自身とのみマッチしました。現在のバージョンでは、キーワードはシンボルなので、パターン変数として扱われます。

     ;; In the old versions
     ;; 以前のバージョン
     (match '(a b) [(:key z) (list :key z)] [_ "nope"])
        => "nope"

     ;; In the current version
     ;; :key is treated just as a pattern variable
     ;; 現在のバージョン
     ;; :keyは単なるパターン変数となる
     (match '(a b) [(:key z) (list :key z)] [_ "nope"])
        => (a b)

The same thing happens to the patterns in syntax-rules.

To make the code work in both versions, explicitly mark the keywords as literals. syntax-rulesでも同じことが起きます。

どのバージョンでも動くコードにするには、マッチさせたいキーワードがリテラルであることを明示してください。

  * For match, quote the keywords you want to be treated as literals. matchでは、キーワードをクオートしてリテラルであることを示します。

          (match '(a b) [(':key z) (list :key z)] [_ "nope"])
             => "nope"

  * For syntax-rules, list the keywords as literals. syntax-rulesでは、キーワードをリテラルリストに含めてください。

          (syntax-rules (:key)
            [(_ :key z) (list :key z)])  ;etc.

As of Gauche 0.9.5, match warns if you have unquoted keywords in match patterns. Gauche 0.9.5から、matchはパターンにクオートされていないキーワードが現れると警告を発します。

Displaying keywords
...................

キーワードの表示
........

(display :key) used to print key (no colon), while it now prints :key.

You can use (display (keyword->string :key)) which prints key in both versions. (display :key)は以前はkey(コロン無し)を表示しましたが、現在は:keyを表示します。

keyを表示したい場合は(display (keyword->string :key))とすれば、どのバージョンでも同じように動作します。

For R7RS code, quote them or import Gauche modules
..................................................

R7RSコードではクオートするかGaucheのモジュールをインポートする
....................................

Keywords (symbols beginning with :) are automatically bound to itself in the gauche.keyword module.

Gauche code inherits the gauche module by default, which inherits keyword, so you can see the binding of the keyword by default.

In R7RS code, however, you don't inherit gauche, so symbols beginning with : are just ordinary symbols by default. Usually you do (import (gauche base)) to use Gauche built-ins, and that makes binding of gauche.keyword available in your code, too (since gauche.base inherits gauche.keyword). But keep this in mind just in case you want to handle keywords in your R7RS code separate from Gauche procedures---you have to either say (import (gauche keyword)) to get just the self-bound keywords, or quote them. キーワード(:で始まるシンボル)はgauche.keywordモジュールの中で自分自身に束縛されます。

Gaucheコードはデフォルトでgaucheモジュールを継承し、それがkeywordモジュールを継承しているので、キーワードの束縛は自動的に見えるようになります。

しかしR7RSコードではgaucheモジュールは継承されないので、 :で始まるシンボルもデフォルトではただのシンボルです。通常、Gaucheの組み込み機能を使うには(import (gauche base))としますが、こうするとキーワードの自分自身への束縛もインポートされるようになっています (gauche.baseがgauche.keywordも継承しているからです)。ただ、Gaucheの手続きとは別にキーワードをR7RSコード中で使いたい場合は注意してください。自己束縛されているキーワードだけが欲しければ (import (gauche keyword))とする必要がありますし、そうしない場合はキーワードに見えるシンボルでもクオートする必要があります。

     (import (scheme base))

     :foo => ERROR: unbound variable: :foo

     (import (gauche base))

     :foo => :foo

In the following example, the R7RS library foo imports only copy-port from (gauche base); in that case, you have to import (gauche keyword) separately in order to use :size keyword without quoting. (Or add :size explicitly in the imported symbol list of (gauche base).) 次の例では、R7RSライブラリfooが(gauche base)から copy-portのみをインポートしています。こういった場合、 :sizeキーワードをクオートなしで使うには、(gauche keyword)も別にインポートしなければなりません。 (あるいは、(gauche base)からインポートするシンボルのリストに :sizeも明示するか)。

     (define-library (foo)
       (import (scheme base)
               (only (gauche base) copy-port)
               (gauche keyword))
       (export cat)

       (begin
         (define (cat)
           (copy-port (current-input-port)
                      (current-output-port)
                      :size 4096))))

Characters
==========

 -- Builtin Class: <char>

 -- Reader Syntax: #\charname
     [R7RS+] Denotes a literal character.

     When the reader reads #\, it fetches a subsequent character. If it is one of ()[]{}" \|;#, this is a character literal of itself. Otherwise, the reader reads subsequent characters until it sees a non word-constituent character.  If only one character is read, it is the character.  Otherwise, the reader matches the read characters with predefined character names.  If it doesn't match any, an error is signaled.

     The following character names are recognized. These character names are case insensitive.

     space
          Whitespace (ASCII #x20)

     newline, nl, lf
          Newline (ASCII #x0a)

     return, cr
          Carriage return (ASCII #x0d)

     tab, ht
          Horizontal tab (ASCII #x09)

     page
          Form feed (ASCII #x0c)

     alarm
          Bell (ASCII #x07)

     backspace
          Backspace (ASCII #x08)

     escape, esc
          Escape (ASCII #x1b)

     delete, del
          Delete (ASCII #x7f)

     null
          NUL character (ASCII #x00)

     xN
          A character whose Unicode codepoint is the integer N, when N is a hexadecimal integer. This is R7RS lexical syntax. (See the compatibility note below).

     uN
          A character whose Unicode codepoint is the integer N, where N is 4-digit or 8-digit hexadecimal number.

          This is legacy Gauche lexical syntax.  Use \xN syntax for the new code. (See the compatibility note below).

     リテラルの文字オブジェクトを表現します。

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

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

     space
          スペース (ASCII #x20)

     newline, nl, lf
          改行文字 (ASCII #x0a)

     return, cr
          復帰文字 (ASCII #x0d)

     tab, ht
          水平タブ (ASCII #x09)

     page
          フォームフィード、改ページ (ASCII #x0c)

     alarm
          ベル (ASCII #x07)

     backspace
          バックスペース (ASCII #x08)

     escape, esc
          エスケープ (ASCII #x1b)

     delete, del
          デリート (ASCII #x7f)

     null
          NUL文字 (ASCII #x00)

     xN
          N が16進表記の整数であるとき、Unicodeコードポイントが整数N であるような文字。これはR7RSの字句構文です。(下の互換性に関する注も見てください。)

     uN
          Nが4桁または8桁の16進数整数であるとき、UCSコードNであるような文字。これはGaucheの古い構文です。新規のコードでは\xNを使ってください。 (下の互換性に関する注も見てください。)

          #\newline => #\newline ; newline character
          #\x0a     => #\newline ; ditto
          #\x41     => #\A       ; ASCII letter 'A'
          #\x3042   => ; Hiragana letter A
          #\x2a6b2  => ; JISX0213 Kanji 2-94-86
          #\newline => #\newline ; 改行文字
          #\x0a     => #\newline ; 改行文字
          #\x41     => #\A       ; ASCII文字 'A'
          #\x3042   => #\あ      ; 平仮名「あ」
          #\x2a6b2  => ; JISX0213 2-94-86

Compatibility note: Before 0.9.4, \xNN syntax uses Gauche's internal character encoding as opposed to Unicode codepoint.  Both are the same if Gauche is compiled with internal encoding utf-8 or none (if it's none, only characters up to U+00ff is supported and in this range the characters are the same as Unicode characters.)   If Gauche is compiled with encoding euc-jp or sjis, the meaning of \xNN beyond ASCII range differs from 0.9.3.3 or before.

If you set the reader mode to legacy (see Reader lexical mode), #\xNN is read as before, keeping the compatibility (but it isn't compatible to R7RS).  Alternatively, you can use #\uNNNN, or a character itself, to make the code work in both new and old versions of Gauche. 互換性に関する注: 0.9.4まで、Gaucheは\xNN構文を、 Unicodeコードポイントでなく内部文字エンコーディングで文字を表記するのに使っていました。Gaucheの内部エンコーディングをutf-8もしくは noneでコンパイルされている場合は両者に違いはありません (noneの場合、U+00ffまでの文字しか扱うことができませんが、扱える範囲内ではUnicodeと一致します)。内部エンコーディングがeuc-jpかsjisの場合、 \xNNで記されたASCIIの範囲外の文字の解釈は、 0.9.3.3およびそれ以前のGaucheとは異なることになります。

リーダのモードをlegacyにセットすれば(Reader lexical mode参照)、 #\xNNは以前と同じ解釈となり、互換性は保たれます (ただし、R7RSとは非互換になります)。あるいは#\uNNNN表記や文字そのものを表記することで、以前のGaucheでも新しいGaucheでも動作するようにできます。

 -- Function: char? obj
     [R7RS base] Returns #t if OBJ is a character, #f otherwise. OBJが文字なら#tを、そうでなければ#fを返します。

 -- Function: char=? char1 char2 char3 ...
 -- Function: char<? char1 char2 char3 ...
 -- Function: char<=? char1 char2 char3 ...
 -- Function: char>? char1 char2 char3 ...
 -- Function: char>=? char1 char2 char3 ...
     [R7RS base] Compares characters.  Character comparison is done in internal character encoding. 文字を比較します。比較は内部の文字エンコーディングで行われます。

 -- Function: char-ci=? char1 char2 char3 ...
 -- Function: char-ci<? char1 char2 char3 ...
 -- Function: char-ci<=? char1 char2 char3 ...
 -- Function: char-ci>? char1 char2 char3 ...
 -- Function: char-ci>=? char1 char2 char3 ...
     [R7RS char] Compares characters in case-insensitive way. The comparison is done in the internal character code of the foldcase of the each character; see char-foldcase below.

     In R7RS, these procedures are in the (scheme char) library. 文字を、大文字小文字を区別せずに比較します。比較はそれぞれの文字のfoldcaseの内部文字エンコーディングに基づいて行われます。 foldcaseについては下のchar-foldcaseを参照してください。

     R7RSではこれらの手続きは(scheme char)ライブラリにあります。

 -- Function: char-alphabetic? char
 -- Function: char-numeric? char
 -- Function: char-whitespace? char
 -- Function: char-upper-case? char
 -- Function: char-lower-case? char
     [R7RS char] Returns true if a character CHAR is an alphabetic character (Unicode character category Lu, Ll, Lt, Lm, Lo, Nl), a numeric character (Unicode character category Nd), a whitespace character, (Unicode character category Zs, Zp, Zl), an upper case character (Unicode character category Lu), or a lower case character (Unicode character category Ll), respectively.

     In R7RS, these procedures are in the (scheme char) library. 文字CHARがそれぞれアルファベット (Unicode文字カテゴリ Lu、Ll、Lt、 Lm、Lo、Nl)、数字 (Unicode文字カテゴリ Nd)、空白文字 (Unicode文字カテゴリ Zs、Zp、Zl)、大文字 (Unicode文字カテゴリ Lu)、小文字 (Unicode文字カテゴリ Ll)の時に真の値を返します。

     R7RSではこれらの手続きは(scheme char)ライブラリにあります。

 -- Function: char-general-category char
     [R6RS] Returns one of the following symbols, representing the Unicode general category of CHAR. 文字CHARのUnicode general categoryを表す、以下のシンボルのいずれかを返します。

     Cc   Other, Control
     Cf   Other, Format
     Cn   Other, Not Assigned
     Co   Other, Private Use
     Cs   Other, Surrogate
     Ll   Letter, Lowercase
     Lm   Letter, Modifier
     Lo   Letter, Other
     Lt   Letter, Titlecase
     Lu   Letter, Uppercase
     Mc   Mark, Spacing Combining
     Me   Mark, Enclosing
     Mn   Mark, Nonspacing
     Nd   Number, Decimal Digit
     Nl   Number, Letter
     No   Number, Other
     Pc   Punctuation, Connector
     Pd   Punctuation, Dash
     Pe   Punctuation, Close
     Pf   Punctuation, Final quote
     Pi   Punctuation, Initial quote
     Po   Punctuation, Other
     Ps   Punctuation, Open
     Sc   Symbol, Currency
     Sk   Symbol, Modifier
     Sm   Symbol, Math
     So   Symbol, Other
     Zl   Separator, Line
     Zp   Separator, Paragraph
     Zs   Separator, Space

     If Gauche is compiled with euc-jp or shift_jis encoding, there are characters that don't have corresponding Unicode codepoint (each of them are represented by one unicode character plus one unicode modifier character).  A provisional category is assigned to those characters.  If future versions of Unicode incorporates these characters, the category may be reassigned. Gaucheがeuc-jpかshift_jisエンコーディングでコンパイルされている場合、 Unicodeに対応するものがない文字がいくつかあります (各文字は、Unicode一文字＋Unicode結合文字で表現できます)。これらの文字については、以下のとおり暫定的にカテゴリを割り当てています。将来のUnicodeにこれらの文字が取り込まれた場合は、Unicodeで決められるカテゴリに変更されるでしょう。

     SJIS   EUC   Cat    Unicode
     82F5   A4F7   Lo   U+304B U+309A (Semi-voiced Hiragana KA)
     82F6   A4F8   Lo   U+304D U+309A (Semi-voiced Hiragana KI)
     82F7   A4F9   Lo   U+304F U+309A (Semi-voiced Hiragana KU)
     82F8   A4FA   Lo   U+3051 U+309A (Semi-voiced Hiragana KE)
     82F9   A4FB   Lo   U+3053 U+309A (Semi-voiced Hiragana KO)
     8397   A5F7   Lo   U+30AB U+309A (Semi-voiced Katakana KA)
     8398   A5F8   Lo   U+30AD U+309A (Semi-voiced Katakana KI)
     8399   A5F9   Lo   U+30AF U+309A (Semi-voiced Katakana KU)
     839A   A5FA   Lo   U+30B1 U+309A (Semi-voiced Katakana KE)
     839B   A5FB   Lo   U+30B3 U+309A (Semi-voiced Katakana KO)
     839C   A5FC   Lo   U+30BB U+309A (Semi-voiced Katakana SE)
     839D   A5FD   Lo   U+30C4 U+309A (Semi-voiced Katakana TSU)
     839E   A5FE   Lo   U+30C8 U+309A (Semi-voiced Katakana TO)
     83F6   A6F8   Lo   U+31F7 U+309A (Semi-voiced small Katakana FU)
     8663   ABC4   Ll   U+00E6 U+0300 (Accented latin small ae)
     8667   ABC8   Ll   U+0254 U+0300 (Accented latin small open o)
     8668   ABC9   Ll   U+0254 U+0301 (Accented latin small open o)
     8669   ABCA   Ll   U+028C U+0300 (Accented latin small turned v)
     866A   ABCB   Ll   U+028C U+0301 (Accented latin small turned v)
     866B   ABCC   Ll   U+0259 U+0300 (Accented latin small schwa)
     866C   ABCD   Ll   U+0259 U+0301 (Accented latin small schwa)
     866D   ABCE   Ll   U+025A U+0300 (Accented latin small schwa w/hook)
     866E   ABCF   Ll   U+025A U+0301 (Accented latin small schwa w/hook)
     8685   ABE5   Sk   U+02E9 U+02E5
     8686   ABE6   Sk   U+02E5 U+02E9

 -- Function: char->integer char
 -- Function: integer->char n
     [R7RS base] char->integer returns an exact integer that represents internal encoding of the character CHAR. integer->char returns a character whose internal encoding is an exact integer N.  The following expression is always true for valid character CHAR:

          (eq? char (integer->char (char->integer char)))

     Note: R7RS defines these procedures to deal with Unicode codepoints.  Gauche complies it when compiled with utf-8 or none internal encoding (for the latter, only characters up to U+00ff are supported).  If Gauche is compiled with euc-jp or sjis internal encoding, you need to use char->ucs/ucs->char below to convert between Unicode codepoints and characters.

     The result is undefined if you pass N to integer->char that doesn't have a corresponding character. char->integerは文字CHARの内部エンコーディングに対応する整数値を返します。integer->charは数値Nと内部エンコーディングが同じ文字を返します。有効な文字CHARに対して以下の式は常に真となります。

          (eq? char (integer->char (char->integer char)))

     註: R7RSでは、これらの手続きはUnicodeコードポイントを扱うとされています。 Gaucheの内部エンコーディングがutf-8かnoneであればそれに合致します (noneの場合はU+00ffまでの文字がサポートされます)。内部エンコーディングがeuc-jpかsjisの場合は、 Unicodeコードポイントと文字の変換には下のchar->ucs/ucs->charを使ってください。

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

 -- Function: char->ucs char
 -- Function: ucs->char n
     Converts a character CHAR to integer UCS codepoint, and integer UCS codepoint N to a character, respectively.

     If Gauche is compiled with UTF-8 encoding, these procedures are the same as char->integer and integer->char.

     When Gauche's internal encoding differs from UTF-8, these procedures implicitly loads gauche.charconv module to convert internal character code to UCS or vice versa (see Character code conversion). If CHAR doesn't have corresponding UCS codepoint, char->ucs returns #f.  If UCS codepoint N can't be represented in the internal character encoding, ucs->char returns #f, unless the conversion routine provides a substitution character. それぞれ、文字CHARをUCSコードポイントを表す整数へ変換し、またUCSコードポイントを表す整数Nを文字へと変換する手続きです。

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

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

 -- Function: char-upcase char
 -- Function: char-downcase char
 -- Function: char-titlecase char
 -- Function: char-foldcase char
     [R7RS char] Returns the upper case, lower case, title case and folded case of CHAR, respectively.

     The mapping is done according to Unicode-defined character-by-character case mapping whenever possible.  If the native encoding doesn't support the mapped character defined in Unicode, the operation becomes no-op. If the native encoding is 'none', we treat the characters as if they are Latin-1 (ISO-8859-1) characters.  So, upcasing Latin-1 character small y with diaresis (U+00ff) maps to capital y with diaeresis (U+0178) if the internal encoding is utf-8, but it is no-op if the internal encoding is none.

     R7RS doesn't have char-titlecase; other three procedures are defined in the (scheme char) library.  R6RS defines all of them. CHARの大文字、小文字、titlecase、foldcaseをそれぞれ返します。

     変換は原則としてUnicodeで定義された文字対文字のマッピングに従います。 Unicodeに従って変換する先の文字が内部エンコーディングでサポートされていない場合は、変換は行いません。内部エンコーディングが'none'の場合は、文字をLatin-1 (ISO-8859-1) であるとみなします。Latin-1の small y with diaresis (U+00ff) をupcaseすると、内部エンコーディングがutf-8の場合はcapital y with diaeresis (U+0178)にマップされますが、内部エンコーディングがnoneであれば元の文字がそのまま返されます。

     R7RSはchar-titlecaseを定義していません。それ以外の3つの手続きは (scheme char)ライブラリにあります。R6RSは全ての手続きを提供しています。

     The character-by-character case mapping doesn't consider a character that may map to more than one characters; a notable example is eszett (latin small letter sharp S, U+00df), which is is mapped to two capital S's in string context, but char-upcase #\ß returns #\ß.  To get a full mapping, use string-upcase etc. in gauche.unicode module (see Full string case conversion). 文字対文字のマッピングでは、一文字が複数文字に展開されるようなケースマッピングは扱いません。有名な例はeszett (latin small letter sharp S, U+00df)で、文字列のコンテキストでは二つの大文字のSへとマップされますが、 char-upcase #\ß は単に #\ß を返します。完全なマッピングが必要なら、gauche.unicodeモジュールの string-upcase等が利用できます (Full string case conversion参照)。

 -- Function: digit->integer char :optional (radix 10) (extended-range? #f)
     If given character CHAR is a valid digit character in radix RADIX number, the corresponding integer is returned.  Otherwise #f is returned. 文字CHARが RADIX進数の数字を構成するのに有効な文字であれば、対応する整数が、そうでなければ#fが返されます。

          (digit->integer #\4) => 4
          (digit->integer #\e 16) => 14
          (digit->integer #\9 8) => #f

     If the optional EXTENDED-RANGE? argument is true, this procedure recognizes not only ASCII digits, but also all characters with Nd general category---such as FULLWIDTH DIGIT ZERO to NINE (U+ff10 - U+ff19). 省略可能引数EXTENDED-RANGE?に真の値が与えられると、この手続きはASCIIの数字だけでなく、Ndカテゴリに属するすべての文字、例えば FULLWIDTH DIGIT ZEROからNINE (U+ff10 - U+ff19) も認識します。

     R7RS has digit-value, which is equivalent to (digit->integer char 10 #t). R7RSにはdigit-valueという手続きが定義されていて、それは (digit->integer char 10 #t)と等価です。

     Note: CommonLisp has a similar function in rather confusing name, digit-char-p. Common Lispには同様の手続きがdigit-char-pというやや曖昧な名で定義されています。

 -- Function: integer->digit integer :optional (radix 10) (basechar1 #\0) (basechar2 #\a)
     Reverse operation of digit->integer.  Returns a character that represents the number INTEGER in the radix RADIX system. If INTEGER is out of the valid range, #f is returned. digit->integerの逆です。整数INTEGERを RADIX進数 ひと桁で表現するのに使われる文字を返します。INTEGERがひと桁で表現できない数値の場合は #fが返されます。

          (integer->digit 13 16) => #\d
          (integer->digit 10) => #f

     The optional BASECHAR1 argument specifies the character that stands for zero; by default, it's #\0.  You can give alternative character, for example, U+0660 (ARABIC-INDIC DIGIT ZERO) to convert an integer to a arabic-indic digit character. 省略可能引数BASECHAR1はゼロに相当する文字を指定します。デフォルトは#\0です。ここに、例えばU+0660 (ARABIC-INDIC DIGIT ZERO) を与えれば、整数をアラビア・インド数字に変換できます。

     Another optional BASECHAR2 argument is used for integers over 10. The default value is #\a.  You can pass #\A to get upper-case hex digits, for example. もうひとつの省略可能引数BASECHAR2は、10を越える整数に使う文字の起点を指定します。デフォルトは#\aです。ここに#\Aを渡せば、 16進数表記で小文字のかわりに大文字を使うようになります。

     Note: CommonLisp's digit-char. Common Lispのdigit-charに当たります。

 -- Function: gauche-character-encoding
     Returns a symbol designates the native character encoding, selected at the compile time. The possible return values are those: コンパイル時に選択された内部文字エンコーディングを表すシンボルを返します。返される値は以下のいずれかです。

     euc-jp
          EUC-JP

     utf-8
          UTF-8

     sjis
          Shift JIS

     none
          No multibyte character support (8-bit fixed-length character). マルチバイトキャラクタをサポートしない(8ビット固定長文字)。

     To switch code at compile time according to the internal encoding, you can use feature identifiers gauche.ces.*--see Platform-dependent features. コンパイル時に内部エンコーディングによってコードを切り替えたい場合は、機能識別子gauche.ces.*が使えます。 Platform-dependent featuresを見てください。

 -- Function: supported-character-encodings
     Returns a list of string names of character encoding schemes that are supported in the native multibyte encoding scheme. ネイティブなマルチバイトエンコーディングスキームでサポートされている文字エンコーディングスキームの名前を表す文字列のリストを返します。

Character Sets
==============

 -- Builtin Class: <char-set>
     Character set class.  Character set object represents a set of characters. Gauche provides built-in support of character set creation and a predicate that tests whether a character is in the set or not.

     The class implements the collection protocol (see Collection framework), so that the standard collection methods provided in the gauche.collection module can be used.

     An instance of <char-set> is applicable to a character, and works as a membership predicate; see char-set-contains? below.

     Further operations, such as set algebra, is defined in SRFI-14 module (see R7RS character sets). 文字の集合を取り扱う、文字集合(キャラクタセット)のクラスです。 Gaucheは文字集合オブジェクトのサポートと、ある文字がその集合に属するかどうかを調べる手続きを言語組み込みで持っています。

     コレクションプロトコル (Collection framework参照) を実装しているので、 gauche.collectionで提供される標準のコレクションメソッドが使えます。

     <char-set>のインスタンスは文字に関数のように適用することができ、その文字が文字集合に属するかどうかを判定する述語として機能します。下記のchar-set-contains?を参照してください。

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

Character set literals
----------------------

 -- Reader Syntax: #[char-set-spec]
     You can write a literal character set in this syntax. char-set-spec is a sequence of characters to be included in the set.  You can include the following special sequences:

     X-Y
          Characters between X and Y, inclusive. X must be smaller than Y in the internal encoding.

     ^
          If char-set-spec begins with caret, the actual character set is a complement of what the rest of char-set-spec indicates.

     \xN;
          A character whose Unicode codepoint is a hexadecimal number N.

     \uXXXX
     \UXXXXXXXX
          This is a legacy Gauche syntax, for a unicode character whose Unicode codepoint is represented by 4-digit and 8-digit hexadecimal numbers, respectively.

     \s
          Whitespace characters (space, newline, tab, form feed, vertical tab, carriage return). Members of char-set:ascii-whitespace.

     \S
          Complement of whitespace characters.

     \d
          Decimal digit characters.  Members of char-set:ascii-digits.

     \D
          Complement of decimal digit characters.

     \w
          Word constituent characters (#[A-Za-z0-9_]). Members of char-set:ascii-word.

     \W
          Complement of word constituent characters.

     \\
          A backslash character.

     \-
          A minus character.

     \^
          A caret character.

     [:alnum:] ...
          Character set a la POSIX.  See the table below for the complete list of recognized character set names.  The set name must be in all lower cases. This notation only includes characters in ASCII range.

     [:^alnum:] ...
          Complement set of [:alnum:] etc.

     [:ALNUM:] ...
          Gauche's extension of character set a la POSIX; the name must be all in upper cases, and includes full Unicode range.  See the table below for the recognized names.

     [:^ALNUM:] ...
          Complement set of [:ALNUM:] etc.

     Here's the list of POSIX-style character class names:

     :alpha:   ASCII alphabets.  char-set:ascii-letter, #[A-Za-z]
     :alnum:   ASCII alphabets and digits.  char-set:ascii-letter+digits, #[0-9A-Za-z].
     :blank:   ASCII blanks.  char-set:ascii-blank, tab and space.
     :cntrl:   ASCII control characters.  char-set:ascii-control, U+0000 to U+001f and U+007f.
     :digit:   ASCII digits.  char-set:ascii-digit, #[0-9].
     :graph:   ASCII graphic characters.  char-set:ascii-graphic.
     :lower:   ASCII lower-case alphabets.  char-set:ascii-lower-case, #[a-z].
     :print:   ASCII printing characters.  char-set:ascii-printing.
     :punct:   ASCII punctuation characters.  char-set:ascii-punctuation.
     :space:   ASCII whitespaces. char-set:ascii-whitespace.
     :upper:   ASCII upper-case characters.  char-set:ascii-upper-case, #[A-Z].
     :word:   ASCII word characters (not POSIX).  char-set:ascii-word, #[0-9A-Za-z_].
     :xdigit:   Hexadecimal digits.  char-set:hex-digit, #[0-9a-fA-F].
     :ascii:   ASCII characters (not POSIX).  char-set:ascii.
     :ALPHA:   Unicode letters (category L*). char-set:letter.
     :ALNUM:   Unicode letters and digits.  char-set:letter+digits.
     :BLANK:   Unicode blanks (tab and category Zs).  char-set:blank.
     :CNTRL:   Unicode control characters (category Cc).  char-set:iso-control.
     :DIGIT:   Unicode digits (category Nd).  char-set:digit.
     :GRAPH:   Unicode graphic characters (letter, digits, punctuation, symbol, and category Nl and No).  char-set:graphic.
     :LOWER:   Unicode lower-case letters (category Ll).  char-set:lower-case, #[a-z].
     :PRINT:   Unicode printing characters (graphic and whitespace).  char-set:printing.
     :PUNCT:   Unicode punctuation characters (category P*).  char-set:punctuation.
     :SPACE:   Unicode whitespaces (tab, LF, vertical tab, FF, CR, and category Z*). char-set:whitespace.
     :TITLE:   Unicode titlecase letters (category Lt).  char-set:title-case.
     :UPPER:   Unicode upper-case letters (category Lu).  char-set:upper-case, #[A-Z].
     :WORD:   Unicode word characters.  char-set:word.
     :XDIGIT:   Hexadecimal digits (same as :xdigit:).

     Here are some examples:

          #[aeiou]       ; a character set consists of vowels
          #[a-zA-Z]      ; alphabet
          #[[:alpha:]]   ; alphabet (using POSIX notation)
          #[\\\-]        ; backslash and minus
          #[]            ; empty charset
          #[\x0d;\x0a;\x3000;] ; carriage return, newline, and ideographic space

     この構文で、リテラル文字集合を記述することができます。 char-set-specには集合に含める文字を列挙します。次の特殊なシーケンスを含めることができます。

     X-Y
          文字Xと文字yの間の文字全て。XとYも含みます。 XはYよりも内部文字コードで比較して小さくなければなりません。

     ^
          カレットがchar-set-specの最初に来た場合、以降に示される文字集合の補集合がこの文字集合となります。

     \xN;
          UnicodeコードポイントがN(16進数表記)の文字。

     \s
          空白文字(space, newline, tab, form feed, vertical tab, carriage return). 文字集合char-set:ascii-whitespaceの要素。

     \S
          空白でない文字。(\sの補集合)

     \d
          10進数の数字。文字集合char-set:ascii-digitの要素。

     \D
          \dの補集合

     \w
          単語を構成する文字の集合(#[A-Za-z0-9_])。文字集合char-set:ascii-wordの要素。

     \W
          \Wの補集合

     \\
          バックスラッシュ文字

     \-
          マイナス文字

     \^
          カレット文字

     [:alnum:] ...
          POSIX風文字集合表記。サポートされる名前については下の表を参照してください。名前は全て小文字でなければなりません。この表記の文字集合はASCII範囲のみを含みます。

     [:^alnum:] ...
          [:alnum:]等の補集合です。

     [:ALNUM:] ...
          POSIX風文字集合表記のGauche拡張。名前は全て大文字でなければなりません。この表記の文字集合はUnicode全範囲を対象とします。サポートされる名前については下の表を参照してください。

     [:^ALNUM:] ...
          [:ALNUM:]等の補集合です。

     POSIX風文字集合表記で認識される名前は次のとおりです。

     :alpha:   ASCIIアルファベット。char-set:ascii-letter, #[A-Za-z]
     :alnum:   ASCIIアルファベットと数字。char-set:ascii-letter+digits, #[0-9A-Za-z].
     :blank:   ASCIIブランク文字。char-set:ascii-blank, tab and space.
     :cntrl:   ASCII制御文字。char-set:ascii-control, U+0000 to U+001f and U+007f.
     :digit:   ASCII数字。char-set:ascii-digit, #[0-9].
     :graph:   ASCIIグラフィック文字。char-set:ascii-graphic.
     :lower:   ASCII小文字アルファベット。char-set:ascii-lower-case, #[a-z].
     :print:   ASCII印字可能文字。char-set:ascii-printing.
     :punct:   ASCII句読点。char-set:ascii-punctuation.
     :space:   ASCII空白文字。char-set:ascii-whitespace.
     :upper:   ASCII大文字アルファベット。char-set:ascii-upper-case, #[A-Z].
     :word:   ASCII単語構成文字(POSIXではありません)。 char-set:ascii-word, #[0-9A-Za-z_].
     :xdigit:   16進数の数字。char-set:hex-digit, #[0-9a-fA-F].
     :ascii:   ASCII文字 (POSIXではありません).  char-set:ascii.
     :ALPHA:   Unicode通常文字。char-set:letter.
     :ALNUM:   Unicode通常文字と数字。char-set:letter+digits.
     :BLANK:   Unicodeブランク文字。char-set:blank.
     :CNTRL:   Unicode制御文字。char-set:iso-control.
     :DIGIT:   Unicode数字。char-set:digit.
     :GRAPH:   Unicodeグラフィック文字。char-set:graphic.
     :LOWER:   Unicode小文字。char-set:lower-case, #[a-z].
     :PRINT:   Unicode印字可能文字。char-set:printing.
     :PUNCT:   Unicode句読点。char-set:punctuation.
     :SPACE:   Unicode空白文字。char-set:whitespace.
     :UPPER:   Unicode大文字。char-set:upper-case, #[A-Z].
     :WORD:   Unicode単語構成文字。char-set:word.
     :XDIGIT:   16進数の数字。(:xdigit:と同じ).

     いくつか例を示します。

          #[aeiou]     ; 母音文字'a', 'e', 'i', 'o', 'u'の集合
          #[a-zA-Z]    ; アルファベット
          #[[:alpha:]] ; アルファベット (POSIX表記)
          #[\\\-]      ; バックスラッシュとマイナス文字
          #[]          ; 空の文字集合
          #[ぁ-ん]     ; 平仮名の集合
          #[\x0d;\x0a;\x3000;]  ; リターン, 改行, 全角空白

     Literal character sets are immutable, as other literal data.  An error is signalled when you attempt to modify an immutable character set. リテラル文字集合は他のリテラルデータ同様、変更不可です。変更しようとした場合はエラーが通知されます。

     Note for the compatibility: We used to recognize a syntax \xNN (two-digit hexadecimal number, without semicolon terminator) as a character; for example, #[\x0d\x0a] as a return and a newline.  We still support it when we don't see the terminating semicolon, for the compatibility. There are ambiguous cases: #[\x0a;] means only a newline in the current syntax, but a newline and a semicolon in legacy syntax.

     Setting the reader mode to legacy restores the old behavior. Setting the reader mode to warn-legacy makes it work like the default behavior, but prints warning when it finds legacy syntax. See Reader lexical mode, for the details.

     To write code that can work both in new and old syntax, use \u escape. 互換性への注: 以前は、\xNN (2桁固定の16進数、終端のセミコロン無し) を文字と認識していました。例えば#[\x0d\x0a]はリターン文字と改行文字集合を意味していました。互換性のため、終端のセミコロンが見当たらない場合は古い構文もサポートされます。しかし曖昧な場合もあります。#[\x0a;]は新しい構文では改行文字のみのセットですが、古い構文では改行文字とセミコロンになります。

     リーダのモードをlegacyにセットすると、常に古い構文で認識されます。リーダのモードをwarn-legacyにセットすると、デフォルトと同じように振る舞いますが、古い構文を見つけた場合は警告が出力されます。詳しくはReader lexical modeを参照してください。

     古い構文と新しい構文の両方で動作するコードが必要な場合は、\uエスケープを使ってください。

Predefined character sets
-------------------------

We provide a bunch of predefined character sets, including the ones defined in R7RS charset library (see R7RS character sets). Those character sets are immutable. 定義済みの文字集合がいくつか提供されています。 R7RS文字集合ライブラリで定義されているものも含まれます(R7RS character sets参照)。これらの文字集合は変更不可です。

 -- Variable: char-set:letter
     [R7RS charset] Letters (Unicode general category Lu, Ll, Lt, Lm and Lo). 文字 (UnicodeカテゴリLu、Ll、Lt、Lm、Lo)。

 -- Variable: char-set:lower-case
 -- Variable: char-set:upper-case
 -- Variable: char-set:title-case
     [R7RS charset] Lower case, upper case and title case letters (Unicode general category Ll, Lu and Lt, respectively). 小文字、大文字、タイトルケース文字 (それぞれ、UnicodeカテゴリLl、Lu、Lt)。

 -- Variable: char-set:digit
     [R7RS charset] Digit characters (Unicode general category Nd).  Note that this contains many more characters than ASCII 0 to 9.  If you need #[0-9], use char-set:ascii-digit. 数字 (UnicodeカテゴリNd)。これには非ASCIIの数字もたくさん含まれています。 ASCIIの数字(#[0-9])だけが欲しい時はchar-set:ascii-digitを使ってください。

 -- Variable: char-set:hex-digit
     [R7RS charset] Digit characters used for hexadecimal, i.e. #[0-9A-Fa-f].  This does not contain other Unicode digit characters, for it isn't practical to mix non-ascii digit characters with hexadecimal notation. 16進数表記に使われる文字、つまり#[0-9A-Fa-f]。これにはASCII外の文字は含まれません。

 -- Variable: char-set:letter+digit
     [R7RS charset] Union of char-set:letter and char-set:digit. char-set:letterとchar-set:digitの和集合です。

 -- Variable: char-set:graphic
     [R7RS charset] Characters that has some glyph.  Union of letters, numbers, punctuations and symbols. 何らかのグリフを持っている文字。通常文字、数字、句読点、シンボルの和集合です。

 -- Variable: char-set:printing
     [R7RS charset] Union of char-set:graphic and char-set:whitespace. char-set:graphicとchar-set:whitespaceの和集合です。

 -- Variable: char-set:whitespace
 -- Variable: char-set:blank
     [R7RS charset] Whitespace and blank characters; char-set:whitespace includes #\tab, #\newline, #\u000B (vertical tab), #\page, #\return, and all characters in general category Zs, Zl, Zp, while char-set:blank includes #\tab and all characters in general category Zs. Note that char-set:whitespace is the same set of characters that Scheme reader treats as whitespace characters. 空白文字およびブランク文字です。空白文字char-set:whitespaceは、 #\tab、#\newline、#\u000B (vertical tab)、 #\page、#\return、および一般カテゴリZs、Zl、Zpの文字です。一方、ブランク文字char-set:blankは、 #\tabと一般カテゴリZsの文字です。 char-set:whitespaceは、Schemeのリーダが空白扱いにする文字の集合と一致します。

 -- Variable: char-set:iso-control
     [R7RS charset] Control characters (Unicode general category Cc). 制御文字 (Unicode一般カテゴリCc)。

 -- Variable: char-set:punctuation
     [R7RS charset] Punctuation characters (Unicode general category Pc, Pd, Ps, Pe, Pi, Pf and Po). 句読点 (Unicode一般カテゴリ Pc, Pd, Ps, Pe, Pi, Pf, Po)。

 -- Variable: char-set:symbol
     [R7RS charset] Symbol characters (Unicode general category Sm, Sc, Sk and So). シンボル文字 (Unicode一般カテゴリ Sm, Sc, Sk, So)。

 -- Variable: char-set:ascii
     [R7RS charset] Contains all ASCII characters (U+0000 to U+007f). すべてのASCII文字 (U+0000 to U+007f)。

 -- Variable: char-set:empty
     [R7RS charset] An empty character set. 空の文字集合。

 -- Variable: char-set:full
     [R7RS charset] A character set that includes all characters. すべての文字を含む文字集合。

 -- Variable: char-set:word
     A word constituent characters.  In the current version, it is equivalent to char-set:ascii-word (#[0-9A-Za-z_]) but in future versions we may extend this to other Unicode characters. If you intend to mean ASCII-only words, use char-set:ascii-word. 単語を構成する文字。今のところ、これはchar-set:ascii-word、つまり#[0-9A-Za-z_]と同じです。ただ、将来はUnicodeの全域に意味を拡張するかもしれません。 ASCIIの範囲内だけを扱いたい場合はchar-set:ascii-wordを使ってください。

 -- Variable: char-set:ascii-letter
 -- Variable: char-set:ascii-lower-case
 -- Variable: char-set:ascii-upper-case
 -- Variable: char-set:ascii-digit
 -- Variable: char-set:ascii-letter+digit
 -- Variable: char-set:ascii-graphic
 -- Variable: char-set:ascii-printing
 -- Variable: char-set:ascii-whitespace
 -- Variable: char-set:ascii-blank
 -- Variable: char-set:ascii-control
 -- Variable: char-set:ascii-punctuation
 -- Variable: char-set:ascii-symbol
 -- Variable: char-set:ascii-word
     These are intersection of char-set:ascii and the corresponding char set without ascii-. (char-set:ascii-control corresponds to char-set:iso-control). これらはそれぞれ、ascii-を除いた名前の文字集合とchar-set:asciiとの積集合です。

     The \d, \s and \w notation in the char-set literal and regexp literal corresponds to char-set:ascii-digit, char-set:ascii-whitespace, and char-set:ascii-word, respectively (not the Unicode set). 文字集合リテラルおよび正規表現リテラルにおける \d、\s、\wはそれぞれ char-set:ascii-digit、 char-set:ascii-whitespace、char-set:ascii-wordに対応します (Unicode版ではなく)。

     The POSIX character class notation, such as [:alpha:] in char-set literal and regexp literal, refers to these ASCII-only charsets. また、[:alpha:]などのPOSIX文字クラス表記もこちらのASCII版の方に対応します。

     Note: We don't have char-set:ascii-title-case and char-set:ascii-hex-digit.  There's no titlecase letter in ASCII range.  And char-set:hex-digit is limited to ASCII by definition. なお、char-set:ascii-title-caseとchar-set:ascii-hex-digitはありません。ASCIIの範囲内にtitlecaseにあたる文字はなく、またchar-set:hex-digitはそれ自体ASCII範囲に限定されています。

 -- Variable: char-set:Lu
 -- Variable: char-set:Ll
 -- Variable: char-set:Lt
 -- Variable: char-set:Lm
 -- Variable: char-set:Lo
 -- Variable: char-set:Mn
 -- Variable: char-set:Mc
 -- Variable: char-set:Me
 -- Variable: char-set:Nd
 -- Variable: char-set:Nl
 -- Variable: char-set:No
 -- Variable: char-set:Pc
 -- Variable: char-set:Pd
 -- Variable: char-set:Ps
 -- Variable: char-set:Pe
 -- Variable: char-set:Pi
 -- Variable: char-set:Pf
 -- Variable: char-set:Po
 -- Variable: char-set:Sm
 -- Variable: char-set:Sc
 -- Variable: char-set:Sk
 -- Variable: char-set:So
 -- Variable: char-set:Zs
 -- Variable: char-set:Zl
 -- Variable: char-set:Zp
 -- Variable: char-set:Cc
 -- Variable: char-set:Cf
 -- Variable: char-set:Cs
 -- Variable: char-set:Co
 -- Variable: char-set:Cn
     Each character set contains the corresponding Unicode characters with the given general category; e.g. char-set:Lu contains all characters of the general category Lu. それぞれ、対応するUniocdeの一般カテゴリに属する文字の集合です。例えばchar-set:Luは一般カテゴリLuの文字の集合です。

 -- Variable: char-set:L
 -- Variable: char-set:LC
 -- Variable: char-set:M
 -- Variable: char-set:N
 -- Variable: char-set:P
 -- Variable: char-set:S
 -- Variable: char-set:Z
 -- Variable: char-set:C
     Each character set contains the Unicode characters with the general category starting with the letter; e.g. char-set:L is union of char-set:Lu, char-set:Ll, char-set:Lt, char-set:Lm and char-set:Lo.

     char-set:LC is for cased-letters, the union of char-set:Lt, char-set:Ll, char-set:Lu. 各文字集合は、その文字で始まるUnicodeの一般カテゴリのすべての文字の集合です。例えばchar-set:Lは、char-set:Lu、 char-set:Ll、char-set:Lt、 char-set:Lm、char-set:Loの和集合です。

     char-set:LCは大文字小文字の区別のある文字の集合、つまり char-set:Lt、char-set:Ll、char-set:Luの和集合です。

Character set operations
------------------------

See also R7RS character sets for the comprehensive character set operations. 包括的な文字集合操作については、R7RS character setsも参照してください。

 -- Function: char-set? obj
     [R7RS charset] Returns true if and only if OBJ is a character set object. OBJが文字集合であれば真の値を返します。

 -- Function: char-set-immutable? char-set
     Returns #t if CHAR-SET is an immutable char-set, #f if it's a mutable char-set. CHAR-SETが変更不可の文字集合であれば#tを、変更可能な文字集合であれば #fを返します。

 -- Function: char-set-contains? char-set char
     [R7RS charset] Returns true if and only if a character set object CHAR-SET contains a character CHAR. 文字集合CHAR-SETが文字CHARを含んでいれば真の値を返します。

          (char-set-contains? #[a-z] #\y) => #t
          (char-set-contains? #[a-z] #\3) => #f

          (char-set-contains? #[^ABC] #\A) => #f
          (char-set-contains? #[^ABC] #\D) => #t

          (char-set-contains? #[あ-お] #\う) => #t
          (char-set-contains? #[あ-お] #\ぷ) => #f

 -- Generic application: CHAR-SET CHAR
     A char-set object can be applied to a character, and it works just like (char-set-contains? char-set char). 文字集合オブジェクトは文字に適用されると、 (char-set-contains? char-set char) のように振る舞います。

          (#[a-z] #\a) => #t
          (#[a-z] #\A) => #f

          (use gauche.collection)
          (filter #[a-z] "CharSet") => (#\h #\a #\r #\e #\t)

 -- Function: char-set char ...
     [R7RS charset] Creates a character set that contains CHAR .... 文字CHAR ... からなる文字集合を作成して返します。

          (char-set #\a #\b #\c)   => #[a-c]
          (char-set #\あ #\い #\う) => #[あいう]

 -- Function: char-set-size char-set
     [R7RS charset] Returns a number of characters in the given charset. 文字集合に含まれる文字数を返します。

          gosh> (char-set-size #[])
          0
          gosh> (char-set-size #[[:alnum:]])
          62

 -- Function: char-set-copy char-set
     [R7RS charset] Copies a character set CHAR-SET. CHAR-SETのコピーを作って返します。

 -- Function: char-set-complement char-set
 -- Function: char-set-complement! char-set
     [R7RS charset] Returns a complement set of CHAR-SET.  The former always returns a new set, while the latter may reuse the given charset. CHAR-SETの補集合を返します。上の手続きは常に新たな集合を作って返しますが、下の手続きは引数を変更して返す可能性があります。

Strings
=======

 -- Builtin Class: <string>
     A string class. 文字列のクラスです。

It should be emphasized that Gauche's internal string object, string body, is immutable. To comply R7RS in which strings are mutable, a Scheme-level string object is an indirect pointer to a string body. Mutating a string means that Gauche creates a new immutable string body that reflects the changes, then swap the pointer in the Scheme-level string object.

This may affect some assumptions on the cost of string operations.

  * Copying string is O(1), no matter how long the string is, since the same string body is shared.

  * Taking substring usually is also O(1), for the resulting string shares the substring of the original string body.  Gauche may copy a part of the string for better memory management, but the visible cost should stay pretty close to O(1).  (However, note that accessing to a specific point by index within the original string may cost O(N) because of multibyte string; which is a different story).

  * On the other hand, mutating a string cost O(N) where N is the length of string, even for replacing a character.

Gauche does not attempt to make string mutation faster; (string-set! s k c) is exactly as slow as to take two substrings, before and after of k-th character, and concatenate them with a single-character string inbetween. So, just avoid string mutations; we believe it's a better practice. See also String constructors. GaucheではSchemeの文字列は、内部的には、変更不可能なオブジェクト(文字列実体)を用いて表現されている、ということを強調しておきます。文字列が変更可能であるR7RSの仕様を満たすために、Schemeレベルの文字列は文字列実体への間接ポインタとなっています。文字列を変更すると、変更を反映した新しいstring bodyが作成され、Schemeレベルの文字列が新しい文字列実体を指すように変更されます。

このことから、文字列操作の性能を見積る場合に注意が必要です。

  * 文字列のコピーは、それがどんなに長い文字列であっても常にO(1)です。文字列実体は共有されるからです。

  * 部分文字列を取る操作も通常はO(1)です。文字列実体を部分的に共有するからです。メモリ管理上の都合から文字列実体の一部がコピーされる可能性はありますが、ほとんどの場合はO(1)とみなして構いません。(ただし、マルチバイト文字処理の都合上、文字インデックスで文字列の途中を指定する操作は別途O(N)を要する場合があります)

  * 一方で、文字列の変更はたとえ1文字の変更であっても、文字列実体の長さNに比例したO(N)のコストを必要とします。

Gaucheはそもそも文字列の変更に関して全く最適化を行っていません。 (string-set! s k c)は、k番目の文字の前後の部分文字列を取って、 c一文字の文字列を間に挟んで継ぎ足すことで新たな文字列を作るのと全く同じコストがかかります。文字列を変更不可として扱う方が良いプログラミングスタイルだと考えるからです。 String constructorsも参照してください。

R7RS string operations are very minimal.  Gauche supports some extra built-in operations, and also a rich string library defined in SRFI-13.   See String library, for details about SRFI-13. R7RSに定義されている文字列操作は非常に限られています。 Gaucheでは追加の組込み手続きのほか、 SRFI-13に定義されている豊富な文字列ライブラリを備えています。 SRFI-13についてはString libraryを参照してください。

String syntax
-------------

 -- Reader Syntax: "..."
     [R7RS+] Denotes a literal string.  Inside the double quotes, the following backslash escape sequences are recognized. リテラル文字列です。ダブルクオートの中では、以下のエスケープシーケンスが認識されます。

     \"
          [R7RS] Double-quote character [R7RS] ダブルクオート文字

     \\
          [R7RS] Backslash character [R7RS] バックスラッシュ文字

     \n
          [R7RS] Newline character (ASCII 0x0a). [R7RS] 改行文字 (ASCII 0x0a)

     \r
          [R7RS] Return character (ASCII 0x0d). [R7RS] 復帰文字 (ASCII 0x0d)

     \f
          Form-feed character (ASCII 0x0c). フォームフィード (ASCII 0x0c)

     \t
          [R7RS] Tab character (ASCII 0x09) [R7RS] タブ文字 (ASCII 0x09)

     \a
          [R7RS] Alarm character (ASCII 0x07). [R7RS] アラーム文字 (ASCII 0x07)

     \b
          [R7RS] Backspace character (ASCII 0x08). [R7RS] バックスペース文字 (ASCII 0x08)

     \0
          ASCII NUL character (ASCII 0x00). NUL文字 (ASCII 0x00)

     \<whitespace>*<newline><whitespace>*
          [R7RS] Ignored.  This can be used to break a long string literal for readability. This escape sequence is introduced in R6RS. [R7RS] 無視されます。長い文字列リテラルを読みやすさのために折り返す時に便利です。このエスケープシーケンスはR6RSで導入されました。

     \xN;
          [R7RS] A character whose Unicode codepoint is represented by hexadecimal number N, which is any number of hexadecimal digits. (See the compatibility notes below.) [R7RS] 16進数Nで表現されたUnicodeコードポイントの文字。 16進数は何桁でも良い。(下の互換性に関する注参照。)

     \uNNNN
          A character whose UCS2 code is represented by four-digit hexadecimal number NNNN. 4桁の16進数NNNNによって示されるUCS2コードを持つ文字。

     \UNNNNNNNN
          A character whose UCS4 code is represented by eight-digit hexadecimal number NNNNNNNN. 8桁の16進数NNNNNNNNによって示されるUCS4コードを持つ文字。

     The following code is an example of backslash-newline escape sequence: 下はバックスラッシュ-改行エスケープシーケンスの使用例です。

          (define *message* "\
            This is a long message \
            in a literal string.")

          *message*
            => "This is a long message in a literal string."

     Note the whitespace just after `message'.   Since any whitespaces before `in' is eaten by the reader, you have to put a whitespace between `message' and the following backslash.  If you want to include an actual newline character in a string, and any indentation after it, you can put '\n' in the next line like this: `message' の後の空白に注意してください。`in'の前の空白は読み込みルーチンによって無視されてしまうので、空白を入れたければ`message'と続くバックスラッシュの間に入れる必要があります。もし文字列中に実際に改行文字を入れ、さらにその後の文字列をインデントさせたい場合は次のようにすると良いでしょう:

          (define *message/newline* "\
            This is a long message, \
            \n   with a line break.")

     Note for the compatibility: We used to recognize a syntax \xNN (two-digit hexadecimal number, without semicolon terminator) as a character in a string; for example, "\x0d\x0a" was the same as "\r\n".  We still support it when we don't see the terminating semicolon, for the compatibility. There are ambiguous cases: "\0x0a;" means "\n" in the current syntax, while "\n;" in the legacy syntax.

     Setting the reader mode to legacy restores the old behavior. Setting the reader mode to warn-legacy makes it work like the default behavior, but prints warning when it finds legacy syntax. See Reader lexical mode, for the details. 互換性に関する注: 以前は、\xNN (2桁固定の16進数、終端のセミコロン無し) を文字列中の文字と認識していました。例えば"\x0d\x0a"は"\r\n"と同じでした。互換性のため、終端のセミコロンが見当たらない場合は古い構文もサポートされます。しかし曖昧な場合もあります。"\x0a;"は新しい構文では "\n"と同じですが、、古い構文では"\n;"となります。

     リーダのモードをlegacyにセットすると、常に古い構文で認識されます。リーダのモードをwarn-legacyにセットすると、デフォルトと同じように振る舞いますが、古い構文を見つけた場合は警告が出力されます。詳しくはReader lexical modeを参照してください。

String predicates
-----------------

 -- Function: string? obj
     [R7RS base] Returns #t if OBJ is a string, #f otherwise. OBJが文字列なら#tを、そうでなければ#fを返します。

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

     String literals, and the strings returned from certain procedures such as symbol->string are immutable.  To ensure you get an immutable string in a program, you can use string-copy-immutable. OBJが変更不可な文字列なら#tを、そうでなければ#fを返します。

     文字列リテラルおよび、symbol->stringなどいくつかの手続きから返される文字列は変更不可です。プログラム中で変更不可の文字列を確実に手に入れたい場合は string-copy-immutableが使えます。

 -- Function: string-incomplete? obj
     Returns #t if OBJ is an incomplete string, #f otherwise OBJが不完全文字列なら#tを、そうでなければ#fを返します。

String constructors
-------------------

 -- Function: make-string k :optional char
     [R7RS base] Returns a string of length K.  If optional CHAR is given, the new string is filled with it.  Otherwise, the string is filled with a whitespace.  The result string is always complete.

          (make-string 5 #\x) => "xxxxx"

     Note that the algorithm to allocate a string by make-string and then fills it one character at a time is extremely inefficient in Gauche, and should be avoided.

     In Gauche, a string is simply a pointer to an immutable string content. If you mutate a string by, e.g. string-set!, Gauche allocates whole new immutable string content, copies the original content with modification, then swap the pointer of the original string.  It is no more efficient than making a new copy.

     You can use an output string port for a string construction (see String ports). Even creating a list of characters and using list->string is faster than using make-string and string-set!. 長さKの文字列を作成して返します。 CHARが与えられればそれで内容を満たします。CHARが与えられなければ空白文字で満たされます。常に完全な文字列が返されます。

          (make-string 5 #\x) => "xxxxx"
          (make-string 5 #\ふ) => "ふふふふふ"

     make-stringで必要な長さの文字列をアロケートして、string-set! で順番に埋めて行くアルゴリズムは、Gaucheでは極めて非効率であることに注意してください。

     Gaucheの文字列オブジェクトは、変更不可能な文字列本体への単なるポインタです。 string-set!等の文字列を破壊的変更する操作は、実際には変更箇所以外は元の文字列本体をコピーした新たな文字列本体をアロケートして、元の文字列オブジェクトのポインタを差し替えるこようになっています。従って、文字列のコピーを作るのと同等の効率となります。

     文字列の順次作成に適しているのは文字列ポートです (文字列ポート参照)。それが使えない場合、文字のリストを作成し、list->stringで変換する方がまだmake-stringと string-set!を使うより良いでしょう。

 -- Function: make-byte-string k :optional byte
     Creates and returns an incomplete string o size K. If BYTE is given, which must be an exact integer, and its lower 8 bits are used to initialize every byte in the created string. 大きさKの不完全な文字列を作成して返します。 BYTEが与えられた場合は、その下位1バイトで文字列の各バイトを初期化します。 BYTEは正確な整数でなければなりません。

 -- Function: string char ...
     [R7RS base] Returns a string consisted by CHAR .... 文字CHAR ... から構成された文字列を返します。

 -- Generic Function: x->string obj
     A generic coercion function. Returns a string representation of OBJ. The default methods are defined as follows: strings are returned as is, numbers are converted by number->string, symbols are converted by symbol->string, and other objects are converted by display.

     Other class may provide a method to customize the behavior. 文字列への強制型変換手続きです。 OBJの文字列表現を返します。デフォルトのメソッドでは、文字列はそのまま返され、数値はnumber->stringで、シンボルはsymbol->stringで変換され、その他のオブジェクトはdisplay表現が使われます。

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

String interpolation
--------------------

The term "string interpolation" is used in various scripting languages such as Perl and Python to refer to the feature to embed expressions in a string literal, which are evaluated and then their results are inserted into the string literal at run time. 「文字列の補間(string interpolation)」という用語は、 PerlやPythonなど様々なスクリプト言語で、文字列リテラル内に式を埋め込んでおき実行時に式を評価した値をそのリテラル内に埋め込む機能を指します。

Scheme doesn't define such a feature, but Gauche implements it as a reader macro. Schemeはそのような機能を定義していませんが、Gaucheではリーダーマクロを使って文字列の補間を実装しました。

 -- Reader Syntax: #STRING-LITERAL
     Evaluates to a string.  If STRING-LITERAL contains the character sequence ~EXPR, where EXPR is a valid external representation of a Scheme expression, EXPR is evaluated and its result is inserted in the original place (by using x->string, see String constructors). 文字列に評価されます。STRING-LITERAL内に、~EXPR というシーケンス(ここでEXPRは有効なScheme式の外部表現)が現われたら、EXPRが評価されてその結果がもとの位置に埋め込まれます。結果の文字列化にはx->stringが使われます(String constructors参照)。

     The tilde and the following expression must be adjacent (without containing any whitespace characters), or it is not recognized as a special sequence. チルダと続く式とは、空白文字等を入れずに隣接していなければなりません。そうでない場合は置換されません。

     To include a tilde itself immediately followed by non-delimiting character, use ~~. すぐ後ろに非空白文字が来る場所にチルダ自身を埋め込みたい場合は ~~とします。

     Other characters in the STRING-LITERAL are copied as is. それ以外のSTRING-LITERAL内の文字シーケンスはそのままコピーされます。

     If you use a variable as EXPR and need to delimit it from the subsequent string, you can use the symbol escape syntax using `|' character, as shown in the last two examples below. EXPRに単独の変数を使う場合で、それに続く文字列と変数名を区切りたい場合は、`|'文字を使ったシンボルエスケープ構文が使えます。下の例の最後の 2つを見て下さい。

          #"This is Gauche, version ~(gauche-version)."
           => "This is Gauche, version."

          #"Date: ~(sys-strftime \"%Y/%m/%d\" (sys-localtime (sys-time)))"
           => "Date: 2002/02/18"

          (let ((a "AAA")
                (b "BBB"))
           #"xxx ~a ~b zzz")
           => "xxx AAA BBB zzz"

          #"123~~456~~789"
           => "123~456~789"

          (let ((n 7)) #"R~|n|RS")
           => "R7RS"

          (let ((x "bar")) #"foo~|x|.")
           => "foobar"

     In fact, the reader expands this syntax into a macro call, which is then expanded into a call of string-append as follows: 実は、リーダーはこの構文をマクロ呼び出しへと変換し、それが最終的には string-appendへの呼び出しへと変換されます。

          #"This is Gauche, version ~(gauche-version)."
           ==
          (string-interpolate* ("This is Gauche, version "
                                (gauche-version)
                                "."))

          ;; then, it expands to...

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

     (NB: The exact spec of string-interpolate* might change in future, so do not rely on the current behavior.) (註: string-interpolate*の厳密な仕様は将来変わるかもしれないので、現在の振る舞いに依存したコードは避けて下さい。)

     Since the #"..." syntax is equivalent to a macro call of string-interpolate*, which is provided in the Gauche module, it must be visible from where you use the interpolation syntax. When you write Gauche code, typically you implicitly inherit the Gauche module so you don't need to worry; however, if you start from R7RS code, make sure you import string-interpolate* (by (import (gauche base)), for example) whenever you use string interpolation syntax.  Also be careful not to shadow string-interpolate* locally. #"..."構文はマクロstring-interpolate*の呼び出しと等価なので、この構文を使う際にはGaucheモジュールのstring-interpolate*が見えている必要があります。Gaucheコードを書く場合、Gaucheモジュールはデフォルトで継承されているので、普通は気にする必要はありません。R7RSコードから始めて #"..."構文を使いたくなった場合は、(import (gauche base))等で string-interpolate*を見えるようにしてください。また、ローカルにstring-interpolate*をシャドウしないように気をつけてください。

 -- Reader Syntax: #`STRING-LITERAL
     This is the old style of string-interpolation.  It is still recognized, but discouraged for the new code.

     Inside STRING-LITERAL, you can use ,EXPR (instead of ~EXPR) to evaluate EXPR.  If comma isn't immediately followed by a character starting an expression, it loses special meaning. これは文字列補間の古い書法です。まだ認識されますが、新たなコードでは使わないでください。

     STRING-LITERALの中で、(~EXPR ではなく) ,EXPR とマークされた部分のEXPRが評価されます。コンマのすぐ次に式を開始する文字がこなければ、コンマはその効力を失います。

          #`"This is Gauche, version ,(gauche-version)"

Rationale of the syntax: There are wide variation of string interpolation syntax among scripting languages.  They are usually linked with other syntax of the language (e.g. prefixing $ to mark evaluating place is in sync with variable reference syntax in some languages).

The old style of string interpolation syntax was taken from quasiquote syntax, because those two are conceptually similar operations (see Quasiquotation). However, since comma character is frequently used in string literals, it was rather awkward.

We decided that tilde is more suitable as the unquote character for the following reasons.

  * Traditionally, Lisp's string formatter format uses ~ to introduce format directives (see Formatting output).  Lispers are used to scan ~'s in a string as variable portions.

  * Gauche's ~ is a universal accessor, and the operator has a nuance of ``taking something out of it'' (see Universal accessor).

  * Clojure, a new Lisp dialect, adopted ~ as the unquote character in the quasiquote syntax, instead of commas.

Note that Scheme allows wider range of characters for valid identifier names than usual scripting languages. Consequently, you will almost always need to use `|' delimiters when you interpolate the value of a variable. For example, while you can write "$year/$month/$day $hour:$minutes:$seconds" in Perl, you should write #"~|year|/~|month|/~day ~|hour|:~|minutes|:~seconds". It may be better always to delimit direct variable references in this syntax to avoid confusion. この構文を採用した理由: スクリプト言語の文字列補間構文には様々なバリエーションがありますが、通常、その言語の他の構文と関連しているものが多いです (例えば、$で変数参照する言語が、$を文字列中の評価部分に前置する等)。

Gaucheの古い形式の文字列補間構文では、準クオートの構文を流用していました (Quasiquotation参照)。準クオートと文字列補間は意味的に似ているからです。けれども、コンマはそれ自体が文字列中によく出てくる文字なので、少々不格好な仕様でした。

そこで、以下のような理由から、チルダの方がアンクオート文字としてふさわしいと判断しました。

  * 伝統的に、Lispの文字列フォーマッティング関数formatでは ~をフォーマット指示子の導入に使ってきました (Formatting output参照)。Lisperは文字列中で~を走査して可変部分を見つけるのに慣れています。

  * Gaucheは ~ を万能アクセサとして使っていて、この文字には「中から何かを取り出す」ニュアンスを付加しています (Universal accessor参照)。

  * 新たなLisp方言であるClojureは、準クオート構文中のアンクオート文字にコンマでなく ~ を採用しています。

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

String cursors
--------------

String cursors are opaque objects that point into strings, similar to indexes. Cursors however are more efficient. For example, to get a character with string-ref using an index on a multibyte string, Gauche needs to iterate from the beginning of the string until that position, or O(n). Using cursors you can access in O(1) (for singlebyte (ASCII) strings or an indexed string, Gauche does it in O(1) even with index.  See String indexing, for the details of indexed string.) 文字列カーソルは文字列の中の文字を指示するオブジェクトです。文字列中の文字を指定するのにインデックスも使えますが、カーソルの方が効率が良いです。例えば、文字インデックスを使ってマルチバイト文字列中の文字をstring-refで取り出すには、 Gaucheは文字列の最初からその文字まで文字列をたどらなければならず、インデックスnに対してO(n)かかります。カーソルを使えばO(1)でアクセスできます (ASCII文字だけからなる文字列や、索引付加済み文字列では文字インデックスを使ったアクセスもO(1)になります。索引付加済み文字列についてはString indexingを参照してください。)

For a string of length n, there can be n+1 cursors. The last cursor at the end of the string does not point to any valid character, it's usually used to determine if nothing is found. 長さnの文字列には、n+1個のカーソルが存在し得ます。一番最後のカーソルは文字列末尾を指し、該当する文字を持ちません。探している文字が無いことを示す値としても使われます。

A string cursor is associated with a specific string and should not be used with another string. A string cursor also becomes invalid when the associated string is modified. Accessing an invalid cursor does not always fail though. Running gosh with -fsafe-string-cursors could help catch these issues, with some performance overhead. See Invoking Gosh. 文字列カーソルは特定の文字列と結びついていて、それ以外の文字列に対して使うのは無効です。また、元の文字列が変更されると文字列カーソルは無効になります。ただ、無効になったカーソルを使っても必ずしもエラーになるとは限りません。 goshを-fsafe-string-cursorsオプションつきで起動すると、性能が落ちますがその種のエラーを検出することができます。詳しくはInvoking Goshを参照してください。

Most of the time, string cursors aren't heap-allocated.  It is only allocated in heap either (1) when it points at a huge byte index, or (2) when you use -fsafe-string-cursors to enable extra run-time check.

The threashold of byte index to cause a string cursor to be heap-allocated is 2^56 on 64bit systems, and 2^24 on 32bit systems, in the current implementation.  On 64bit systems you will never hit the threashold practically. On 32bit systems you may, if you have a huge string, but you may want to consider using other data structure rather than keeping such data in one string object. ほとんどの場合、文字列カーソルはヒープアロケーションを伴いません。文字列カーソルがヒープにアロケートされるのは (1)巨大なバイトインデックスを指す場合か、 (2)-fsafe-string-cursorsを使って追加の実行時検査を有効にした場合です。

現在の実装では、カーソルがヒープアロケートされる閾値は、64bitシステムでは 2^56、32bitシステムでは2^24です。 64bitシステムでこの閾値を越えることは現実的にはありえないでしょう。 32bitシステムでは、超巨大な文字列オブジェクトを使った場合にあり得るかもしれませんが、それほど大きなデータを扱うならば、単一の文字列ではなくデータ構造を工夫した方が良いかもしれません。

Most procedures that take indexes in Gauche can also take cursors. Relying on this though is unportable. For example, the substring procedure in RnRS standards does not mention anything about cursors even though the Gauche version accepts cursors. For portable programs, you should only use cursors on procedures from srfi-130 module (see Cursor-based string library). 文字インデックスを取るGaucheの文字列手続きのほとんどはカーソルも受け付けます。但し、それに依存したコードは移植性がありません。例えばsubstringは、 Gauche版ではインデックスもカーソルも使えますが、RnRSではインデックスしか許していません。移植性のあるプログラムを書く際には、srfi-130モジュールにある手続きでのみカーソルを使うようにしてください (Cursor-based string library参照)。

 -- Builtin Class: <string-cursor>
     Represents a cursor. When printed out, you'll see the byte offset from the beginning of the string, not the character index. 文字列カーソルのクラスです。書き出される時に表示される数字は、文字インデックスではなく文字へのバイトオフセットです。

          (string-index->cursor "あかさたな" 2)
           => #<string-cursor 6>

 -- Function: string-cursor? OBJ
     [SRFI-130] Returns #t if OBJ is a string cursor, #f otherwise. OBJが文字列カーソルなら#tを、そうでなければ#fを返します。

 -- Function: string-cursor-start STR
     [SRFI-130] Returns a cursor pointing to the start of a string STR. It returns a valid cursor on an empty string too. It's the same as string-cursor-end in that case. 文字列STRの先頭を指す文字列カーソルを返します。 STRが空文字列でも有効な文字列カーソルが返されます。 (STRが空文字列の場合、string-cursor-endが返すカーソルは同じものです)。

 -- Function: string-cursor-end STR
     [SRFI-130] Returns a cursor pointing to the end of STR (the point after the last character.)  If STR is empty, it is the same as string-cursor-start. This cursor does not point to any valid character of the string. 文字列STRの末尾(最後の文字の直後)を指す文字列カーソルを返します。 STRが空文字列の場合、string-cursor-startが返すカーソルと同じものが返されます。このカーソルは有効な文字を指しません。

 -- Function: string-cursor-next STR CUR
     [SRFI-130] Returns the cursor into STR following CUR. CUR can also be an index.  An error is signaled if CUR points to the end of the string. 文字列STR中で、CURが指す文字の次を指すカーソルを返します。 CURに文字インデックスを渡すこともできます。CURが文字列末尾を指している場合はエラーが投げられます。

 -- Function: string-cursor-prev STR CUR
     [SRFI-130] Returns the cursor into STR preceding CUR. CUR can also be an index.  An error is signaled if CUR points to the beginning of the string. 文字列STR中で、CURが指す文字の一つ前を指すカーソルを返します。 CURには文字インデックスを渡すこともできます。CURが文字列先頭を指している場合はエラーが投げられます。

 -- Function: string-cursor-forward STR CUR N
     [SRFI-130] Returns the cursor into STR following CUR by N characters. CUR can also be an index. 文字列STR中で、カーソルCURが指す文字からN文字先を指すカーソルを返します。CURに文字インデックスを渡すこともできます。

 -- Function: string-cursor-back STR CUR N
     [SRFI-130] Returns the cursor into STR preceding CUR by N characters. CUR can also be an index. 文字列STR中で、カーソルCURが指す文字からN文字前を指すカーソルを返します。CURに文字インデックスを渡すこともできます。

 -- Function: string-index->cursor STR INDEX
     [SRFI-130] Convert an INDEX to a cursor. If INDEX is a cursor it will be returned as-is. 文字列インデックスINDEXをカーソルに変換します。 INDEXが既にカーソルであった場合はそれがそのまま返されます。

 -- Function: string-cursor->index STR CUR
     [SRFI-130] Convert a cursor to an index. If CUR is a an index it will be returned as-is. 文字列カーソルCURをインデックスに変換します。 CURが既にインデックスであった場合はそれをそのまま返します。

 -- Function: string-cursor-diff STR START END
     [SRFI-130] Returns the number of characters between START and END. It should be non-negative if START precedes END, non-positive otherwise. START and END also accept index. 二つの文字列カーソルSTARTとENDの間にある文字数を返します。 STARTよりENDが後を指していれば結果は正に、 ENDがSTARTより手前にあれば結果は負になります。 STARTとENDは文字インデックスであっても構いません。

 -- Function: string-cursor=? CUR1 CUR2
 -- Function: string-cursor<? CUR1 CUR2
 -- Function: string-cursor<=? CUR1 CUR2
 -- Function: string-cursor>? CUR1 CUR2
 -- Function: string-cursor>=? CUR1 CUR2
     [SRFI-130] Compares two cursors or two indexes (but not a cursor and an index) and returns #t or #f accordingly. 二つの文字列カーソル、もしくは二つのインデックスの前後関係を比較します (カーソルとインデックスは比較できません)。

String indexing
---------------

Since Gauche stores strings in multibyte encoding, random access requires O(N) by default.  In most cases, string access is either sequential or search-and-extract pattern, and Gauche provides direct means for these operations, so you don't need to deal with indexed access. However, there may be a case that you have need more efficient random access string (mostly when porting third-party code, we imagine). Gaucheは文字列をマルチバイト形式で保持しているので、デフォルトではランダムアクセスにO(N)の時間がかかります。ほとんどの場合、文字列へのアクセスは最初から順に見て行くか、検索してマッチした箇所を見るかで、Gaucheはそれらの操作をプリミティブで提供しているので、文字列を文字のインデックスでアクセスする必要は滅多にないでしょう。けれどもどうしても文字列をランダムにアクセスしたい場合があるかもしれません (サードパーティ製のライブラリの移植、などが考えられます)。

There are a couple of ways to achieve O(1) random access. O(1)ランダムアクセスを実現する方法は二つばかりあります。

First, instead of integer character indexes, you can use string cursors (see String cursors).  It is defined by srfi-130, and you can use the code that's using srfi-130 as is, without worring about slow access.  However, if external interface gives you integer character index, converting index to cursor and vice versa takes O(N) after all. 一つは、文字へのインデックスのかわりに、文字列カーソルを使うことです(String cursors参照)。文字列カーソルはsrfi-130で定義され、srfi-130のインタフェースを使っているコードはそのまま、効率的に動きます。ただ、もし外部に向けたインタフェースが文字インデックスを要求していたなら、カーソルとインデックス間の相互変換のところで O(N)時間がかかってしまいます。

There's another way.  You can precompute string index, mapping from integer character index to the position in the multibyte string.  It costs O(N) of time and space to compute it, but once computed, you have O(1) random access.  (We store positions for every K characters, where K is between 16 to 256, so it won't take up as large storage as the actual string body). もう一つの方法は、文字のインデックスとマルチバイト文字列内の位置を表す文字列索引をあらかじめ計算しておくことです。計算時にはO(N)の時間・空間コストがかかりますが、一度計算すれば以降はO(1)でランダムアクセスできます。 (実際には、文字列の長さに応じて16から256文字ごとに位置を記録するので、文字列本体に比べて索引はそれほどメモリを取りません)。

For portability, srfi-135 Immutable Texts provides O(1) accessible string as ``texts''.  On Gauche, a text is just an immutable string with index attached. srfi-135 (変更不可なテキスト) はO(1)アクセス可能な文字列を「テキスト」という型で扱っています。Gaucheでは、テキストは単に文字列索引つきの変更不可な文字列です。

 -- Function: string-build-index! str
     Computes and attaches index to a string STR, and returns STR itself.  The operation doesn't alter the content of STR, and you can pass immutable string as well. 文字列STRの索引を計算して、STR自身を返します。この操作はSTR自体の内容を変えるものではないため、変更不可な文字列にも適用できます。

     If STR is a single-byte string (ASCII-only, or incomplete), or a short one (less than 64 octets), no index is attached. It is ok to pass a string which already has an index; then index computation is skipped. STRがシングルバイト文字列(ASCIIのみからなるか、不完全な文字列)の場合、あるいは短い(64バイト以下)の場合、索引は実際には計算されません。また、既に索引がある文字列を渡しても構いません。その場合、単に索引の計算はスキップされます。

     The index is attached to the string's content.  If you alter STR by e.g. string-set!, the index is discarded. 索引は文字列の内容そのものに対してつけられます。STRの内容をstring-set!などで置き換えた際には、索引は破棄されます。

 -- Function: string-fast-indexable? str
     Returns #t iff index access of a string STR is effectively O(1), that is, STR is either a single-byte string, a short string, or a long multibyte string with index computed. 文字列STRへの文字インデックスでのアクセスがO(1)で行える場合に#tを、そうでなければ#fを返します。 #tが返されるのは、STRがシングルバイト文字列か、短い文字列か、文字列索引が付加された長い文字列である場合です。

String accessors & modifiers
----------------------------

 -- Function: string-length string
     [R7RS base] Returns a length of (possibly incomplete) string STRING. 文字列STRINGの長さ(文字数)を返します。 STRINGは不完全な文字列であっても構いません。

 -- Function: string-size string
     Returns a size of (possibly incomplete) STRING. A size of string is a number of bytes STRING occupies on memory. The same string may have different sizes if the native encoding scheme differs.

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

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

 -- Function: string-ref cstring k :optional fallback
     [R7RS+] Returns K-th character of a complete string CSTRING. It is an error to pass an incomplete string.

     By default, an error is signaled if k is out of range (negative, or greater than or equal to the length of CSTRING). However, if an optional argument FALLBACK is given, it is returned in such case.  This is Gauche's extension.

     If CSTRING is a multibyte string without index attached, this procedure takes O(K) time.  See String indexing, for ensuring O(1) access.

     K can also be a string cursor (also Gauche's extension). Cursor acccess is O(1). 完全な文字列CSTRINGのK番目の文字を返します。不完全な文字列を渡すのはエラーです。

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

     CSTRINGがマルチバイト文字列でインデックスが付加されていない場合、この手続きはO(K)時間かかります。O(1)アクセスを得る方法は String indexingを参照してください。

     Kに文字列カーソルを渡すこともできます (これもGaucheの拡張です)。カーソルによるアクセスはO(1)です。

 -- Function: string-byte-ref string k
     Returns K-TH byte of a (possibly incomplete) string STRING. Returned value is an integer in the range between 0 and 255. K must be greater than or equal to zero, and less than (string-size STRING). (多分、不完全な)文字列STRINGのK番目のバイトを返します。戻り値は、0から255の範囲の整数です。Kは0以上、 (string-size STRING)より小でなければなりません。

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

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

     See the notes in make-string about performance consideration. STRINGのK番目の文字をCHARで置き換えます。 Kは0以上、(string-length STRING)より小でなければなりません。戻り値は未定義です。

     STRINGが不完全文字列の場合、CHARの下位8ビットの整数値は、 STRINGのK番目のバイトをセットするために使われます。

     パフォーマンス上の考慮点について、make-stringの説明を参照して下さい。

 -- Function: string-byte-set! string k byte
     Substitute STRING's K-th byte by integer BYTE. BYTE must be in the range between 0 to 255, inclusive. K must be greater than or equal to zero, and less than (string-size STRING). If STRING is a complete string, it is turned to incomplete string by this operation. Return value is undefined. STRINGのK番目のバイトを整数BYTEで置き換えます。 BYTEは0から255の範囲(255を含む)でなければなりません。 Kは0以上、(string-size STRING)より小である必要があります。 STRINGが完全文字列の場合、この操作により不完全文字列になります。戻り値は未定義です。

String comparison
-----------------

 -- Function: string=? string1 string2 string3 ...
     [R7RS base] Returns #t iff all arguments are strings with the same content. 全ての引数が内容の等しい文字列であれば#tを返します。

     If any of arguments is incomplete string, it returns #t iff all arguments are incomplete and have exactly the same content. In other words, a complete string and an incomplete string never equal to each other. もし引数に不完全文字列がひとつでもある場合、全ての文字列が不完全でありかつ内容が同じである場合に限り#tが返ります。言い換えれば、完全な文字列と不完全な文字列は決して等しくなりません。

 -- Function: string<? string1 string2 string3 ...
 -- Function: string<=? string1 string2 string3 ...
 -- Function: string>? string1 string2 string3 ...
 -- Function: string>=? string1 string2 string3 ...
     [R7RS base] Compares strings in codepoint order.  Returns #t iff all the arguments are ordered. 文字列同士をコードポイントの順序で比較します。全ての引数が順序どおりであれば #tが、そうでなければ#fが返されます。

     Comparison between an incomplete string and a complete string, or between two incomplete strings, are done by octet-to-octet comparison.  If a complete string and an incomplete string have exactly the same binary representation of the content, a complete string is smaller. 不完全文字列と完全文字列、もしくは不完全文字列同士の比較は、内容のオクテット同士の比較となります。内容のバイナリ表現が一致する完全文字列と不完全文字列を比較した場合は、完全文字列の方が小さいとみなされます。

 -- Function: string-ci=? string1 string2 string3 ...
 -- Function: string-ci<? string1 string2 string3 ...
 -- Function: string-ci<=? string1 string2 string3 ...
 -- Function: string-ci>? string1 string2 string3 ...
 -- Function: string-ci>=? string1 string2 string3 ...
     Case-insensitive string comparison. 大文字小文字を無視する文字列比較です。

     These procedures fold argument character-wise, according to Unicode-defined character-by-character case mapping.  See char-foldcase for the details (Characters). Character-wise case folding doesn't handles the case like German eszett: これらの手続きは、引数に「文字ごとの大文字小文字変換」を適用します。 (変換にはUnicodeの文字単位の大文字小文字マッピングテーブルを使います)。詳しくはchar-foldcaseの説明を見てください (Characters)。文字ごとの大文字小文字変換は、ドイツ語のエスツェットのような特別な場合を考慮しません。

          (string-ci=? "\u00df" "SS") => #f

     R7RS requires string-ci* procedures to use string case folding. Gauche provides R7RS-conformant case insensitive comparison procedures in gauche.unicode (see Full string case conversion). If you write in R7RS, importing (scheme char) library, you'll use gauche.unicode's string-ci* procedures. R7RSでは、string-ci*手続きは文字列としての大文字小文字変換を要求しています。 Gaucheは、R7RSに準拠した大文字小文字の違いを無視する比較手続きを gauche.unicodeモジュールに用意しています(Full string case conversion参照)。 R7RSでプログラミングする際に(scheme char)をインポートした場合は、 gauche.unicodeモジュールのstring-ci=?などが使われます。

String utilities
----------------

 -- Function: substring string start end
     [R7RS+ base] Returns a substring of STRING, starting from START-th character (inclusive) and ending at END-th character (exclusive). The START and END arguments must satisfy 0 <= START < N, 0 <= END <= N, and START <= END, where N is the length of the string.

     START and END can also be string cursors, but this is an extension of Gauche. STRINGのSTART番目の文字(これを含む)から、END番目の文字(これを含まない)までの部分文字列を返します。引数STARTおよび ENDは以下を満さなければなりません。 0 <= START < N、 0 <= END <= N、 START <= END。ただし、Nは与えられた文字列の長さです。

     When START is zero and END is N, this procedure returns a copy of STRING. STARTがゼロでかつENDがNの場合には、STRINGのコピーが返ります。

     Actually, extended string-copy explained below is a superset of substring.  This procedure is kept mostly for compatibility of R7RS programs. See also subseq in Sequence framework, for the generic version. 実は後述する拡張されたstring-copyはsubstringのスーパーセットになっています。この手続きの役割は主にR7RSとの互換性のためです。 Sequence frameworkのジェネリック版subseqも参照してください。

 -- Function: string-append string ...
     [R7RS base] Returns a newly allocated string whose content is concatenation of STRING .... STRING ...を連結した内容を含む文字列を新しくアロケートして返します。

     See also string-concatenate in SRFI-13 String reverse & append. SRFI-13 String reverse & appendのstring-concatenateも参照してください。

 -- Function: string->list string :optional start end
 -- Function: list->string list
     [R7RS base] Converts a string to a list of characters or vice versa. 文字列を文字のリストへ、またはその逆の変換をします。

     You can give an optional start/end indexes to string->list. string->listにはオプショナル引数として開始、終了位置のインデックスを渡せます。

     For list->string, every elements of LIST must be a character, or an error is signaled.  If you want to build a string out of a mixed list of strings and characters, you may want to use tree->string in Lazy text construction. list->stringではLISTの要素はすべて文字でなければなりません。そうでなければ、エラーシグナルがあがります。文字列や文字がまざったリストから文字列を構成したい場合にはLazy text constructionにある tree->stringが使えます。

 -- Function: string-copy string :optional start end
     [R7RS base] Returns a copy of STRING.  You can give START and/or END index to extract the part of the original string (it makes string-copy a superset of substring effectively). STRINGのコピーを返します。STARTおよび/あるいはENDの位置インデックスを渡すと元の文字列の部分文字列を取り出せます。 (したがってstring-copyは事実上substringのスーパーセットです)。

     If only START argument is given, a substring beginning from START-th character (inclusive) to the end of STRING is returned.  If both START and END argument are given, a substring from START-th character (inclusive) to END-th character (exclusive) is returned. See substring above for the condition that START and END should satisfy. START引数のみを与えた場合には、部分文字列はSTART番目の文字 (これを含む)からSTRINGの最後までで、それが返ります。 STARTとENDの両方を与えたときは、部分文字列はSTART番目の文字(これを含む)から、END番目の文字(これを含まない)までで、それが返ります。STARTとENDが満すべき条件については前述のsubstringの項を見てください。

     Node: R7RS's destructive version string-copy! is provided by srfi-13 module (see String library). 註: R7RSの破壊的バージョンstring-copy!はsrfi-13モジュールで提供されます (String library参照)。

 -- Function: string-copy-immutable string :optional start end
     If STRING is immutable, return it as is.  Otherwise, returns an immutable copy of STRING.  It is a dual of string-copy which always returns a mutable copy.

     The optional START and END argument may be a nonnegative integer character index and/or string cursors to restrict the range of STRING to be copied. STRINGが変更不可であればそれをそのまま返し、変更可能であれば変更不可なコピーを返します。 string-copyが常に変更可能なコピーを返すのと対照的です。

     STARTとENDは非負整数の文字インデックスか文字列カーソルで、 STRING中のコピーされる範囲を指定します。

 -- Function: string-fill! string char :optional start end
     [R7RS base] Fills STRING by CHAR.  Optional START and END limits the effective area. STRING を CHAR で埋めます。オプションの START と END は、影響を受ける領域を制限します。

          (string-fill! "orange" #\X)
            => "XXXXXX"
          (string-fill! "orange" #\X 2 4)
            => "orXXge"

     See the notes in make-string about performance consideration. パフォーマンス上の考慮点について、make-stringの説明を参照して下さい。

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

     The argument GRAMMAR may be one of the following symbol to specify how the strings are concatenated. [SRFI-13] リスト STRS 中にある文字列を、文字列 DELIM を'糊' として連結します。

     引数 GRAMMAR は、文字列がどのように連結されるかを指定するシンボルで、以下のうちの一つです。

     infix
          Use DELIM between each string.  This mode is default. Note that this mode introduce ambiguity when STRS is an empty string or a list with a null string. それぞれの文字列の間に DELIM を使います。このモードがデフォルトです。STRS が空文字列かヌル文字列を含むリストである場合は、曖昧に(適当に)動作します。

               (string-join '("apple" "mango" "banana") ", ")
                 => "apple, mango, banana"
               (string-join '() ":")
                 => ""
               (string-join '("") ":")
                 => ""

     strict-infix
          Works like infix, but empty list is not allowed to STRS, thus avoiding ambiguity. infix のように動作しますが、STRS には空リストは許されません。したがって、曖昧さはありません。

     prefix
          Use DELIM before each string. DELIM をそれぞれの文字列の前に補います。

               (string-join '("usr" "local" "bin") "/" 'prefix)
                 => "/usr/local/bin"
               (string-join '() "/" 'prefix)
                 => ""
               (string-join '("") "/" 'prefix)
                 => "/"

     suffix
          Use DELIM after each string. DELIM をそれぞれの文字列の後ろに補います。

               (string-join '("a" "b" "c") "&" 'suffix)
                 => "a&b&c&"
               (string-join '() "&" 'suffix)
                 => ""
               (string-join '("") "&" 'suffix)
                 => "&"

 -- Function: string-scan string item :optional return
 -- Function: string-scan-right string item :optional return
     Scan ITEM (either a string or a character) in STRING. While string-scan finds the leftmost match, string-scan-right finds the rightmost match. STRING から ITEM (文字列あるいは文字)を探します。 string-scanは最も左にある一致を、 string-scan-rightは最も右にある一致を見つけます。

     The RETURN argument specifies what value should be returned when ITEM is found in STRING.  It must be one of the following symbols. 引数 RETURN は、STRING 中に ITEM が見つかった場合にどの値が返されるかを指定します。それは以下のシンボルのうちの一つでなければなりません。

     index
          Returns the index in STRING if ITEM is found, or #f. This is the default behavior. ITEM が見つかった場合はSTRING 内でのインデックス、そうでなければ #f を返します。これがデフォルトの振る舞いです。

               (string-scan "abracadabra" "ada") => 5
               (string-scan "abracadabra" #\c) => 4
               (string-scan "abracadabra" "aba") => #f

     before
          Returns a substring of STRING before ITEM, or #f if ITEM is not found. ITEM よりも前にある STRING の部分文字列、あるいは ITEM が見つからなければ #f を返します。

               (string-scan "abracadabra" "ada" 'before) => "abrac"
               (string-scan "abracadabra" #\c 'before) => "abra"

     after
          Returns a substring of STRING after ITEM, or #f if ITEM is not found. ITEM より後ろにある STRING の部分文字列、あるいは ITEM が見つからなければ #f を返します。

               (string-scan "abracadabra" "ada" 'after) => "bra"
               (string-scan "abracadabra" #\c 'after) => "adabra"

     before*
          Returns a substring of STRING before ITEM, and the substring after it.  If ITEM is not found, returns (values #f #f). ITEM の前にある STRING の部分文字列と後ろにある STRING の部分文字列を返します。ITEM が見つからない場合は、 (values #f #f) を返します。

               (string-scan "abracadabra" "ada" 'before*)
                 => "abrac" and "adabra"
               (string-scan "abracadabra" #\c 'before*)
                 => "abra" and "cadabra"

     after*
          Returns a substring of STRING up to the end of ITEM, and the rest.  If ITEM is not found, returns (values #f #f). STRING のうち、ITEM の終端までの部分文字列とその残りを返します。ITEM が見つからなかった場合は、(values #f #f) を返します。

               (string-scan "abracadabra" "ada" 'after*)
                 => "abracada" and "bra"
               (string-scan "abracadabra" #\c 'after*)
                 => "abrac" and "adabra"

     both
          Returns a substring of STRING before ITEM and after ITEM.  If ITEM is not found, returns (values #f #f). STRING のうち、ITEM の前と ITEM の後ろの部分文字列を返します。ITEM が見つからない場合、 (values #f #f) を返します。

               (string-scan "abracadabra" "ada" 'both)
                 => "abrac" and "bra"
               (string-scan "abracadabra" #\c 'both)
                 => "abra" and "adabra"

 -- Function: string-split string splitter :optional grammar limit start end
 -- Function: string-split string splitter :optional limit start end
     [SRFI-152+] Splits STRING by SPLITTER and returns a list of strings. SPLITTER can be a character, a character set, a string, a regexp, or a procedure.

     If SPLITTER is a character or a string, it is used as a delimiter.  Note that srfi-152's string-split only allows strings for SPLITTER (it also interprets the first optional argument as a grammar; see below for the compatibility note.)

     If SPLITTER is a character set, any consecutive characters that are member of the character set are used as a delimiter.

     If a procedure is given to SPLITTER, it is called for each character in STRING, and the consecutive characters that caused SPLITTER to return a true value are used as a delimiter. STRING を SPLITTER で分割し、文字列のリストを返します。 SPLITTER には、文字、文字集合、文字列、正規表現、手続きが使えます。

     SPLITTER が文字か文字列の場合、それがそのままデリミタとして使われます。なお、srfi-152のstring-splitはデリミタとして文字列しか許しません。 (また、省略可能引数の最初のものは常にGRAMMARとして扱われます。後述する互換性への註を参照)。

     SPLITTER が文字集合の場合は、その文字集合に含まれる文字の連続がデリミタとして使われます。

     SPLITTER に手続きが与えられた場合、STRING にある各文字に対してその手続きが呼ばれ、SPLITTER が真の値を返すような連続した文字群がデリミタとして使われます。

          (string-split "/aa/bb//cc" #\/)    => ("" "aa" "bb" "" "cc")
          (string-split "/aa/bb//cc" "/")    => ("" "aa" "bb" "" "cc")
          (string-split "/aa/bb//cc" "//")   => ("/aa/bb" "cc")
          (string-split "/aa/bb//cc" #[/])   => ("" "aa" "bb" "cc")
          (string-split "/aa/bb//cc" #/\/+/) => ("" "aa" "bb" "cc")
          (string-split "/aa/bb//cc" #[\w])  => ("/" "/" "//" "")
          (string-split "/aa/bb//cc" char-alphabetic?) => ("/" "/" "//" "")

          ;; some boundary cases
          (string-split "abc" #\/) => ("abc")
          (string-split ""    #\/) => ("")

     The GRAMMAR argument is the same as string-join above; it must be one of symbols infix, strict-infix, prefix or suffix.  When omitted, infix is assumed. GRAMMAR引数の意味は上のstring-joinと同じです。シンボルinfix、strict-infix、prefix、 suffixのいずれかでなければなりません。省略時はinfixが指定されたのと同じです。

          (string-split "/a/b/c/" "/" 'infix)  => ("" "a" "b" "c" "")
          (string-split "/a/b/c/" "/" 'prefix) => ("a" "b" "c" "")
          (string-split "/a/b/c/" "/" 'suffix) => ("" "a" "b" "c")

     In general, the following relationship holds: 一般的に、以下の関係が成り立ちます。

          (string-join XS DELIM GRAMMAR) => S
          (string-split S DELIM GRAMMAR) => XS

     If LIMIT is given and not #f, it must be a nonnegative integer and specifies the maximum number of match to the SPLITTER. Once the limit is reached, the rest of string is included in the result as is. LIMIT引数が与えられた場合、それは#fか非負整数でなければなりません。非負整数の場合はSPLITTERがマッチするデリミタの最大数を指定します。デリミタがその数だけ見つかったら、残りの文字列は分割されずにそのまま結果に含められます。

          (string-split "a.b..c" "." 'infix 0)   => ("a.b..c")
          (string-split "a.b..c" "." 'infix 1)   => ("a" "b..c")
          (string-split "a.b..c" "." 'infix 2)   => ("a" "b" ".c")

     Compatibility note: The GRAMMAR argument is added for the consistency of srfis (srfi-130, srfi-152, see String library (reduced)). However, for the backward compatibility and the convenience, it also accepts LIMIT without GRAMMAR argument; it is distinguishable since GRAMMAR is a symbol and LIMIT is an integer. For the code that's compatible to srfi-152, use the first form that takes GRAMMAR argument. 互換性への註: GRAMMAR引数はsrfi-130およびsrfi-152(String library (reduced)参照) との一貫性のために追加されました。しかし、互換性および簡便性のため、GRAMMARを省略してLIMITを与えることもできます。GRAMMARはシンボルでLIMITは整数なので判別可能です。 srfi-152と互換性のあるコードを書く場合はGRAMMAR引数を取る最初の形式を使ってください。

          (string-split "a.b..c" "." 2)   => ("a" "b" ".c")

     The START and END arguments limits input string in the given range before splitting. STARTとEND引数は分割する前に入力文字列を指定の範囲に制限します。

     See also string-tokenize in (see SRFI-13 Other string operations). string-tokenize (SRFI-13 Other string operations) も参照して下さい。

 -- Function: string-map proc str str2 ...
 -- Function: string-map proc str :optional start end
     [R7RS base][SRFI-13] Applies PROC over each character in the input string, and gathers the characters returned from PROC into a string and returns it.  It is an error if PROC returns non-character.

     Because of historical reasons, this procedure has two interfaces. The first one takes one or more input strings, and PROC receives as many characters as the number of input strings, each character being taken from each string.  Iteration stops on the shortest string. This is defined in R7RS-small, and consistent with map, vector-map, etc.

     The second one takes only one string argument, and optional start/end arguments, which may be nonnegative integer indexes or string cursors to limit the input range of the string.  This is defined in srfi-13, string library.

     The order in which PROC is applied is not guaranteed to be left to right. You shouldn't depend on the order.

     If PROC saves a continuation and it is invoked later, the result already returned from string-map won't be affected (as specified in R7RS). 入力文字列中の各文字に対してPROCを適用し、その結果の文字を集めた文字列を返します。PROCは文字を返さねばなりません。

     歴史的経緯により、この手続きは2種類のインタフェースを持ちます。最初のインタフェースは1個以上の文字列を取ります。 PROCには文字列引数の数だけ、各文字列から取られた文字が渡されます。繰り返しは最も短い文字列でストップします。これはR7RS-smallで定義され、 map、vector-map等と一貫性があります。

     二番目のインタフェースでは、文字列引数はひとつだけで、省略可能なSTART/END 引数を取ります。STARTとENDは非負整数のインデックスか文字列カーソルで、入力文字列を使う範囲を制限します。

     PROCが適用される順序は左から右とは限りません。順序に依存しないようにしてください。

     PROCが継続を補足し、それが再び起動された場合、既にstring-mapから返された結果は影響を受けません。(R7RSで指定されています)

          (string-map char-upcate "apple") => "APPLE"
          (string-map (^[a b] (if (char>? a b) a b)) "orange" "apple") => "orpng"
          (string-map char-upcase "pineapple" 0 4) => "PINE"

 -- Function: string-for-each proc str str2 ...
 -- Function: string-for-each proc str :optional start end
     [R7RS base][SRFI-13] Applies PROC over each character in the input string in left-to-right order.  The results of PROC is discarded.

     Because of historical reasons, this procedure has two interfaces, first one defined in R7RS and second one defined in srfi-13. See string-map above for the explanation. PROCを入力文字列の各文字に左から右の順で適用します。PROCの結果は捨てられます。

     歴史的経緯から、この手続きは2種類のインタフェースを持ちます。最初のインタフェースはR7RSで、二番目のインタフェースはsrfi-13で定義されています。詳しくは上のstring-mapの項を参照してください。

Incomplete strings
------------------

A string can be flagged as "incomplete" if it may contain byte sequences that do not consist of a valid multibyte character in the Gauche's native encoding. Gaucheの内部エンコーディングで正当なマルチバイト文字で構成されていないようなバイト列を含む文字列は「不完全文字列」となります。

Incomplete strings may be generated in several circumstances; reading binary data as a string, reading a string data that has been 'chopped' in middle of a multibyte character, or concatenating a string with other incomplete strings, for example. 不完全文字列が生成される状況はいくつかあります。たとえば、バイナリデータを文字列として読み込んだとき、マルチバイト文字の途中で切れた文字列を読み込んだとき、別の不完全文字列が連結された場合などです。

Incomplete strings should be regarded as an exceptional case. It used to be a way to handle byte strings, but now we have u8vector (see Uniform vectors) for that purpose. In fact, we're planning to remove it in the future releases. 不完全文字列は例外的な状況であるとみなすべきです。これまではバイト列処理を使っていましたが、現在はu8vector (Uniform vectors参照)を使うことができますので、将来のリリースでは削除する計画です。

Just in case, if you happen to get an incomplete string, you can convert it to a complete string by string-incomplete->complete. 万が一、不完全文字列に出会ってしまったら string-incomplete->completeで完全な文字列に変換することができます。

 -- Reader Syntax: #**"..."
     Denotes incomplete string.  The same escape sequences as the complete string syntax are recognized. 不完全な文字列のリテラル表記です。完全な文字列と同様のエスケープシーケンスが使えます。

     Rationale of the syntax: #* is used for bit vectors. Since an incomplete strings is really a byte vector, it has similarity. #* という構文はCommon Lispでビットベクタの表記に使われています。不完全な文字列は実際はバイトベクタであることから、類似点を認めてこの構文を採用しました。

     Note: We used #*"...." for an incomplete string on 0.9.9 and before.  It turned out that it couldn't coexist with bitvectors, for #* is a valid bitvector literal (zero-length vector), and " is a delimiter, so #*"...." can be parsed as a zero-length bitvector followed by a string.  From 0.9.10, we changed the incomplete string literal to #**"...".  It's a bit lengthy, but incomplete strings are anomalies and shouldn't be used often anyway.

     For the backward compatibility, #*"..." is still read as an incomplete string literal, unless the reader lexical mode is strict-r7 (see Reader lexical mode, for the details). If the reader lexical mode is warn-legacy, it is read as an incomplete string, but a warning is issued. If the mode is strict-r7, it is read as a zero-length bitvector followed by a string.

     In future releasers, #*"..." would be warned by default, and later we'll gradually move to strict-r7 behavior. 註: 0.9.9までは、不完全文字列リテラルとして#*"..."を使っていました。しかし、それはビットベクタリテラルと共存できないことが判明しました。 #*は有効なビットベクタリテラル(長さ0のビットベクタ)で、また"はデリミタなので、#*"...."は長さ0のビットベクタと通常の文字列、とパーズできてしまいます。 0.9.10からは、不完全文字列リテラルは#**"..."になりました。ちょっと長いですが、もともと不完全文字列は例外的に現れるもので、積極的に使うべきではありません。

     後方互換性のため、デフォルトでは#*"..."はリーダー字句モードが strict-r7でない限りは不完全文字列リテラルとして読まれます。 (リーダー字句モードについてはReader lexical mode参照。) リーダ字句モードがwarn-legacyだった場合は、このリテラルは不完全文字列として読まれますが、警告が出されます。リーダ字句モードがstrict-r7であれば、このリテラルは長さ0のビットベクタと、通常の文字列として読まれます。

     将来のリリースでは、デフォルトで#*"..."は警告を出すようにし、その後strict-r7の振る舞いに移行する予定です。

 -- Function: string-incomplete->complete str :optional handling filler
     Reinterpret the content of an incomplete string STR and returns a newly created complete string from it. 不完全文字列STRの内容を再解釈して、あらたに完全文字列を返します。 The HANDLING argument specifies how to handle the illegal byte sequences in STR. HANDLING引数でSTR中の不正なバイト列の扱いかたを指定します。

     #f
          If STR contains an illegal byte sequence, give up the conversion and returns #f.  This is the default behavior. STRが不正なバイト列を含んでいる場合、変換を諦めて#fを返します。これがデフォルトのふるまいです。

     :omit
          Omit any illegal byte sequences. 不正なバイト列を捨てます。

     :replace
          Replace each byte in illegal byte sequences by a character given in FILLER argument, defaulted to ?.

     1文字
          不正なバイト列中の各バイトを、FILLER引数に与えられ文字で置き換えます。 FILLER引数のデフォルトは?です。

     :escape
          Replace each byte in illegal byte sequences by a sequence of FILLER <hexdigit> <hexdigit>. Besides, the FILLER characters in the original string is replaced with FILLER FILLER.

     1文字
          不正なバイト列中の各バイトを、FILLER <hexdigit> <hexdigit> の3文字で置き換えます。さらに、元文字列中にFILLERが登場した場合はそれぞれを FILLER FILLER で置き換えます。

     If STR is already a complete string, its copy is returned. STRが完全文字列なら、そのコピーが返されます。

     The procedure always returns a complete string, except when the HANDLING argument is #f (default) and the input is an incomplete string, in which case #f is returned. この手続きは、HANDLING引数が#f (デフォルト) で入力が不完全文字列だった場合に#fを返す以外は、常に完全文字列を返します。

     When Gauche's internal encoding is utf-8, the procedure works as follows: Gaucheの内部エンコーディングがutf-8であれば、この手続きは次のとおり動作します。

          (string-incomplete->complete #*"_abc")
            => "_abc"     ; can be represented as a complete string

          (string-incomplete->complete #*"_ab\x80;c")
            => #f        ; can't be represented as a complete string

          (string-incomplete->complete #*"_ab\x80;c" :omit)
            => "_abc"     ; omit the illegal bytes

          (string-incomplete->complete #*"_ab\x80;c" :replace #\_)
            => "_ab_c"    ; replace the illegal bytes

          (string-incomplete->complete #*"_ab\x80;c" :escape #\_)
            => "__ab_80c" ; escape the illegal bytes and escape char itself

Regular expressions
===================

Gauche has a built-in regular expression engine which is mostly upper-compatible of POSIX extended regular expression, plus some extensions from Perl 5 regexp.

A special syntax is provided for literal regular expressions. Also regular expressions are applicable, that is, it works like procedures that match the given string to itself. Combining with these two features enables writing some string matching idioms compact. GaucheはPOSIXの拡張正規表現にほぼ上位互換で、さらに Perl 5の正規表現から拡張機能を採り入れた正規表現エンジンを持っています。 Gaucheはまた、リテラル正規表現用の構文を備えています。

正規表現用のリテラル構文が用意されており、また、正規表現オブジェクトは適用可能、つまり文字列に対して手続きのように振る舞い、自分自身にマッチするかどうかを判定できるようになっています。この二つの機能によって、文字列のマッチをスキャンするようなイディオムを簡潔に書けるようになっています。

     (find #/pattern/ list-of-strings)
       => match object or #f

Regular expression syntax
-------------------------

 -- Reader Syntax: #/regexp-spec/
 -- Reader Syntax: #/regexp-spec/i
     Denotes literal regular expression object.  When read, it becomes an instance of <regexp>. リテラルの正規表現オブジェクトを表記します。読まれた際に<regexp>のインスタンスとなります。

     If a letter 'i' is given at the end, the created regexp becomes case-folding regexp, i.e. it matches in the case-insensitive way. 末尾に文字iが与えられた場合は、マッチ時に大文字小文字を区別しない正規表現オブジェクトとなります。

     The advantage of using this syntax over string->regexp is that the regexp is compiled only once.  You can use literal regexp inside loop without worrying about regexp compilation overhead. If you want to construct regexp on-the-fly, however, use string->regexp. string->regexpに対してこの構文を使う利点は、正規表現のコンパイルが一度しか行われない点です。この構文は、内部ループの中でも、正規表現のコンパイルのオーバヘッドを気にせずに使うことができます。動的に正規表現を作成したい場合のみstring->regexpを使って下さい。

Gauche's built-in regexp syntax follows POSIX extended regular expression, with a bit of extensions taken from Perl. (Scheme Regulare Expression (SRE) is also supported as an alternative syntax; see R7RS regular expressions, for the details of SRE.) Gaucheの組み込み正規表現構文はPOSIX拡張正規表現に準じたものに、 Perlの拡張の一部を採り入れたものです。 (別構文として、Scheme正規表現(SRE)もサポートされています。 SREについてはR7RS regular expressionsを参照してください。)

re*
     Matches zero or more repetition of re. reの0回以上の繰り返しにマッチします。

re+
     Matches one or more repetition of re. reの1回以上の繰り返しにマッチします。

re?
     Matches zero or one occurrence of re. reの0回または1回の出現にマッチします。

re{n}
re{n,m}
     Bounded repetition.  re{n} matches exactly n occurrences of re. re{n,m} matches at least N and at most M occurrences of re, where N <= M. In the latter form, either N or M can be omitted; omitted N is assumed as 0, and omitted M is assumed infinity. 回数に範囲のある繰り返しです。 re{n}はreのn回の繰り返しにマッチします。 re{n,m}はreのn回以上、m回以下の繰り返しにマッチします。但しN <= Mとします。 2番目の形式ではNかMのどちらかを省略することができます。Nが省略された場合は0とみなされます。 Mが省略された場合は無限大とみなされます。

re*?
re+?
re??
re{n,m}?
     Same as the above repetition construct, but these syntaxes use "non-greedy" or "lazy" match strategy.  That is, they try to match the minimum number of occurrences of re first, then retry longer ones only if it fails.  In the last form either N or M can be omitted. Compare the following examples: 上記の繰り返し構造とほぼ同じですが、これらの構文は「non-greedy」または「lazy」と呼ばれるマッチ戦略を用います。すなわち、まずreがマッチする最小の回数を試し、それが失敗したら順に繰り返しの回数を増やしてゆきます。最後の形式ではNかMのどちらかは省略できます。次の例を比べてみてください：

          (rxmatch-substring (#/<.*>/ "<tag1><tag2><tag3>") 0)
            => "<tag1><tag2><tag3>"

          (rxmatch-substring (#/<.*?>/ "<tag1><tag2><tag3>") 0)
            => "<tag1>"

(re...)
     Clustering with capturing.  The regular expression enclosed by parenthesis works as a single re.  Besides, the string that matches re ... is saved as a submatch. 捕捉クラスタリング。括弧でくくられた正規表現の列がグループとして扱われ、またそれにマッチした文字列はサブマッチとして保存されます。

(?:re...)
     Clustering without capturing.   re ... works as a single re, but the matched string isn't saved. 捕捉無しクラスタリング。re ...はグループとして扱われますが、サブマッチとして保存されません。

(?<name>re...)
     Named capture and clustering.  Like (re...), but adds the name name to the matched substring. You can refer to the matched substring by both index number and the name.

     When the same name appears more than once in a regular expression, it is undefined which matched substring is returned as the submatch of the named capture. 名前つきの捕捉とクラスタリング。(re...)と同様ですが、マッチした文字列に名前nameがつけられます。マッチした文字列にはインデックスの数字と名前のどちらでも参照できます。

     同じ名前が複数回正規表現内に出現した場合、どの名前付き捕捉にマッチした部分文字列が返されるかは不定です。

(?i:re...)
(?-i:re...)
     Lexical case sensitivity control. (?i:re...) makes re... matches case-insensitively, while (?-i:re...) makes re... matches case-sensitively.

     Perl's regexp allows several more flags to appear between '?' and ':'. Gauche only supports above two, for now. 大文字小文字の区別の制御。 (?i:re...)はre...が大文字小文字にかかわらずマッチするようにします。 (?-i:re...)はその逆です。

     Perlの正規表現では'?'と':'の間に他のいくつかのフラグを使うことができますが、Gaucheでは今のところこのフラグのみをサポートしています。

pattern1|pattern2|...
     Alternation.  Matches either one of patterns, where each pattern is re .... パターンのいずれかにマッチします。

\n
     Backreference.  n is an integer. Matches the substring captured by the n-th capturing group. (counting from 1).  When capturing groups are nested, groups are counted by their beginnings. If the n-th capturing group is in a repetition and has matched more than once, the last matched substring is used. バックリファレンス。nは整数です。 n番目(1から数える)の捕捉カッコに捕捉された文字列と一致する場合に、\nがマッチします。補足カッコがネストしている場合、開きカッコの順番で数えます。 n番目のカッコが繰り返しの中にあり、複数回マッチしている場合は、最後にマッチした文字列との比較が行われます。

\k<name>
     Named backreference.  Matches the substring captured by the capturing group with the name name. If the named capturing group is in a repetition and has matched more than once, the last matched substring is used. If there are more than one capturing group with name, matching will succeed if the input matches either one of the substrings captured by those groups. 名前によるバックリファレンス。名前nameを持つ捕捉カッコで捕捉された文字列と一致する場合に、 \k<name>がマッチします。参照しているカッコが繰り返しの中にあり、複数回マッチしている場合は、最後にマッチした文字列との比較が行われます。同じ名前nameを持つ捕捉カッコが複数ある場合には、それらのカッコの最後にマッチした文字列のいずれかと一致する場合、マッチが成功します。

.
     Matches any character (including newline). 任意の1文字にマッチします。改行文字にもマッチします。

[char-set-spec]
     Matches any of the character set specified by char-set-spec. See Character sets, for the details of char-set-spec. char-set-specで指定される文字集合内の文字にマッチします。 char-set-specについてはCharacter setsを参照して下さい。

\s, \d, \w
     Matches a whitespace character (char-set:ascii-whitespace, #[\u0009-\u000d ]), a digit character(char-set:ascii-digit, #[0-9]), or a word-constituent character (char-set:ascii-word, #[A-Za-z0-9_]), respectively. Note that they don't include characters outside ASCII range.

     Can be used both inside and outside of character set. それぞれ空白文字(char-set:ascii-whitespace, #[\u0009-\u000d ])、数字(char-set:ascii-digit, #[0-9])、単語を構成する文字(char-set:ascii-word, #[A-Za-z0-9_])にマッチします。 ASCIIの外の文字は含まれないことに注意してください。

     文字集合内でも、その外でも使えます。

\S, \D, \W
     Matches the complement character set of \s, \d and \w, respectively. それぞれ\s、\d、\wで指定される文字集合の補集合の文字にマッチします。

^, $
     Beginning and end of string assertion, when appears at the beginning or end of the pattern, or optionally, beginning and end of line in multi-line mode. それぞれ、パターンの最初または最後に指定された場合、文字列の最初か最後にマッチします。

     These characters loses special meanings and matches the characters themselves if they appear in the position other than the beginning of the pattern (for ^) or the end (for $).  For the sake of recognizing those characters, lookahead/lookbehind assertions ((?=...), (?!...), (?<=...), (?<!...)) and atomic clustering ((?>...)) are treated as if they are a whole pattern.  That is, ^ at the beginning of those groupings are beginning-of-string assertion no matter where these group appear in the containing regexp. So as $ at the end of these groupings. これらの文字は、パターンの最初(^の場合)か最後($の場合)に現れた時のみ特別な意味を持ち、それ以外の場所ではこれらの文字自身にマッチします。これらの文字を特殊文字と認識する段階では、肯定および否定の先読み ((?=...), (?!...), (?<=...), (?<!...))とアトミックなクラスタリング((?>...))はあたかもそれが独立したパターンであるかのように扱われます。つまり、^がこれらの構造の先頭に現れた場合は、これらの構造が全体の正規表現中のどこにあるかには関わらず、文字列先頭へのマッチとみなされます。$がこれらの構造の末尾に現れたば場合も同様です。

\b, \B
     Word boundary and non word boundary assertion, respectively. That is, \b matches an empty string between word-constituent character and non-word-constituent character, and \B matches an empty string elsewhere. \bは単語の境界の空文字列にマッチします。 \Bはその逆です。

\;
\"
\#
     These are the same as ;, ", and #, respectively, and can be used to avoid confusing Emacs or other syntax-aware editors that are not familiar with Gauche's extension. これらはそれぞれ;、"、および#と同じです。 Emacs等、Scheme構文を理解するエディタを混乱させないために使うことができます。

(?=pattern)
(?!pattern)
     Positive/negative lookahead assertion. Match succeeds if pattern matches (or does not match) the input string from the current position, but this doesn't move the current position itself, so that the following regular expression is applied again from the current position.

     For example, the following expression matches strings that might be a phone number, except the numbers in Japan (i.e. ones that begin with "81"). 肯定および否定の先読み。 patternが文字列の現在の位置にマッチする(あるいはマッチしない)ときにマッチが成功しますが、現在の位置は変更しないので、後に続く正規表現は現在と同じ位置から適用されます。

     例えば、次の表現は、電話番号のうち日本の番号("81"から始まるもの) を除く文字列にマッチします。

          \+(?!81)\d{9,}

(?<=pattern)
(?<!pattern)
     Positive/negative lookbehind assertion. If the input string immediately before the current input position matches PATTERN, this pattern succeeds or fails, respectively.   Like lookahead assertion, the input position isn't changed.

     Internally, this match is tried by reversing PATTERN and applies it to the backward of input character sequence.  So you can write any regexp in PATTERN, but if the submatches depend on the matching order, you may get different submatches from when you match PATTERN from left to right. 肯定および否定の後読み。現在の位置の左側にPATTERNにマッチする文字列がある場合にマッチが成功(あるいは失敗)します。先読みと同様、現在の位置は変更しません。

     内部的にこの表現は、patternを逆転させたうえで、現在の位置から左に向かってマッチを進めることで実現されています。したがって、 patternには任意のものにマッチする表現を含めることができますが、マッチの順番や長さが重要な場合(例えば2通りにマッチしうる捕捉のカッコ)などは、左から右に現在位置が進むときとは異なる場所にマッチするかもしれません。

(?>pattern)
     Atomic clustering.  Once pattern matches, the match is fixed; even if the following pattern fails, the engine won't backtrack to try the alternative match in pattern. アトミックなクラスタリング。patternがいったんマッチすると、そのマッチは確定します。後続のパターンが失敗した場合でも、 pattern内にバックトラックして他のマッチが試みられることはありません。

re*+
re++
re?+
     They are the same as (?>re*), (?>re+), (?>re?), respectively. それぞれ(?>re*)、(?>re+)、(?>re?)と同じです。

(?test-pattern then-pattern)
(?test-pattern then-pattern|else-pattern)
     Conditional matching.   If TEST-PATTERN counts true, THEN-PATTERN is tried; otherwise ELSE-PATTERN is tried when provided.

     TEST-PATTERN can be either one of the following:

     (integer)
          Backreference.  If INTEGER-th capturing group has a match, this test counts true.

     (?=pattern)
     (?!pattern)
          Positive/negative lookahead assertion.  It tries PATTERN from the current input position without consuming input, and if the match succeeds or fails, respectively, this test counts true.

     (?<=pattern)
     (?<!pattern)
          Positive/negative lookbehind assertion.  It tries PATTERN backward from the left size of the current input position, and if the match succeeds or fails, respectively, this test counts true.

     条件つきマッチング。TEST-PATTERNが成功すれば THEN-PATTERNへと、そうでなければ ELSE-PATTERNへと(もしあれば)マッチを進めます。

     TEST-PATTERNには以下の形式が書けます。

     (integer)
          バックリファレンス。INTEGER番目の捕捉クラスタリングのマッチに成功していた場合に成功となります。

     (?=pattern)
     (?!pattern)
          肯定および否定の先読み。入力の現在位置から、入力を消費することなく PATTERNのマッチを試み、それがそれぞれ成功もしくは失敗した場合に、このTEST-PATTERNを成功とみなします。

     (?<=pattern)
     (?<!pattern)
          肯定および否定の後読み。入力の現在位置から左側に向かって、 PATTERNの逆向きにマッチを試みます、それがそれぞれ成功もしくは失敗した場合に、このTEST-PATTERNを成功とみなします。

Using regular expressions
-------------------------

Regexp object and rxmatch object
................................

Regexpオブジェクトとrxmatchオブジェクト
..........................

 -- Builtin Class: <regexp>
     Regular expression object.  You can construct a regexp object from a string by string->regexp or sre->regexp at run time.  Gauche also has a special syntax to denote regexp literals, which construct regexp object at loading time.

     Gauche's regexp engine is fully aware of multibyte characters. 正規表現オブジェクトのクラスです。string->regexp あるいはsre->regexpを使って実行時に作成できます。また、Gaucheはリテラルの正規表現を表す構文を持っており、ロード時に作成することもできます。

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

 -- Builtin Class: <regmatch>
     Regexp match object.  A regexp matcher rxmatch returns this object if match.  This object contains all the information about the match, including submatches.

     The advantage of using match object, rather than substrings or list of indices, is efficiency.  The regmatch object keeps internal state of match, and computes indices and/or substrings only when requested.  This is particularly effective for multibyte strings, for index access is slow on them. 正規表現マッチオブジェクトのクラスです。正規表現エンジンrxmatchは、一致した場合にこのオブジェクトを返します。部分一致の情報を含めた全てのマッチに関する情報がこのオブジェクトに含まれています。

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

 -- Function: string->regexp string :key case-fold multi-line
     Takes STRING as a regexp specification, and constructs an instance of <regexp> object. 文字列STRINGを正規表現とみなして、<regexp>のインスタンスを作成して返します。

     If a true value is given to the keyword argument CASE-FOLD, the created regexp object becomes case-folding regexp. (See the above explanation about case-folding regexp). キーワード引数CASE-FOLDに真の値が与えられた場合、作成される正規表現は大文字小文字を区別しないものとなります。 (大文字小文字を区別しない正規表現に関しては上の説明を参照して下さい)。

     If a true value is given to the keyword argument MULTI-LINE, ^ and $ will assert the beginning and end of line in addition to beginning and end of string. Popular line terminators (LF only, CRLF and CR only) are recognized. キーワード引数MULTI-LINEに真の値が与えられた場合、 ^と$はそれぞれ入力文字列の最初と最後に加え、各行の先頭と末尾にもマッチします。行の区切りはLFのみ、CRLF、あるいはCRのみのいずれも認識されます。

 -- Function: sre->regexp sre :key multi-line
     Takes a scheme regexp SRE and returns a <regexp> object. The zero-th group is always captured.

     If a false value is given to the keyword argument MULTI-LINE, which is the default, bol and eol behave like bos and eos (i.e. only match at the beginning or end of string). Scheme正規表現 SRE を取り、コンパイルした<regexp>オブジェクトを返します。正規表現全体が常に0番の捕捉グループになります。

     キーワード引数MULTI-LINEに偽の値が与えられた場合 (デフォルト)、bolとeolはそれぞれbosとeosのように振る舞います (つまり、入力文字列の最初と最後にのみマッチします)。

 -- Function: regexp? OBJ
     Returns true iff OBJ is a regexp object. OBJが正規表現オブジェクトなら真の値を返します。

 -- Function: regexp->string REGEXP
     Returns a source string describing the regexp REGEXP. The returned string is immutable. 正規表現REGEXPを記述する元になった文字列を返します。返される文字列は変更不可な文字列です。

 -- Function: regexp->sre REGEXP
     Returns a scheme regexp (SRE) describing the regexp REGEXP. See R7RS regular expressions, for the details of SRE. 正規表現REGEXPを生成するScheme正規表現式(SRE)を返します。 SREについて詳しくはR7RS regular expressionsを参照してください。

 -- Function: regexp-num-groups regexp
 -- Function: regexp-named-groups regexp
     Queries the number of capturing groups, and an alist of named capturing groups, in the given REGEXP, respectively.

     The number of capturing groups corresponds to the number of matches returned by rxmatch-num-matches.  Note that the entire regexp forms a group, so the number is always positive.

     The alist returned from regexp-named-groups has the group name (symbol) in car, and its subgroup number in cdr. Note that the order of groups in the alist isn't fixed. 正規表現REGEXP中の、捕捉グループ(サブマッチに使われるグループ)の総数、及び名前つき捕捉グループのalistをそれぞれ返します。

     捕捉グループの総数は、この正規表現でマッチした場合のマッチオブジェクトの rxmatch-num-matchesと同じになります。正規表現全体もひとつのグループだとみなされるので、総数は常に1以上です。

     regexp-named-groupsから返されるalistは carに名前(シンボル)、cdrにそのサブマッチ番号を持つペアを要素とします。alist内でのグループの順番は不定です。

          (regexp-num-groups #/abc(?<foo>def)(ghi(?<bar>jkl)(mno))/)
            => 5
          (regexp-named-groups #/abc(?<foo>def)(ghi(?<bar>jkl)(mno))/)
            => ((bar . 3) (foo . 1))

Trying a match
..............

マッチを試みる
.......

 -- Function: rxmatch regexp string :optional start end
     REGEXP is a regular expression object. A string STRING is matched by REGEXP.  If it matches, the function returns a <regmatch> object.  Otherwise it returns #f. 正規表現オブジェクトREGEXPに一致するものを文字列STRINGから探します。一致が見付かった場合は<regmatch>オブジェクトを返し、見付からなかった場合は#fを返します。

     If START and/or END are given, only the substring between START (inclusive) and END (exclusive) is searched.

     This is called match, regexp-search or string-match in some other Scheme implementations. 他のScheme処理系ではこれは match、regexp-search、string-matchなど様々な名で呼ばれています。

     Internally, Gauche uses backtracking for regexp match. When regexp has multiple match possibilities, Gauche saves an intermediate result in a stack and try one choice, and if it fails try another.  Depending on regexp, the saved results may grow linear to the input.  Gauche allocates a fixed amount of memory for that, and if there are too many saved results, you'll get the following error: 内部的に、Gaucheは正規表現のマッチにバックトラックを使っています。複数のマッチの可能性がある場合、その時点の状態をスタックにセーブして一つの可能性を試し、だめだったら戻ってもう一つの可能性を試します。正規表現によっては、セーブする状態が入力の大きさに比例してしまう場合があります。セーブする状態が大きくなりすぎると、次のエラーが投げられます。

          ERROR: Ran out of stack during matching regexp #/.../. Too many retries?

     If you get this error, consider using hybrid parsing approach. Our regexp engine isn't made to do everything-in-one-shot parsing; in most cases, the effect of complex regexp can be achieved better with more powerful grammar than regular grammar. このエラーが起きた場合、他のパーズ手法を組み合わせることを検討してください。 Gaucheの正規表現エンジンはそれ一つで何もかもやってしまうことを目的として作られてはいません。多くの場合、複雑な正規表現を駆使するよりも、正規文法より強力な文法を使う方がうまくいきます。

     To apply the match repeatedly on the input string, or to match from the input stream (such as the data from the port), you may want to check grxmatch in gauche.generator (see Generator operations). 入力から複数のマッチを取り出したり、あるいはストリーム入力 (ポートから読み出すデータなど) にマッチをかけたい場合は、gauche.generatorモジュールのgrxmatch も使えるかもしれません (Generator operations参照)。

 -- Generic application: REGEXP STRING
     A regular expression object can be applied directly to the string. This works the same as (rxmatch REGEXP STRING), but allows shorter notation.   See Applicable objects, for generic mechanism used to implement this. 正規表現オブジェクトは直接文字列に対して適用することもできます。これは(rxmatch REGEXP STRING)と同じ動作をしますが、表記が短くて済みます。この機能はApplicable objects で述べているメカニズムを使って実装されています。

Accessing the match result
..........................

マッチの結果を取り出す
...........

 -- Function: rxmatch-start match :optional (i 0)
 -- Function: rxmatch-end match :optional (i 0)
 -- Function: rxmatch-substring match :optional (i 0)
     MATCH is a match object returned by rxmatch. If I equals to zero, the functions return start, end or the substring of entire match, respectively. With positive integer I, it returns those of I-th submatches.  It is an error to pass other values to I. rxmatchが返すマッチオブジェクトMATCHから情報を取り出します。 Iが省略されるか0の場合、これらの手続きはそれぞれ一致した文字列の開始インデックス、終了インデックス、および一致した部分文字列を返します。Iに正の整数が与えられた場合は、I番目のサブマッチに関する情報を返します。Iにシンボルが与えられた場合は、名前 Iを持つサブマッチの情報を返します。同じ名前Iを持つ複数のサブマッチがある場合には、成功したサブマッチの情報を返します。 Iにそれ以外の値を与えるのはエラーです。

     It is allowed to pass #f to MATCH for convenience. The functions return #f in such case. 簡便のために、MATCHに#fを渡すことも許されています。その場合、これらの手続きは#fを返します。

     These functions correspond to scsh's match:start, match:end and match:substring. これらの手続きはScshでmatch:start、match:end、 match:substringと呼ばれているものと等価です。

 -- Function: rxmatch-after match :optional (i 0)
 -- Function: rxmatch-before match :optional (i 0)
     Returns substring of the input string after or before MATCH. If optional argument is given, the I-th submatch is used (0-th submatch is the entire match). マッチオブジェクトMATCHの前および後の文字列を返します。正の整数がIに与えられた場合はi番目のサブマッチの前および後の文字列を返します。シンボルが与えられた場合は、その名前を持つサブマッチの前後の文字列を返します。

          (define match (rxmatch #/(\d+)\.(\d+)/ "pi=3.14..."))

          (rxmatch-after match) => "..."
          (rxmatch-after match 1) => ".14..."

          (rxmatch-before match) => "pi="
          (rxmatch-before match 2) => "pi=3."

 -- Function: rxmatch-substrings match :optional start end
 -- Function: rxmatch-positions match :optional start end
     Retrieves multiple submatches (again, 0-th match is the entire match), in substrings and in a cons of start and end position, respectively. 複数のサブマッチ (0番目のサブマッチはマッチ全体) を取り出す手続きです。それぞれ、部分文字列のリストと、開始位置と終了位置のコンスのリストが返されます。

          (rxmatch-substrings (#/(\d+):(\d+):(\d+)/ "12:34:56"))
            => ("12:34:56" "12" "34" "56")

          (rxmatch-positions (#/(\d+):(\d+):(\d+)/ "12:34:56"))
            => ((0 . 8) (0 . 2) (3 . 5) (6 . 8))

     For the convenience, you can pass #f to MATCH; those procedures returns () in that case. 簡便のために、MATCHに#fを渡すことも許されています。その場合、これらの手続きは()を返します。

     The optional START and END arguments specify the range of submatch index.  If omitted, START defaults to 0 and END defaults to (rxmatch-num-matches match). For example, if you don't need the whole match, you can give 1 to START as follows: 省略可能なSTARTとEND引数は取り出すサブマッチのインデックスの範囲を指定します。省略された場合、STARTは0、 ENDは(rxmatch-num-matches match)の値が使われます。例えばマッチ全体が不要なら、STARTに1を渡せば良いのです。

          (rxmatch-substrings (#/(\d+):(\d+):(\d+)/ "12:34:56") 1)
            => ("12" "34" "56")

 -- Function: rxmatch->string regexp string :optional selector ...
     A convenience procedure to match a string to the given regexp, then returns the matched substring, or #f if it doesn't match.

     If no SELECTOR is given, it is the same as this: 文字列に正規表現でマッチをかけ、マッチした文字列を得る、便利な関数です。マッチしなかった場合は#fが帰ります。

     SELECTORが与えられなかった場合、この手続きは次の式と同じです。

          (rxmatch-substring (rxmatch REGEXP STRING))

     If an integer is given as a selector, it returns the substring of the numbered submatch. SELECTORに整数が与えられた場合は、それで指定されるサブマッチの文字列が返されます。

     If a symbol after or before is given, it returns the substring after or before the match.  You can give these symbols and an integer to extract a substring before or after the numbered submatch. SELECTORにはシンボルafterかbeforeを与えることも出来ます。その場合は、マッチした文字列の前や後の文字列が返されます。これらのシンボルの後にさらにサブマッチを指定する整数を与えることもできます。

          gosh> (rxmatch->string #/\d+/ "foo314bar")
          "314"
          gosh> (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com" 2)
          "example.com"
          gosh> (rxmatch->string #/(\w+)@([\w.]+)/ "foo@example.com" 'before 2)
          "foo@"

 -- Generic application: REGMATCH :optional INDEX
 -- Generic application: REGMATCH 'before :optional INDEX
 -- Generic application: REGMATCH 'after :optional INDEX
     A regmatch object can be applied directly to the integer index, or a symbol before or after. They works the same as (rxmatch-substring REGMATCH INDEX), (rxmatch-before REGMATCH), and (rxmatch-after REGMATCH), respectively. This allows shorter notation.  See Applicable objects, for generic mechanism used to implement this. マッチオブジェクトは直接整数のインデックスもしくはシンボルに対して適用することができます。整数に適用したときは(rxmatch-substring REGMATCH INDEX)、シンボルbeforeのときは(rxmatch-before REGMATCH)、シンボル afterのときは(rxmatch-after REGMATCH)、そのほかのシンボルのときは (rxmatch-substring REGMATCH SYMBOL)と同じ動作をします。

     表記が短くて済みます。この機能はApplicable objects で述べているメカニズムを使って実装されています。

          (define match (#/(\d+)\.(\d+)/ "pi=3.14..."))

            (match)           => "3.14"
            (match 1)         => "3"
            (match 2)         => "14"

            (match 'after)    => "..."
            (match 'after 1)  => ".14..."

            (match 'before)   => "pi="
            (match 'before 2) => "pi=3."

          (define match (#/(?<integer>\d+)\.(?<fraction>\d+)/ "pi=3.14..."))

            (match 1)         => "3"
            (match 2)         => "14"

            (match 'integer)  => "3"
            (match 'fraction) => "14"

            (match 'after 'integer)   => ".14..."
            (match 'before 'fraction) => "pi=3."

 -- Function: rxmatch-num-matches match
 -- Function: rxmatch-named-groups match
     Returns the number of matches, and an alist of named groups and whose indices, in MATCH. This corresponds regexp-num-groups and regexp-named-groups on a regular expression that has been used to generate MATCH. These procedures are useful to inspect MATCH object without having the original regexp object.

     The number of matches includes the "whole match", so it is always a positive integer for a <regmatch> object.  The number also includes the submatches that don't have value (see the examples below). The result of rxmatch-named-matches also includes all the named groups in the original regexp, not only the matched ones.

     For the convenience, rxmatch-num-matches returns 0 and rxmatch-named-groups returns () if MATCH is #f. それぞれ、MATCHの持つマッチの数、および名前つきグループの名前とインデックスのalistを返します。これらは、MATCHを返した正規表現オブジェクトに対する regexp-num-groupsとregexp-named-groups手続きに対応します。元の正規表現オブジェクトなしに、MATCHの中身を調べたい時に便利です。

     返されるマッチの数には「マッチ全体」も含まれます。つまり、<regmatch>オブジェクトに対しては常に正の整数が返ることになります。値を持たないマッチもカウントされます(下の例を参照)。 rxmatch-named-matchesが返すalistについても、元の正規表現の持つ名前つきグループの情報がマッチの有無によらず返されます。

     簡便のために、MATCHに#fを渡すこともできます。その場合、rxmatch-num-matchesは0を、 rxmatch-named-groupsは()を返します。

          (rxmatch-num-matches (rxmatch #/abc/ "abc")) => 1
          (rxmatch-num-matches (rxmatch #/(a(.))|(b(.))/ "ba")) => 5
          (rxmatch-num-matches #f) => 0

          (rxmatch-named-groups
           (rxmatch #/(?<h>\d\d):(?<m>\d\d)(:(?<s>\d\d))?/ "12:34"))
           => ((s . 4) (m . 2) (h . 1))

Convenience utilities
.....................

便利なユーティリティ
..........

 -- Function: regexp-replace regexp string substitution
 -- Function: regexp-replace-all regexp string substitution
     Replaces the part of STRING that matched to REGEXP for SUBSTITUTION.  regexp-replace just replaces the first match of REGEXP, while regexp-replace-all repeats the replacing throughout entire STRING. STRING中でregexpにマッチした部分をSUBSTITUTIONで置き換えます。regexp-replaceは最初にマッチした部分のみを置き換え、 regexp-replace-allは全てのマッチを置き換えます。

     SUBSTITUTION may be a string or a procedure.  If it is a string, it can contain references to the submatches by digits preceded by a backslash (e.g. \2) or the named submatch reference (e.g. \k<NAME>. \0 refers to the entire match.  Note that you need two backslashes to include backslash character in the literal string; if you want to include a backslash character itself in the SUBSTITUTION, you need four backslashes. SUBSTITUTIONは文字列か手続きです。文字列の場合、バックスラッシュに続く数値、もしくは \k<NAME>という形式でサブマッチ文字列を参照できます \0はマッチ文字列全体を参照します。文字列リテラルにバックスラッシュを埋め込む場合は二つのバックスラッシュが必要であることに注意して下さい。バックスラッシュそのものをSUBSTITUTION中で使いたい場合は二つのバックスラッシュを重ねます; 文字列リテラルの場合は4つのバックスラッシュが必要になります。

          (regexp-replace #/def|DEF/ "abcdefghi" "...")
            => "abc...ghi"
          (regexp-replace #/def|DEF/ "abcdefghi" "|\\0|")
            => "abc|def|ghi"
          (regexp-replace #/def|DEF/ "abcdefghi" "|\\\\0|")
            => "abc|\\0|ghi"
          (regexp-replace #/c(.*)g/ "abcdefghi" "|\\1|")
            => "ab|def|hi"
          (regexp-replace #/c(?<match>.*)g/ "abcdefghi" "|\\k<match>|")
            => "ab|def|hi"

     If SUBSTITUTION is a procedure, for every match in STRING it is called with one argument, regexp-match object.  The returned value from the procedure is inserted to the output string using display. SUBSTITUTIONが手続きである場合、STRING中の各マッチについて、マッチオブジェクトを引数としてその手続きが呼ばれます。その手続きが返す値をdisplayで表現したものが置換文字列として使われます。

          (regexp-replace #/c(.*)g/ "abcdefghi"
                          (lambda (m)
                            (list->string
                             (reverse
                              (string->list (rxmatch-substring m 1))))))
           => "abfedhi"

     Note: regexp-replace-all applies itself recursively to the remaining of the string after match.  So the beginning of string assertion in REGEXP doesn't only mean the beginning of input string. 註: regexp-replace-all は文字列でマッチした部分の後ろの部分について再帰的に自分自身を適用します。従って、REGEXPが文字列先頭のアサーション (^) を含んでいても、それはSTRINGの先頭だけにマッチするとは限りません。

     Note: If you want to operate on multiple matches in the string instead of replacing it, you can use lrxmatch in gauche.lazy module or grxmatch in gauche.generator module.  Both can match a regexp repeatedly and lazily to the given string, and lrxmatch returns a lazy sequence of regmatches, while grxmatch returns a generator that yields regmatches. 註: 文字列中の、正規表現にマッチする部分すべてに対して何か操作をしたいが、置き換えた文字列が欲しいわけではない、という場合は、 gauche.lazyモジュールのlrxmatchや、 gauche.generatorモジュールのgrxmatchが使えるでしょう。これらは文字列に対して繰り返し正規表現でのマッチを、必要に応じて適用し、前者はマッチオブジェクトの遅延シーケンスを、後者はマッチオブジェクトを生成するジェネレータを返します。

          (map rxmatch-substring (lrxmatch #/\w+/ "a quick brown fox!?"))
           => ("a" "quick" "brown" "fox")

 -- Function: regexp-replace* string rx1 sub1 rx2 sub2 ...
 -- Function: regexp-replace-all* string rx1 sub1 rx2 sub2 ...
     First applies regexp-replace or regexp-replace-all to STRING with a regular expression RX1 substituting for SUB1, then applies the function on the result string with a regular expression RX2 substituting for SUB2, and so on.  These functions are handy when you want to apply multiple substitutions sequentially on a string. まず、regexp-replace あるいは regexp-replace-all を正規表現 RX1、置換 SUB1 で STRING に適用し、その結果にさらに regexp-replace あるいは regexp-replace-all を正規表現 RX2、置換 SUB2 で適用し、以下同様です。これらの関数はひとつの文字列上で複数回置換を行うときに便利です。

 -- Function: regexp-quote string
     Returns a string with the characters that are special to regexp escaped. STRING中で、正規表現において特別な意味を持つ文字を全てエスケープした文字列を返します。

          (regexp-quote "[2002/10/12] touched foo.h and *.c")
           => "\\[2002/10/12\\] touched foo\\.h and \\*\\.c"

In the following macros, MATCH-EXPR is an expression which produces a match object or #f. Typically it is a call of rxmatch, but it can be any expression. 以下のマクロにおいて、MATCH-EXPRはマッチオブジェクトか #fを生成する式でなければなりません。通常それは rxmatchを呼ぶ式になりますが、それだけに限られるわけではありません。

 -- Macro: rxmatch-let match-expr (var ...) form ...

     Evaluates MATCH-EXPR, and if matched, binds VAR ... to the matched strings, then evaluates FORMs. The first VAR receives the entire match, and subsequent variables receive submatches.  If the number of submatches are smaller than the number of variables to receive them, the rest of variables will get #f. MATCH-EXPRを評価し、それがマッチオブジェクトを返したら、マッチした文字列をVAR ...に束縛し、FORMを評価します。最初のVARはマッチした文字列全体に束縛され、以降の変数はサブマッチ文字列に束縛されます。実際のサブマッチ文字列が与えられた変数より少なかった場合は、余った変数は#fに束縛されます。

     It is possible to put #f in variable position, which says you don't care that match. 特定のマッチ文字列を受け取る必要が無いときは、その場所の変数の変わりに#fを置いておくこともできます。

          (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                                "Jan  1 23:59:58, 2001")
             (time hh mm ss)
            (list time hh mm ss))
           => ("23:59:58" "23" "59" "58")

          (rxmatch-let (rxmatch #/(\d+):(\d+):(\d+)/
                                "Jan  1 23:59:58, 2001")
             (#f hh mm)
            (list hh mm))
           => ("23" "59")

     This macro corresponds to scsh's let-match. このマクロはscshのlet-matchに相当します。

 -- Macro: rxmatch-if match-expr (var ...) then-form else-form
     Evaluates MATCH-EXPR, and if matched, binds VAR ... to the matched strings and evaluate THEN-FORM. Otherwise evaluates ELSE-FORM. The rule of binding VARs is the same as rxmatch-let. MATCH-EXPRを評価し、それがマッチオブジェクトを返したらマッチした文字列を変数VAR ...に束縛してTHEN-FORMを評価します。マッチオブジェクトが返されなければ束縛は行われず、 ELSE-FORMが評価されます。変数VARをマッチ文字列に束縛するルールはrxmatch-letと同じです。

          (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11:22:33")
              (time)
            (format #f "time is ~a" time)
            "unknown time")
           => "time is 11:22"

          (rxmatch-if (rxmatch #/(\d+:\d+)/ "Jan 1 11-22-33")
              (time)
            (format #f "time is ~a" time)
            "unknown time")
           => "unknown time"

     This macro corresponds to scsh's if-match. このマクロはscshのif-matchに相当します。

 -- Macro: rxmatch-cond clause ...
     Evaluate condition in CLAUSEs one by one. If a condition of a clause satisfies, rest portion of the clause is evaluated and becomes the result of rxmatch-cond. CLAUSE may be one of the following pattern. CLAUSEの条件を順に評価してゆき、条件を満たすものが現れたらそのCLAUSEの残りのフォームを評価し、最後のフォームの値を rxmatch-condの値とします。CLAUSEは以下のいずれかの形式でなければなりません。

     (MATCH-EXPR (VAR ...) FORM ...)
          Evaluate MATCH-EXPR, which may return a regexp match object or #f.  If it returns a match object, the matches are bound to VARs, like RXMATCH-LET, and FORMs are evaluated. MATCH-EXPRを評価し、それがマッチオブジェクトを返した場合はマッチ文字列を変数VAR ...に束縛した上で FORM ...を評価します。

     (test EXPR FORM ...)
          Evaluates EXPR.  If it yields true, evaluates FORMs. EXPRを評価し、それが真の値を返した場合はFORM ...を評価します。

     (test EXPR => PROC)
          Evaluates EXPR and if it is true, calls PROC with the result of EXPR as the only argument. EXPRを評価し、それが真の値を返した場合はそれを唯一の引数として手続きPROCを呼びます。

     (else FORM ...)
          If this clause exists, it must be the last clause. If other clauses fail, FORMs are evaluated. このCLAUSEは、もし与えられたとすれば最後のCLAUSEでなければなりません。全てのCLAUSEが失敗した場合に、FORM ...が評価されます。

     If no else clause exists, and all the other clause fail, an undefined value is returned. else CLAUSEが与えられず、かつ全てのCLAUSEが失敗した場合の戻り値は未定義です。

          ;; parses several possible date format
          ;; 何通りかの日付のフォーマットをパーズする
          (define (parse-date str)
            (rxmatch-cond
              ((rxmatch #/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ str)
                  (#f mm dd yyyy)
                (map string->number (list yyyy mm dd)))
              ((rxmatch #/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ str)
                  (#f yyyy mm dd)
                (map string->number (list yyyy mm dd)))
              ((rxmatch #/^\d+\/\d+\/\d+$/ str)
                  (#f)
               (errorf "ambiguous: ~s" str))
              (else (errorf "bogus: ~s" str))))

          (parse-date "2001/2/3") => (2001 2 3)
          (parse-date "12/25/1999") => (1999 12 25)

     This macro corresponds to scsh's match-cond. このマクロはscshのmatch-condに相当します。

 -- Macro: rxmatch-case string-expr clause ...
     STRING-EXPR is evaluated, and CLAUSEs are interpreted one by one.  A CLAUSE may be one of the following pattern. STRING-EXPRがまず評価され、続いてCLAUSEが順に検査されます。 CLAUSEは以下のいずれかの形式でなければなりません。

     (RE (VAR ...) FORM ...)
          RE must be a literal regexp object (see Regular expressions). If the result of STRING-EXPR matches RE, the match result is bound to VARs and FORMs are evaluated, and rxmatch-case returns the result of the last FORM. REはリテラル正規表現オブジェクトでなければなりません (Regular expressions参照)。STRING-EXPRの結果が文字列であり REにマッチした場合は、マッチ文字列が変数VAR ...に束縛され、FORMが評価されます。最後のFORMの値がrxmatch-case の値となります。

          If RE doesn't match the result of STRING-EXPR, STRING-EXPR yields non-string value, the interpretation proceeds to the next clause. STRING-EXPRの結果の文字列がREにマッチしないか、 STRING-EXPRの結果が文字列以外であった場合は次のCLAUSEへと処理が進みます。

     (test PROC FORM ...)
          A procedure PROC is applied on the result of STRING-EXPR. If it yields true value, FORMs are evaluated, and rxmatch-case returns the result of the last FORM. 手続きPROCがSTRING-EXPRの結果を引数として呼ばれます。それが真の値を返した場合はFORMが順に評価され、最後のFORMの値がrxmatch-caseの値として返されます。

          If PROC yields #f, the interpretation proceeds to the next clause. PROCが#fを返した場合は次のCLAUSEへと処理が進みます。

     (test PROC => PROC2)
          A procedure PROC is applied on the result of STRING-EXPR. If it yields true value, PROC2 is applied on the result, and its result is returned as the result of rxmatch-case. 手続きPROCがSTRING-EXPRの結果を引数として呼ばれます。それが真の値を返した場合は、その値を引数としてPROC2が呼ばれ、その返り値がrxmatch-caseの値として返されます。

          If PROC yields #f, the interpretation proceeds to the next clause. PROCが#fを返した場合は次のCLAUSEへと処理が進みます。

     (else FORM ...)
          This form must appear at the end of CLAUSEs, if any. If other clauses fail, FORMs are evaluated, and the result of the last FORM becomes the result of rxmatch-case. このフォームは、与えられる場合は最後のCLAUSEでなければなりません。他の全てのCLAUSEが失敗した場合に、FORMが順に評価され、最後のFORMの値がrxmatch-caseの値として返されます。

     (else => PROC)
          This form must appear at the end of CLAUSEs, if any. If other clauses fail, PROC is evaluated, which should yield a procedure taking one argument.  The value of STRING-EXPR is passed to PROC, and its return values become the return values of rxmatch-case. rx このフォームは、与えられる場合は最後のCLAUSEでなければなりません。他の全てのCLAUSEが失敗した場合に、PROCが評価されます。その値は一引数の手続きにならなければなりません。その手続きが、STRING-EXPRの値を引数として呼ばれます。 PROCの結果がrxmatch-caseの値となります。

     If no else clause exists, and all other clause fail, an undefined value is returned. else CLAUSEが与えられず、かつ全てのCLAUSEが失敗した場合の戻り値は未定義です。

     The parse-date example above becomes simpler if you use rxmatch-case 上のparse-dateの例はrxmatch-caseを使うとより単純になります。

          (define (parse-date2 str)
            (rxmatch-case str
              (test (lambda (s) (not (string? s))) #f)
              (#/^(\d\d?)\/(\d\d?)\/(\d\d\d\d)$/ (#f mm dd yyyy)
               (map string->number (list yyyy mm dd)))
              (#/^(\d\d\d\d)\/(\d\d?)\/(\d\d?)$/ (#f yyyy mm dd)
               (map string->number (list yyyy mm dd)))
              (#/^\d+\/\d+\/\d+$/                (#f)
               (errorf "ambiguous: ~s" str))
              (else (errorf "bogus: ~s" str))))

Inspecting and assembling regular expressions
---------------------------------------------

When Gauche reads a string representation of regexp, first it parses the string and construct an abstract syntax tree (AST), performs some optimizations on it, then compiles it into an instruction sequence to be executed by the regexp engine. Gaucheはregexpの文字列表記を読むと、その文字列をパーズして抽象構文木 (AST) を作り、それにいくらかの最適化を施したのち、正規表現エンジンで実行されるインストラクション列へとコンパイルします。

The following procedures expose this process to user programs.  It may be easier for programs to manipulate an AST than a string representation. 以下の手続きはこのプロセスをユーザプログラムに見せるものです。プログラム的に正規表現をいじる場合は、文字列形式よりも ASTの方が扱いやすいでしょう。

 -- Function: regexp-parse string :key case-fold multi-line
     Parses a string specification of regexp in STRING and returns its AST, represented in S-expression. See below for the spec of AST. 正規表現の文字列表記であるSTRINGをパーズし、S式で表現された ASTを返します。ASTの仕様は下で述べます。

     When a true value is given to the keyword argument CASE-FOLD, returned AST will match case-insensitively. (Case insensitive regexp is handled in parser level, not by the engine). CASE-FOLDキーワード引数に真の値が与えられた場合は、大文字小文字を区別せずにマッチを行うASTが変えされます (エンジン自体に「大文字小文字を区別しない」モードがあるわけではなく、パーザの段階で異なるASTが生成されます。)

 -- Function: regexp-parse-sre sre
     Parses SRE as a Scheme Regular Expression (SRE) as described in SRFI-115 and returns its AST. See R7RS regular expressions SREをsrfi-115で定義されるScheme正規表現(SRE)としてパーズし、結果をASTで返します。 SREについて詳しくはR7RS regular expressionsを参照してください。 see R7RS regular expressions.

 -- Function: regexp-optimize ast
     Performs some rudimental optimization on the regexp AST, returning regexp AST.

     Currently it only optimizes some trivial cases.  The plan is to make it cleverer in future. 正規表現のASTに対して、いくつかの原始的な最適化を施して結果のASTを返します。

     現在のところ、最適化はごく簡単なものです。将来はもっと賢くする予定です。

 -- Function: regexp-compile ast :key multi-line
     Takes a regexp AST and returns a regexp object. Currently the outermost form of AST must be the zero-th capturing group.  (That is, AST should have the form (0 #f X ...).) The outer grouping is always added by regexp-parse to capture the entire regexp. 正規表現のASTを受け取り、マッチに使える正規表現オブジェクトを返します。渡されるASTの一番外側は、0番めの捕捉グループでなければなりません (ASTは(0 #f X ...)という形でなければならない、ということです)。regexp-parseは常にこの捕捉グループを追加します。正規表現にマッチした全体の文字列を捕捉するためです。

     Note: The function does some basic check to see the given AST is valid, but it may not reject invalid ASTs.  In such case, the returned regexp object doesn't work properly.  It is caller's responsibility to provide a properly constructed AST. (Even if it rejects an AST, error messages are often incomprehensible.  So, don't use this procedure as a AST validness checker.) 註：この関数は渡されたASTが有効なものであるかどうかについて簡単なチェックを行いますが、有効でないASTを受け入れてしまうかもしれません。その場合、変えされる正規表現オブジェクトの動作は不定です。正しい形式のASTを渡すのは呼出側の責任です (この関数が有効でないASTを見つけてエラーにする場合でも、そのエラーメッセージからどこがおかしいかを判断するのが難しい場合があります。この手続きをASTが有効であるかどうかのチェッカーとして使うのは避けましょう。)

 -- Function: regexp-ast regexp
     Returns AST used for the regexp object REGEXP. 正規表現オブジェクトREGEXPが使っているASTを返します。

 -- Function: regexp-unparse ast :key (on-error :error)
     From the regexp's AST, reconstruct the string representation of the regexp.  The keyword argument ON-ERROR can be a keyword :error (default) or #f.  If it's the former, an error is signaled when AST isn't valid regexp AST. If it's the latter, regexp-unparse just returns #f. 正規表現のASTから、その正規表現の文字列表記を再構成して返します。キーワード引数ON-ERRORは、キーワード:error (デフォルト) もしくは#fです。それが:errorの場合、ASTが不正であればエラーが報告され、#fの場合はregexp-unparseから #fが返されます。

This is the structure of AST.  Note that this is originally developed only for internal use, and not very convenient to manipulate from the code (e.g. if you insert or delete a subtree, you have to renumber capturing groups to make them consistent.) 以下にASTの構造を示します。この仕様は当初、内部的に使うためだけに設計されたので、コードで直接いじるのには若干不便です (例えば、部分木を削除したり追加した場合、捕捉グループの番号を振りなおして一貫性を保つ必要があるかもしれません。)

     <ast> : <clause>   ; special clause
           | <item>     ; matches <item>

     <item> : <char>       ; matches char
            | <char-set>   ; matches char set
            | (comp . <char-set>) ; matches complement of char set
            | any          ; matches any char
            | bos | eos    ; beginning/end of string assertion
            | bol | eol    ; beginning/end of line assertion
            | bow | eow | wb | nwb ; word-boundary/negative word boundary assertion
            | bog | eog    ; beginning/end of grapheme assertion

     <clause> : (seq <ast> ...)       ; sequence
            | (seq-uncase <ast> ...)  ; sequence (case insensitive match)
            | (seq-case <ast> ...)    ; sequence (case sensitive match)
            | (alt <ast> ...)         ; alternative
            | (rep <m> <n> <ast> ...) ; repetition at least <m> up to <n> (greedy)
                                    ; <n> may be `#f'
            | (rep-min <m> <n> <ast> ...)
                                    ; repetition at least <m> up to <n> (lazy)
                                    ; <n> may be `#f'
            | (rep-while <m> <n> <ast> ...)
                                    ; like rep, but no backtrack
            | (<integer> <symbol> <ast> ...)
                                    ; capturing group.  <symbol> may be #f.
            | (cpat <condition> (<ast> ...) (<ast> ...))
                                    ; conditional expression
            | (backref . <integer>) ; backreference by group number
            | (backref . <symbol>)  ; backreference by name
            | (once <ast> ...)      ; standalone pattern.  no backtrack
            | (assert . <asst>)     ; positive lookahead assertion
            | (nassert . <asst>)    ; negative lookahead assertion

     <condition> : <integer>     ; (?(1)yes|no) style conditional expression
            | (assert . <asst>)  ; (?(?=condition)...) or (?(?<=condition)...)
            | (nassert . <asst>) ; (?(?!condition)...) or (?(?<!condition)...)

     <asst> : <ast> ...
            | ((lookbehind <ast> ...))

Vector family
=============

Vectors are fixed-size, O(1) accessible sequence of values. Scheme has traditionally offered a vector of arbitrary objects, which is described in Vectors.

In R7RS-large, there're also homogeneous numeric vectors (uvectors), which can contain fixed range of numeric objects efficiently. We explain them in Uniform vectors.

Gauche also supports bitvectors, which can contain sequence of bits. See Bitvectors, for the details.

Finally, weak vectors are a vector of arbitrary objects using weak pointers.  See Weak vectors. ベクタは固定長でO(1)アクセス可能な値の並びです。 Schemeは伝統的に、任意の値を格納できるベクタを提供してきました。これはVectorsで説明されます。

R7RS-largeでは、均質な数値型だけを効率よく格納できるベクタ(uvector)も定義されています。 Uniform vectorsを見てください。

Gaucheはまた、ビット列を格納するビットベクタも提供します。 Bitvectorsで説明します。

最後に、weakベクタは任意の要素をweakポインタを使って格納できるベクタです。 Weak vectors参照。

Vectors
-------

 -- Builtin Class: <vector>
     A vector is a simple 1-dimensional array of Scheme objects. You can access its element by index in constant time. Once created, a vector can't be resized.

     Class <vector> inherits <sequence> and you can use various generic functions such as map and fold on it.   See Collection framework, and see Sequence framework.

     If you keep only a homogeneous numeric type, you may be able to use SRFI-4 homogeneous vectors (see Homogeneous vectors).

     R7RS defines bytevectors; in Gauche, they're just u8vectors in gauche.uvector module (r7rs modules defines aliases. see R7RS base library).

     See R7RS vectors, for additional operations on vectors. ベクタはSchemeオブジェクトの単純な一次元配列です。インデックスを用いて定数時間でその要素にアクセスできます。一度作成されたベクタはその大きさを変えることはできません。

     <vector>クラスはまた<sequence>クラスを継承し、 mapやfoldなど様々な総称関数を使うことができます。 Collection framework と Sequence framework を参照して下さい。

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

     R7RSはバイトベクタを定義しています。Gaucheではそれは単に gauche.uvectorモジュールのu8vectorです (R7RSモジュールは別名を定義しています。R7RS base library参照。)

     より多くのベクタに対する操作がR7RS vectorsで提供されています。

 -- Function: vector? obj
     [R7RS base] Returns #t if OBJ is a vector, #f otherwise. OBJがベクタなら#tを、そうでなければ#fを返します。

 -- Function: make-vector k :optional fill
     [R7RS base] Creates and returns a vector with length K. If optional argument FILL is given, each element of the vector is initialized by it.  Otherwise, the initial value of each element is undefined. 長さKのベクタを作成して返します。省略可能な引数FILLが与えられていれば、ベクタの各要素はその値で初期化されます。そうでなければベクタの各要素の値は不定です。

 -- Function: vector obj ...
     [R7RS base] Creates a vector whose elements are OBJ .... 要素がOBJ ...であるようなベクタを作成して返します。

 -- Function: vector-tabulate len proc
     Creates a vector of length LEN, initializing I-th element of which by (PROC I) for all I between 0 and LEN 長さLENのベクタを作成し、0以上LEN未満のIについて I番目の要素を(PROC I)の値で初期化します。

          (vector-tabulate 5 (^x (* x x)))
            => #(0 1 4 9 16)

 -- Function: vector-length vector
     [R7RS base] Returns the length of a vector VECTOR.

     With gauche.collection module, you can also use a method size-of. ベクタVECTORの長さを返します。

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

 -- Function: vector-ref vector k :optional fallback
     [R7RS+] Returns K-th element of vector VECTOR.

     By default, vector-ref signals an error if K is negative, or greater than or equal to the length of VECTOR. However, if an optional argument FALLBACK is given, it is returned for such case.  This is an extension of Gauche.

     With gauche.sequence module, you can also use a method ref. ベクタVECTORのK番目の要素を返します。

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

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

 -- Function: vector-set! vector k obj
     [R7RS base] Sets K-th element of the vector VECTOR to OBJ. It is an error if K is negative or greater than or equal to the length of VECTOR.

     With gauche.sequence module, you can also use a setter method of ref. ベクタVECTORのK番目の要素をOBJに変更します。 Kが負数であったりベクタの長さより大きい場合はエラーとなります。

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

 -- Function: vector->list vector :optional start end
 -- Function: list->vector list :optional start end
     [R7RS+] Converts a vector to a list, or vice versa.

     The optional START and END arguments limit the range of the source. (R7RS don't define START and END arguments for list->vector.) ベクタをリストに変換したり、その逆を行う手続きです。

     省略可能な引数STARTとENDを与えることにより、値を取り出す範囲を制限することができます。 (R7RSのlist->vectorはSTARTとEND引数を規定していません。)

          (vector->list '#(1 2 3 4 5))     => (1 2 3 4 5)
          (list->vector '(1 2 3 4 5))      => #(1 2 3 4 5)
          (vector->list '#(1 2 3 4 5) 2 4) => (3 4)
          (list->vector (circular-list 'a 'b 'c) 1 6)
            => #(b c a b c)

     With GAUCHE.COLLECTION module, you can use (coerce-to <list> VECTOR) and (coerce-to <vector> LIST) as well. gauche.collectionモジュールをロードしていれば、 (coerce-to <list> VECTOR) と (coerce-to <vector> LIST) も同じ目的で使えます。

 -- Function: reverse-list->vector list :optional start end
     [R7RS vector] Without optional arguments, it returns the same thing as (list->vector (reverse list)), but does not allocate the intermediate list.   The optional START and END argument limits the range of the input list. 省略可能引数が無い場合、 (list->vector (reverse list))と同じ結果を返しますが、中間リストを作りません。省略可能引数STARTおよびENDが与えられた場合は、それはLISTの範囲を指定します。

          (reverse-list->vector '(a b c d e f g) 1 5)
            => #(e d c b)

 -- Function: vector->string vector :optional start end
 -- Function: string->vector string :optional start end
     [R7RS base] Converts a vector of characters to a string, or vice versa. It is an error to pass a vector that contains other than characters to vector->string.

     The optional START and END arguments limit the range of the source. 文字のベクタを文字列に変換したり、その逆を行う手続きです。 vector->stringに、文字以外の要素を含むベクタを渡した場合はエラーになります。

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

          (vector->string '#(#\a #\b #\c #\d #\e))     => "abcde"
          (string->vector "abcde")                     => #(#\a #\b #\c #\d #\e)
          (vector->string '#(#\a #\b #\c #\d #\e) 2 4) => ("cd")

     With GAUCHE.COLLECTION module, you can use (coerce-to <string> VECTOR) and (coerce-to <vector> STRING) as well. gauche.collectionモジュールをロードしていれば、 (coerce-to <string> VECTOR) と (coerce-to <vector> STRING) も同じ目的で使えます。

 -- Function: vector-fill! vector fill :optional start end
     [R7RS base] Sets all elements in a vector VECTOR to FILL.

     Optional START and END limits the range of effect between START-th index (inclusive) to END-th index (exclusive).  START defaults to zero, and END defaults to the length of VECTOR. ベクタVECTORの全ての要素をFILLに変更します。

     省略可能な引数STARTとENDが与えられた場合、 START番目の要素からEND-1番目の要素までのみに FILLを格納します。STARTとENDの既定値はそれぞれ0とVECTORの大きさです。

 -- Function: vector-copy vector :optional start end fill
     [R7RS base] Copies a vector VECTOR.  Optional START and END arguments can be used to limit the range of VECTOR to be copied. If the range specified by START and END falls outside of the original VECTOR, the FILL value is used to fill the result vector. ベクタVECTORをコピーします。引数STARTとENDを与えることでコピーされる範囲を制限することができます。 STARTとENDで指定される範囲が元のVECTORの範囲を越えた場合は、その部分がFILLで埋められます。

          (vector-copy '#(1 2 3 4 5))     => #(1 2 3 4 5)
          (vector-copy '#(1 2 3 4 5) 2 4) => #(3 4)
          (vector-copy '#(1 2 3 4 5) 3 7 #f) => #(4 5 #f #f)

 -- Function: vector-copy! target tstart source :optional sstart send
     [R7RS base] Copies the content of SOURCE vector into the TARGET vector starting from TSTART in the target.  The TARGET vector must be mutable. Optional SSTART and SEND limits the range of source vector. ベクタSOURCEの内容をベクタTARGETのインデックスTSTART以降にコピーします。TARGETは変更可能でなければなりません。省略可能なSSTARTとSEND引数はコピー元ベクタの範囲を限定します。

          (rlet1 v (vector 'a 'b 'c 'd 'e)
            (vector-copy! v 2 '#(1 2)))
            => #(a b 1 2 e)
          (rlet1 v (vector 'a 'b 'c 'd 'e)
            (vector-copy! v 2 '#(1 2 3 4) 1 3))
            => #(a b 2 3 e)

     An error is raised if the portion to be copied is greater than the room in the target (that is, between TSTART to the end). コピーされるデータが、コピー先の領域(TSTARTから末尾まで)より大きい場合はエラーが報告されます。

     It is ok to pass the same vector to TARGET and SOURCE; it always works even if the regions of source and destination are overlapping. TARGETとSOURCEに同じベクタを渡しても構いません。コピー元とコピー先の領域に重なりがある場合でもこの手続きは使えます。

 -- Function: vector-append vec ...
     [R7RS base] Returns a newly allocated vector whose contents are concatenation of elements of VEC in order. ベクタVECを順に継ぎ足した内容を持つベクタを新たに作成して返します。

          (vector-append '#(1 2 3) '#(a b)) => #(1 2 3 a b)
          (vector-append) => #()

 -- Function: vector-map proc vec1 vec2 ...
     [R7RS base] Returns a new vector, I-th of which is calculated by applying PROC on the list of each I-th element of VEC1 VEC2 .... The length of the result vector is the same as the shortest vector of the arguments. ベクタVEC1 VEC2 ...の各I番目の要素にPROCを適用したものをI番目の要素とする新たなベクタを作って返します。結果のベクタの長さは、引数のベクタのうち最も短いものと同じになります。

          (vector-map + '#(1 2 3) '#(4 5 6 7))
           => #(5 7 9)

     The actual order PROC is called is undefined, and may change in the future versions, so PROC shouldn't use side effects affected by the order. PROCが呼ばれる順番は定義されておらず、将来のバージョンで変わるかもしれないので、 PROCでは順序に影響されるような副作用を起こしてはいけません。

     Note: If you use gauche.collection, you can get the same function by (map-to <vector> proc vec1 vec2 ...). 註: gauche.collectionをuseして (map-to <vector> proc vec1 vec2 ...) としても同じ機能は得られます。

 -- Function: vector-map-with-index proc vec1 vec2 ...
     Like vector-map, but PROC receives the current index as the first argument. vector-mapと似ていますが、PROCの第1引数に現在のインデックスが渡されます。

          (vector-map-with-index list '#(a b c d e) '#(A B C))
           => #((0 a A) (1 b B) (2 c C))

     This is what SRFI-43 calls vector-map.  See Vector library (Legacy). これがSRFI-43でvector-mapと呼ばれている手続きです。 Vector library (Legacy)参照。

     Note: If you use gauche.collection, you can get the same function by (map-to-with-index <vector> proc vec1 vec2 ...). 註: gauche.collectionをuseして (map-to-with-index <vector> proc vec1 vec2 ...) としても同じ機能は得られます。

 -- Function: vector-map! proc vec1 vec2 ...
     [R7RS vector] For each index I, calls PROC with I-th index of VEC1 VEC2 ..., and set the result back to VEC1.  The value is calculated up to the minimum length of input vectors. 各インデックスIについて、ベクタVEC1 VEC2 ...の I番目の要素を引数としてPROCを呼び出した結果、VEC1の I番目の要素にセットします。ベクタの長さが異なる場合は最も短いベクタの範囲が計算されます。

          (rlet1 v (vector 1 2 3)
            (vector-map! ($ + 1 $) v))
            => #(2 3 4)

          (rlet1 v (vector 1 2 3 4)
            (vector-map! + v '#(10 20)))
            => #(11 22 3 4)

 -- Function: vector-map-with-index! proc vec1 vec2 ...
     Like vector-map!, but PROC receives the current index as the first argument.  This is equivalent to SRFI-43's vector-map! (see Vector library (Legacy)). vector-map!と似ていますが、PROCの第1引数に現在のインデックスが渡されます。SRFI-43でvector-map! と定義されているものと同じ動作です (Vector library (Legacy)参照)。

          (rlet1 v (vector 'a 'b 'c)
            (vector-map-with-index! list v))
            => #((0 a) (1 b) (2 c))

 -- Function: vector-for-each proc vec1 vec2 ...
     [R7RS base] For all I below the minimum length of input vectors, calls PROC with I-th elements of VEC1 VEC2 ..., in increasing order of I. 0から渡されたベクタのうち一番短いものの最大のインデックスまでのIについて、 VEC1 VEC2 ...のそれぞれI番目の要素を引数に PROCを呼び出します。

          (vector-for-each print '#(a b c))
           => prints a, b and c.

 -- Function: vector-for-each-with-index proc vec1 vec2 ...
     Like vector-for-each, but PROC receives the current index in the first argument.

     This is equivalent to SRFI-43's vector-for-each. See Vector library (Legacy). vector-for-eachと似ていますが、PROCの第1引数に現在のインデックスが渡されます。

     この手続きはSRFI-43のvector-for-eachと等価です。 Vector library (Legacy)参照。

Uniform vectors
---------------

Uniform vectors, or homogeneous numeric vectors, are a special type of vectors whose elements are of the same numeric type. It was introduced originally as srfi-4, revised by srfi-160, and now a part of R7RS large (as scheme.vector.@). ユニフォームベクタ、あるいは同質な数値ベクタは、要素として特定の数値型のみを格納する特別なベクタです。もともとsrfi-4として導入され、srfi-160で改訂されたのち、 R7RS largeの一部となりました(scheme.vector.@モジュール)。

The @ part is actually one of the following tags, indicating the type of elements: @の部分は実際には要素の型を示す以下のタグのいずれかです。

u8
     Unsigned 8-bit integer - an exact integer between 0 and 255. 8ビット符号無し整数 - 0から255までの正確な整数。

s8
     Signed 8-bit integer - an exact integer between -128 and 127. 8ビット符号つき整数 - -128から127までの正確な整数。

u16
     Unsigned 16-bit integer - an exact integer between 0 and 65535. 16ビット符号無し整数 - 0から65535までの正確な整数。

s16
     Signed 16-bit integer - an exact integer between -32678 and 32767. 16ビット符号つき整数 - -32768から32767までの正確な整数。

u32
     Unsigned 32-bit integer - an exact integer between 0 and 2^32 - 1. 32ビット符号無し整数 - 0から 2^32 - 1 までの正確な整数。

s32
     Signed 32-bit integer - an exact integer between -(2^31) and 2^31 - 1. 32ビット符号つき整数 - -(2^31) から 2^31 - 1 までの正確な整数。

u64
     Unsigned 64-bit integer - an exact integer between 0 and 2^64 - 1. 64ビット符号無し整数 - 0から 2^64 - 1 までの正確な整数。

s64
     Signed 64-bit integer - an exact integer between -(2^63) and 2^63 - 1. 64ビット符号つき整数 - -(2^63) から 2^63 - 1 までの正確な整数。

f16
     16-bit floating point number (10-bit mantissa and 5-bit exponent), as inexact real. 16ビット浮動小数点数(仮数部10ビット、指数部5ビット)で表される不正確な実数

f32
     IEEE single-precision floating point number as inexact real. IEEE単精度浮動小数点数で表される不正確な実数

f64
     IEEE double-precision floating point number as inexact real. IEEE倍精度浮動小数点数で表される不正確な実数

c32
     Inexact complex, consists of a pair of 16-bit floating point numbers. 2つの16ビット浮動小数点数で表される不正確な複素数

c64
     Inexact complex, consists of a pair of IEEE single-precision floating point numbers. 2つのIEEE単精度浮動小数点数で表される不正確な複素数

c128
     Inexact complex, consists of a pair of IEEE double-precision floating point numbers. 2つのIEEE倍精度浮動小数点数で表される不正確な複素数

There are some advantages of using uniform vectors over normal (heterogeneous) vectors.  It may be more compact than the normal vectors.  Some operations (especially Gauche's extension of vector arithmetic operations) can bypass type check and conversion of individual elements, thus be more efficient.  And it is much easier and efficient to communicate with external libraries that require homogeneous array of numbers; for example, OpenGL binding of Gauche uses uniform vectors extensively. 通常のベクタではなくユニフォームベクタを使うことにより得られる利点がいくつかあります。まず、ユニフォームベクタは通常のベクタよりもコンパクトです。いくつかのオペレーション(特に、Gaucheの拡張仕様であるベクタ上の数値演算)では、型検査と型変換を個々の要素に対して行わなくても良いため、極めて効率の良い演算が可能です。さらに、数値の配列を扱う外部のライブラリとのインタフェースが容易です。例えば、GaucheのOpenGLバインディングではユニフォームベクタを多用しています。

Gauche has only a handful primitive operations on uniform vectors as a built-in, but the gauche.uvector module, or scheme.vector.@ module ((scheme vector @) library in R7RS programs), provide a complehensive set of operations. See Uniform vector library, and see R7RS uniform vectors. Gaucheは組み込みではごく基本的な手続きしか提供しませんが、 gauche.uvectorモジュールやscheme.vector.@モジュール (R7RSでは(scheme vector @)ライブラリ)では包括的な操作を提供しています。 Uniform vector libraryおよびR7RS uniform vectors参照。

Uvector classes
...............

uvectorクラス
..........

 -- Abstract Class: <uvector>
     The base class of uniform vector classes.  It inherits <sequence> (see Sequence framework). ユニフォームベクタクラスのベースクラスです。<sequence>を継承します (Sequence framework参照)。

 -- Builtin Class: <@vector>
     A class for @vector, where @ is one of the uvector tags (u8, s8, ...). It inherits <uvector>.

     It implements sequence protocol (see Sequence framework)), so you can convert a sequence of real numbers into a uvector using coerce-to, if every elements is valid for the uvector. @vectorのクラス。@の部分はuvectorタグ (u8、s8、...) です。 <uvector>を継承します。

     sequenceプロトコル(Sequence framework参照)を実装しているので、数値の並びをcoerce-toを使ってuvectorに変換することができます。ただし各要素はuvectorの要素として有効な範囲の値でなればなりません。

          (use gauche.sequence)
          (coerce-to <u8vector> '(1 2 3)) => #u8(1 2 3)

Uvector literals
................

uvectorリテラル
...........

 -- Reader Syntax: #u8(N ...)
 -- Reader Syntax: #s8(N ...)
 -- Reader Syntax: #u16(N ...)
 -- Reader Syntax: #s16(N ...)
 -- Reader Syntax: #u32(N ...)
 -- Reader Syntax: #s32(N ...)
 -- Reader Syntax: #u64(N ...)
 -- Reader Syntax: #s64(N ...)
 -- Reader Syntax: #f16(N ...)
 -- Reader Syntax: #f32(N ...)
 -- Reader Syntax: #f64(N ...)
 -- Reader Syntax: #c32(N ...)
 -- Reader Syntax: #c64(N ...)
 -- Reader Syntax: #c128(N ...)
     Denotes a literal homogeneous vector.

     (Note: R7RS bytevector is the same as u8vector, and can be written as #u8(...).) リテラルの単一型のベクタを記述します。

     (註: R7RSのバイトベクタはu8vectorと同じで、#u8(...)で表記できます。)

          #s8(3 -2 4)
          #u32(4154 88357 2 323)
          #f32(3.14 0.554525 -3.342)

Uvector generic operations
..........................

uvectorのジェネリックな操作
.................

 -- Function: uvector? obj
     Returns #t iff OBJ is one of the uniform vectors. See below for predicates for specific type of uvector. OBJがユニフォームベクタのいずれかなら#tを、そうでなければ#fを返します。特定の型のuvectorを検査する述語については後で説明します。

 -- Function: uvector-length uv
     Returns the length (the number of elements) of uvector UV. An error is raised if UV is not a uvector.

     Type specific length procedures are provided in scheme.vector.@ and gauche.uvector (see Uniform vector library).

     To get the size of the binary data the content of the uvector actually occupies, use uvector-size in gauche.uvector. uvectorUVの長さ(要素数)を返します。 UVがuvectorでなければエラーを投げます。

     特定の型のuvectorの長さを取る手続きは、scheme.vector.@および gauche.uvectorにあります (Uniform vector library参照)。

     uvectorの内容がバイナリデータとして占有する大きさを知りたければ、 gauche.uvectorのuvector-sizeが使えます。

 -- Function: uvector-ref uv k :optional fallback
     Generic uvector accessor.  Returns K-th element of a uniform vector UV.  If K is out-of-range, FALLBACK is returned if provided, or an error is thrown otherwise.

     This is handy to write a generic code that works on any kind of uniform vector, but this is slower than the specific versions. Gauche's compiler recognizes the specific versions of referencer and generate very efficient code for them, while this generic version becomes a normal procedure call.   In inner-loop it can make a big difference.

     See below for the type-specific accessors.

     (setter uvector-ref) is uvector-set!. 汎用的なuvectorのアクセサです。uvector UVのK番目の要素を返します。Kが範囲外の場合、FALLBACKが与えられていればそれが返され、そうでなければエラーが投げられます。

     この手続きは様々な種類のユニフォームベクタに対して動作するような一般的なコードを書く際にとても便利ですが、それぞれの種類のユニフォームベクタ専用のアクセサに比べると遅いです。Gaucheのコンパイラは@vector-refの呼び出しを認識して非常に効率の良いコードを出すのに対し、この手続きは通常の手続き呼び出しになるからです。内部のループ内で呼び出す場合、これは大きな差になるかもしれません。

     型ごと専用のアクセサは下で説明します。

     なお、(setter uvector-ref)はuvector-set!です。

 -- Function: uvector-set! uv k val :optional clamp
     Generic uvector setter.  Mutate K-th element of uvector UV with VAL. An error is thrown if K is out-of-range, or UV is immutable.

     Optional CLAMP argument specifies the behavior when VAL is out of valid range.  It can be #f or one of the symbols low, high, or both. See Uniform vector library, for the meanings of the clamp argument. The default is #f, which raises an error on out-of-range value. 汎用的なuvectorのセッターです。uvector UVのK番目の要素を VALで置き換えます。 Kが範囲外であったり、 UVが変更不可である場合はエラーが投げられます。

     省略可能な引数CLAMPが、VALが正しい範囲外の数であった場合の動作を指定します。この引数は#fか、シンボルlow、high、bothのいずれかでなければなりません。この意味についてはUniform vector libraryを参照してください。デフォルトは#fで、範囲外の値についてはエラーを投げます。

Uvector type-specific operations
................................

uvectorの型ごとの操作
..............

Type-specific predicates, accessors and modifiers are provided in the core library; all the rest are in scheme.vector.@ or gauche.uvector (see Uniform vector library). 型ごとの述語、アクセサ、セッタはここで提供されます。他の手続きについてはscheme.vector.@やgauche.uvectorを利用してください (Uniform vector library参照)。

 -- Function: @vector? obj
     [R7RS vector.@] Returns #t iff OBJ is a @vector, #f otherwise. The @ part is one of the uvector tags (u8 etc.). OBJが@vectorなら#tを、そうでなければ#fを返します。 @の部分はuvectorタグ(u8等)です。

 -- Function: @vector-ref vec k :optional fallback
     [R7RS vector.@] Returns the K-th element of @vector VEC. The @ part is one of the uvector tags (u8 etc.).

     If the index K is out of the valid range, an error is signaled unless an optional argument FALLBACK is given; in that case, FALLBACK is returned.

     Note that the generic function ref can be used as well, if you import gauche.collection. @vector VECのK番目の要素を返します。 @の部分はuvectorタグ(u8等)です。

     Kが有効な範囲外であった場合、通常はエラーが通知されますが、省略可能な引数FALLBACKが与えられている場合はそれが返されます。

     モジュールgauche.collectionをインポートしていれば、総称関数refを使うこともできます。

          (u16vector-ref '#u16(111 222 333) 1) => 222

          (use gauche.collection)
          (ref '#u16(111 222 333) 1) => 222

     Setter of @vector-ref is @vector-set!. @vector-refのsetterは@vector-set!です。

          (use gauche.uvector)
          (define v (u8vector 1 2 3))
          (set! (u8vector-ref v 1) 99)

          v => #u8(1 99 3)

 -- Function: @vector-set! vec k n :optional clamp
     [R7RS vector.@] Sets a number N to the K-th element of @vector VEC. The @ part is one of the uvector tags (u8 etc.).

     Optional CLAMP argument specifies the behavior when N is out of valid range.   It can be #f or one of the symbols low, high, or both. See Uniform vector library, for the meanings of the clamp argument. The default is #f, which raises an error on out-of-range value.

     Note that the setter of the generic function ref can be used as well, if you import gauche.collection. @vector VECのK番目の要素に数値Nをセットします。 @の部分はuvectorタグ(u8等)です。省略可能な引数CLAMPが、Nが正しい範囲外の数であった場合の動作を指定します。この引数は#fか、シンボルlow、high、bothのいずれかでなければなりません。この意味についてはUniform vector libraryを参照してください。デフォルトは#fで、範囲外の値についてはエラーを投げます。

     モジュールgauche.collectionをインポートしていれば、総称関数refのsetter手続きを使うこともできます。

          (let ((v (s32vector -439 852 8933)))
            (s32vector-set! v 1 4)
            v)
           => #s32vector(-439 4 8933)

          (use gauche.collection)
          (let ((v (s32vector -439 852 8933)))
            (set! (ref v 1) 4)
            v)
           => #s32vector(-439 4 8933)

Bitvectors
----------

A bitvector is a sequence of bits.  Each bit can be considered either an exact integer 0/1, or a boolean values #f/#t. In the former view, it is similar to a uniform vector, but it has the interface sufficiently different from uvectors and we provided it as a disjoint type.

Gauche provides a handful of procedures in the core. SRFI-178 provides comprehensive bitvector library. See Bitvector library, for the details. ビットベクタはビットの並びです。各「ビット」は、0/1の数値としても、 #f/#tの論理値としても解釈可能です。最初の見方では、ビットベクタをユニフォームベクタの一種と考えることもできますが、インタフェースがそこそこ違っているので、別の型としました。

Gaucheはコアでごく基本的な手続きを提供します。 SRFI-178に包括的なビットベクタライブラリがあります。 Bitvector libraryを参照してください。

 -- Builtin class: <bitvector>
     Bitvector class.  Inherits <sequence>, so generic sequence opertaions can be used.  (Generic ref uses bitvector-ref/int, for it matches the external representation of a bitvector.) ビットベクタクラス。<sequence>を継承し、ジェネリックなシーケンス操作も使えます。 (ジェネリックなrefについては、外部表現との親和性からbitvector-ref/intが使われます)。

 -- Reader Syntax: #*B...
     [SRFI-178] A bitvector literal is #* followed by zero or more binary digits 0 or 1. ビットベクタリテラルは、#*のあとに0や1が0個以上続いたものです。

          #*10010010           ; bitvector of length 8
          #*                   ; bitvector of length 0

     A bitvector literal is delimited by one of delimiter character or an EOF. ビットベクタリテラルはデリミタ文字かEOFで区切られます。

          #*10010abc           ; error
          #*10001(a b c)       ; a bitvector, followed by a list

     Note: With this rule, #*"..." should be read as a zero-length bitvector followed by a string, for " is a delimiter.  However, Gauche used that syntax for incomplete strings (our overlook!). Since incomplete string literals is rare (incomplete strings are something that unexpectedly happen in the practical situation, but not to be used actively), we changed incomplete string literals to #**"..." since 0.9.10 (see Incomplete strings). 註: このルールでは、#*"..."は、長さゼロのビットベクタと文字列、と解釈されるべきです。"は区切り文字ですから。しかし、Gaucheでは長らくこの構文を不完全文字列に使っていました。 (長さゼロのビットベクタがあることを見落としてました!) 不完全文字列の外部表記が必要になることは滅多にないので (不完全文字列は現実のデータを扱う際にどうしても「生じてしまう」もので、積極的に使うべきではありません)、その表記は0.9.10から#**"..."に変更されました (Incomplete strings)。

     For the backward compatibility, the current version reads #*"..." is read as an incomplete string.  If the reader lexical mode is warn-legacy (see Reader lexical mode), such literals are warned.  We'll gradually migrate to make #*"..." read as a bytevector followed by a string. 後方互換性のため、現在のバージョンでは#*"..."は不完全文字列として読まれます。リーダー字句モードがwarn-legacyであれば、この形のリテラルに対して警告が出されます (Reader lexical mode)。将来的には#*"..."はビットベクタと文字列として読まれるように徐々に以降する予定です。

 -- Function: bit->integer bit
 -- Function: bit->boolean bit
     [SRFI-178] Many bitvector operations can accept bit as a boolean (#f/#t) or an exact integer (0/1).  These are utility procedures to obtain desired type.  The BIT argument must be either one of #f, #t, 0 or 1.  They return 0/1 and #f/#t, respectively. An error is signalled if BIT is other than those values. ビットベクタAPIでビットが必要なところには、論理値(#f/#t)あるいは正確な整数 (0/1)を渡すことができます。これらの手続きは有効なビット値をそれぞれ0/1もしくは #f/#tに揃えます。BITが有効なビット値でなければエラーが投げられます。

 -- Function: bitvector b ...
     [SRFI-178] Creates and returns a bitvector whose elements are B .... Each argument must be a bit (boolean or 0 or 1). 要素がB ...であるビットベクタを作って返します。各引数はビット値でなければなりません (論理値か0か1)。

          (bitvector 0 1 0 0 1 0 0 0 1) => #*010010001
          (bitvector) => #*

 -- Function: make-bitvector len :optional init
     [SRFI-178] Creates and returns a bitvector with length LEN, and all elements being initialized by INIT, which must be a bit (boolean or 0 or 1).

     If INIT is omitted, the content of the bitvector is undefined (currently we fill it with 0, but don't count on it.) 長さLENのビットベクタを作って返します。各要素はINITで初期化されます。 INITはビット値(論理値か0か1)でなければなりません。

     INITが省略された場合、ビットベクタの内容は未定義です。 (今のところ0で初期化されますが、それをあてにしてはいけません)。

          (make-bitvector 5 #f)  => #*00000
          (make-bitvector 7 1)   => #*1111111

 -- Function: list->bitvector lis
     [SRFI-178] LIS must be a list of bits (0, 1 or booleans).  Returns a bitvector whose elements consist of elements of LIS. LISはビット値(論理値、0、1)のリストでなければなりません。それらの値を要素とするビットベクタを作って返します。

          (list->bitvector '(#t #f #t #t #f))  => #*10110
          (list->bitvector '(0 1 1 1 0 1 0 1)) => #*01110101

 -- Function: string->bitvector s
     [SRFI-178] If S is a valid bitvector literal (#*B... where B is either 0 or 1), returns a bitvector represented by the string.  Otherwise, #f is returned. sがビットベクタリテラルとして有効な文字列 (#*B...でBが0か1) であれば、それで表現されるビットベクタを返します。そうでなければ#fが返されます。

          (string->bitvector "#*1010001") => #*1010001
          (string->bitvector "#*1001020") => #f

     Note that this isn't a sequence-conversion, but rather a conversion from external representation. これはシーケンスとしての変換ではなく、外部表現からの変換であることに注意してください。

 -- Function: bitvector->string bv
     [SRFI-178] Convert a bitvector BV to a string representation #*B.... ビットベクタBVの外部表現#*B...を文字列として返します。

          (bitvector->string #*1001010) => "#*1001010"

     Note that this isn't a sequence-conversion, but rather a conversion to external representation. これはシーケンスとしての変換ではなく、外部表現への変換であることに注意してください。

 -- Function: bitvector-ref/int bv k :optional fallback
 -- Function: bitvector-ref/bool bv k :optional fallback
     [SRFI-178+] Retrieves the K-th bit of a bitvector BV as an integer or a boolean value, respectively.  If K is out of range, FALLBACK is returned if it is given, or an error is raised otherwise. The FALLBACK argument is Gauche's extension. ビットベクタBVのK番目の要素を、それぞれ整数0/1か論理値として返します。 Kが範囲外だった場合、FALLBACKが与えられていればそれが返され、与えられていなければエラーが投げられます。 FALLBACK引数はGaucheの拡張です。

          (bitvector-ref/int #*1010001 0)  => 1
          (bitvector-ref/bool #*1010001 0) => #t

     If you use a universal accessor ref/~, it returns the bit value as an integer (see Universal accessor). 万能アクセサref/~をビットベクタに使った場合は、整数値が返されます (Universal accessor)。

          (~ #*11001001 1) => 1

 -- Function: bitvector-set! bv k bit
     [SRFI-178] Sets the K-th bit of a bitvector BV with BIT, which must be either one of 0, 1, #f or #t.  An error is raised if K is out of range. ビットベクタBVのK番目の要素にビット値BITをセットします。 BITは0、1、#f、#tのいずれかでなければなりません。 Kが範囲外ならエラーが投げられます。

     This procedure is set as the setter of bitvector-ref/int and bitvector-ref/bool. Since a bitvector is a sequence, you can also use (setter ref)/(setter ~): この手続きはbitvector-ref/intとbitvector-ref/boolのsetterとして設定されています。また、ビットベクタはシーケンスなので、 (setter ref)/(setter ~)も使えます。

          (rlet1 z (make-bitvector 5 0)
            (set! (~ z 2) #t))
            => #00100

 -- Function: bitvector-copy bv :optional start end
     [SRFI-178] Returns a copy of a bitvector BV.  If optional START and END indexes are given, the copy is limited in that range, where START is inclusive and END is exclusive. ビットベクタBVのコピーを作って返します。省略可能引数START、ENDでインデックスが与えられた場合は、その範囲内がコピーされます。STARTは含まれ、ENDは含まれません。

          (bitvector-copy #*101001000 3)   => #*001000
          (bitvector-copy #*100101000 2 7) => #*01010

 -- Function: bitvector-copy! target tstart src :optional sstart send
     [SRFI-178] Copy a bitvector SRC into a mutable bitvector TARGET starting from TSTART, mutating TARGET.  Optional SSTART and SEND delimits the range in SRC. ビットベクタSRCの内容を、変更可能なビットベクタTARGETのTSTARTインデックス以降にコピーして TARGETの内容を書き換えます。省略可能なSSTART、SENDは SRCのコピーされる範囲を限定します。

          (rlet1 v (make-bitvector 10 0)
            (bitvector-copy! v 3 #*101101110 2 6))
            => #*0001101000

Weak vectors
------------

A weak pointer is a reference to an object that doesn't prevent the object from being garbage-collected. Gauche provides weak pointers as a weak vector object. A weak vector is like a vector of objects, except each object can be garbage collected if it is not referenced from objects other than weak vectors.   If the object is collected, the entry of the weak vector is replaced for #f. Weak ポインタとは、それが参照しているオブジェクトがガベージコレクトされることを許すようなポインタです。 Gaucheはweak ベクタオブジェクトによってweak ポインタの機能を提供します。 Weak ベクタは通常のベクタに似ていますが、要素のオブジェクトがweak ベクタ以外から参照されていない場合、オブジェクトはガベージコレクトされ、weak ベクタの該当するエントリは #fで置き換えられます。

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

See R7RS ephemerons, for R7RS-large way of weak pointers. R7RS-largeでのweakポインタについてはR7RS ephemeronsを参照してください。

 -- Builtin Class: <weak-vector>
     The weak vector class.  Inherits <sequence> and <collection>, so you can use gauche.collection (see Collection framework) and gauche.sequence (see Sequence framework). Weak ベクタのクラスです。<sequence>と<collection>を継承しているので、 gauche.collection (Collection framework参照) と gauche.sequence (Sequence framework参照) も使えます。

          (coerce-to <weak-vector> '(1 2 3 4))
            => a weak vector with four elements

 -- Function: make-weak-vector size
     Creates and returns a weak vector of size SIZE. 大きさSIZEのweak ベクタを作成して返します。

 -- Function: weak-vector-length wvec
     Returns the length of a weak vector WVEC. weak ベクタ WVECの大きさを返します。

 -- Function: weak-vector-ref wvec k :optional fallback
     Returns K-th element of a weak vector WVEC.

     By default, weak-vector-ref signals an error if K is negative, or greater than or equal to the size of WVEC. However, if an optional argument FALLBACK is given, it is returned for such case.

     If the element has been garbage collected, this procedure returns FALLBACK if it is provided,  #f otherwise.

     With gauche.sequence module, you can also use a method ref. weak ベクタ WVECのK番目の要素を返します。

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

     該当する要素が既にガベージコレクトされていた場合、FALLBACKが与えられていればそれが、そうでなければ#fが返されます。

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

 -- Function: weak-vector-set! wvec k obj
     Sets K-th element of the weak vector WVEC to OBJ. It is an error if K is negative or greater than or equal to the size of WEC. weak ベクタ WVECのK番目の要素をOBJに変更します。 Kが負数であったりベクタの長さより大きい場合はエラーとなります。

Dictionaries
============

A dictionary is a data structure that associates key to value. Gauche provides hashtables (see Hashtables) and treemaps (see Treemaps) as the built-in dictionaries.  Some additional libraries provide more dictionary-type data structures.

A generic interface is defined as a dictionary framework (see Dictionary framework), by which you can use dictionaries without knowing its details.

R7RS also defines an abstract dictionary interface as mapping; see R7RS mappings, for the details. ディクショナリは、キーと値を結びつけるデータ構造です。 Gaucheは組み込みのディクショナリとして、ハッシュテーブル(Hashtables参照)とツリーマップ(Treemaps参照)を用意しています。ライブラリには他にもディクショナリとして振る舞うデータ構造がいくつか提供されます。

さらに、ディクショナリ汎用のインタフェースが、ディクショナリフレームワークとして提供されます (Dictionary framework参照)。ディクショナリの種類に関わらない操作を書くのに使えます。

R7RSでは、抽象化されたディクショナリインタフェースをマッピングとして定義しています。 R7RS mappingsを参照してください。

Hashtables
----------

R7RS-large defines hashtable (scheme.hash-table module, see R7RS hash tables) but its API is not completely consistent with Gauche's original hashtables and other native APIs.

Rather than mixing different flavor of APIs, we keep Gauche's native API consistent, and provide R7RS procedures that are inconsistent with aliases---specifically, those procedures are suffixed with -r7 in gauche module.  For portable programs, you can import scheme.hash-table to get R7RS names. R7RS-largeにはハッシュテーブルが定義されています (scheme.hash-tableモジュール、R7RS hash tables参照)。しかし、そのAPIはGaucheにもともとあったハッシュテーブルや他のネイティブAPIと一貫性を欠いている部分があります。

APIをごちゃまぜにするよりは、GaucheのネイティブなAPIの一貫性を保つことを重視し、 R7RSの手続きのうちGaucheにそぐわないものは、組み込み関数では別名 (サフィックス-r7がついたもの)をつけて提供しています。ポータブルなコードを書く場合は、scheme.hash-tableをインポートすれば R7RSの名前が使えます。

 -- Builtin Class: <hash-table>
     Hash table class.  Inherits <collection> and <dictionary>.

     Gauche doesn't provide immutable hash tables for now. (If you need immutable maps, see Immutable map). ハッシュテーブルのクラスです。<collection>と<dictionary>を継承します。

     Gaucheは今のところ、変更不可なハッシュテーブルは提供しません。 (変更不可なマップが必要な場合は、Immutable mapを参照してください。)

Hash table properties
---------------------

ハッシュテーブルのプロパティ
--------------

 -- Function: hash-table? obj
     [R7RS hash-table] Returns #t iff OBJ is a hash table. OBJがハッシュテーブルであれば#tを返します。

 -- Function: hash-table-mutable? ht
     [R7RS hash-table] Returns #t iff a hash table HT is mutable. Gauche doesn't have immutable hash tables, so this procedure always returns #t for any hash tables. ハッシュテーブルHTが変更可能なら#tを返します。 Gaucheは変更不可なハッシュテーブルを持たないので、どんなハッシュテーブルに関しても手続きは#tを返します。

 -- Function: hash-table-comparator ht
     Returns a comparator used in the hashtable HT. ハッシュテーブルHTで使われている比較器を返します。

 -- Function: hash-table-type ht
     This is an old API, superseded by hash-table-comparator.

     Returns one of symbols eq?, eqv?, equal?, string=?, general, indicating the type of the hash table HT. これは古いAPIで、hash-table-comparatorによって置き換えられました。

     ハッシュテーブルHTのタイプに応じて、シンボル eq?、eqv?、equal?、string=?、 generalのいずれかを返します。

 -- Function: hash-table-num-entries ht
 -- Function: hash-table-size ht
     [R7RS hash-table] Return the number of entries in the hash table HT. R7RS name is hash-table-size. ハッシュテーブルHT中の要素の個数を返します。 R7RSの名前はhash-table-size.

Hash table constructors and converters
--------------------------------------

ハッシュテーブルのコンストラクタとコンバータ
----------------------

 -- Function: make-hash-table :optional comparator
     [R7RS+ hash-table] Creates a hash table.  The COMPARATOR argument specifies key equality and hash function using a comparator (see Basic comparators).  If omitted, eq-comparator is used.  Note that in R7RS, COMPARATOR argument can't be omitted.

     As Gauche's extension, the COMPARATOR argument can also be one of the symbols eq?, eqv?, equal? or string=?. If it is one of those symbols, eq-comparator, eqv-comparator, equal-comparator and string-comparator will be used, respectively.

     The comparator must have hash function, of course.  See Hashing, for the built-in hash functions.  In general, comparators derived from other comparators having hash functions also have appropriate hash functions. ハッシュテーブルを作成します。COMPARATOR引数には、キーの等価判定とハッシュに使う比較器(Basic comparators参照)を渡します。省略された場合はeq-comparatorが使われます。 (R7RSではCOMPARATORは省略できません。)

     Gauche独自拡張として、COMPARATORにシンボル eq?、eqv?、equal?、string=?のいずれかを指定することもできます。 eq-comparator、 eqv-comparator、equal-comparator、 string-comparatorが使われます。

     比較器はハッシュ関数を持っていなければなりません。組み込みのハッシュ関数については Hashingを参照してください。比較器を組み合わせて作られた比較器については、元の比較器がハッシュ関数を持っていれば、通常は適切なハッシュ関数が設定されます。

 -- Function: hash-table-from-pairs comparator key&value ...
     Constructs and returns a hash table from given list of arguments. The COMPARATOR argument is the same as of make-hash-table. Each KEY&VALUE must be a pair, and its car is used as a key and its cdr is used as a value.

     Note: This is called hash-table by 0.9.5.  R7RS introduced a procedure with the same name, but different interface. We see R7RS version makes more sense, so we'll eventually switch to it, but the transition will take long time. The R7RS interface is available as hash-table-r7, and we urge you to use it in the new code, and replace existing hash-table with hash-table-from-pairs. 与えられたキーと値の列からハッシュテーブルを構築して返します。COMPARATOR引数の意味はmake-hash-tableと同じです。各KEY&VALUEはペアでなければならず、そのcarがキー、cdrが値として使われます。

     註：これは0.9.5までhash-tableと呼ばれていた手続きです。 R7RSは同名で異なるインタフェースを持つインタフェースを定義しました。そちらの方が使いやすいので、長期的にはR7RSインタフェースへとスイッチする予定ですが、それはかなり将来のことになります。 R7RSインタフェースはhash-table-r7という名前で利用可能なので、新たなコードはそちらを使うことを強くお勧めします。また、既存のコードでhash-tableを使っていたら、 hash-table-from-pairsに直してください。

          (hash-table-from-pairs 'eq? '(a . 1) '(b . 2))
            ==
            (rlet1 h (make-hash-table 'eq?)
               (hash-table-put! h 'a 1)
               (hash-table-put! h 'b 2))

 -- Function: hash-table comparator key&value ...
     An alias of hash-table-from-pairs above.  R7RS introduced the same name procedure with different interface (see hash-table-r7 below), and we'd like to switch to it in future.  For now, use either hash-table-from-pairs or hash-table-r7, or import scheme.hash-table and write in R7RS. hash-table-from-pairsの別名です。 R7RSが同名で別インタフェースの手続き(下のhash-table-r7参照)を導入し、将来的にはGaucheもそちらに移行する予定です。なので今のところ、 hash-table-from-pairsかhash-table-r7を使うか、 scheme.hash-tableをインポートしてR7RSとして書いてください。

 -- Function: hash-table-r7 comparator args ...
     Create and returns a hash table using COMPARATOR. The ARGS ... are the contents, alternating keys and values.

     This is defined as hash-table in R7RS scheme.hash-table (see R7RS hash tables). COMPARATORを比較器に使うハッシュテーブルを作って返します。 ARGS ...はキーと値を交互に並べたもので、ハッシュテーブルの内容を指定します。

     これはR7RS scheme.hash-tableでhash-tableと定義されている手続きです (R7RS hash tables参照)。

          (hash-table-r7 'eq? 'a 1 'b 2)
            ==
            (rlet1 h (make-hash-table 'eq?)
               (hash-table-put! h 'a 1)
               (hash-table-put! h 'b 2))

     Note: An R7RS compliant implementation of hash-table may return an immutable hash table.  Since Gauche doesn't have immutable hash tables (we have immutable maps instead; see Immutable map), we return mutable hash tables.  However, the portable program should refrain from mutating the returned hash tables. 註: R7RS準拠の実装には、hash-tableが変更不可なハッシュテーブルを返すものがあります。Gaucheは変更不可なハッシュテールを持っていないので (変更不可なマップならあります: Immutable map参照)、変更可能なハッシュテーブルが返されます。ただ、ポータブルなプログラムを書いている場合は、この手続きが返したハッシュテーブルを変更しないように注意してください。

 -- Function: hash-table-unfold p f g seed comparator :rest args
     [R7RS hash-table] Constructs and returns a new hash table with those repetitive steps. Each iteration keeps the current seed value, whose initial value is SEED.

      1. Apply a stop predicate P to the current seed value.  If it returns a true value, stop.

      2. Apply a value producer F to the current seed value.  It must return two values, which are used as a key and the corresponding value, of the hash table.

      3. Apply a next procedure G to the current seed value.  The value it returns becomes the next seed value.

     次の手順で新たなハッシュテーブルを作り返します。各繰り返しは「現在のシード値」を参照しますが、その初期値はSEEDです。

      1. 停止述語Pを現在のシード値に適用します。それが真の値を返したら、そこで終了です。

      2. 生産手続きFを現在のシード値に適用します。Fは二つの値を返さねばなりません。最初の値がキー、二番目がキーに対応する値として、作られているハッシュテーブルに挿入されます。

      3. 手続きGが現在のシード値に適用され、その戻り値が次の繰り返しでのシード値となります。

 -- Function: hash-table-copy ht :optional mutable?
     [R7RS hash-table] Returns a new copy of a hash table HT.

     R7RS defines this procedure to return an immutable hash table if the implementation supports one, unless the optional MUTABLE? argument is provided and not false.  Gauche doesn't have immutable hash tables so it ignores the optional argument and always returns a mutable hash table.  But when you write a portable programs, keep it in mind. ハッシュテーブルHTのコピーを作って返します。

     R7RSは、実装が変更不可なハッシュテーブルをサポートする場合、 MUTABLE?引数に真の値が与えられない限りは、この手続きは変更不可なハッシュテーブルを返すと規定しています。 Gaucheは変更不可なハッシュテーブルを持たないので、MUTABLE?引数は無視され、常に変更可能なハッシュテーブルが返されますが、ポータブルなコードを書いている場合は気をつけてください。

 -- Function: hash-table-empty-copy ht
     [R7RS hash-table] Returns a new mutable empty hash table that has the same properties as the given hash table HT. ハッシュテーブルHTと同じ性質を持つ空の変更可能なハッシュテーブルを作成して返します。

 -- Function: alist->hash-table alist :optional comparator
     [R7RS+ hash-table] Creates and returns a hash table that has entries of each element in alist, using its car as the key and its cdr as the value.  The COMPARATOR argument is the same as in make-hash-table.  The default value of COMPARATOR is eq-comparator.

     R7RS doesn't allow to omit COMPARATOR. alistに含まれるそれぞれの要素をエントリとして持つハッシュテーブルを作成して返します。その時、要素のcarがキーとして、要素のcdrが値として使われます。COMPARATOR引数の意味はmake-hash-tableと同じです。 COMPARATORのデフォルト値はeq-comparatorです。

     R7RSではCOMPARATORは省略不可です。

 -- Function: hash-table->alist hash-table
     [R7RS hash-table]

            (hash-table-map h cons)

Hash table lookup and mutation
------------------------------

ハッシュテーブルのルックアップと変更
------------------

 -- Function: hash-table-get ht key :optional default
     Search KEY from a hash table HT, and returns its value if found.  If the key is not found in the table and DEFAULT is given, it is returned.  Otherwise an error is signaled. キーKEYをハッシュテーブルHTから探します。見つかればキーに対応する値を返します。キーが見つからなかった場合、DEFAULTが与えられていればそれを返し、そうでなければエラーを報告します。

 -- Function: hash-table-put! ht key value
     Puts a key KEY with a value VALUE to the hash table HT. キーKEYと対応する値VALUEをハッシュテーブルHTに挿入します。

 -- Method: ref (ht <hash-table>) key :optional default
 -- Method: (setter ref) (ht <hash-table>) key value
     Method versions of hash-table-get and hash-table-put!. hash-table-getとhash-table-put!のメソッド版です。

 -- Function: hash-table-ref ht key :optional failure success
     [R7RS hash-table] This is R7RS way to look up a hash table.

     Look up a value associated to the KEY in the table HT, then pass it to a procedure SUCCESS, and returns its value. If SUCCESS is omitted, an identity function is used.

     If there's no association for KEY in HT, a thunk FAILURE is called and its result is returned. The default value of FAILURE throws an error.

     It is more general than Gauche's hash-table-get, but if you need to simply return a fallback value in case of failure, you need to wrap it with a clojure, which is annoying.  In R7RS, you can use hash-table-ref/default below. これがR7RS方式のハッシュテーブルルックアップです。

     ハッシュテーブルHT中の、KEYに結びつけられた値を探し、それを手続きSUCCESSに渡して、その結果を返します。 SUCCESSが省略された場合は単に値そのものが返されます。

     KEYに対応する値がHTに無い場合は、引数を取らない手続きFAILUREが呼ばれ、その結果が返されます。FAILUREが省略されていた場合はエラーが報告されます。

     これはGaucheのhash-table-getよりも汎用的ですが、キーが見つからなかった場合に単純に既定値を返したいといった場合に、それをいちいちクロージャで包むのは面倒です。R7RSではそのために下に説明するhash-table-ref/defaultがあります。

 -- Function: hash-table-ref/default ht key default
     [R7RS hash-table] Looks up KEY in a hash table HT and returns the associated value.  If there's no KEY in the table, returns DEFAULT.

     This is same as Gauche's hash-table-get, except that DEFAULT is not optional.  We provide both, for hash-table-get is short and handy. ハッシュテーブルHTからKEYを探し、対応する値を返します。 KEYが見つからない場合はDEFAULTを返します。

     これは、DEFAULTが省略できないことを除いては、Gaucheの hash-table-getと同じです。hash-table-getの方が短くて便利なので両方提供しています。

 -- Function: hash-table-set! ht args ...
     [R7RS hash-table] This is R7RS version to put associations into a hash table. The ARGS ... is a list of alternating keys and values; so, unlike Gauche's hash-table-put!, you can insert more than one associations at once.  It is an error if ARGS ... have odd number of arguments. これが、ハッシュテーブルに新たなエントリを追加するR7RS式のインタフェースです。 ARGS ...にはキーと値を交互に並べたリストを指定します。 Gaucheのhash-table-put!と違い、いくつものエントリを一度に追加することができます。 ARGS ...が偶数要素でなければエラーです。

          (hash-table-set! ht 'a 1 'b 2)
            ==
            (begin (hash-table-put! ht 'a 1)
                   (hash-table-put! ht 'b 2))

 -- Function: hash-table-intern!-r7 ht key failure
     This is defined in R7RS as hash-table-intern!.  We add -r7 suffix to remind that it takes a failure thunk, which is consistent with R7RS hash-table interface but not Gauche's way.

     Lookup KEY in HT.  If there's already an entry, it just returns the value. Otherwise, it calls a thunk FAILURE, and insert the association of KEY and the return value of FAILURE into HT, and returns the value. これはR7RSでhash-table-intern!として定義されています。 Gaucheの慣習と異なり、R7RSの方式でFAILUREにサンクを取ることを強調するために -r7サフィックスをつけました。

     HTからKEYを探します。もし既にエントリがあれば、その値を返します。エントリが無ければ、サンクFAILUREを呼び、その戻り値をKEYに対応する値としてHTに挿入して、FAILUREの戻り値を返します。

 -- Function: hash-table-exists? ht key
 -- Function: hash-table-contains? ht key
     [R7RS hash-table] Returns #t if a hash table HT has a key KEY.

     R7RS name is hash-table-contains?. ハッシュテーブルHTにキーKEYを持つエントリがあれば#tを返します。

     R7RSでの名前はhash-table-contains?です。

 -- Function: hash-table-delete! ht key
     Deletes an entry that has a key KEY from the hash table HT. Returns #t if the entry has exist, or #f if the entry hasn't exist.   The same function is called hash-table-remove! in STk (except that it returns an undefined value); I use `delete' for consistency to SRFI-1, SRFI-13 and other parts of the libraries.

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

     註: これはR7RSのhash-table-delete!と異なります。 R7RSインタフェースはhash-table-delete!-r7という別名で提供されます。

 -- Function: hash-table-delete!-r7 ht key ...
     Delets entries that have KEY ... from the hash table HT. The KEY which isn't in HT has no effect.  Returns the number of entries actually deleted.

     This is called hash-table-delete! in R7RS, and so as in scheme.hash-table.  We provide this under different name, for Gauche's hash-table-delete! returns a boolean value. KEY ...を持つエントリをハッシュテーブルHTから削除します。 HTに含まれなかったキーは単に無視されます。実際に削除されたエントリの数が返されます。

     これはR7RSでhash-table-delete!と呼ばれており、 scheme.hash-tableでもその名前で提供されます。 Gaucheのhash-table-delete!は真偽値を返すので、組み込みとしては別名で提供することにしました。

 -- Function: hash-table-clear! ht
     [R7RS hash-table] Removes all entries in the hash table HT. ハッシュテーブルHTの全てのエントリを削除します。

 -- Function: hash-table-push! ht key value
     Conses VALUE to the existing value for the key KEY in the hash table HT and makes it the new value for KEY. If there's no entry for KEY, an entry is created with the value (list VALUE).

     Works the same as the following code, except that this function only looks up the KEY once, thus it's more efficient. ハッシュテーブルHT中の、キーKEYに対応する値にVALUEをコンスし、それをKEYに対する新たな値とします。もしKEYに対応する値がまだ無ければ、新たなエントリが作成され、(list VALUE)がその値となります。

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

          (hash-table-put! HT KEY
              (cons VALUE (hash-table-get HT KEY '())))

 -- Function: hash-table-pop! ht key :optional default
     Looks for the value for the key KEY in the hash table HT. If found and it is a pair, replaces the value for its cdr and returns car of the original value.  If no entry for KEY is in the table, or the value is not a pair, the table is not modified and the procedure returns DEFAULT if given, or signals an error otherwise.

     During the operation the key is looked for only once, thus runs efficiently.

     Note: R7RS has hash-table-pop! but its totally different. We provide R7RS version as an alias hash-table-pop!-r7 ハッシュテーブルHT中のキーKEYに対応する値が存在し、かつペアであった場合に、そのエントリーを元の値のcdrで置き換え、元の値のcarを返します。 KEYに対応する値が存在しないかペアではなかった場合、テーブルは変更されず、 DEFAULTが与えられていればそれが返され、与えられていなければエラーが報告されます。

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

     註：R7RSもhash-table-pop!を定義していますが、全く違う操作です。そこで、R7RSバージョンはhash-table-pop!-r7として提供しています。

 -- Function: hash-table-pop!-r7 ht
     Removes one arbitrary entry from HT, and returns the removed entry's key and value as two values.  If HT is empty, an error is thrown.

     This is called hash-table-pop! in R7RS, and so as in scheme.hash-table. ハッシュテーブルHT中の任意のエントリをひとつ削除し、そのエントリのキーと値を二つの戻り値として返します。 HTが空ならエラーが報告されます。

     R7RSではこれがhash-table-pop!と呼ばれていて、 scheme.hash-tableでもその名前で提供されます。

 -- Function: hash-table-update! ht key proc :optional default
     A more general version of hash-table-push! etc. It works basically as the following code piece, except that the lookup of KEY is only done once. hash-table-push!等のより一般的なバージョンです。ハッシュテーブルの探索が一度しか行われないことを除いては、基本的に次のように動作します。

          (let ((tmp (PROC (hash-table-get HT KEY DEFAULT))))
            (hash-table-put! HT KEY tmp)
            tmp)

     For example, when you use a hash table to count the occurrences of items, the following line is suffice to increment the counter of the item, regardless of whether ITEM has already appeared or not. 例えば、ハッシュテーブルを使ってオブジェクトの個数を数えているとしましょう。次の1行で、オブジェクトITEMが既に出現したかどうかを気にせずにその個数をインクリメントできます。

          (hash-table-update! ht item (cut + 1 <>) 0))

     R7RS provides hash-table-update! with different interface, so we provide R7RS version as an alias hash-table-update!-r7. R7RSもhash-table-update!を定義していますが、インタフェースが異なるので、 GaucheではR7RS版を別名hash-table-update!-r7として提供します。

 -- Function: hash-table-update!-r7 ht key updater :optional failure success
     This is R7RS version of hash-table-update!.  With no optional arguments, it works like Gauche's hash-table-update!.  But in practice you often needs to specify the behavior when KEY hasn't been in HT, in which case R7RS differs from Gauche.

     The R7RS version works like this but potentially more efficiently: これがR7RS版のhash-table-update!です。省略可能引数を全て省略した場合はGaucheのhash-table-update!と同じになりますが、実際にはKEYがHTに無かった場合の振る舞いを指定する必要があることが多く、その場合R7RSのインタフェースはGaucheと異なってきます。

     R7RS版は、効率を除けば次のとおり動作します。

          (hash-table-put! ht key (updater (hash-table-ref ht key failure success)))

 -- Function: hash-table-update!/default ht key updater default
     [R7RS hash-table] This is the same as Gauche's hash-table-default!, except that the default value can't be omitted. これはDEFAULTが省略できないことを除けば、 Gaucheのhash-table-update!と同じです。

Hash table scanners
-------------------

ハッシュテーブルの走査
-----------

 -- Function: hash-table-for-each ht proc
 -- Function: hash-table-map ht proc
     A procedure PROC is called with two arguments, a key and its associated value, over all the entries in the hash table HT. ハッシュテーブルHT内の全てのエントリについて、各エントリのキーと値を 2つの引数として手続きPROCを呼びます。

 -- Function: hash-table-fold ht kons knil
     For all entries in the hash table HT, a procedure KONS is called with three arguments; a key, its associated value, and the previous return value of KONS. The first call of KONS receives KNIL as the third argument. The return value of the last call of KONS is returned from hash-table-fold. ハッシュテーブルHT内の全てのエントリについてKONSを呼びます。 KONSには3つの引数が渡されます。各エントリのキーと値、および一つ前のKONSの返り値です。最初のKONSの呼び出しの時には、第3引数にKNILが渡されます。最後のKONSの返り値がhash-table-foldの返り値となります。

 -- Function: hash-table-find ht pred :optional failure
     Apply PRED with each key and value in the hash table HT. Once PRED returns a true value, that return value is immediately returned from hash-table-find. If no key-value satisfies PRED, a thunk FAILURE is invoked and its result is returned.  If FAILURE is omitted, (lambda () #f) is assumed. PREDをハッシュテーブルHTの各エントリのキーと値を引数にして呼び出し、それが真の値を返したら直ちにそれを戻り値とします。 PREDを満たすキーと値が無ければ、無引数の手続きFAILUREが呼び出され、その値が戻り値となります。FAILUREが省略された場合は (lambda () #f)が使われます。

     Note: The convention starting from srfi-1 is that *-find returns an item in the collection that satisfy the predicate, while *-any returns a non-false value the predicate returns.  SRFI-125 broke the convention. The justification given in SRFI-125 discussion was that the ``any'' semantics is strictly upper-compatible to the ``find'' semantics so we can combine two.  So far, though, SRFI-125 is the only exception of this convention. 註: srfi-1から始まった慣習では、*-findというAPIは述語を満たすようなコレクション内の要素を返し、*-anyというAPIが述語が偽でない値を返した時にその値をそのまま返り値とします。 SRFI-125が慣習を破った理由は、 ``any''のセマンティクスで従来の ``find'' の動作もエミュレートできるので ``find''が ``any'' の動作も兼ねてしまえばよいというものです。しかし、現在までのところ、この慣習を破っているのはSRFI-125のみです。

          ;; Find if hash tables ha and hb has a common key.
          ;; ハッシュテーブルhaとhbに共通のキーがあるかどうか調べる
          (hash-table-find ha (^[k v] (hash-table-exists? hb k)))

 -- Function: hash-table-keys ht
 -- Function: hash-table-values ht
     Returns all the keys or values of hash table HT in a list, respectively. それぞれ、ハッシュテーブルHT内の全てのキーまたは値をリストにして返します。

Hash table as sets
------------------

集合としてのハッシュテーブル
--------------

 -- Function: hash-table-compare-as-sets ht1 ht2 :optional value=? fallback
     A hash table can be viewed as a set of pairs of key and value. This procedure compares two hash tables HT1 and HT2 as such sets.

     The key comparators of two tables must match (in terms of equal? of the comparators).  Otherwise, an error is signaled.

     Two elements of the set are equal to each other iff their keys match with the equality predicate of the key comparator, and their values match with VALUE=? procedure.  If omitted, equal? is used for VALUE=? ハッシュテーブルは、キーと値の組を要素とする集合とみなすことができます。この手続きは二つのハッシュテーブルHT1とHT2を集合として比較します。

     二つのハッシュテーブルのキー比較器は同じ (equal?の意味で) でなければなりません。そうでない場合はエラーが投げられます。

     二つの要素は、キー同士がキー比較器によって等価と判断され、かつ値同士がVALUE=?手続きによって等価と判断された場合に等しいとみなされます。 VALUE=?が省略された場合はequal?が使われます。

     There can be four cases.

       * If HT1 is a pure subset of HT2, returns -1 (HT1 is smaller than HT2).

       * If HT2 is a pure subset of HT1, returns 1 (HT1 is greater than HT2).

       * If HT1 and HT2 contains exactly the same elements, returns 0 (HT1 equals to HT2).

       * Neither HT1 nor HT2 is a subset of another.  In this case, FALLBACK is returned if it is given, or an error is thrown.

     4通りの結果が有り得ます。

       * HT1がHT2の純粋部分集合である場合は-1が返されます (HT1 ＜ HT2)。

       * HT2がHT1の純粋部分集合である場合は1が返されます (HT1 ＞ HT2)。

       * HT1とHT2がまったく同じだけの要素を含んでいる場合は0が返されます (HT1 ＝ HT2)。

       * HT1とHT2がお互いに相手の部分集合でない場合は、 FALLBACKが与えられていればそれが返され、省略された場合はエラーが投げられます。

 -- Function: hash-table=? value-cmpr ht1 ht2
     [R7RS hash-table] This also compares two hash tables HT1 and HT2 as sets, and returns true iff two are the same.  That is, every element in HT1 is also in HT2 and vice versa.

     Two element are the same iff their keys are the same in terms of the equality predicate of the tables' key comparator, and their values are the same in terms of the equality predicate of a comparator VALUE-CMPR.

     It is an error if HT1 and HT2 has different key comparators. See also hash-table-compare-as-sets above. この手続きもHT1とHT2を集合として比較し、二つのテーブルが等しい集合である場合、つまりHT1の要素がすべてHT2の要素でもあり、またその逆も真である場合に#tを、そうでなければ#fを返します。

     二つの要素は、キー同士がキー比較器によって等価と判定され、かつまた値同士が比較器VALUE-CMPRによって等価と判定された場合に等しいとみなされます。

     HT1とHT2のキー比較器が異なっていた場合はエラーが投げられます。上のhash-table-compare-as-setsも参照してください。

 -- Function: hash-table-union! ht1 ht2
 -- Function: hash-table-intersection! ht1 ht2
 -- Function: hash-table-difference! ht1 ht2
 -- Function: hash-table-xor! ht1 ht2
     [R7RS hash-table] Perform set operations on two hashtables HT1 and HT2, and modify HT1 to store the result. Note that these procedures only look at the keys for operation; if the values of the same key differ between HT1 and HT2, the value in HT1 is taken. 二つのハッシュテーブル間で集合演算を行い、結果をHT1に格納します。これらの手続きでは、集合の要素としてキーだけを見ます。もし同じキーを持つ要素の値がHT1とHT2で異なっていた場合、 HT1の値が優先されます。

       * The union operation picks each entry that is in at least one of HT1 or HT2. unionは、HT1かHT2の少なくとも一方に入っている要素を集めます。

       * The intersection operation picks each entry that is both in HT1 and HT2. intersectionは、HT1とHT2の両方に含まれる要素のみを集めます。

       * The difference operation picks each entry that is in HT1 but not in HT2. differenceは、HT1に含まれるがHT2には含まれない要素のみを集めます。

       * The xor operation picks each entry that is in only one of HT1 or HT2, but not in both. xorは、HT1かHT2の一方のみに含まれる要素のみを集めます。

Treemaps
--------

 -- Builtin Class: <tree-map>
     Tree map class.   Tree maps are a data structure that maps key objects to value objects.  It's like hash tables except tree maps uses balanced tree internally.  Insertion and lookup is O(log n). ツリーマップクラス。ツリーマップはキーオブジェクトから値オブジェクトへの写像をあらわすデータ構造です。ツリーマップでは平衡木を使うということ以外はハッシュテーブルと同じです。ツリーマップでは挿入と検索の手間は O(log n)です。

     Unlike hashtables, a tree map keeps the order of the keys, so it is easy to traverse entries in the order of keys, to find minimum/maximum keys, or to find a key closest to the given value. ハッシュテーブルとはちがい、キーの順序は保存されます。したがってキーの順序どおりにトラバースするのは簡単で、キーの最小値/最大値を見つけたり、指定したキーにもっとも近いキーを探すのも簡単です。

     The <tree-map> class inherits <sequence> and <ordered-dictionary>. <tree-map>クラスは<sequence>および <ordered-dictionary>を継承しています。

 -- Function: make-tree-map :optional comparator
 -- Function: make-tree-map key=? key<?
     Creates and returns an instance of <tree-map>. The keys are compared by COMPARATOR, whose default is default-comparator. The comparator must have a comparison procedure, for we need a total order in the keys. See Basic comparators, for the details.

     For the backward compatibility, make-tree-map also accepts a procedure as a COMPARATOR; the procedure must take two keys and returns either -1, 0, or 1, depending on whether the first key is less than, equal to, or greater than the second key, respectively.  In other words, it is a comparison procedure of a comparator.

     The second form of make-tree-map is also for the backward compatibility; it takes two procedures, each must be a procedure that takes two keys; the first one returns #t iff two keys are equal, and the second one returns #t iff the first key is strictly smaller than the second. <tree-map>オブジェクトを作成して返します。キーは比較器COMPARATORを使って比較されます。COMPARATORのデフォルト値はdefault-comparatorです。キーには全順序関係が必要なので、比較器は比較手続きを持っていなければなりません。詳しくはBasic comparatorsを参照してください。

     互換性のため、make-tree-mapはCOMPARATOR引数に単なる手続きを取ることもできます。渡される手続きは2引数を取り、最初の引数が2番目の引数より小さいか、等しいか、大きいかに応じて -1、0、1をそれぞれ返します。つまりこの手続きは比較器の比較手続きそのものです。

     make-tree-mapの2番目の呼び出し形式も互換性のためのものです。それぞれ2引数の2つの手続きを取り、最初の手続きKEY=?は、2つのキーが等しい場合にのみ真を返し、 2番目の手続きKEY<?は、最初のキーが2番目のキーより前にある(小さい)場合にのみ真を返すようにします。

 -- Function: tree-map-comparator tree-map
     Returns the comparator used in the tree map. TREE-MAPで使われている比較器を返します。

 -- Function: tree-map-copy tree-map
     Copies and returns  TREE-MAP.  Modification on the returned tree doesn't affect the original tree. TREE-MAPのコピーを作り、それを返します。返された木に対する破壊的操作は、元の木に影響を与えません。

 -- Function: tree-map-empty? tree-map
     Returns #t if TREE-MAP doesn't have any elements, or #f otherwise. TREE-MAPが要素を持たないなら#tを、そうでなければ#fを返します。

 -- Function: tree-map-num-entries tree-map
     Returns the number of elements in TREE-MAP. TREE-MAP内の要素の個数を返します。

 -- Function: tree-map-exists? tree-map key
     Returns #t if TREE-MAP has an entry with KEY, or #f otherwise. TREE-MAPにキーKEYを持つエントリがあれば#tを、そうでなければ#fを返します。

 -- Function: tree-map-get tree-map key :optional fallback
     Looks for KEY in TREE-MAP.  If the entry is found, returns a value corresponding to the key.  Otherwise, returns FALLBACK if it is provided, or signals an error. キーKEYをTREE-MAPから探します。見つかればKEYに対応する値を返します。キーが見つからなかった場合、FALLBACKが与えられていればそれを返し、そうでなければエラーを報告します。

 -- Function: tree-map-put! tree-map key value
     Inserts an entry with a KEY and corresponding VALUE into TREE-MAP.  If there already exists an entry with a key which is equivalent (under KEY=?), the entry is modified to have VALUE. キーKEYと対応する値VALUEをTREE-MAPに挿入します。もし、KEYと、 KEY=?における意味で同じキーがすでに存在する場合、キーに対応する値は新たな値に置き換えられます。

 -- Function: tree-map-delete! tree-map key
     Deletes an entry with KEY from TREE-MAP if such an entry exists, and returns #t. If TREE-MAP doesn't have such an entry, #f is returned. TREE-MAPからキーKEYを持つエントリを削除します。KEYを持つエントリが実際に存在して削除された場合は#tを、エントリが存在しなかった場合は#fを返します。

 -- Function: tree-map-clear! tree-map
     Removes all entries in TREE-MAP. TREE-MAP内の全てのエントリを削除します。

 -- Function: tree-map-update! tree-map key proc :optional fallback
     A generalized version of tree-map-push! etc. It works like the following code, except that searching for the key is done only once. tree-map-push!等のより一般的なバージョンです。木の探索が一度しか行われないことを除いては、基本的に次のように動作します。

          (let ((tmp (proc (tree-map-get TREE-MAP KEY FALLBACK))))
            (tree-map-put! TREE-MAP KEY tmp)
            tmp)

 -- Function: tree-map-push! tree-map key value
     Looks for an entry with KEY in TREE-MAP.  If it exists, the procedure conses VALUE to the original value and makes it as a new value. Otherwise, the procedure creates a new entry for the KEY and makes (list VALUE) its value. TREE-MAP中の、キーKEYに対応する値にVALUEをコンスし、それをKEY に対する新たな値とします。もしKEYに対応する値がまだ無ければ、新たなエントリが作成され、(list VALUE)がその値となります。

 -- Function: tree-map-pop! tree-map key :optional fallback
     Looks for an entry with KEY in TREE-MAP.  If it exists and its value is a pair, then the procedure updates its value with cdr of the original value, and returns car of the original entry.   If such an entry does not exist, or has a non-pair value, the procedure doesn't modify TREE-MAP and returns FALLBACK if it is given, otherwise reports an error. TREE-MAP中のキーKEYに対応する値が存在し、かつペアであった場合に、そのエントリの値を元の値のcdrで置き換え、元の値のcarを返します。 KEYに対応する値が存在しないかペアではなかった場合、TREE-MAPは変更されず、FALLBACKが与えられていればそれが返され、与えられていなければエラーが報告されます。

 -- Function: tree-map-min tree-map
 -- Function: tree-map-max tree-map
     Returns a pair of a key and its value with the minimum or maximum key, respectively.   If TREE-MAP is empty, #f is returned. それぞれ、TREE-MAPに含まれる最小および最大のキーを探索し、そのキーと値のペアを返します。TREE-MAPが空だった場合は#fが返されます。

 -- Function: tree-map-pop-min! tree-map
 -- Function: tree-map-pop-max! tree-map
     Looks for an entry with minimum or maximum key, respectively, then deletes the entry from TREE-MAP and returns a pair of the key and its value of the original entry. If TREE-MAP is empty, #f is returned. それぞれ、TREE-MAPに含まれる最小および最大のキーを探索し、そのエントリをTREE-MAPから削除したうえで、そのキーと値のペアを返します。TREE-MAPが空だった場合は#fが返されます。

 -- Function: tree-map-fold tree-map proc seed
 -- Function: tree-map-fold-right tree-map proc seed
     Iterate over elements in TREE-MAP, applying PROC which has a type (key, value, seed) -> seed. The difference of tree-map-fold and tree-map-fold-right is the associative order of applying PROC, just like the difference between fold and fold-right. TREE-MAPの各要素に対し、(key, value, seed) -> seed の型を持つ PROCを適用してゆきます。 tree-map-foldとtree-map-fold-rightの違いは foldのfold-right違いと同じ、すなわち結合の方向にあります。

          tree-map-fold:
            (proc Kn Vn (proc Kn-1 Vn-1 ... (proc K0 V0 seed)))

          tree-map-fold-right
            (proc K0 V0 (proc K1 V1 ... (proc Kn Vn seed)))

     Some examples: 例:

          (define tree (alist->tree-map '((3 . a) (7 . b) (5 . c)) = <))

          (tree-map-fold tree list* '())
             => (7 b 5 c 3 a)
          (tree-map-fold-right tree list* '())
             => (3 a 5 c 7 b)

 -- Function: tree-map-map tree-map proc
     Calls PROC, which must take two arguments, with each key/value pair in TREE-MAP, and collect the results into a list and returns it.  The order of results corresponds to the order of keys---that is, the first element of the result list is what PROC returns with minimum key and its value, and the last element of the result list is what PROC returns with the maximum key and its value. (Note: Like map, the order that PROC is actually called is unspecified; PROC is better to be side-effect free.) 2引数を取る手続きPROCを、TREE-MAPの各キーおよび値のペアに対して呼び出し、結果をリストにして返します。結果のリストは、キーの昇順に並んでいます。つまり、最小のキーとその値で呼び出した PROCの結果が最初の要素に、最大のキーとその値で呼び出したPROCの結果が最後の要素になります。 (mapと同様、実際にPROCが呼ばれる順序は保証されていません。したがってPROCは副作用の無いものにすべきです)。

 -- Function: tree-map-for-each tree-map proc
     Calls PROC, which must take two arguments, with each key/value pair in TREE-MAP, in the increasing order of the keys.  PROC is called purely for side effects; the returned values are discarded. 2引数を取る手続きPROCを、TREE-MAPの各キーおよび値のペアに対して、キーの昇順に呼び出します。PROCは副作用のためだけに呼ばれ、結果は捨てられます。

 -- Function: tree-map-floor tree-map probe :optional fallback-key fallback-value
 -- Function: tree-map-ceiling tree-map probe :optional fallback-key fallback-value
 -- Function: tree-map-predecessor tree-map probe :optional fallback-key fallback-value
 -- Function: tree-map-successor tree-map probe :optional fallback-key fallback-value
     These procedures search the entry which has the closest key to the given PROBE.  If such an entry is found, returns two values, its key and its value.  Otherwise, returns two values, FALLBACK-KEY and FALLBACK-VALUE, both defaulted to #f.

     The criteria of ``closest'' differ slightly among these procedures; tree-map-floor finds the maximum key which is no greater than PROBE; tree-map-ceiling finds the minimum key which is no less than PROBE; tree-map-predecessor finds the maximum key which is strictly less than PROBE; and tree-map-successor finds the minimum key which is strictly greater than PROBE. これらの手続きは、PROBEに最も近いキーを持つエントリをTREE-MAPから探します。そのようなエントリが見つかれば、該当するキーと値が2つの戻り値となります。見つからない場合は、FALLBACK-KEYとFALLBACK-VALUEが 2つの戻り値として返されます。それぞれの省略時の値は#fです。

     それぞれの手続きは異なった「最も近い」の基準を持っています。 tree-map-floorはPROBE以下で最大のキーを、 tree-map-ceilingはPROBE以上で最小のキーを、 tree-map-predecessorはPROBE未満で最大のキーを、 tree-map-successorはPROBEを越える最小のキーを探します。

 -- Function: tree-map-floor-key tree-map probe OPTIONAL fallback-key
 -- Function: tree-map-ceiling-key tree-map probe OPTIONAL fallback-key
 -- Function: tree-map-predecessor-key tree-map probe OPTIONAL fallback-key
 -- Function: tree-map-successor-key tree-map probe OPTIONAL fallback-key
     Like tree-map-floor etc., but only returns the key of the found entry (or FALLBACK-KEY if there's no entry which satisfies the criteria). tree-map-floor等と同様ですが、見つかったエントリのキーのみを返します。該当エントリが見つからない場合はFALLBACK-KEYの値(デフォルトは#f)が返されます。

 -- Function: tree-map-floor-value tree-map probe OPTIONAL fallback-value
 -- Function: tree-map-ceiling-value tree-map probe OPTIONAL fallback-value
 -- Function: tree-map-predecessor-value tree-map probe OPTIONAL fallback-value
 -- Function: tree-map-successor-value tree-map probe OPTIONAL fallback-value
     Like tree-map-floor etc., but only returns the value of the found entry (or FALLBACK-VALUE if there's no entry which satisfies the criteria). tree-map-floor等と同様ですが、見つかったエントリの値のみを返します。該当エントリが見つからない場合はFALLBACK-VALUEの値(デフォルトは#f)が返されます。

 -- Function: tree-map-keys tree-map
 -- Function: tree-map-values tree-map
     Returns a list of all keys and all values, respectively. The keys and values are in ascending order of the keys. それぞれ、TREE-MAP内の全てのキーまたは値をリストにして返します。返されるリストの要素はキーの昇順に並んでいます。

 -- Function: tree-map->alist tree-map
     Returns a list of pairs of keys and values for all entries. The pairs are in ascending order of the keys. TREE-MAP含まれる要素を連想リストにして返します。返される連想リストのキーは昇順に並んでいます。

 -- Function: alist->tree-map alist :optional comparator
 -- Function: alist->tree-map alist key=? key<?
     Creates a new tree map with the COMPARATOR or KEY=?/KEY<? procedures, then populates it with ALIST, each pair in which are interpreted as a cons of a key and its value. The meaning of COMPARATOR, KEY=? and KEY<? are the same as make-tree-map. COMPARATORまたはKEY=?, KEY<? によって新たなtreemapを作成し、連想リストALISTに含まれる要素を追加した上で返します。 ALISTの各ペアのcarがキーに、cdrが値に使われます。 COMPARATOR, KEY=?, key<?引数の意味は make-tree-mapと同じです。

The following two procedures compares two tree maps with slightly different views. 以下の二つの手続きは二つのツリーマップを比較しますが、見方が異なります。

 -- Function: tree-map-compare-as-sets tree-map1 tree-map2 :optional value=? fallback
     Compares two tree maps as sets of entries.  If we look at tree maps as sets of entries, we can define a partial order between two maps; they are equal to each other if they have exactly the same entries, and tree-map A is smaller than tree-map B if A us a strict subset of B.

     If TREE-MAP1 and TREE-MAP2 are the same, 0 is returned.  If TREE-MAP1 is smaller than TREE-MAP2, -1 is returned.  If TREE-MAP1 is greater than TREE-MAP2, 1 is returned.

     If one argument isn't subset of the other, we can't determine the order. In such a case, if FALLBACK is given, it is returned.  Otherwise, an error is signalled.

     The comparators of TREE-MAP1 and TREE-MAP2 must be the same (equal?), otherwise an error is signalled. See Basic comparators, about the comparators.

     An entry is equal to another entry if their keys match in terms of the comparator of the tree-map, and also their values match with the provided VALUE=? predicate, which is defaulted to equal?. 二つのツリーマップを、エントリの集合として比較します。エントリの集合として見れば、ツリーマップ間に半順序関係を定義できます。すなわち、全てのエントリが等しければツリーマップ同士も等しく、ツリーマップAがツリーマップBの真部分集合であれば AはBより小さい、とします。

     TREE-MAP1とTREE-MAP2が等しければ0が、 TREE-MAP1の方がTREE-MAP2より小さければ-1が、 TREE-MAP1の方がTREE-MAP2より大きければ1が返されます。

     どちらのツリーマップも相手の部分集合になっていない場合は、順序が決められません。その場合、FALLBACK引数が与えられていればその値が返され、与えられていなければエラーが報告されます。

     TREE-MAP1とTREE-MAP2の比較器はequal?の意味で等しくなければなりません。比較器についてはBasic comparatorsを参照してください。

     エントリは、それぞれのキーがツリーマップの比較器による比較で等しく、かつ対応する値がVALUE=?手続きによる比較で等しい場合にのみ等しいとみなされます。 VALUE=?が省略された場合はequal?が使われます。

          (tree-map-compare-as-sets
           (alist->tree-map '((1 . a) (2 . b) (3 . c)) default-comparator)
           (alist->tree-map '((3 . c) (1 . a) (2 . b)) default-comparator))
           => 0

          (tree-map-compare-as-sets
           (alist->tree-map '((1 . a) (3 . c)) default-comparator)
           (alist->tree-map '((3 . c) (1 . a) (2 . b)) default-comparator))
           => -1

          (tree-map-compare-as-sets
           (alist->tree-map '((1 . a) (3 . c) (4 . d) (2 . b)) default-comparator)
           (alist->tree-map '((3 . c) (1 . a) (2 . b)) default-comparator))
           => 1

          (tree-map-compare-as-sets
           (alist->tree-map '((1 . a) (3 . c) (4 . d)) default-comparator)
           (alist->tree-map '((3 . c) (1 . a) (2 . b)) default-comparator))
           => ERROR: tree-maps can't be ordered

          (tree-map-compare-as-sets
           (alist->tree-map '((1 . a) (3 . c) (4 . d)) default-comparator)
           (alist->tree-map '((3 . c) (1 . a) (2 . b)) default-comparator)
           eq?
           #f)
           => #f

 -- Function: tree-map-compare-as-sequences tree-map1 tree-map2 :optional value-cmp
     Compares two tree maps as sequence of entries, ordered by keys. If both maps have entries with the same key, we use a comparator VALUE-CMP to break the tie (naturally, VALUE-CMP must have ordering predicate.) If VALUE-CMP is omitted, default-comparator is used.

     The comparators of TREE-MAP1 and TREE-MAP2 must be the same (equal?), otherwise an error is signalled. See Basic comparators, about the comparators.

     If TREE-MAP1 and TREE-MAP2 are the same, 0 is returned.  If TREE-MAP1 is smaller than TREE-MAP2, -1 is returned.  If TREE-MAP1 is greater than TREE-MAP2, 1 is returned.

     Unlike tree-map-compare-as-sets, this procedure defines total order of tree maps which share the same comparator. 二つのツリーマップを、キーの順序で並べられたエントリのシーケンスとして比較します。両マップにキーが同じであるエントリがあった場合は、対応する値同士をVALUE-CMP比較器で比べます (従って、VALUE-CMPは比較述語を持っていなければなりません。) VALUE-CMPが省略された場合はdefault-comparatorが使われます。

     TREE-MAP1とTREE-MAP2の比較器はequal?の意味で等しくなければなりません。比較器についてはBasic comparatorsを参照してください。

     TREE-MAP1とTREE-MAP2が等しければ0が、 TREE-MAP1の方がTREE-MAP2より小さければ-1が、 TREE-MAP1の方がTREE-MAP2より大きければ1が返されます。

     tree-map-compare-as-setsと異なり、この手続きは比較器が同じであるようなツリーマップについて全順序関係を定義します。

          (tree-map-compare-as-sequences
           (alist->tree-map '((1 . a) (3 . c)) default-comparator)
           (alist->tree-map '((3 . c) (2 . b)) default-comparator))
           => -1

          (tree-map-compare-as-sequences
           (alist->tree-map '((2 . b) (3 . d)) default-comparator)
           (alist->tree-map '((3 . c) (2 . b)) default-comparator))
           => 1

Procedures and continuations
============================

In Scheme, procedures are fundamental blocks to build a program (see Making procedures). A procedure represents a certain computation, possibly parameterized, and can be applied to the actual arguments to execute the computation.  Scheme also provides the means to extract the continuation of the current computation and wraps it in a procedure (see Continuations). Schemeでは、プログラムを組み立てる最も基本となるブロックが手続きです (Making proceduresも参照)。手続きは、特定の計算を表現します。引数を取ることも出来ます。そして、実引数に適用されると、その計算を実行します。 Schemeはまた、現在の計算の継続を取り出して手続きにラップして返す手段を提供しています(Continuations参照)。

Gauche extends the concept of procedure application, allowing you to apply any object as if it's a procedure; for example, you can set up Gauche to accept ("abc" 2) can be a valid application syntax. See Applicable objects, for the details. Gaucheは手続きの適用の概念を拡張し、どんなオブジェクトでもそれが手続きであるかのように適用できるようにしました。例えば("abc" 2)が有効な適用であるように Gaucheをセットアップすることができます。詳しくはApplicable objectsを参照してください。

Procedure class and applicability
---------------------------------

 -- Builtin Class: <procedure>
     Represents a procedure.  Ordinary Scheme procedures created by lambda is an instance of this class, as well as built-in primitive procedures written in C.  Note that, in Gauche, other type of objects can behave as a procedure; so checking whether an object is a procedure or not doesn't mean much unless you want to mess around with Gauche internals. 手続きのクラスです。lambdaで作られた手続きや組み込みのプリミティブ手続きはこのクラスのインスタンスです。 Gaucheではどんな型のオブジェクトも適用可能にできるので、あるオブジェクトが <procedure>クラスのインスタンスであるかとうかということはあまり気にする必要はありません。Gaucheの中身をいじってみる時以外は。

 -- Function: procedure? obj
     [R7RS base] Returns #t if OBJ is inherently applicable objects, #f otherwise.  By inherently applicable we mean Gauche unconditionally understands that OBJ can be called as a procedure; an instance of <procedure> is so, as well as generic functions (<generic>) and methods (<method>). See Generic function and method, for the details. OBJが生得的に適用可能なオブジェクトであれば#tを、そうでなければ#fを返します。生得的にというのは、 Gaucheが最初から手続きとして呼び出せるオブジェクトとして備えているもの、程度の意味です。 <procedure>クラスのインスタンスや、ジェネリックファンクションやメソッドがそうです。 (ジェネリックファンクションとメソッドに関しては Generic function and methodを参照してください)。

     Since you can make any type of objects applicable at any time (see Applicable objects), the fact that procedure? returned #f doesn't mean that the object cannot be applied. To check if an object can be applied or not, use applicable? below. Gaucheでは、どんなオブジェクトも適用可能にすることができます (Applicable objects参照)。従って、procedure?が#fを返したからといってそのオブジェクトを手続きのように呼び出せないとは限りません。オブジェクトが適用可能かどうかをより正確に調べるには、下に説明するapplicable?を使ってください。

 -- Function: apply proc arg1 ... args
     [R7RS base] Calls a procedure PROC with a list of arguments, (ARG1 ... . ARGS). The last argument ARGS must be a proper list. Returns (a) value(s) PROC returns. (ARG1 ... . ARGS)を引数として手続きPROCを呼びます。最後の引数ARGSは正規のリストでなければなりません。 PROCが返す値をそのまま返します。

          (apply list 'a 'b '(c d e)) => (a b c d e)

          (apply + 1 2 '(3 4 5))      => 15

 -- Function: applicable? obj class ...
     Checks if OBJ can be called with the types of arguments listed in CLASS ....  That is, when (applicable? foo <string> <integer>) returns #t, then you can call foo as (foo "x" -2), for example. (It doesn't mean you won't get an error; foo may be accept only nonnegative integers, which you cannot tell from the result of applicable?.  But if applicable? returns #t, Gauche won't complain ``foo is not applicable'' when you call foo. それぞれの型がCLASS ...であるような引数リストを伴って OBJを呼び出すことができるかどうかを調べます。例えば(applicable? foo <string> <integer>)が#tを返したなら、fooを(foo "x" -2)のように呼び出せるということです。 (これは、エラーが出ないことを保証するものではありません。fooはもしかする非負整数しか受け取れないかもしれませんが、そのことは applicable?の結果からはわかりません。でも、applicable?が#tを返したなら、fooを呼び出した時に``foo is not applicable''と Gaucheに文句を言われることはありません。)

     This procedure takes applicable objects into account.  So, for example, (applicable? #/a/ <string>) returns #t, for the regular expressions are applicable to a string (see Regular expressions). この手続きは適用可能オブジェクトも考慮に入れます。従って、例えば(applicable? #/a/ <string>)は#tを返します。正規表現は文字列に適用可能だからです (Regular expressions参照)。

     For generic functions, applicable? returns #t if it has at least one method such that each of its specifiers is a superclass of the corresponding CLASS argument given to applicable?. ジェネリックファンクションに対しては、渡されたCLASS引数それぞれが、対応する特定化子と一致するかサブクラスになっているようなメソッドが最低ひとつあれば、applicable?は#tを返します。

          (define-method foo ((x <sequence>) (y <integer>)) #f)

          (applicable? foo <sequence> <integer>) => #t
          (applicable? foo <string> <integer>) => #t
          (applicable? foo <hash-table> <integer>) => #f
          (applicable? foo <string> <real>) => #f

     The second example returns #t since <string> is a subclass of <sequence>, while the third example returns #f since <hash-table> isn't a subclass of <sequence>.  The fourth example returns #f since <real> isn't a subclass of <integer>. 2番目の例では、<string>は<sequence>のサブクラスなので #tが返ります。一方、3番目の例では<hash-table>は <sequence>のサブクラスではないので#fとなります。 4番めの例が#fなのは、<real>が<integer>のサブクラスではないからです。

     Traditional Scheme procedures (such as ones created by lambda) only cares the number of arguments but not their types; it accepts any type as far as the number of arguments matches.  To check such a condition, pass <top> as the argument class.  (<top> is a superclass of all classes.) 伝統的なSchemeの手続き (lambdaで作られるようなもの) は引数の数のみで呼び出し可能かどうかが判断されます。オブジェクトが引数の型にかかわらず、特定の個数の引数を取るかどうかを判定するには、 CLASS引数に<top>を渡します。(<top>は全てのクラスのスーパークラスです。)

          (applicable? cons <top> <top>) => #t

     If you want to check an object is applicable to a certain number of some class of arguments, you can pass <bottom> as the argument class instead.   (<bottom> is a subclass of all classes.) 逆に、何らかの特定の型の引数を取るかどうかを調べたい場合は、 <bottom>を渡してください。(<bottom>は全てのクラスのサブクラスです。)

          (define-method foo ((x <sequence>) (y <integer>)) #f)

          (applicable? foo <top> <top>) => #f
          (applicable? foo <bottom> <bottom>) => #t

     See Types and classes, for the details of <top>, <bottom> and Gauche's type handling. <top>, <bottom>クラスおよびGaucheでの型の扱いについては Types and classesを参照してください。

Universal accessor
------------------

 -- Function: ~ obj key keys ...
 -- Function: (setter ~) obj key keys ...
     The procedure ~ can be used to access a part of various aggregate types. 手続き~は、様々な集合型のオブジェクトの部分にアクセスするのに使えます。

          ;; Access to an element of a sequence by index
          (~ '(a b c) 0)       => a
          (~ '#(a b c) 2)      => c
          (~ "abc" 1)          => #\b
          (~ '#u8(10 20 30) 1) => 20

          ;; Access to an element of a collection by key
          (~ (hash-table 'eq? '(a . 1) '(b . 2)) 'a)
            => 1

          ;; Access to a slot of an object by slot name
          (~ (sys-localtime (sys-time)) 'hour)
            => 20

     The access can be chained: アクセスはチェインすることができます。

          (~ '#((a b c) (d e f) (g h i)) 1 2) => f

          (~ (hash-table 'eq? '(a . "abc") '(d . "def")) 'a 2)
            => #\c

     You can think ~ as left-associative, that is, ~は左結合します。つまり、

          (~ x k j) == (~ (~ x k) j)

     and so on. 等。

     The generalized setter set! can be used with ~ to replace the specified element. 一般化されたset!を~に使えば、アクセスされる要素を置き換えることができます。

          (define z (vector 'a 'b 'c))
          (set! (~ z 1) 'Z)

          z => #(a Z c)

          (define z (vector (list (vector 'a 'b 'c)
                                  (vector 'd 'e 'f)
                                  (vector 'g 'h 'i))
                            (list (vector 'a 'b 'c)
                                  (vector 'd 'e 'f)
                                  (vector 'g 'h 'i))))

          z => #((#(a b c) #(d e f) #(g h i))
               (#(a b c) #(d e f) #(g h i)))

          (set! (~ z 1 2 0) 'Z)
          z =>  #((#(a b c) #(d e f) #(g h i))
               (#(a b c) #(d e f) #(Z h i)))

Internally, a call to ~ is implemented by a generic function ref.  See Object system for more about generic functions. ~は内部的にジェネリックファンクションrefを使って実現されています。ジェネリックファンクションについて詳しくはObject systemを参照してください。

 -- Generic function: ref object key :optional args ...
 -- Generic function: (setter ref) object key value
     Many aggregate types defines a specialized method of these to provide uniform access and mutation.   Meaning of optional arguments ARGS of ref depends on each specialized method, but it is common that the first optional argument of ref is a fallback value, which is to be returned when OBJECT doesn't have a meaningful association with KEY. 多くの集合型はこのジェネリックファンクションを特殊化し、統一されたアクセス方法と変更方法を提供しています。 refのオプショナル引数ARGSの意味はメソッド毎に異なりますが、最初のオプショナル引数は、OBJECTのKEYに対する値が無い場合のフォールバック値として使われるのが普通です。

     The manual entry of each aggregate type shows the specialized method and its semantics in detail. 正確な動作の定義は、refメソッドを提供しているクラスごとに説明されています。

Conceptually, ~ can be understood as follows: ~の動作は次のコードで理解できるでしょう。

     (define ~
       (getter-with-setter
        (case-lambda
          [(obj selector) (ref obj selector)]
          [(obj selector . more) (apply ~ (ref obj selector) more)])
        (case-lambda
          [(obj selector val) ((setter ref) obj selector val)]
          [(obj selector selector2 . rest)
           (apply (setter ~) (ref obj selector) selector2 rest)])))

(Gauche may use some short-cut for optimization, though, so this code may not reflect the actual implementation.) (Gaucheは最適化のためにいくつかの型で短絡経路を使うこともあるので、実際の実装とは異なります)

Combinators
-----------

Gauche has some primitive procedures that allows combinatory programming. Gaucheには、combinatory programmingに使えるいくつかの基本手続きがあります。

 -- Function: pa$ proc arg ...
     Partial application.  Returns a procedure, and when it is called with arguments M ..., it is equivalent to call (proc arg ... m ...). 部分適用。手続きを返します。その手続きが引数M ...を伴って呼ばれた場合、それは(proc arg ... m ...)と等価になります。

          (define add3 (pa$ + 3))
          (add3 4) => 7

          (map (pa$ * 2) '(1 2 3)) => (2 4 6)

     Macros cut and cute defined in SRFI-26 provide a similar abstraction, with a bit more flexible but less compact notation.  See Making procedures. SRFI-26で定義されているマクロcutとcuteも似たような抽象化の方法を提供しますが、pa$より多少柔軟性が高く、その分やや冗長です。 Making proceduresを参照して下さい。

 -- Function: apply$ proc
 -- Function: map$ proc
 -- Function: for-each$ proc
     Partial application versions of apply, map and for-each. apply, mapとfor-eachの部分適用版です。

          (define map2* (map$ (pa$ * 2)))
          (map2* '(1 2 3)) => (2 4 6)

 -- Function: count$ pred
 -- Function: fold$ kons :optional knil
 -- Function: fold-right$ kons :optional knil
 -- Function: reduce$ f :optional ridentity
 -- Function: reduce-right$ f :optional ridentity
 -- Function: filter$ pred
 -- Function: remove$ pred
 -- Function: partition$ pred
 -- Function: member$ item
 -- Function: find$ pred
 -- Function: find-tail$ pred
 -- Function: any$ pred
 -- Function: every$ pred
 -- Function: delete$ pred
 -- Function: assoc$ item
     Partial application versions of some srfi-1 (R7RS (scheme list)) procedures (see R7RS lists). SRFI-1 (R7RS (scheme list)) (R7RS lists参照)の手続に対応する部分適用版手続。

 -- Function: .$ f ...
 -- Function: compose f ...
     Combine procedures.  All arguments must be procedures. When two procedures are given, (.$ f g) is equivalent to the following code: 複数の手続きを結合します。引数は全て手続きでなければなりません。 2つの引数が渡された時、(.$ f g)は次の式と等価です。

          (lambda args (call-with-values (lambda () (apply g args)) f))

     When more than two arguments are passed, they are composed as follows: 2つ以上の引数が渡された場合は、次のように結合されます。

          (.$ f g h ...) == (.$ (.$ f g) h ...)

     Some examples: いくつか例を示します。

          (define not-zero? (.$ not zero?))
          (not-zero? 3) => #t
          (not-zero? 0) => #f

          (define dot-product (.$ (apply$ +) (map$ *)))
          (dot-product '(1 2 3) '(4 5 6)) => 32

     A couple of edge cases: if only one argument is given, the argument itself is returned.  If no arguments are given, the procedure values is returned. 境界のケース：ひとつだけ引数が渡された場合は、その引数がそのまま返されます。引数が全く渡されなかった場合は手続きVALUESが返されます。

     Note: The name .$ comes from the fact that . is commonly used for function composition in literatures and some programming languages, and that Gauche uses suffix $ to indicate combinators.   However, since it is not a valid R7RS identifier, portable programs may want to use the alias compose, with which you can easily add a portable definition using srfi-0, for example. 註: .$という名前は、文献やいくつかの他のプログラミング言語で .が関数合成によく使われること、そしてGaucheではコンビネータの末尾に $をつける習慣があることから来ています。ただ、これはR7RSの範囲内では有効な識別子でないので、ポータビリティを考えるプログラムは別名のcomposeを使った方が良いでしょう。そうすればsrfi-0などを使って容易に移植が可能です。

 -- Function: identity obj
     Returns OBJ. OBJを返します。

 -- Function: constantly obj
     Returns a procedure that takes arbitrary number of arguments, discards them, and returns OBJ.  Same as (^ _ obj). 任意個の引数をとり、それらを無視してOBJを返す関数を返します。 (^ _ obj)と同じです。

 -- Function: complement pred
     Returns a procedure that reverses the meaning of the predicate PRED. That is, for the arguments for which PRED returns true return false, and vice versa. 述語PREDの意味を逆にした手続きを返します。すなわち、PREDが真を返すような引数にたいして偽を返す、またその逆も同様であるような手続きです。

          (map (complement even?) '(1 2 3)) => '(#t #f #t)
          (map (complement =) '(1 2 3) '(1 1 3)) => '(#f #t #f)
          ((complement (lambda () #f))) => #t

 -- Function: any-pred pred ...
     Returns a procedure which applies given argument(s) to each predicate PRED.  If any PRED returns a non-#f value, the value is returned.  If all the PREDs return #f, #f is returned. 与えられた引数をそれぞれ述語PREDに適用する手続きを返します。いずれかのPREDが#fでない値を返す場合、その値を返します。全てのPREDが#fを返す場合、#fを返します。

          (define string-or-symbol? (any-pred string? symbol?))
          (string-or-symbol? "abc") => #t
          (string-or-symbol? 'abc)  => #t
          (string-or-symbol? 3)     => #f

          (define <> (any-pred < >))
          (<> 3 4) => #t
          (<> 3 3) => #f

          ((any-pred (cut memq <> '(a b c))
                     (cut memq <> '(1 2 3)))
           'b)  => '(b c)

 -- Function: every-pred pred ...
     Returns a procedure which applies given argument(s) to each predicate PRED.  If every PRED returns a non-#f value, the value returned by the last PRED is returned.  If any PRED returns #f, every-pred returns #f without calling further PREDs. 与えられた引数をそれぞれ述語PREDに適用する手続きを返します。全てのPREDが#fでない値を返す場合、戻り値は最後の PREDの戻り値になります。いずれかのPREDが#fを返す場合、every-predはそれ以降のPREDを呼び出さずに #fを返します。

          ((every-pred odd? positive?) 3)  => #t
          ((every-pred odd? positive?) 4)  => #f
          ((every-pred odd? positive?) -3) => #f

          (define safe-length (every-pred list? length))
          (safe-length '(a b c))  => 3
          (safe-length "aaa")     => #f

Optional argument parsing
-------------------------

Gauche supports optional and keyword arguments in extended lambda syntax (see Making procedures).  However, you can also use the following macros to parse optional and keyword arguments, without relying Gauche's extension. Gaucheは省略可能引数やキーワード引数を拡張lambda構文でサポートしています (Making procedures参照)。けれども、Gauche拡張に頼らずに、以下のマクロを使って独自にこれらの引数をパーズすることもできます。

     (define (foo a b :optional (c #f) (d 'none))
       body ...)

     ;; is roughly equivalent to ...
     ;; は次の式とだいたい同じ:

     (define (foo a b . args)
       (let-optionals* args ((c #f) (d 'none))
         body ...))

Explicitly parsing the extended arguments may be useful for portable programs, since it is rather straightforward to implement those macros rather than extend lambda syntax.

Those macros can also be useful to factor out common argument parsing routines. 明示的に拡張引数をパーズする方法は、ポータブルなコードを書く時に役に立つでしょう。以下のマクロを実装するのは、lambdaの構文を拡張するより簡単だからです。

また、共通する拡張引数の処理ルーチンを括り出す場合にもこれらのマクロは有用です。

 -- Macro: let-optionals* restargs (var-spec ...) body ...
 -- Macro: let-optionals* restargs (var-spec ... . restvar) body ...
     Given a list of values RESTARGS, binds variables according to VAR-SPEC, then evaluates BODY. 与えられた値のリストRESTARGSを、VAR-SPECにしたがって変数に束縛し、BODYを評価します。

     VAR-SPEC can be either a symbol, or a list of two elements and its car is a symbol.  The symbol is the bound variable name. The values in RESTARGS are bound to the symbol in order. If there are not as many values in RESTARGS as VAR-SPEC, the rest of SYMBOLs are bound to the default values, determined as follows: If VAR-SPEC is just a symbol, the default value is undefined.  If VAR-SPEC is a list, the default value is the result of evaluation of the second element of the list. In the latter case the second element is only evaluated when there are not enough arguments. The binding proceeds in the order of VAR-SPEC, so the second element may refer to the bindings of previous VAR-SPEC. VAR-SPECはシンボルか、そのcarがシンボルである2要素のリストのいずれかです。シンボルは束縛された変数名です。 RESTARGSにある値は、順番にシンボルに束縛されます。 RESTARGSにVAR-SPECに示される数の値がない場合は、残りのSYMBOLは以下に従ってデフォルト値が束縛されます。 VAR-SPECが単なるシンボルなら、デフォルト値は未定義です。 VAR-SPECがリストなら、デフォルト値はリストの2番目の要素を評価した結果です。後者の場合、2番目の要素は十分な引数がない場合にのみ評価されます。束縛はVAR-SPECの順番にしたがって行われるので、2番目の要素は以前のVAR-SPECのバインディングを参照するかも知れません。

     In the second form, RESTVAR must be a symbol and bound to the list of values whatever left from RESTARGS after binding to VAR-SPEC. 2番目のフォームでは、RESTVARはシンボルでなければならず、 VAR-SPECに束縛された後、RESTARGSに残っている値のリストに束縛されます。

     It is not an error if RESTARG has more values than VAR-SPECs. The extra values are simply ignored in the first form. RESTARGがVAR-SPECよりも多い値を持っていてもエラーではありません。最初のフォームでは、余分な値は単に無視されます。

          (define (proc x . args)
            (let-optionals* args ((a 'a)
                                  (b 'b)
                                  (c 'c))
              (list x a b c)))

          (proc 0)         => (0 a b c)
          (proc 0 1)       => (0 1 b c)
          (proc 0 1 2)     => (0 1 2 c)
          (proc 0 1 2 3)   => (0 1 2 3)

          (define (proc2 . args)
            (let-optionals* args ((a 'a) . b)
              (list a b)))

          (proc2)          => (a ())
          (proc2 0)        => (0 ())
          (proc2 0 1)      => (0 (1))
          (proc2 0 1 2)    => (0 (1 2))

          (define (proc3 . args)
            (let-optionals* args ((a 0)
                                  (b (+ a 1))
                                  (c (+ b 1)))
              (list a b c)))

          (proc3)          => (0 1 2)
          (proc3 8)        => (8 9 10)
          (proc3 8 2)      => (8 2 3)
          (proc3 8 2 -1)   => (8 2 -1)

 -- Macro: get-optional restargs default
     This is a short version of let-optionals* where you have only one optional argument.  Given the optional argument list RESTARGS, this macro returns the value of optional argument if one is given, or the result of DEFAULT otherwise.  DEFAULT is not evaluated unless RESTARGS is an empty list. これはlet-optionals*の短いバージョンで、オプショナル引数が 1つしかないときに使います。オプショナル引数のリストとしてRESTARGSが与えらると、このマクロはオプショナル引数が与えられていればその値を返し、そうでなければDEFAULTの結果を返します。DEFAULTはRESTARGSが空リストでなければ評価されません。

          (define (proc x . maybe-opt)
            (let ((option (get-optional maybe-opt #f)))
              (list x option)))

          (proc 0)         => (0 #f)
          (proc 0 1)       => (0 1)

 -- Macro: let-keywords restarg (var-spec ...) body ...
 -- Macro: let-keywords restarg (var-spec ... . restvar) body ...
     This macro is for keyword arguments.  VAR-SPEC can be one of the following forms: このマクロはキーワード引数のためのものです。VAR-SPECは以下のフォームのうちのいずれかです。

     (SYMBOL EXPR)
          If the RESTARG contains keyword which has the same name as SYMBOL, binds SYMBOL to the corresponding value.  If such a keyword doesn't appear in RESTARG, binds SYMBOL to the result of EXPR. RESTARGがSYMBOLと同じ名前を持つキーワードを含んでいる場合、 SYMBOLを対応する値に束縛します。そのようなキーワードがRESTARGにない場合は、SYMBOLをEXPRの結果に束縛します。

     (SYMBOL KEYWORD EXPR)
          If the RESTARG contains keyword KEYWORD, binds SYMBOL to the corresponding value.  If such a keyword doesn't appear in RESTARG, binds SYMBOL to the result of EXPR. RESTARGがキーワードKEYWORDを含む場合、 SYMBOLを対応する値に束縛します。そのようなキーワードがRESTARGにない場合、SYMBOLをEXPRの結果に束縛します。

     The default value EXPR is only evaluated when the keyword is not given to the RESTARG. デフォルト値EXPRは、RESTARGにキーワードが与えられてなかった場合にのみ評価されます。

     If you use the first form, let-keyword throws an error when restarg contains a keyword argument that is not listed in VAR-SPECs. When you want to allow keyword arguments other than listed in VAR-SPECs, use the second form.

     In the second form, RESTVAR must be either a symbol or #f. If it is a symbol, it is bound to a list of keyword arguments that are not processed by VAR-SPECs.  If it is #f, such keyword arguments are just ignored. 1番目のフォームでは、VAR-SPECにないキーワード引数がRESTARGに現れるとエラーとなります。他のキーワード引数を許したい場合は次の2番目のフォームを使ってください。

     2番目のフォームでは、RESTVARはシンボルか#fでなければなりません。シンボルのときは、VAR-SPECに束縛されなかったRESTARGSのキーワードリストがRESTVARに束縛されます。#fのときは、それらのRESTARGS のキーワードは単に無視されます。

          (define (proc x . options)
            (let-keywords options ((a 'a)
                                   (b :beta 'b)
                                   (c 'c)
                                   . rest)
              (list x a b c rest)))

          (proc 0)         => (0 a b c ())
          (proc 0 :a 1)    => (0 1 b c ())
          (proc 0 :beta 1) => (0 a 1 c ())
          (proc 0 :beta 1 :c 3 :unknown 4) => (0 a 1 3 (:unknown 4))

 -- Macro: let-keywords* restarg (var-spec ...) body ...
 -- Macro: let-keywords* restarg (var-spec ... . restvar) body ...
     Like let-keywords, but the binding is done in the order of VAR-SPECs.  So each EXPR can refer to the variables bound by preceding VAR-SPECs. このマクロはlet-keywordsとほぼ同じですが、束縛がVAR-SPECでの順番に行われるところが異なります。EXPRは以前のVAR-SPECにより束縛された変数を参照できます。

Procedure arity
---------------

Interface to query procedure's arity. The API is taken from MzScheme (PLT Scheme). 手続きのアリティを問い合わせるインターフェースです。 APIは、MzScheme (PLT Scheme)を参考にしました。

 -- Function: arity PROC
     Given procedure PROC, returns an integer, an arity-at-least object, or a list of integer(s) and arity-at-least objects. 手続きPROCを与え、整数、arity-at-leastオブジェクト、整数とarity-at-leastオブジェクトからなるリストのいずれかを返します。

     An integer result indicates PROC takes exactly that number of arguments.  An arity-at-least indicates PROC takes at least (arity-at-least-value arity-at-least) arguments.   The list indicates there are multiple procedures with different arities. 整数の戻り値は、PROCが正確にその数の引数を取ることを表します。 arity-at-leastは、PROCが最低でも引数(arity-at-least-value arity-at-least)を取ることを表します。リストは、異なるアリティを持つ複数の手続きがあることを表します。

     Since one can add methods to an existing procedure or generic function at any moment in Gauche, the value returned by arity only indicates the current state of the procedure.  It will change if new method is added to the procedure/generic-function. Gaucheではいつでも、既存の手続きやジェネリック関数にメソッドを追加できるので、arityが返す値はその手続きの現在の状態を示すに過ぎません。その手続きやジェネリック関数に新しいメソッドが追加されると、それも変更されます。

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

 -- Function: arity-at-least? OBJ
     Returns true if OBJ is an arity-at-least object. OBJがarity-at-leastオブジェクトなら、真を返します。

 -- Function: arity-at-least-value ARITY-AT-LEAST
     Returns the number of required arguments the arity-at-least object indicates. arity-at-leastオブジェクトが表す必須引数の数を返します。

 -- Function: procedure-arity-includes? PROC K
     If a procedure PROC can take K arguments, returns #t. Otherwise returns #f. 手続きPROCが引数Kを取れる場合、#tを返します。そうでなければ#fを返します。

Applicable objects
------------------

Gauche has a special hook to make an arbitrary object applicable. Gaucheでは、特別な組み込みの機構によって任意のオブジェクトを「適用可能」にすることができます。

 -- Generic Function: object-apply OBJECT ARG ...
     If an object that is neither a procedure nor a generic function is applied to some arguments, the object and the arguments are passed to a generic function object-apply.

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

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

For example, suppose you try to evaluate the following expression: 例えば、次のような式を評価しようとしたとします。

     ("abcde" 2)

The operator evaluates to a string, which is neither a procedure nor a generic function.  So Gauche interprets the expression as if it were like this: オペレータは文字列に評価されますから、手続きでもジェネリックファンクションでもありません。そこで、Gaucheはこの式を、あたかも次のような式が与えられたかのように解釈します。

     (object-apply "abcde" 2)

Gauche doesn't define a method of object-apply that takes <string> and <integer> by default, so this signals an error. However, if you define such a method: デフォルトでは、<string>と<integer>を引数とする object-applyのメソッドは定義されていないので、この式はエラーになります。しかし、次のようなメソッドを定義すると：

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

Then the first expression works as if a string is applied on the integer: 最初の式はまるで文字列が整数に適用されたかのように動作します。

     ("abcde" 2) => #\c

This mechanism works on almost all occasions where a procedure is allowed. このメカニズムは手続きが許されるほとんどの箇所で使うことができます。

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

Among Gauche built-in objects, <regexp> object and <regmatch> object have object-apply defined. See Regular expressions. Gauche組み込みオブジェクトのうち、<regexp>オブジェクトと <regmatch>オブジェクトに対してはobject-applyメソッドが定義されています。Regular expressionsを参照して下さい。

Note: Defining object-apply method affect globally.  Although it is cool to define object-apply on strings as in the above example, it is not recommended as a general trick, for it'll change the behavior of string across the entire program.

Keep the above example personal experiments.  In general, you should only define object-apply on your own classes. 註: object-applyメソッドの定義はグローバルに影響します。上の例のように文字列にobject-applyを定義するのはおもしろいですが、一般的なトリックとしては推奨されません。これによってプログラム全体での文字列の振る舞いが変わってしまうからです。

上の例は個人的な実験に留めておきましょう。一般的には、自分で定義したクラスに対してのみobject-applyを定義するのが良いです。

 -- Generic Function: (setter object-apply) OBJECT ARG ... VALUE
     If a form of applying an applicable object appears in the first position of set! form, this method is called, that is: 適用可能オブジェクトを適用するフォームがset!フォームの第一ポジションに現れた場合、そのフォームは下に示すように展開され、このメソッドが呼ばれます。

          (set! (OBJECT ARG ...) VALUE)
           => ((setter object-apply) OBJECT ARG ... VALUE)

Continuations
-------------

 -- Function: call-with-current-continuation proc
 -- Function: call/cc proc
     [R7RS base] Encapsulates the current continuation to a procedure (``continuation procedure''), and calls PROC with it. When PROC returns, its value becomes call/cc's value. When the continuation procedure is invoked with zero or more arguments somewhere, the further calculation is abandoned and call/cc returns with the arguments given to the continuation procedure. 現在の継続を手続き (継続手続き) にパッケージ化して、それを引数として PROCを呼び出します。PROCが戻ったら、その返り値がcall/ccの値となります。作成された継続手続きがどこかで0個または複数個の引数を伴って呼ばれたら、あたかもcall/ccから戻ったかのように実行が継続されます。その場合、 call/ccは、継続手続きに与えられた引数を複数の値として返します。

     First class continuation is one of the most distinct feature of Scheme, but this margin is too small to contain explanation. Please consult to the appropriate documents. ファーストクラスの継続はSchemeの最も特徴的な機能のひとつですが、それを十分に説明するにはこの本の余白は狭すぎます。適切なドキュメントを参照してください。

     There's a nontrivial interaction between C language runtime and Scheme continuation.   Suppose the following scenario: Schemeの継続とC言語の実行環境との間に、ちょっとわかりずらい干渉が生じることがあります。次のシナリオを考えます。

      1. An application's C runtime calls back a Scheme routine.  For example, GUI framework calls back a draw routine written in Scheme. アプリケーションのCランタイムがSchemeで書かれた手続きをコールバックします。例えば、GUIフレームワークがSchemeで書かれた描画ルーチンを呼ぶ、というようなケースを考えてください。

      2. A continuation is captured in the Scheme routine. そのSchemeルーチンで継続が捕捉される。

      3. The Scheme routine returns to the C runtime. Schemeルーチンが終了してCランタイムに制御を戻す。

      4. The continuation captured in 2 is invoked. 2で捕捉した継続が起動される。

     It is no problem to invoke the continuation, but if the control is about to return to the Scheme routine to the C runtime (that is, to execute step 3 again), an error is signaled as follows. 継続を起動すること自体には問題は無いのですが、制御がSchemeからCへと再び戻ろうとすると (つまり、step 3が再び実行されようとすると) 次のようなエラーが投げられます。

          *** ERROR: attempt to return from a ghost continuation.

     This is because C routines don't expect the calling function to return more than once.  The C stack frame on which the Scheme callback was originally called is likely to be deallocated or modified at the time the continuation is invoked.

     If you think of a continuation as a chain of control frames, growing from root towards upward, you can imagine that, once a control returns to the C world, the chain is cut at the boundary.  You can still execute such rootless continuations, but you have to move the control away from it before it tries to return to its root that no longer exists. You can call another continuation, or raise an exception, for example. これは、Cの世界では関数が1回より多く戻ってくることを想定していないからです。最初にSchemeのコールバックが呼ばれた時のCのスタックフレームは、継続が再び呼ばれた時には状態が変わっているか、捨てられてしまっているでしょう。

     継続を、根から上へ向かって成長する制御フレームの連鎖のようにイメージした場合、 Cの世界へ戻った時点でその連鎖が断ち切られる、と考えることができます。そのような根無しの継続も実行することはできますが、既に失った根に戻る前に別の箇所へと制御を移さねばなりません。他の箇所で捕まえた継続を呼んだり、例外を投げるといったことが考えられます。

     Using partial continuations (or delimited continuations) is another way to avoid such complications. See Partial continuations. 部分継続(限定継続)を使うのも手です。 Partial continuationsを参照してください。

 -- Macro: let/cc var body ...
     This macro expands to : このマクロは次のように展開されます : (call/cc (lambda (VAR) BODY ...)). The API is taken from PLT Scheme. APIはPLT Schemeから取りました。

 -- Function: dynamic-wind before body after
     [R7RS base] This is a primitive to manage dynamic environment. Dynamic environment is a set of states which are kept during execution of a certain expression.  For example, the current output ports are switched during execution of with-output-to-port. They can be nested dynamically, as opposed to the lexical environment, in which nesting is determined statically from the program source.

     BEFORE, BODY and AFTER are all procedures with no arguments. In normal situation, dynamic-wind calls BEFORE, then BODY, then AFTER, then returns whatever value(s) BODY returned.

     The intention is that the BEFORE thunk sets up the dynamic environment for execution of BODY, and the AFTER thunk restores it to the previous state.

     If a control flow goes out from BODY by invoking a continuation captured outside of the dynamic scope of dynamic-wind (for example, an error is signaled in BODY), AFTER is called.

     If a control flow goes into BODY by invoking a continuation captured inside BODY from outside of the dynamic scope of dynamic-wind, BEFORE is called. これは動的環境を管理するための基本手続きです。動的環境とは、ある式を実行している間、維持される状態のセットのことです。例えば「現在の出力ポート」というのは、with-output-to-port手続きの実行中だけ切り替えることができます。動的環境は動的にネストできます。これは、プログラムのソースから静的にネストが決定できる字句環境とは異なります。

     BEFORE、BODYおよびAFTER は引数を取らない手続きです。 dynamic-windはまずBEFOREを呼び出し、続いてBODYを呼び出し、続いてAFTERを呼び出します。そしてBODYが返した値を返します。

     BEFORE手続きがBODYを実行するための動的環境を設定し、AFTER手続きが動的環境を元に戻す、ということが意図されています。

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

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

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

     Note: Since AFTER is guaranteed to be called when an error causes BODY to abort, it may appear tempting to use dynamic-wind to use resource clean-up, just like try-catch construct in Java.  It's not for that. Since the control may return to BODY, the situation dynamic-wind handles should be considered more like a context switch.

     For resource clean-up, you can use exception handling mechanism such as guard and unwind-protect (see Handling exceptions), which is built on top of dynamic-wind.

     As a rule of thumb, AFTER should do things that can be reverted by BEFORE, such as manipulating error handler stack (instead of actually handling errors). 註：エラーによりBODYが中断された時に必ずAFTERが呼ばれることから、 dynamic-windを例えばJavaのtry-catch構文のように考えてリソースの後処理などに使いたくなるかもしれません。しかしdynamic-windはそのためのものではありません。一旦離れた制御がBODYに再び戻ってくる可能性があるので、 dynamic-windが管理するのはむしろコンテキストスイッチに近い状況です。

     リソースの後処理には、guardやunwind-protectなどの例外処理が使えます(Handling exceptions参照)。それらはdynamic-windを使って構築されています。

     基本的な指針として、AFTERは常にBEFOREによって効果を戻せる処理だけを行うべきです。例えば、(エラーを直接処理するのではなく) エラーハンドラスタックを操作する、といった具合に。

Multiple values
---------------

 -- Function: values obj ...
     [R7RS base] Returns OBJ ... as multiple values. Caller can capture multiple values by a built-in syntax receive or let-values (Binding constructs), or the R7RS procedure call-with-values described below. OBJ ... を多値として返します。呼び出し側は、組み込み構文の receiveやlet-values (Binding constructs参照)か、下に説明するR7RSの手続きcall-with-valuesを使って多値を受け取ることができます。

          (values 1 2) => 1 and 2

 -- Function: call-with-values producer consumer
     [R7RS base] Call a procedure PRODUCER with no argument. Then applies a procedure CONSUMER on the value(s) PRODUCER returned.  Returns the value(s) CONSUMER returns. 手続きPRODUCERを引数無しで呼びます。そして、それが返した値を引数としてCONSUMERを呼びます。CONSUMERが返す値を返します。

          (call-with-values (lambda () (values 1 2)) cons)
            => (1 . 2)

 -- Macro: values-ref mv-expr k
     Returns K-th value of what MV-EXPR returns. Conceptually, it is the same as the following code. MV-EXPRが返す多値のK-番目の値を返します。概念としては、以下のコードと同じです。

          (call-with-values (lambda () mv-expr) (lambda r (list-ref r k)))

     This macro uses shortcuts for the typical cases like K is zero.

     Similar to Common Lisp's nth-value, but the argument order is flipped to match other Scheme's *-ref procedures. このマクロは k がゼロであるような典型的な場合にはより単純な形へと展開されます。

     Common Lisp の nth-value に似ていますが、引数の順が逆になっています。 Scheme の他の*-ref 手続きと合わせるためです。

 -- Macro: values->list mv-expr
     Evaluates MV-EXPR, puts all the results into a list and returns it.   It is called multiple-value-list in Common Lisp. MV-EXPRを評価し、結果の値をリストにして返します。Common Lispで multiple-value-listと呼ばれているものです。

          (values->list (div-and-mod 10 3)) => (3 1)

          (values->list 1) => (1)

Folding generated values
------------------------

Sometimes a procedure is used as a generator of a series of values, by yielding one value at a time.  Customary an EOF object is used to mark the end of the series.  For example, read-char is such a procedure that yields a series of characters, terminated by EOF. 一回呼ばれる度にひとつの値を生成するような手続きは、一連の値を生成するジェネレータとして使われることがあります。値の終端を表すマークとしては、慣例としてEOFが使われます。例えばread-charはそうした、一連の文字を生成し、終端としてEOFを返す手続きです。

Since it is such a handy abstraction, Gauche provides a set of utilities (see Generators) to construct and generators out of various sources, including other generators. こうした抽象化は手軽であるため、Gaucheは、他のジェネレータを含むさまざまなソースからジェネレータを構築するユーティリティをひとそろい提供しています。

The generated values needs to be consumed eventually.  Here we provide several procedures to do that.  These are useful when combined with input procedures like read, so we have them built-in instead of putting them in a separate module. 生成された値は最終的に消費されなければなりません。そのための手続きもいくつか提供されています。こうした手続きは、readのような入力手続きと組み合わせるのに有用です。このため、別のモジュールに分割するのではなく、組み込み手続きになっています。

 -- Function: generator-fold proc seed gen gen2 ...
     [R7RS generator] Works like fold on the generated values by generator procedures GEN GEN2 ... (see Walking over lists, for the details of fold). ジェネレータである手続き GEN GEN2 ... が生成する値に対して fold のように働きます(foldの詳細はWalking over lists参照)。

     When one generator is given, for each value V generated by GEN, PROC is called as (PROC V R), where R is the current accumulated result; the initial value of the accumulated result is SEED, and the return value from PROC becomes the next accumulated result. When GEN returns EOF, the accumulated result at that time is returned from generator-fold. 引数としてジェネレータがひとつ与えられると、その GEN が生成する各値 V に対して、PROC が (PROC V R) のように呼び出されます。 Rは現在の積算結果であり、その初期値は SEED です。そして、PROC が返す値が次回の PROC 呼び出し時の積算値として渡されることになります。 GENがEOFを返すと、その時点の積算値が generator-fold から値として返されます。

     When more than one generator is given, PROC is called as (PROC V1 V2 ... R), where V1, V2 ... are the values yielded from GEN, GEN2, ..., respectively, and R is the current accumulated result.  The iteration terminates when any one of the generators returns EOF. 2つ以上のジェネレータが渡された場合は、PROCは (PROC V1 V2 ... R) のように呼び出されます。 V1, V2 ... はそれぞれ GEN, GEN2, ... が生成した値であり、Rは現在の積算値です。ジェネレータのどれかひとつ以上がEOFを返すと、イテレーションは終了します。

          (with-input-from-string "a b c d e"
            (cut generator-fold cons 'z read))
            => (e d c b a . z)

 -- Function: generator-fold-right proc seed gen gen2 ...
     Works like fold-right on the generated values by generator procedures GEN GEN2 ... (see Walking over lists, for the details of fold-right). ジェネレータである手続きGEN GEN2 ...が生成する値に対して fold-rightのように働きます(fold-rightの詳細はWalking over lists参照)。

     This is provided for completeness, but it isn't a good way to handle generators; in order to combine values right-associatively, we should read all the values from the generators (until any one of the generator returns EOF), then start calling PROC as この手続きは完全性のために提供されていますが、ジェネレータとの相性はあまり良くありません。値を右結合で計算していくためには、ジェネレータから(少なくともどれかひとつのジェネレータがEOFを返すまで) 全ての値を読み取らなければなりません。そうして初めて PROC の呼び出しが始まることになります。

          (proc v0_0 v1_0 ... (proc v0_1 v1_1 ... (proc v0_n v1_n ... seed) ...))

     where VN_M is the M-th value yielded by N-th generator. VN_Mは、N番目のジェネレータがM回目の呼び出しで返した値です。

          (with-input-from-string "a b c d e"
            (cut generator-fold-right cons 'z read))
            => (a b c d e . z)

     As you see, keeping all intermediate values kind of defeats the benefit of generators. ごらんのように、全ての中間値を保持することで、ジェネレータの利点がある意味帳消しになってしまうのです。

 -- Function: generator-for-each proc gen gen2 ...
     [R7RS generator] A generator version of for-each.  Repeatedly applies PROC on the values yielded by GEN, GEN2 ... until any one of the generators yields EOF.  The values returned from PROC are discarded. ジェネレータ版のfor-eachです。GEN, GEN2 ... が生成する値に対して、ジェネレータのどれかがEOFを返すまで PROC を繰り返し適用していきます。 PROCが返す値は無視されます。

     This is a handy procedure to consume generated values with side effects. これは、生成される値を副作用で消費するのに便利です。

 -- Function: generator-map proc gen gen2 ...
     A generator version of map.  Repeatedly applies PROC on the values yielded by GEN, GEN2 ... until any one of the generators yields EOF.   The values returned from PROC are collected into a list and returned. ジェネレータ版のmapです。GEN, GEN2 ... が生成する値に対して、ジェネレータのどれかがEOFを返すまで PROC を繰り返し適用していきます。 PROCが返す値をひとつのリストに束ねて返します。

          (with-input-from-string "a b c d e"
            (cut generator-map symbol->string read))
            => ("a" "b" "c" "d" "e")

     The same effects can be achieved by combining generator->list and gmap (see Generator operations).  This procedure is provided for the backward compatibility. generator->listとgmap(Generator operations参照)の組み合わせと同じ挙動を実現します。この手続きは後方互換性のために提供されています。

          (generator->list (gmap proc gen gen2 ...))

 -- Function: generator-find pred gen
     [R7RS generator] Returns the first item from the generator GEN that satisfies the predicate PRED. ジェネレータGENから返された中から、述語PREDを満たす最初の要素を返します。

     The following example returns the first line matching the regexp #/XYZ/ from the file foo.txt. 以下の例は、ファイルfoo.txtの中から正規表現#/XYZ/にマッチする最初の行を返します。

          (with-input-from-file "foo.txt"
            (cut generator-find #/XYZ/ read-line))

     Note: If you want to pick all the lines matching the regexp, like the grep command, you can use gfilter and generator->list. 註: grepコマンドのように、正規表現にマッチする全ての行を取り出したいなら、 gfilterとgenerator->listが使えます。

Parameters
==========

A parameter is Scheme's way to implement dynamically scoped states. In Gauche, it also realizes thread-local storage. It is codified in srfi-39 and incorporated into R7RS. 「パラメータ」はSchemeで動的スコープを持つ状態を実現します。 Gaucheではスレッドローカルな状態の格納にも使えます。もともとsrfi-39で仕様が定められ、R7RSからは言語の一部になりました。

It is a special procedure created by make-parameter.  It accepts zero or one argument.  When called without an argument, it returns the current value.  If an argument is passed, it alters its current value with the given value, and returns the previous value.

Using parameterize macro, which is similar to let syntactially, rebinds the parameters' value during execution of its body, dynamically rather than lexically. parameterizeマクロはletに構文的に似ていて、本体の実行の間、パラメータの値を一時的に置き換えます。これは字句的(静的スコープ)ではなく動的スコープで動作します。

     (define var (make-parameter 0))

     (define (show-var) (print (var)))

     (show-var)  ; prints 0

     (parameterize ((var 1))
       (show-var))    ; prints 1

     (define f)

     (parameterize ((var 2))
       (set! f (lambda () (show-var))))

     (f) ; prints 0, since its out of the dynamic extent of var=2

If a control trasfers from or to parameterize's body by continuations, the parameter refers to the value corresponding the dynamic envrionment it is accessed. 継続などにより制御がparameterizeの本体から飛び出したり本体へ飛び込んだりした場合、パラメータは常にそれがアクセスされる動的環境のもとでの値を返します。

Gauche enhances R7RS parameters in a few ways. GaucheはR7RSのパラメータを次のとおり拡張しています。

  * It is thread-local.  A parameter created in one thread can be used from other threads, but the storage is independent.  When a new thread is created, it inherits the values of existing parameters. スレッドローカルです。ひとつのスレッドで作られたパラメータは他のスレッドからもアクセスできますが、参照される領域はスレッドごとに独立しています。新たなスレッドが作られた時、それまでにあるパラメータの値は引き継がれます。

  * You can attach observer procedures to a parameter, which is invoked whenever the value of the parameter is altered, either directly or by parameterize.   (This feature is only available when you use gauche.parameter module, see Parameters (extra)). パラメータに監視手続きをつけることができます。パラメータの値が変わる度に (parameterizeでも直接設定でも)監視手続きが呼ばれます。 (この機能はgauche.parameterをuseすることで使えるようになります。 Parameters (extra)参照。

  * You can use generaized set! with parameters. パラメータに対しても一般化されたset!を使えます。

          (define p (make-parameter 'a))
          (p) => a
          (set! (p) 'b)
          (p) => b

 -- Function: make-parameter value :optional filter
     [R7RS base] Creates a parameter whose initial value is VALUE. If an optional argument FILTER is given, it must be a procedure that takes one argument and returns one value; whenever the parameter's value is about to change, the procedure is called with the given value, and the value the procedure returns will be the parameter's value.  The filter procedure can raise an error or reject to change the parameter's value. 初期値がVALUEであるパラメータを作成します。もし省略可能な引数FILTERが与えられた場合、それは一つの引数を取る手続きでなければなりません。パラメータの値が変更されようとした時、FILTERは与えられた値を引数として呼ばれ、FILTERが返した値がパラメータの新しい値となります。FILTERはエラーを報告したりパラメータの値を変えずに置くことも可能です。

     NB: In 0.9.9 and before, this procedure returns a parameter object, and we used object-apply method to make it behave like a procedure.  However, R7RS explicitly defines the return values to be a procedure; notably, portable code expects (procedure? (make-parameter 'z)) returns #t.

     As of 0.9.10, we switched make-procedure to return a procedure.  It won't change the external behavior, except when you test the parameter P with (is-a? p <parameter>); you have to use parameter? instead. 註: 0.9.9までは、この手続きはパラメータオブジェクトを返していました。パラメータオブジェクトは object-applyメソッドによって手続きであるかのように振る舞います。しかし、R7RSはmake-parameterが手続きを返すように規定しており、ポータブルなコードでは (procedure? (make-parameter 'z))は#tでなければなりません。

     0.9.10から、make-procedureは手続きを返すようになりました。通常のパラメータの使い方をしている限り、外部に見える振る舞いは変わりません。ただし、make-parameterで作られたオブジェクトかどうかを (is-a? p <parameter>)でテストしているコードは後述するparameter?を使うように変更する必要があります。

 -- Macro: parameterize ((param value) ...) body ...
     [R7RS base] Evaluates BODY ..., with change parameter PARAM's value to the given VALUE within the dynamic scope of BODY .... Returns the value(s) of the result of the last BODY. BODY ...を評価します。但し、BODY ... の実行中のみ、パラメータPARAMの値を VALUEに変更します。最後のBODYの返した値を返します。

Some examples: 例：

     (define a (make-parameter 1))
     (a) => 1
     (a 2) => 1
     (a) => 2
     (parameterize ((a 3))
       (a)) => 3
     (a) => 2

 -- Function: parameter? obj
     Returns #t iff OBJ is an object created by make-parameter. OBJがmake-parameterで作られたものであった場合は#tを、そうでなければ#fを返します。

     Note: Some built-in procedures such as current-input-port behaves like parameters.  They aren't created by make-parameter, though, and returns #f for parameter?. 註: 組み込みの手続きの中には、パラメータのように動作するものがあります (例: current-input-port)。しかしそれらは、make-parameterで作られたものでない限り、parameter?に対して#fを返します。

Boxes
=====

A box is a mutable container that can hold (possibly multiple) values. It can be used as a minimal data storage, or a sort of mutable indirect ``pointer''.

Traditionally, a list or a vector has been used for this purpose. However, such datatypes imply sequences of objects,   Using boxes emphasizes your intention is just for indirection, and not so much for sequencing.

It is originally introduced by srfi-111, which was later adopted in R7RS-large as scheme.box.  Srfi-195 enhances it to deal with multiple values.

The srfis leaves some details to implementations.  Here are our choices:

  * We don't support autoboxing; that is, it is an error to pass non-box value to the procedure expecting boxed value and vice versa.

  * Comparing two boxes with equal? compares their contents when two are not eqv?.  In the spec, when two boxes are eqv? then they must also be equal? to each other, but it's up to the implementation when two are not eqv?.

When you're writing portable code, be careful not to depend on the equal? behavior.

 -- Function: box val ...
     [R7RS box][SRFI-195] Returns a fresh box object that contains the value val ....

 -- Function: box? obj
     [R7RS box] Returns #t iff OBJ is a box object.

 -- Function: box-arity box
     [SRFI-195] Returns the number of values BOX holds.

 -- Function: unbox box
     [R7RS box] Returns BOX's content.  If BOX has N values, it returns N values.

 -- Function: unbox-value box i
     [SRFI-195] Returns I-th value held in BOX.

 -- Function: set-box! box val ...
     [R7RS box][SRFI-195] Alters the content of BOX with VAL .... The numer of values must match the arity of the box. Returns unspecified value.

 -- Function: set-box-value! box i val
     [SRFI-195] Alters I-th value of BOX with VAL. Returns unspecified value.

Lazy evaluation
===============

Gauche has two primitive lazy evaluation mechanisms. Gaucheには、ふたつの組み込みの遅延評価メカニズムがあります。

The first one is an explicit mechanism, defined in the Scheme standard: You mark an expression to be evaluated lazily by delay, and you use force to make the evaluation happen when needed.  Gauche also support another primitive lazy, as defined in srfi-45, for space-efficient tail-recursive lazy algorithms. ひとつめはScheme標準で定められている、明示的なメカニズムです。遅延評価したい式を delay構文でマークし、値が必要になったところでforceにより評価を強制します。Gaucheはさらに、srfi-45で導入された、末尾再帰アルゴリズムでメモリを効率的に利用するためのlazyというプリミティブもサポートしています。

The second one is a lazy sequence, in which evaluation happens implicitly.  From a Scheme program, a lazy sequence just looks as a list---you can take its car and cdr, and you can apply map or other list procedures on it.  However, internally, its element isn't calculated until it is required. もうひとつは遅延シーケンスです。こちらは評価をforceで明示する必要がありません。Schemeプログラムからは、遅延シーケンスは通常のリストと全く同じに見えます。carやcdrを使ったり、mapを始めとする様々なリスト手続きをそのまま適用することができます。けれども内部的には、遅延シーケンスの要素は必要になるまで計算されません。

Delay, force and lazy
---------------------

Scheme has traditionally provided an explicit delayed evaluation mechanism using delay and force.  After R5RS, however, it is found that it didn't mix well with tail-recursive algorithms: It required unbound memory, despite that the body of the algorithm could be expressed in iterative manner. Srfi-45 showed that introducing another primitive syntax lazy addresses the issue. For the detailed explanation please look at the srfi-45 document. Here we explain how to use those primitives. Schemeは伝統的に、delayとforceを使った明示的な遅延評価メカニズムを提供してきました。しかし、R5RSの後で、それが末尾再帰的なアルゴリズムとの相性がよくないことがわかりました。末尾再帰的なアルゴリズムの本体が反復的に表現できるにもかかわらず、メモリを際限なく要求してしまうのです。SRFI-45によって、新たなプリミティブ構文lazyを使えばその問題が回避できることが示されました。詳しい議論はSRFI-45のドキュメントを見てください。ここではこれらのプリミティブの使い方を説明します。

 -- Special Form: delay expression
 -- Special Form: lazy expression
     [R7RS lazy][SRFI-45] These forms creates a promise that delays the evaluation of EXPRESSION.  EXPRESSION will be evaluated when the promise is passed to force. これらの形式はEXPRESSIONの評価を遅延するプロミスを生成します。EXPRESSION はこのプロミスがforceにわたったときに評価されます。

     If EXPRESSION itself is expected to yield a promise, you should use lazy.  Otherwise, you should use delay. If you can think in types, the difference may be clearer. EXPRESSION自身がプロミスを返す式ならlazyを、そうでなければ、delayを使います。型で考えるとわかりやすいでしょう。

          lazy  : Promise a -> Promise a
          delay : a -> Promise a

     Since we don't have static typing, we can't enforce this usage. The programmer has to choose appropriate one from the context. Generally, lazy appears only to surround the entire body of function that express a lazy algorithm. Schemeでは静的な型付けをしないので、この使い分けを強制することができません。文脈にしたがってプログラマが適切に選択する必要があります。一般的にはlazyは遅延アルゴリズムを表現している関数本体全体を囲む場合にのみ出現します。

     NB: In R7RS, lazy is called delay-force, for the operation is conceptually similar to (delay (force expr)) (note that the type of force is Promise a -> a). 註: R7RSではlazyはdelay-forceと呼ばれています。概念的に (delay (force expr))という操作と考えられるからです (forceの型はPromise a -> aであると考えられます)。

     For the real-world example of use of lazy, you may want to check the implementation of util.stream (see Stream library). lazyの実用的な使用例についてはutil.stream (Stream library)の実装をチェックするといいでしょう。

 -- Function: eager obj
     [SRFI-45] Returns a promise that returns the value of OBJ. Since that eager is a procedure, OBJ is evaluated before EAGER is called; so it works as a type converter (<code>a -> Promise a</code>) without delaying the evaluation. Used mainly to construct promise-returning functions. OBJの値を返すプロミスを作って返します。 eagerは通常の手続きなので、OBJの評価は遅延されせん。評価を遅延することなく型変換(<code>a -> Promise a</code>)だけを行いたい場合に使います。プロミスを返すことが要求される手続きで使われます。

 -- Function: force promise
     [R7RS lazy] If PROMISE is not a promise, it is just returned.

     Otherwise, if PROMISE's value hasn't been computed, force makes PROMISE's encapsulated expression be evaluated, and returns the result.

     Once PROMISE's value is computed, it is memorized in it so that subsequent force on it won't cause the computation. もし、PROMISEがプロミスでなければ、それをそのまま返します。

     そうではない場合で、もしPROMISEの値がまだ計算されていない場合には、 forceはPROMISEが内包している式を評価し、その結果を返します。

     いったん、PROMISEの値が計算されると、その値はメモ化され、あとで再びforceされても、再計算がおこなわれることはありません。

 -- Function: promise? obj
     [R7RS lazy] Returns #t iff OBJ is a promise object. OBJがプロミスオブジェクトである場合に #tを返します。

Lazy sequences
--------------

Introduction
............

イントロダクション
.........

A lazy sequence is a list-like structure whose elements are calculated lazily. Internally we have a special type of pairs, whose cdr is evaluated on demand. However, in Scheme level, you'll never see a distinct ``lazy-pair'' type.   As soon as you try to access a lazy pair, Gauche automatically force the delayed calculation, and the lazy pair turns into an ordinary pair. 遅延シーケンスはリストのようなデータ構造ですが、要素は必要になるまで計算されません。内部的には、これはcdrの評価が遅延される特別な種類のペアを使って実現されています。しかし、Schemeのレベルで「遅延ペア」のような特別なデータ型が見えることは決してありません。遅延ペアにアクセスしようとした途端、Gaucheは自動的に遅延されていた計算をforceして、遅延ペアは通常のペアに変化してしまうからです。

It means you can pass lazy sequences to ordinary list-processing procedures such as car, cdr or map. これはつまり、遅延シーケンスをcar、cdr、mapといった通常のリスト処理手続きにそのまま渡せるということです。

Look at the following example; generator->lseq takes a procedure that generates one value at a time, and returns a lazy sequence that consists of those values. 次の例を見てください。generator->lseqは、「呼ばれる度に次の値を返す」という手続きを取り、返される値からなる遅延シーケンスにして返す手続きです。

     (with-input-from-file "file"
       (^[] (let loop ([cs (generator->lseq read-char)] [i 0])
              (match cs
                [() #f]
                [(#\c (or #\a #\d) #\r . _) i]
                [(c . cs) (loop cs (+ i 1))]))))

It returns the position of the first occurrence of character sequence ``car'' or ``cdr'' in the file file. The loop treats the lazy sequence just like an ordinary list, but characters are read as needed, so once the sequence is found, the rest of the file won't be read.  If we do it eagerly, we would have to read the entire file first no matter how big it is, or to give up using the mighty match macro and to write a basic state machine that reads one character one at a time. このコードは、ファイルfile中に最初に出現する ``car''または``cdr''という文字列の場所を返します。ループは遅延シーケンスを通常のリストのように扱っていますが、文字は必要に応じて読まれ、目的の文字列が見つかれば残りは読まれません。これを遅延無しでやろうとすると、一旦全てのファイルを読み込んでリストに変換するか、あるいは便利なmatchマクロを使うのを諦めて一文字つづ読み込んで処理する原始的な状態機械を書くしかないでしょう。

Other than implicit forcing, Gauche's lazy sequences are slightly different than the typical lazy stream implementations in Scheme in the following ways: 暗黙のforceの他にも、Gaucheの遅延シーケンスは Schemeの典型的な遅延ストリーム実装に比べて次のような違いがあります。

 1. When you construct a lazy sequence in an iterative lazy algorithm, only cdr side of the lazy pair is lazily evaluated; the car side is evaluated immediately.  On the other hand, with stream-cons in util.stream (see Stream library), both car and cdr sides won't be evaluated until it is absolutely needed. 遅延シーケンスを、繰り返しによる怠惰なアルゴリズムから構築する際に、遅延ペアのcdr側のみが遅延評価の対象となります。ペアのcar側は直ちに評価されます。一方、util.streamのstream-consでは、 carとcdrのどちらも遅延評価の対象となり、必要となるまで評価されません (Stream library参照)。

 2. Gauche's lazy sequence always evaluates one item ahead. Once you get a lazy pair, its car part is already calculated, even if you don't use it.  In most cases you don't need to care, for calculating one item more is a negligible overhead.  However, when you create a self-referential lazy structure, in which the earlier elements of a sequence is used to calculate the latter elements of itself, a bit of caution is needed; a valid code for fully lazy circular structure may not terminate in Gauche's lazy sequences.  We'll show a concrete example later.  This bit of eagerness is also visible when side effects are involved; for example, lazy character sequence reading from a port may read one character ahead. Gaucheの遅延シーケンスは、常にひとつ余分に評価します。遅延ペアを手にした段階で、その中身にアクセスするかしないかにかかわらず、既にそのcarは評価済みであるということです。ひとつ余分に計算してしまうことのコストは、通常はあまり問題にならないでしょう (全てを余分に計算するよりは良いわけですから)。けれども、自分自身を参照する遅延データ構造、つまり、遅延シーケンスの次の要素を計算するためにそのシーケンスの前の方の要素を参照する必要がある場合は注意が必要です。遅延評価言語で正しい自己参照遅延データの生成コードが、そのままではGaucheで停止しなくなる場合があります。後で例を示します。また、評価に副作用がある場合にもこの差異が観測される場合があります。例えば、ポートから一文字づつ読む遅延シーケンスは、見かけよりも一文字余分に読むことになるでしょう。

Note: R7RS scheme.lseq (srfi-127) provides a portable alternative of lazy sequence (see R7RS lazy sequences).  It uses dedicated APIs (e.g. lseq-cdr) to operate on lazy sequences so that portable implementation is possible.  In Gauche, we just use our built-in lazy sequence as srfi-127 lazy sequence; if you want your code to be portable, consider using srfi-127, but be careful not to mix lazy sequences and ordinary lists; Gauche won't complain, but other Scheme implementation may choke on it. 註: ポータブルな遅延シーケンスはR7RSのscheme.lseq (srfi-127)でも提供されています (R7RS lazy sequences参照)。srfi-127では、遅延シーケンスを扱う専用のAPI (lseq-cdr等) を提供することで、ポータブルな実装を可能にしています。 Gaucheではsrfi-127の遅延シーケンスはGaucheの組み込み遅延シーケンスそのものです。移植性が重要であれば、srfi-127を使うのが良いでしょう。但し、遅延シーケンスと通常のリストを混ぜないように気をつけてください。Gaucheは問題なく処理しますが、他のScheme処理系は喉を詰まらせてしまうかもしれません。

Primitives
..........

プリミティブ
......

 -- Function: generator->lseq generator
 -- Function: generator->lseq item ... generator
     [R7RS lseq] Creates a lazy sequence that consists of items produced by GENERATOR, which is just a procedure with zero arguments that yields an item at a time.  Returning EOF marks the end of the sequence (EOF itself isn't included in the sequence). For example, read-char can work as a generator. Gauche has a set of convenient utilities to deal with generators (see Generators). ジェネレータ手続きGENERATORから生成される値の列を、遅延シーケンスとして返します。ジェネレータ手続きは引数を取らない手続きで、呼ばれる度に次の値を返すようなものです。 EOFが返されたら、シーケンスの終了とみなされます (EOF自体はシーケンスには含まれません)。例えばread-charはそのままGENERATORに渡せます。ジェネレータ手続きを作ったり加工したりする便利なユーティリティが gauche.generatorモジュールで提供されています (Generators参照)。

     In the second form, the returned lazy sequence is prepended by ITEM ....  Since there's no way to distinguish lazy pairs and ordinary pairs, you can write it as (cons* item ... (generator->lseq generator)), but that's more verbose. 二番目の形式では、ITEM ...が遅延シーケンスの先頭に配置されます。遅延ペアと通常のペアは区別できないので、これは (cons* item ... (generator->lseq generator))とも書けますが、少々冗長になるでしょう。

     Internally, Gauche's lazy sequence is optimized to be built on top of generators, so this procedure is the most efficient way to build lazy sequences. 内部的には、Gaucheの遅延シーケンスはジェネレータを使うように最適化されています。遅延シーケンスを作る最も効率の良い方法はこの手続きを使うことです。

     Note: Srfi-127 also has generator->lseq, which is exactly the same as this in Gauche. 註: srfi-127もgenerator->lseqを定義していますが、Gaucheではそれはこの手続きと同じものです。

 -- Macro: lcons car cdr
     Returns a lazy pair consists of CAR and CDR. The expression CAR is evaluated at the call of lcons, but evaluation of CDR is delayed. CARとCDRからなる遅延ペアを作って返します。 CARはlconsを呼び出した時点で評価されますが、 CDRの評価は遅延されます。

     You can't distinguish a lazy pair from an ordinary pair.  If you access either its car or cdr, or even you ask pair? to it, its cdr part is implicitly forced and you get an ordinary pair. 遅延ペアと通常のペアを区別する方法はありません。ペアのcarやcdrにアクセスしたり、それどころかpair?によって型を確かめただけでも、遅延ペアのcdr側はforceされて、遅延ペアは通常のペアへと変化します。

     Unlike cons, CDR should be an expression that yields a (lazy or ordinary) list, including an empty list. In other words, lazy sequences can always be a null-terminated list when entirely forced; there are no ``improper lazy sequences''. (Since Scheme isn't statically typed, we can't force the CDR expression to be a proper list before actually evaluating it. Currently if CDR expression yields non-list, we just ignore it and treat as if it yielded an empty list.) consと違って、遅延ペアのCDRはリスト (遅延でも通常でも) を返す関数でなければなりません。遅延シーケンスは全てforceされたら、常に空リストで終端されているリストになる、と言っても良いでしょう。つまり、ドット対を最後に持つような「不完全なリスト」に対応する「不完全な遅延シーケンス」というものはありません。(Schemeは静的型ではないので、実際に評価するまで CDRが完全なリストを生成することを保証することができません。現在の実装では、CDRがリストでない値を生成した場合、それを単に無視して空リストが返されたかのように扱います)。

          (define z (lcons (begin (print 1) 'a) (begin (print 2) '())))
           => ; prints '1', since the car part is evaluated eagerly.
           => ; car部はすぐに評価されるので、'1'が表示される

          (cdr z) => () ;; and prints '2'
          (cdr z) => () ;; そして'2'が表示される

          ;; This also prints '2', for accessing car of a lazy pair forces
          ;; its cdr, even the cdr part isn't used.
          ;; これも'2'を表示する。遅延ペアのcarにアクセスすると、その時点で
          ;; cdr部の評価もforceされるので。
          (car (lcons 'a (begin (print 2) '()))) => a

          ;; So as this; asking pair? to a lazy pair causes forcing its cdr.
          ;; これも同じ。pair?と聞くだけで遅延ペアはforceされる
          (pair? (lcons 'a (begin (print 2) '()))) => #t

          ;; To clarify: This doesn't print '2', because the second lazy
          ;; pair never be accessed, so its cdr isn't evaluated.
          ;; 念のため。次の例では'2'は出力されない。二番目の遅延ペアはアクセス
          ;; されていないので、そのcdrも評価されない。
          (pair? (lcons 'a (lcons 'b (begin (print 2) '())))) => #t

     Now, let me show you a case where ``one item ahead'' evaluation becomes an issue.  The following is an elegant definition of infinite Fibonacci sequence using self-referential lazy structure (lmap is a lazy map, defined in gauche.lazy module): Gaucheの「一つ先の要素まで計算」が問題となる例も見ておきましょう。次の例は、自己参照する遅延シーケンスを使った、とても美しい無限フィボナッチ数列の定義です (lmapは遅延バージョンのmapで、gauche.lazyモジュールで提供されています)。

          (use gauche.lazy)  ;; for lmap
          (define *fibs* (lcons* 0 1 (lmap + *fibs* (cdr *fibs*)))) ;; BUGGY

     Unfortunately, Gauche can't handle it well. 残念ながら、Gaucheではこれはうまく動きません。

          (car *fibs*)
           => 0
          (cadr *fibs*)
           => *** ERROR: Attempt to recursively force a lazy pair.

     When we want to access the second argument (cadr) of *fibs*, we take the car of the second pair, which is a lazy pair of 1 and (lmap ...).  The lazy pair is forced and its cdr part needs to be calculated.  The first thing lmap returns needs to see the first and second element of *fibs*, but the second element of *fibs* is what we're calculating now! *fibs*の二番目の要素(cadr)にアクセスするということは、 *fibs*の二番目のペアのcarを取るということです。*fibs*の二番目のペアは1と(lmap ...)の遅延ペアになっています。 carを取ろうとした時点でこの遅延ペアはforceされ、そのcdrが計算されます。 lmapが最初に返さなければならないのは、*fibs*の一番目と二番目の要素の和です。しかし*fibs*の二番目の要素は、今まさにアクセスしようとしている値です!

     We can workaround this issue by avoiding accessing the immediately preceding value. Fibonacci numbers F(n) = F(n-1) + F(n-2) = 2*F(n-2) + F(n-3), so we can write our sequence as follows. この問題は、ある要素を計算するために直前の要素を参照しなければ回避できます。フィボナッチ数はF(n) = F(n-1) + F(n-2) = 2*F(n-2) + F(n-3)と変形できるので、遅延フィボナッチシーケンスはこう定義できます。

          (define *fibs*
            (lcons* 0 1 1 (lmap (^[a b] (+ a (* b 2))) *fibs* (cdr *fibs*))))

     And this works! これでok!

          (take *fibs* 20)
            => (0 1 1 2 3 5 8 13 21 34 55 89 144 233
               377 610 987 1597 2584 4181)

     Many lazy algorithms are defined in terms of fully-lazy cons at the bottom.  When you port such algorithms to Gauche using lcons, keep this bit of eagerness in mind. 多くの遅延アルゴリズムは、完全な遅延評価をするconsを基礎にしています。そういったアルゴリズムをlconsを使ってGaucheに移植する際には、 Gaucheのこのちょっとした「熱心さ」に気をつけてください。

     Note also that lcons needs to create a thunk to delay the evaluation.  So the algorithm to construct lazy list using lcons has an overhead of making closure for each item. For performance-critical part, you want to use generator->lseq whenever possible. lconsは、実行の度にcdr部の評価を遅延するためのクロージャを作るということにも注意してください。lconsを使った遅延アルゴリズムでは要素ひとつにつきクロージャをひとつ作るオーバヘッドがかかります。性能が重要な部分では、可能な限りgenerator->lseqを使いましょう。

Utilities
.........

ユーティリティ
.......

 -- Macro: lcons* x ... tail
 -- Macro: llist* x ... tail
     A lazy version of cons* (see List constructors). Both lcons* and llist* do the same thing; both names are provided for the symmetry to cons*/list*. 遅延バージョンのcons*です (List constructors参照)。 lcons*とllist*は全く同じです。 cons*/list*との対称性から両方の名前が定義されています。

     The TAIL argument should be an expression that yields a (possibly lazy) list.   It is evaluated lazily.  Note that the preceding elements X ... are evaluated eagerly. The following equivalences hold. TAIL引数は(遅延もしくは通常の)リストを生成する式でなければなりません。 TAIL引数の評価は遅延されます。X ...引数はすぐに評価されます。次の関係が成り立ちます。

          (lcons* a)           == a
          (lcons* a b)         == (lcons a b)
          (lcons* a b ... y z) == (cons* a b ... (lcons y z))

 -- Function: lrange start :optional end step
     Creates a lazy sequence of numbers starting from START, increasing by STEP (default 1), to the maximum value that doesn't exceed END.  The default of END is +inf.0, so it creates an infinite list.  (Don't type just (lrange 0) in REPL, or it won't terminate!) STARTからSTEPづつ増加し、ENDを越える直前までの遅延数列を返します。STEPのデフォルトは1、ENDのデフォルトは無限大です。 ENDを省略すると無限数列になるので、REPLで安易に (lrange 0)など評価しないようにしましょう。

     If any of START or step is inexact, the resulting sequence has inexact numbers. STARTとSTEPの少なくとも一方が不正確数なら、不正確数列が返されます。

          (take (lrange -1) 3) => (-1 0 1)

          (lrange 0.0 5 0.5)
            => (0.0 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5)

          (lrange 1/4 1 1/8)
            => (1/4 3/8 1/2 5/8 3/4 7/8)

 -- Function: liota :optional (count +inf.0) (start 0) (step 1)
     A lazy version of iota (see List constructors); returns a lazy sequence of COUNT integers (default: positive infinity), starting from START (default: 0), stepping by STEP (default: 1). 遅延バージョンのiotaです (List constructors参照)。 START(デフォルト0)からSTEP(デフォルト1)づつ増加する、 COUNT個(デフォルト無限大)の遅延数列を返します。

     Just like iota, the result consists of exact numbers if and only if both START and STEP are exact; otherwise the result consists of inexact numbers. iotaと同様、STARTとSTEPの両方が正確数の時に限り、結果は正確数のリストとなり、そうでなければ非正確数のリストとなります。

 -- Function: port->char-lseq :optional port
 -- Function: port->byte-lseq :optional port
 -- Function: port->string-lseq :optional port
 -- Function: port->sexp-lseq :optional port
     These are the same as the following expressions, respectively. They are provided for the convenience, since this pattern appears frequently. これらの手続きは以下の式とそれぞれ同等です。このパターンは良く現れるので、簡便のために用意しました。

          (generator->lseq (cut read-char port))
          (generator->lseq (cut read-byte port))
          (generator->lseq (cut read-line port))
          (generator->lseq (cut read port))

     If PORT is omitted, the current input port is used.

     Note that the lazy sequence may buffer some items, so once you make an lseq from a port, only use the resulting lseq and don't ever read from PORT directly. PORTが省略された場合はcurrent-input-portが使われます。

     遅延シーケンスが入力をいくらかバッファする可能性があるので、一度lseqを作った後では、PORTから直接読み出しをしないようにしてください。

     Note that the lazy sequence terminates when EOF is read from the port, but the port isn't closed.  The port should be managed in larger dynamic extent where the lazy sequence is used. 遅延シーケンスはポートがEOFを返した時点で終端となりますが、ポート自体はクローズされないことに注意してください。ポートの管理は、遅延シーケンスを使う部分全体を囲むような大きな動的エクステントで行う必要があります。

     You can also convert input data into various lists by the following expressions (see Input utility functions). Those procedures read the port eagerly until EOF and returns the whole data in a list, while lseq versions read the port lazily. 入力ポートを色々なリストに変換するには、他に次のような手続きがあります (Input utility functions参照)。lseq版がポートを必要に応じて読むのに対し、これらの手続きはポートをEOFに達するまで一気に読み込み、全てのデータをリストにしてから返します。

          (port->list read-char port)
          (port->list read-byte port)
          (port->string-list port)
          (port->sexp-list port)

     Those procedures make (lazy) lists out of ports.  The opposite can be done by open-input-char-list and open-input-byte-list; see Virtual ports, for the details. これらの手続きは、ポートからリストを作りだします。反対の手続きとして、 open-input-char-listとopen-input-byte-listがあります (Virtual ports参照)。

See also Lazy sequence utilities, for more utility procedures that creates lazy sequences. 遅延シーケンスを作るユーティリティ関数は他にもたくさん提供されています。 Lazy sequence utilitiesを参照してください。

Examples
........

例
.

Let's consider calculating an infinite sequence of prime numbers. (Note: If you need prime numbers in your application, you don't need to write one; just use math.prime. see Prime numbers). 素数の無限列を計算してみましょう。(註: アプリケーションで素数が必要な場合は、わざわざ書かなくても math.primeが使えます。Prime numbers参照。)

Just pretend we already have some prime numbers calculated in a variable *primes*, and you need to find a prime number equal to or grater than N (for simplicity, we assume N is an odd number). まず、既にある程度の計算済みの素数列が*primes*にあるとします。すると、与えられたN以上の素数をひとつ見つける手続きが次のとおり書けます (Nは奇数とします。)

     (define (next-prime n)
       (let loop ([ps *primes*])
         (let1 p (car ps)
           (cond [(> (* p p) n) n]
                 [(zero? (modulo n p)) (next-prime (+ n 2))]
                 [else (loop (cdr ps))]))))

This procedure loops over the list of prime numbers, and if no prime number P less than or equal to (sqrt n) divides N, we can say N is prime.  (Actual test is done by (> (* p p) n) instead of (> p (sqrt n)), for the former is faster.) If we find some P divides N, we try a new value (+ n 2) with next-prime. この手続きは素数列をループし、(sqrt n)以下の素数で Nを割ろうとします。一つも割りきれる素数がなければ、Nが素数です。 (実際の条件は、(> p (sqrt n))より効率の良い(> (* p p) n)を使っています)。 Nを割り切る素数があった場合は、 next-primeを再帰的に呼んで(+ n 2)を試します。

Using next-prime, we can make a generator that keeps generating prime numbers.  The following procedure returns a generator that returns primes above LAST. next-primeを使うと、次々に素数を生成してゆくジェネレータを書くことができます。次の手続きはLASTより大きい素数を次々に生成するジェネレータです。

     (define (gen-primes-above last)
       (^[] (set! last (next-prime (+ last 2))) last))

Using generator->lseq, we can turn the generator returned by gen-primes-above into a lazy list, which can be used as the value of *prime*.  The only caveat is that we need to have some pre-calculated prime numbers: generator->lseqを使えば、 gen-primes-aboveを遅延シーケンスに変換することができ、それを*prime*の値とすることができます。最初の方の素数を計算するために、あらかじめ計算済みの素数をいくつか用意しておくのがポイントです。

     (define *primes* (generator->lseq 2 3 5 (gen-primes-above 5)))

Be careful not to evaluate *primes* directly on REPL, since it contains an infinite list and it'll blow up your REPL. You can look the first 20 prime numbers instead: *primes*を直接REPLで評価しないように。無限リストなので、 REPLの表示が終わらなくなります。かわりに、例えばこんなふうにして最初の20個の素数を見たり:

     (take *primes* 20)
      => (2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)

Or find what the 10000-th prime number is: 10000番目の素数は何かを見たり:

     (~ *primes* 10000)
      => 104743

Or count how many prime numbers there are below 1000000: あるいは1000000以下の素数はいくつあるかを調べたりできます:

     (any (^[p i] (and (>= p 1000000) i)) *primes* (lrange 0))
      => 78498

Note: If you're familiar with the lazy functional approach, this example may look strange.  Why do we use side-effecting generators while we can define a sequence of prime numbers in pure functional way, as follows? 註：遅延評価な関数型言語に慣れたプログラマには、この例は奇妙に見えるかもしれません。わざわざ副作用のあるジェネレータを経由しないでも、次に示すとおり、素数列は純粋に関数的な方法で定義できます。

     (use gauche.lazy)

     (define (prime? n)
       (not (any (^p (zero? (mod n p)))
                 (ltake-while (^k (<= (* k k) n)) *primes*))))

     (define (primes-from k)
       (if (prime? k)
         (lcons k (primes-from (+ k 2)))
         (primes-from (+ k 2))))

     (define *primes* (llist* 2 3 5 (primes-from 7)))

(The module gauche.lazy provides ltake-while, which is a lazy version of take-while.  We don't need lazy version of any, since it immediately stops when the predicate returns a true value.) (gauche.lazyモジュールには、take-whileの遅延バージョンltake-whileが定義されています。 anyについては、遅延バージョンは必要ありません。anyはもともと述語が真を返したら直ちに評価をやめて残りは見ないからです)。

The use of lcons and co-recursion in primes-from is a typical idiom in functional programming.  It's perfectly ok to do so in Gauche; except that the generator version is much faster (when you take first 5000 primes, generator version ran 17 times faster than co-recursion version on the author's machine). primes-fromでのlconsを使った余再帰は、関数型プログラミングでの典型的なイディオムです。もちろん、 Gaucheでもこのようなコードを書くことに何の問題もありません。ただし、Gaucheではジェネレータを使った方がずっと効率が良くなります (筆者のマシンでは、最初の5000個の素数を計算するのに、ジェネレータ版は余再帰版より17倍速いです)。

It doesn't mean you should avoid co-recursive code; if an algorithm can be expressed nicely in co-recursion, it's perfectly ok.  However, watch out the subtle semantic difference from lazy functional languages---straightforward porting may or may not work. だからといって何が何でも余再帰を避けるべきということにはなりません。アルゴリズムが余再帰で自然にかけるならそうして構わないでしょう。ただその場合でも、遅延評価な関数型言語とのセマンティクスの違いをいつも気をつけるようにしてください。単に遅延評価アルゴリズムのコードをそのまま移植しても動くとは限りません。

Exceptions
==========

Gauche's exception system consists of three components; (1) the way to signal an exceptional case has occurred, (2) the way to specify how to handle such a case, and (3) the standard objects (conditions) to communicate the code that signals an exceptional case and the code that handles it. Gaucheの例外システムは次の3つのコンポーネントから構成されています。 (1)例外状況が発生したことを通知する方法、 (2)例外状況をどのように処理するかを指定する方法、 (3)例外状況を知らせたコードとそれを処理するコードがやりとりするための標準オブジェクト(コンディション)。

Those three components are typically used together, so first we explain the typical usage patterns using examples.  Then we describe each feature in detail. 普通これらの3つのコンポーネントは一緒に使われます。そこで、最初に例を用いて典型的な使い方について説明し、そのあとでそれぞれの機能について詳しく解説します。

Note for terminology: some languages use the word exception to refer to an object used to communicate the code that encountered an exceptional situation with a handler that deals with it. Gauche uses a term condition to refer to such objects, following SRFI-35.  Exception is the situation, and condition is a runtime object that describes it. 用語について: いくつかの言語では例外(exception)というと、例外的状況に遭遇したコードとそのハンドラがやりとりをするために用られるオブジェクトのことを指します。Gaucheではそのようなオブジェクトのことを言うときには、 SRFI-35にならってコンディション(condition)を使います。例外というのは、状況であり、コンディションはそれを記述する実行時のオブジェクトです。

Exception handling overview
---------------------------

Catching specific errors
........................

特定のエラーを捕まえる
...........

One of the most typical exception handling is to catch a specific error raised by some built-in or library procedures. A macro guard can be used for such a purpose.  The code looks like this: 最もよくある例外処理のひとつは、組み込みあるいはライブラリの手続きから発生した特定のエラーを捕捉するというものです。 guardマクロがこのような目的の場合に使えます。コードは以下のような感じになるでしょう。

     (guard (exc [(condition-has-type? exc <read-error>)
                  (format #t "read error!")
                  'read-error]
                 [else 'other-error])
       (read-from-string "(abc"))

The cadr of guard clause is a form of (VARIABLE CLAUSE ...).  In this example, the variable is exc, and it has two clauses. Each CLAUSE has the form like the one in cond. guard節の cadr 部は (VARIABLE CLAUSE ...) という形式です。この例では、変数は excで、2つの節があります。それぞれの CLAUSE は cond と似た形式になります。

The cddr of guard is the body, a list of expressions.  This example has only one expression, (read-from-string "(abc"). guard の cddr 部は本体で、式のリストです。この例では、式は (read-from-string "(abc") のひとつだけです。

guard starts executing its body. read-from-string raises an error of type <read-error> when it encounters syntactic errors.  The form guard intercepts the error, and binds the condition object to the variable EXC, then checks the clauses following EXC in a similar manner to cond---in this case, the thrown condition is of type <read-error>, so the test of the first clause is satisfied, and the rest of clause is executed, i.e. "read error!" is printed and a symbol read-error is returned. guard はその本体部を実行するところから始めます。 read-from-string は構文エラーに出くわすと、<read-error>型のエラーを発生させます。guardフォームがこのエラーを捕捉し、そのコンディションオブジェクトを変数EXCに束縛し、EXCの後の節を、condと同じようにチェックします。この場合、投げられたコンディションは <read-error>なので、最初の節のテストを満し、その節の残りの部分が実行されます。すなわち、"read error!" が印字され、シンボル read-error が返ります。

If you're familiar with other languages, you may recognize the pattern.  The cddr of guard form is like TRY clause of C++/Java or the cadr of handler-case of Common Lisp; and the cdadr of guard form is like catch clauses or the cddr of handler-case. 他の言語を使い慣れていれば、同じパターンであることがわかると思います。 guard フォームの cddr 部は、C++やJavaの TRY 節、あるいは、 Common Lisp の handler-case の cadr 部に似ています。また、guard フォームの cdadr 部は、catch 節あるいは、 handler-case の cddr 部に似ています。

In the test expressions it is common to check the type of thrown condition.  The function condition-has-type? is defined in SRFI-35 but it's rather lengthy.  Gauche's condition classes can also work like a predicate, so you can write the above expression like this. テスト式においては、投げられたコンディションのタイプをチェックするのが普通です。condition-has-type? という関数が SRFI-35 で定義されていますが、これはちょっと冗長です。Gauche のコンディションクラスは述語のようにも使えるようになっており、上の式は以下のように書くこともができます。

     (guard (exc [(<read-error> exc)
                  (format #t "read error!")
                  'read-error]
                 [else 'other-error])
       (read-from-string "(abc"))

Note: Generally you can't use is-a? to test if the thrown condition is of a specific type, since a condition may be compound.  See Conditions about compound conditions. 注意事項: 一般的には、投げられたコンディションが特定のタイプであるかをチェックするのにis-a?は使えません。コンディションが合成されたものである可能性があるからです。合成されたコンディションについての詳細は Conditions を参照してください。

If no tests of CLAUSEs satisfy and no else clause is given, the exception `falls off' the guard construct, i.e. it will be handled by the outer level of guard form or top-level.  For example, the following guard form only handles <read-error> and <system-error>; if the body throws other type of conditions, it must be handled by outer level. もし、CLAUSE のどのテストも満されず、かつ else 節があたえられていなければ、その例外は guard から「抜け」ます。すなわち、guard の外側のレベルあるいはトップレベルで処理されることになります。たとえば、以下の guard フォームでは、<read-error> と <system-error> としか処理できず、もし、本体が他のタイプのコンディションを投げてきたら、その外側のレベルで処理しなければなりません。

     (guard (exc [(<read-error> exc) (handle-read-error)]
                 [(<system-error> exc) (handle-system-error)])
       body ...)

See Handling exceptions for more details on guard and other lower-level exception handling constructs. guardおよび他の低レベルの例外処理の構成についての詳細は Handling exceptions を参照してください。

Signaling exceptions from your code
...................................

自分のコードから例外を通知する
...............

The generic way to signal an exception is to use raise procedure. 例外を通知する一般的な方法は raise手続きを使うことです。

     (raise CONDITION)

You can pass any object to CONDITION; its interpretation solely depends on the exception handler.  If you know the code raises an integer as a condition, you can catch it by guard as this: CONDITIONにはどんなオブジェクトでも渡すことができます。それをどのように解釈するかはひとえに例外ハンドラにかかってます。もし、コンディションとして整数があがってくるというのが判っていれば、 guard で以下のように捕捉することができます。

     (guard (exc [(integer? exc) 'raised])
       (raise 3))

However, as a convention, it is preferable to use an instance of <condition> or one of its subclasses.  A macro condition can be used to create a condition object.  The following examples show how to create a condition with some slot values and then raise it. とはいうものの、<condition> あるいはそのサブクラスのインスタンスを使うのが好ましいというのが通例です。condition マクロはコンディションオブジェクトを作成するのに使えます。以下の例は、いくつかのスロット値をもちそれらを発生させるコンディションの作りかたを示したものです。

     ;; create and raise an error condition
     (raise (condition
             (<error> (message "An error occurred."))))

     ;; create and raise a system error condition
     (raise (condition
             (<system-error> (message "A system error occurred.")
                             (errno EINTR))))

See Conditions for the details of condition macro and what kind of condition classes are provided. condition マクロおよび、どのようなコンディションクラスが用意されているかの詳細については Conditions を参照してください。

The most common type of condition is an error condition, so a convenience procedure error and errorf are provided.  They create an error condition with a message and raise it. 最も一般的なコンディションのタイプはエラーコンディションなので、 error および errorf という便利な手続きが用意されています。これらはメッセージ付きのエラーコンディションを生成し、それを発生させます。

     ;; `error' concatenates the arguments into a message.
     (unless (integer? obj)
       (error "Integer expected, but got:" obj))

     ;; `errorf' uses format to create a message.
     (unless (equal? x y)
       (errorf "~s and ~s don't match" x y))

Unlike the exception throwing constructs in some languages, such as throw of C++/Java, which abandons its continuation, Scheme's raise may return to its caller.   If you don't want raise to return, a rule of thumb is always to pass one of error conditions to it; then Gauche guarantees raise wont return.   See the description of raise in Signaling exceptions for more details. いくつかの言語での例外を投げる機構、たとえば、 C++やJavaの throw はその継続を破棄します。これとは違い Schemeの raise はその呼び出し元へ戻ることができます。もし、 raise で元へもどらないで欲しいのなら、簡便な方法としては、常にエラーコンディションの一つをわたるようにするというのがあります。そうすると Gauche では raise は戻らないことを保証します。 raiseの詳細については、Signaling exceptionsを参照してください。

Note: R7RS adopted slightly different semantics; it splits raise and raise-continuable, the former is for noncontinuable exception (if the exception handler returns, it raises another error), and the latter is for continuable exception.  When you're in R7RS environment, R7RS-compatible raise will be used instead of this raise. 註: R7RSでは少し違ったセマンティクスを採用しています。 raiseは継続不可能な例外を投げるものとして(もし例外ハンドラから制御が戻ってきたら、別のエラーを報告します)、別に継続可能な例外を投げるraise-continuableという手続きを設けました。R7RS環境にいるときは、本項のraiseではなく R7RS互換のraiseが見えるようになっています。

Defining your own condition
...........................

独自のコンディションを定義する
...............

You can also define your own condition classes to pass application-specific information from the point of raising exception to the handlers. 独自のコンディションクラスを定義することが可能で、そうすることで、アプリケーション固有の情報を例外が発生した点からハンドラへ渡すことができます。

To fit to Gauche's framework (SRFI-35), it is desirable that the new condition class inherits a built-in <condition> class or one of its descendants, and also is an instance of a metaclass <condition-meta>. Gauche のフレームワーク(SRFI-35)に適合させるためには、新しく定義するコンディションクラスは組み込みの <condition> クラスあるいはその子孫を継承し、また、メタクラス <condition-meta> のインスタンスであることが望まれます。

One way of ensuring the above convention as well as increasing portability is to use define-condition-type macro, defined in SRFI-35. 可搬性を増すと同時に上の慣例を確実にするための方法のひとつは、 define-condition-typeマクロを使うことです。これは、 SRFI-35で定義されています。

     (define-condition-type <myapp-error> <error>
       myapp-error?
       (debug-info myapp-error-debug-info)
       (reason myapp-error-reason))

This defines a condition type (which is a class in Gauche) <myapp-error>, with a predicate myapp-error? and slots with accessors.   Then you can use the new condition type like the following code: これは、(Gauche内のクラス)<myapp-err>を定義するもので、このクラスにはmyapp-error?という述語とアクセサのあるスロットがあります。こうすれば、以下のようなコードで新しいコンディション型が使えます。

     (guard (exc
              [(myapp-error? exc)
               (let ([debug-info (myapp-error-debug-info exc)]
                     [reason (myapp-error-reason exc)])
                 ... handle myapp-error ...)])
       ...
       ...
       (if (something-went-wrong)
         (raise (condition
                  (<myapp-error> (debug-info "during processing xxx")
                                 (reason "something went wrong")))))
       ...
       ...
       )

If you don't mind to lose srfi compatibility, you can use Gauche's extended error and errorf procedures to write more concise code to raise a condition of subtype of <error>: SRFIとの互換性が重要でないなら、Gaucheの拡張されたerror手続きを使うと<error>のサブタイプであるコンディションを投げるコードをより簡潔に書くことができます。

       (if (something-went-wrong)
         (error <myapp-error>
                :debug-info "during processing xxx"
                :reason "something went wrong"))

See the description of define-condition-type macro for how the condition type is implemented in Gauche's object system. Gauche のオブジェクトシステムでコンディション型がどのように実装されているかは define-condition-typeマクロの解説を参照してください。

Signaling exceptions
--------------------

Signaling errors
................

エラーの通知
......

The most common case of exceptions is an error. Two convenience functions to signal an error condition in simple cases are provided. To signal a compound condition, you can use raise as explained below. 最も良くある例外ケースはエラーです。単純なエラーを通知するために、ふたつの簡単な関数が用意されています。複合コンディションを通知する必要がある場合は下で説明するraise手続きを使って下さい。

 -- Function: error string arg ...
 -- Function: error condition-type keyword-arg ... string arg ...
     [R7RS+][SRFI-23+] Signals an error.  The first form creates an <error> condition, with a message consists of STRING and ARG ..., and raises it.  It is compatible to R7RS and SRFI-23's error behavior. エラーを通知します。最初の形式は、 STRINGとARG ...からなるメッセージを持つ <error>コンディションを作成それをraiseします。この形式はR7RS及びSRFI-23のerrorと互換です。

          gosh> (define (check-integer x)
                  (unless (integer? x)
                     (error "Integer required, but got:" x)))
          check-integer
          gosh> (check-integer "a")
          *** ERROR: Integer required, but got: "a"
          Stack Trace:
          _______________________________________

     The second form can be used to raise an error other than the <error> condition.  CONDITION-TYPE must be a condition type (see Conditions for more explanation of condition types).  It may be followed by keyword-value list to initialize the condition slots, and then optionally followed by a string and other objects that becomes an error message. 2番目の形式は<error>以外のエラーコンディションを通知したいときに使います。CONDITION-TYPEはコンディションタイプでなければなりません (コンディションタイプについてはConditionsを参照して下さい)。その後に、キーワードと値のリストを与えることでコンディションのスロットを初期化することができます。また、その後にメッセージを構成する文字列と他のオブジェクトのリストを与えることができます。

          (define-condition-type <my-error> <error> #f
            (reason)
            (priority))

          ...
            (unless (memq operation *supported-operations*)
              (error <my-error>
                     :reason 'not-supported :priority 'urgent
                     "Operation not supported:" operation))
          ...

 -- Function: errorf fmt-string arg ...
 -- Function: errorf condition-type keyword-arg ... fmt-string arg ...
     Similar to error, but the error message is formatted by format, i.e. the first form is equivalent to: errorに似ていますが、エラーメッセージはformatによりフォーマットされます。すなわち、最初のフォームは以下と等価です。

          (define (errorf fmt . args)
            (error (apply format #f fmt args)))

     The second form can be used to raise an error other than an <error> condition.  Meaning of CONDITION-TYPE and KEYWORD-ARGs are the same as error. 2番目の形式は<error>以外のエラーコンディションを通知するのに使えます。CONDITION-TYPE, KEYWORD-ARGの意味については errorと同じです。

Signaling generic conditions
............................

一般的な条件の通知
.........

 -- Function: raise condition
     [SRFI-18][R7RS base] This is the base mechanism of signaling exceptions.

     The procedure invokes the current exception handler. The argument CONDITION represents the nature of the exception, and passed to the exception handler. Gauche's built-in and library functions always use an instance of <condition> or one of its subclasses as CONDITION, but you can pass any Scheme object to raise.  The interpretation of CONDITION is up to the exception handler.

     Note: Unlike some of the mainstream languages in which "throwing" an exception never returns, you can set up an exception handler in the way that raise may return.  The details are explained in Handling exceptions.

     If you don't want raise to return, the best way is to pass a condition which is an instance of <serious-condition> or one of its subclasses.  Gauche's internal mechanism guarantees raising such an exception won't return. See Conditions for the hierarchy of built-in conditions.

     R7RS adopted slightly different semantics regarding returning from raise; in R7RS, raise never returns---if the exception handler returns, another exception is raised. R7RS has raise-continuable to explicitly allow returning from the exception handler.  For portable programs, always pass <serious-condition> or its subclasses to raise. これは、例外事態を通知する基本となるメカニズムです。

     この手続きは現在の例外ハンドラを呼び出します。引数CONDITIONは例外の性質を表現するのに使われ、例外ハンドラに渡されます。 Gaucheの組み込み手続きやライブラリ手続きは常に、<condition>クラスもしくはそのサブクラスのインスタンスをCONDITIONとして用いますが、ユーザは任意のオブジェクトをraiseに渡すこともできます。渡されたCONDITIONの解釈は例外ハンドラに任されます。

     注意事項: いくつかの主流の言語では、例外を「投げる」と制御はそこに戻りません。Gaucheではraiseから戻って来れるようにセットアップすることが可能です。詳細はHandling exceptionsを参照してください。

     raiseから戻って来ることが無いようにしたい場合は、 <serious-condition>やそのサブクラスのインスタンスをCONDITION としてraiseに渡すのが確実です。組み込みコンディションのクラス階層についてはConditionsを参照して下さい。

     R7RSではやや異なるセマンティクスを採用しています。R7RSのraiseは決して戻りません---もしハンドラが戻ってきた場合は、別の例外が投げられます。 R7RSはraise-continuableという別の手続きで、ハンドラから戻っても良いことを明示します。ポータブルなプログラムでは、 raiseには常に<serious-condition>かそのサブクラスを渡すようにするのが良いでしょう。

Handling exceptions
-------------------

High-level exception handling mechanism
.......................................

上位レベルの例外処理機構
............

 -- Macro: guard (var clause ...) body ...
     [R7RS base] This is the high-level form to handle errors in Gauche. これはGaucheでのエラー処理の高水準フォームです。

     VAR is a symbol, and CLAUSEs are the same form as cond's clauses, i.e. each clause can be either one of the following forms: VAR はシンボルで CLAUSE は cond 節と同じ形式です。つまり、各節は以下の形式のどれかひとつです。

      1. (TEST EXPR ...)

      2. (TEST => PROC)

     The last CLAUSE may be (else EXPR ...). 最後のCLAUSEは(else EXPR ...)という形式も許されます。

     This form evaluates BODY ... and returns the value(s) of the last BODY expression in normal case. If an exception is raised during the evaluation of body expressions, the raised exception is bound to a variable VAR, then evaluates TEST expression of each clause.  If one of TEST expressions returns true value, then the corresponding EXPRs are evaluated if the clause is the first form above, or an PROC is evaluated and the result of TEST is passed to the procedure PROC if the clause is the second form. このフォームは通常の場合には BODY ... を評価し最後の BODY の式の値を返します。本体の式を評価している最中に例外が発生した場合、発生した例外を変数 VAR に束縛し、その後各節の TEST 式を評価します。もし、TEST 式のひとつが真値を返したとき、その節が上述の最初の形式であれば、対応する EXPR が評価されます。あるいは、節が二番目の形式であれば、手続きPROCにTESTの結果が渡されます。

     When the TEST(s) and EXPR(s) in the clauses are evaluated, the exception handler that is in effect of the caller of guard are installed; that is, if an exception is raised again within CLAUSEs, it is handled by the outer exception handler or guard form. 指定された節の TEST および EXPR が評価されるとき、 guardを呼び出した時点での例外ハンドラが設定されます。つまり、 CLAUSE 内部で再び例外が発生した場合、その例外は、外側の例外ハンドラまたは guard フォームで処理されます。

     If no TEST returns true value and the last clause is else clause, then the associated EXPRs are evaluated. If no TEST returns true value and there's no else clause, the raised exception is re-raised, to be handled by the outer exception handler. もし、どの TEST も真値を返さず、最後の clause が else 節であれば、それに結びつけられた EXPR が評価されます。もし、どの TEST も真値を返さず、else 節がなければ、再び例外が発生し、外側の例外ハンドラで処理されます。

     When the exception is handled by one of clauses, guard returns the value(s) of the last EXPR in the handling clause. 例外が clause のどれかで処理された時には、guard はそれを処理した節の最後の EXPR の値を返します。

     The CLAUSEs are evaluated in the same dynamic environment as the guard form, i.e. any dynamic-winds inside body are unwound before evaluation of the CLAUSEs.  It is different from the lower level forms with-error-handler and with-exception-handler, whose handler is evaluated before the dynamic environment are unwound. CLAUSEはguardと同じ動的環境で評価されます。すなわち、 body中のdynamic-windはCLAUSEの評価の前に巻戻されます。これは低レベル関数のwith-error-handlerや with-exception-handlerとは異なることに注意してください。これら低レベル関数では例外ハンドラが呼ばれてから動的環境が巻戻されます。

          (let ([z '()])
            (guard (e [else (push! z 'caught)])
              (dynamic-wind (lambda () (push! z 'pre))
                            (lambda () (error "foo"))
                            (lambda () (push! z 'post))))
            (reverse z))
           => (pre post caught)

          (guard (e [else (print 'OUTER) #f])
            (with-output-to-string
              (lambda ()
                (print 'INNER)
                (error "foo"))))
           => prints OUTER to the current output port of guard,
                not to the string port.
           => OUTERを文字列ポートではなくguard実行時の
                current-output-portに出力。

 -- Macro: unwind-protect expr cleanup ...
     Executes EXPR, then executes CLEANUPs, and returns the result(s) of EXPR.  If an uncontinuable exception is raised within EXPR, CLEANUPs are executed before the exception escapes from the unwind-protect form. For example, the following code calls start-motor, drill-a-hole, and stop-motor in order if everything goes ok, and if anything goes wrong in start-motor or drill-a-hole, stop-motor is still called before the exception escapes unwind-protect. EXPRを実行してからCLEANUP ...を実行し、EXPRの結果を返します。 EXPR内で継続不可能な例外が挙がった場合、その例外がunwind-protectフォームを抜ける前に、CLEANUP ...が実行されます。たとえば、以下のコードではなにも問題が起きなければ、start-motor、drill-a-hole、 stop-motorが、この順で呼ばれます。何か不具合が start-motorあるいはdrill-a-holeで起った場合でも、例外が unwind-protectを抜ける前にstop-motorが呼ばれます。

          (unwind-protect
            (begin (start-motor)
                   (drill-a-hole))
            (stop-motor))

     The CLEANUP forms are evaluated in the same dynamic environment as unwind-protect. If an exception is thrown within CLEANUP, it will be handled outside of the unwind-protect form. CLEANUPフォームはunwind-protectと同じ動的環境で評価されます。例外がCLEANUP内で投げられた場合その例外は、 unwind-protectフォームの外側で処理されることになります。

     Although this form looks similar to dynamic-wind, they work at different layers and should not be confused. dynamic-wind is the bottom-level building block and used to manage current exception handlers, current i/o ports, parameters, etc. dynamic-wind's BEFORE and AFTER thunks are called whenever any of those control flow transition occurs. On the other hand, unwind-protect only cares about the Gauche's exception system.  unwind-protect's CLEANUP is called only when EXPR exits normally or throws Gauche's exception. In the above example, if control escapes from drill-a-hole by calling a continuation captured outside of unwind-protect, CLEANUP is not called; because the control may return to drill-a-hole again.  It can happen if user-level thread system is implemented by call/cc, for example. このフォームはdynamic-windと似ていますが、この2つは動作するレイヤが違いますので混同しないようにしてください。 dynamic-windは最下位レイヤのもので、現在の例外ハンドラ、現在の入出力ポート、パラメータなどを管理するのに用います。 dynamic-windのBEFOREおよびAFTERのサンクは対応する制御フローの遷移が起きたときに必ず呼ばれます。一方、unwind-protectはGaucheの例外システムの面倒しか見ません。 unwind-protectのCLEANUPはEXPRが正常終了するか Gaucheの例外を投げたときにのみ呼びだされます。上述の例で、unwind-protectの外側で補足された継続が呼ばれ、制御がdrill-a-holeを抜けると、 CLEANUPは呼ばれません。制御が再びdrill-a-holeに戻る可能性があるからです。たとえば、ユーザレベルのスレッドシステムが call/ccで実装されているような場合にこのようなことが起こる可能性があります。

     You can go back to the body EXPR from outside of unwind-protect by invoking continuations captured within EXPR.

     However, keep in mind that once CLEANUP are executed, some resources might not be available in EXPR. We still allow it since the reexecuted part of EXPR may not depend on the resources cleaned up with CLEANUP.

     Even if EXPR returns (normally or abnormally), CLEANUP only executed once, in the first time. EXPR内で捕捉された継続をunwind-protectの外側で起動することで、 EXPR内に再び戻ることは可能です。

     ただ、ひとたびCLEANUPが実行されてしまったら、それによってクリーンアップされたリソースはEXPR内から使えなくなっているという可能性に留意してください。そういったリソースに依存しない計算なら再実行できるので、再起動自体は禁止されていません。

     EXPRから複数回戻った場合(通常の評価でもエラーでも)、CLEANUPが実行されるのは最初の時のみです。

     The name of this form is taken from Common Lisp.  Some Scheme systems have similar macros in different names, such as try-finally. このフォームの名前はCommon Lispから取りました。同様のマクロに try-finallyというような別の名前を使っているSchemeの処理系もあります。

 -- Function: with-error-handler handler thunk
     Makes HANDLER the active error handler and executes THUNK. If THUNK returns normally, the result(s) will be returned. If an error is signaled during execution of THUNK, HANDLER is called with one argument, an exception object representing the error, with the continuation of with-error-handler. That is, with-error-handler returns whatever value(s) HANDLER returns. HANDLERをアクティブなエラーハンドラにし、THUNKを実行します。 THUNKが正常に戻ったら、その結果が返されます。 THUNKの実行中にエラーが通知されたら、エラーを表す例外オブジェクトを 1引数とするHANDLERが、with-error-handlerの継続とともに呼ばれます。すなわち、with-error-handlerは、HANDLERが返す値を返します。

     If HANDLER signals an error, it will be handled by the handler installed when with-error-handler called. HANDLERがエラーを通知したら、それはwith-error-handlerが呼ばれたときにインストールされていたハンドラにより処理されます。

     The dynamic environment where HANDLER is executed is the same as the error occurs.  If dynamic-wind is used in THUNK, its AFTER method is called after HANDLER has returned, and before with-error-handler returns. HANDLERが実行される場合の動的な環境は、エラーが起きたときのそれと同じです。THUNK内でdynamic-windが使われていたら、そのAFTERメソッドはHANDLERが戻った後、かつwith-error-handlerが戻る前に呼ばれます。

     Note: Using this procedure directly is no longer recommended, since guard is more safe and portable.  We'll keep this for a while for the backward compatibility, but we recommend to rewrite code to use guard instead of this. The common idiom of "cleanup on error" code: 註: この手続きを直接使うことはもはや推奨されません。guardの方がより安全でポータブルだからです。互換性を保つためまだしばらくはこの手続きを残しますが、この手続きを使っているコードをguardによって書き直すことを推奨します。「エラー時に後始末をする」というよくある次のような処理は：

          (with-error-handler (lambda (e) (cleanup) (raise e))
            (lambda () body ...))

     should be written like this: 次のように書き直すことができます。

          (guard (e [else (cleanup) (raise e)])
            body ...)

Behavior of unhandled exception
...............................

処理されなかった例外のふるまい
...............

If an exception is raised where no program-defined exception handler is installed, the following action is taken. プログラムで定義した例外ハンドラを設定していないところで例外が発生した場合以下のようなことが起ります。

     If an unhandled exception occurs within a thread other than the primordial one, it terminates the thread, and the thrown condition is wrapped by <uncaught-exception> condition and stored in the thread object.  If other thread calls thread-join! to retrieve result, the the <uncaught-exception> is thrown in that thread. Note that no messages are displayed when the original uncaught exception is thrown.  See Thread programming tips, for the details. もしメインスレッド以外のスレッドで捕捉されない例外が起きた場合、そのスレッドは終了し、投げられた例外は<uncaught-exception>でラップされてスレッドオブジェクトに保存されます。他のスレッドがthread-join!でスレッドの結果を取り出そうとした時に、その<uncaught-exception>が投げられます。元の捕捉されない例外が起きた時点では何もメッセージなどが表示されないことに注意してください。詳しくはThread programming tipsを参照。

 1. Otherwise, if the program is running interactively (in repl), the information of the thrown exception and stack trace are displayed, and the program returns to the toplevel prompt. そうでなく、プログラムが対話的に走っている場合(REPL)、投げられた例外の情報とスタックトレースが表示され、プログラムはトップレベルのプロンプトに戻ります。

 2. If the program is running non-interactively, the information of the thrown exception and stack trace are displayed, then the program exits with an exit status EX_SOFTWARE (70). そうでなく、プログラムが対話的に走っているのではない場合は、投げられた例外の情報とスタックトレースが表示された後、プログラムは終了コード EX_SOFTWARE (70)で終了します。

The default error message and stack trace in the above case 2 and case 3 is printed by report-error procedure.  You can use it in your error handler if you need the same information. 上の2と3でのエラーメッセージとスタックトレースは、report-error手続きによって出力されています。自分のエラーハンドラ内で同じ情報を出力したければこれを使うことができます。

 -- Function: report-error exn :optional sink
     Prints type and message of a thrown condition object EXN, then print the current stack trace.  This is the procedure the system calls when you see an error reported on REPL.

     Since you can raise any object, EXN can be any object; it's not needed to be an instance of <condition>. A suitable message is chosen by report-error.

     You can specify where the output goes by the optional SINK argument: If it is an output port, the output goes there; you can also pass #t for the current output port and #f for the output string port, just like format.  That is, when you pass #f, the message goes to a temporary output string port, and gathered string is returned.  For all the other cases, an undefined value is returned.  If SINK is omitted or any other object listed above, the current error port is used.

     Note: As of 0.9.5, this procedure prints stack trace of the context where report-error is called, rather than the context where EXN is thrown.  It doesn't matter much as far as you call report-error directly inside the error handler, but in general what you want to print is the latter, and we have a plan to attach stack trace info to <condition> object in future. 投げられたコンディションオブジェクトEXNの型とメッセージを表示し、それからスタックトレースを出力します。REPLでエラーが報告される時の表示を出しているのがこの手続きです。

     raiseは任意のオブジェクトをコンディションとして投げることが出来るので、 EXNも<condition>オブジェクトのインスタンスである必要はなく、どんな型でも許されます。 report-errorは適切なメッセージを選んで表示します。

     出力の行き先は省略可能引数SINKで指定できます。出力ポートを渡せばそこに出力されます。また、formatと同様に、#tを渡すことで現在の出力ポートに、#fを渡すことで一時的な文字列ポートに出力できます。 #fを渡した場合、一時的な文字列ポートに出力された文字列が返り値となります。その他の場合は未定義値が返されます。 SINKが省略されるか、上記以外の値であった場合は現在のエラーポートが使われます。

     註: 0.9.5の時点で、この手続きはEXNが投げられたコンテキストでのスタックトレースではなく、report-error自身が呼ばれたコンテキストでのスタックトレースを表示します。report-errorをエラーハンドラから直接呼んでいる限りにおいてはあまり違いは出ませんが、一般的に望ましいのは前者なので、将来的には<condition>オブジェクトにスタックトレース情報をつける予定があります。

Low-level exception handling mechanism
......................................

下位レベルの例外処理機構
............

This layer provides SRFI-18 compatible simple exception mechanism. You can override the behavior of higher-level constructs such as with-error-handler by using with-exception-handler. このレイヤはSRFI-18互換のシンプルな例外メカニズムを提供します。 with-error-handlerのような高次元の構造の振る舞いを、 with-exception-handlerを使って上書きすることができます。

Note that it is a double-edged sword.  You'll get a freedom to construct your own exception handling semantics, but the Gauche system won't save if something goes wrong.   Use these primitives when you want to customize the system's higher-level semantics or you are porting from other SRFI-18 code. これは諸刃の剣であることに注意して下さい。あなたは独自の例外処理セマンティクスを構築する自由がありますが、Gaucheシステムは何か間違いがあっても救ってくれません。システムの高次元のセマンティクスをカスタマイズしたいか、他のSRFI-18準拠のコードを移植している場合にのみ、これらのプリミティブを使って下さい。

 -- Function: current-exception-handler
     [SRFI-18] Returns the current exception handler. 現在の例外ハンドラを返します。

 -- Function: with-exception-handler handler thunk
     [SRFI-18] A procedure HANDLER must take one argument.  This procedure sets HANDLER to the current exception handler and calls THUNK. (Note that this slightly differs from R7RS with-exception-handler; we'll explain it below.) HANDLERは1引数を取る手続きです。この手続きは、HANDLERを現在の例外ハンドラにセットし、THUNKを呼び出します。 (この手続きはR7RSのwith-exception-handlerと微妙に異なります。)

When an exception is raised by raise or error, HANDLER is called with the thrown condition in the exactly same dynamic environment of raise or error. It means the exception handler is also the same, so calling raise in HANDLER reinvokes HANDLER again. It also means that when HANDLER returns, it returns from RAISE.

The behavior is specified in SRFI-18, intending this procedure to be the most primitive building block of exception handling mechanism. If you need to switch handlers, you can do it by yourself.

If you need the typical semantics where raising exception in the exception handler is handled by outer handler, you should use guard. Use this procedure only when you want to play with the most primitive layer of exception handling.

R7RS has a procedure with the same name, but has one difference---it changes the active exception handler to the ``outer'' handler before calling HANDLER.  See R7RS base library, for the description of R7RS's with-exception-handler. 例外がraiseやerrorで通知されると、投げられたコンディションを引数としてHANDLERが呼び出し元と全く同じ動的環境で呼び出されます。つまり、HANDLER中でraiseを呼び出すと、再びHANDLERが呼ばれます。また、HANDLERから戻ると、制御はraiseの呼び出し元に戻ります。

この振る舞いはSRFI-18により定義されました。これは、この手続きが例外制御の最もプリミティブな構成要素になることを意図しています。例外処理中にアクティブなハンドラを切り替えたければ、自分でそう書く必要があります。

通常、例外処理中に例外が発生したら、それは「外側の」ハンドラで処理したいでしょう。そういった典型的な使い方には、guardを使ってください。この手続きはあくまで、例外処理の最も低層にアクセスしたい時のみ使うとよいでしょう。

R7RSにも同名の手続きがありますが、一つだけ違いがあります。 R7RS版はHANDLERを呼び出す前に現在の例外ハンドラを一つ「外側」の例外ハンドラに置き換えます。R7RSのwith-exception-handlerの説明は R7RS base libraryを参照してください。

If an exception is raised by error, or the thrown condition inherits <serious-condition>, it is prohibited to return from HANDLER.  If HANDLER ever returns in such cases, another error is signaled, with replacing the current exception handler to the outer handler.  So the caller of error, or the caller of raise with <serious-condition>, can assume it never returns. 例外がerrorにより投げられた場合、あるいは投げられたコンディションが <serious-condition>を継承していた場合、 HANDLERから戻ることは禁止されます。もし戻ってしまったら、ハンドラを外側のものに置き換えた上で別のエラーが投げられます。したがって、errorの呼び出し元、あるいは<serious-condition>を引数としたraiseの呼び出し元は、その呼び出しが決して戻らないと考えて構いません。

The behavior of those procedures can be explained in the following conceptual Scheme code. これらの手続きの振る舞いは、次の概念的なSchemeコードによって説明されるでしょう。

     ;; Conceptual implementation of low-level exception mechanism.
     ;; Suppose %xh is a list of exception handlers
     ;; 低レベルな例外メカニズムの概念的な実装
     ;; %xhは例外ハンドラのリスト

     (define (current-exception-handler) (car %xh))

     (define (raise exn)
       (receive r ((car %xh) exn)
         (when (uncontinuable-exception? exn)
           (set! %xh (cdr %xh))
           (raise (make-error "returned from uncontinuable exception")))
         (apply values r)))

     (define (with-exception-handler handler thunk)
       (let ((prev %xh))
         (dynamic-wind
           (lambda () (set! %xh (cons handler %xh)))
           thunk
           (lambda () (set! %xh prev)))))

Conditions
----------

Built-in Condition classes
..........................

組み込みコンディションクラス
..............

Gauche currently has the following hierarchy of built-in condition classes.  It approximately reflects SRFI-35 and SRFI-36 condition hierarchy, although they have Gauche-style class names.  If there's a corresponding SRFI condition type, the class has the SRFI name as well. 現在のところGaucheには以下の組み込みコンディションクラスの階層があります。これは、おおよそのところ SRFI-35 および SRFI-36 のコンディションの階層を反映したものですが、Gauche風のクラス名になっています。対応する SRFI のコンディションタイプがあるものについては、SRFI でのクラス名も使えます。

       <condition>
         +- <compound-condition>
         +- <serious-condition>
         |    +- <serious-compound-condition> ; also inherits <compound-condition>
         +- <message-condition>
              +- <error>                      ; also inherits <serious-condition>
                   +- <system-error>
                   +- <unhandled-signal-error>
                   +- <read-error>
                   +- <io-error>
                        +- <port-error>
                             +- <io-read-error>
                             |    +- <io-decoding-error>
                             +- <io-write-error>
                             |    +- <io-encoding-error>
                             +- <io-closed-error>
                             +- <io-unit-error>
                             +- <io-invalid-position-error>

Note that some conditions may occur simultaneously; for example, error during reading from a file because of device failure may consist both <system-error> and <io-read-error>. In such cases, a compound condition is raised. So you can't just use, for instance, (is-a? obj <io-read-error>) to check if <io-read-error> is thrown. See the "Condition API" section below. いくつかのコンディションが同時に発生することがあることに注意してください。たとえば、ファイルの読み込がデバイスの欠陥により失敗した場合は、 <system-error> および <io-read-error> の両方からなるエラーとなるでしょう。このような場合、合成したコンディション (compound condition) が発生します。したがって、たとえば、<io-read-error> が投げられたかどうかをチェックするのに、単に (is-a? obj <io-read-error>) を使えばよいというわけにはいきません。後述の「コンディション API」の節を参照してください。

 -- Metaclass: <condition-meta>
     Every condition class is an instance of this class. This class defines object-apply so that you can use a condition class as a predicate, e.g.: すべてのコンディションクラスはこのクラスのインスタンスです。このクラスは object-apply を定義していますので、コンディションクラスは述語として使うことができます。たとえば、

          (<error> obj) == (condition-has-type? obj <error>)

 -- Class: <condition>
 -- Condition Type: &condition
     [SRFI-35] The root class of the condition hierarchy. コンディションの階層のルートクラスです。

 -- Class: <compound-condition>
     Represents a compound condition.  A compound condition can be created from one or more conditions by make-compound-condition. Don't use this class directly. 合成コンディションを表現します。合成コンディションは make-compound-condition を用いて1つ以上のコンディションから生成することができます。このクラスを直接使ってはいけません。

     A compound condition returns #t for condition-has-type? if any of the original conditions has the given type. 合成コンディションはcondition-has-type? に対して、元のコンディションのどれかが、与えられたタイプなら、#t を返します。

 -- Class: <serious-condition>
 -- Condition Type: &serious
     [SRFI-35] Conditions of this class are for the situations that are too serious to ignore or continue.  Particularly, you can safely assume that if you raise this type of condition, it never returns. このクラスのコンディションは無視して先を続けることはできない深刻な状況のためにあります。特に、このタイプのコンディションを raise したら、それは元には絶対に戻らないと考えて問題ありません。

 -- Class: <serious-compound-condition>
     This is an internal class to represent a compound condition with any of its component condition is serious.   Inherits both <compound-condition> and <serious-condition>. make-compound-condition uses this class if the passed conditions includes a serious one. Don't use this class directly. 深刻なコンディションを含む合成コンディションを表現するための内部クラスです。<compound-condition> および <serious-condition> の両方を継承しています。 make-compound-condition は深刻なコンディションを含む複数のコンディションを渡されると、このクラスを使います。このクラスを直接使ってはいけません。

 -- Class: <message-condition>
 -- Condition Type: &message
     [SRFI-35] This class represents a condition with a message.  It has one slot. このクラスはメッセージ付のコンディションを表現し、スロットを一つもっています。

      -- Instance Variable of <message-condition>: message
          A message. メッセージ

 -- Class: <error>
 -- Condition Type: &error
     [SRFI-35] Indicates an error.  Inherits <serious-condition> and <message-condition>, thus has message slot. エラーを表します。<serious-condition> および <message-condition> を継承しています。したがって、 message スロットを持っています。

     Note: SRFI-35 &error condition only inherits &serious and not &message, so you have to use compound condition to attach a message to the error condition.  Gauche uses multiple inheritance here, largely because of backward compatibility. To write a portable code, an error condition should be used with a message condition, like this: 注意事項: SRFI-35 の&errorコンディションは &serious のみを継承し、&message は継承していません。したがって、このエラーコンディションにメッセージを付与するためには、合成コンディションを使わなければなりません。Gauche は主として過去のバージョンとの互換性を確保するために、ここで多重継承を用いています。可搬性のあるコードを書くには、以下のようにメッセージコンディション付きのエラーコンディションを使うべきです。

          (condition
            (&message (message "Error message"))
            (&error))

 -- Class: <system-error>
     A subclass of <error>. When a system call returns an error, this type of exception is thrown.  The message slot usually contains the description of the error (like the one from strerror(3)). Besides that, this class has one more instance slot: <error> のサブクラス。システムコールがエラーを返したとき、この型の例外が投げられます。 message スロットには通常エラーの(strerror(3)のような)説明が含まれています。それ以外に、このクラスにはもうひとつ次のようなインスタンススロットがあります。

      -- Instance Variable of <system-error>: errno
          Contains an integer value of system's error number.

          Error numbers may differ among systems.  Gauche defines constants for typical Unix error values (e.g. EACCES, EBADF, etc), so it is desirable to use them instead of literal numbers. See the description of sys-strerror in System inquiry for available constants. システムのエラー番号の整数値を持ちます。

          エラー番号はシステムによって異なる可能性があります。Gaucheは典型的な Unixのエラー番号に対して定数を定義している(例: EACCES, EBADF)ので、それを使うと良いでしょう。定義されている定数に関しては System inquiryのsys-strerrorの説明を参照してください。

     This class doesn't have corresponding SRFI condition type, but important to obtain OS's raw error code.  In some cases, this type of condition is compounded with other condition types, like <io-read-error>. このクラスには対応する SRFI のコンディションタイプがありませんが、 OSの生のエラーコードを取得するのに重要です。いくつかのケースでこのタイプのコンディションは他の、たとえば <io-read-error> のようなコンディションと合成されます。

 -- Class: <unhandled-signal-error>
     A subclass of <error>.  The default handler of most of signals raises this condition.   See Handling signals for the details. <error>のサブクラス。多くのシグナルのデフォルトハンドラはこのコンディションを投げます。詳しくはHandling signalsを参照してください。
      -- Instance Variable of <unhandled-signal-error>: signal
          An integer indicating the received signal number. There are constants defined for typical signal numbers; see Signals and signal sets. 受け取ったシグナル番号を示す整数値。典型的なシグナル番号については定数が定義されています。Signals and signal setsを参照のこと。

 -- Class: <read-error>
 -- Condition Type: &read-error
     [SRFI-36] A subclass of <error>. When the reader detects a lexical or syntactic error during reading an S-expression, this type of condition is raised. <error> のサブクラス。リーダがS式を読み込み中に、字句エラーまたは構文エラーを検出したとき、この型のコンディションが投げられます。

      -- Instance Variable of <read-error>: port
          A port from which the reader is reading. (NB: SRFI-36's &read-error doesn't have this slot.  Portable program shouldn't rely on this slot). リーダがS式を読みこんでいたポート。 (註: SRFI-36 の &read-error はこのスロットを定義していません。ポータブルなプログラムを書く場合はこのスロットを使わないで下さい)。

      -- Instance Variable of <read-error>: line
          A line count (1-base) of the input where the reader raised this error. It may be -1 if the reader is reading from a port that doesn't keep track of line count. リーダがこのエラーを発生させたときの入力行カウント(1がベース)。リーダが行カウントを保持しないポートから読み込むときには、-1 となる。

      -- Instance Variable of <read-error>: column
      -- Instance Variable of <read-error>: position
      -- Instance Variable of <read-error>: span
          These slots are defined in SRFI-36's &read-error. For the time being, these slots always hold #f. これらのスロットは、SRFI-36 の &read-error で定義されています。今のところ、これらのスロットは常に #f を保持するようになっています。

 -- Class: <io-error>
 -- Condition Type: &io-error
     [SRFI-36] A base class of I/O errors.  Inherits <error>. I/O エラーのベースとなるクラス。<error> を継承しています。

 -- Class: <port-error>
 -- Condition Type: &io-port-error
     [SRFI-36] An I/O error related to a port.   Inherits <io-error>. ポート関連の I/O エラー。<io-error> を継承しています。

      -- Instance Variable of <port-error>: port
          Holds the port where the error occurred. エラーを起したポートを保持。

 -- Class: <io-read-error>
 -- Condition Type: &io-read-error
     [SRFI-36] An I/O error during reading from a port.  Inherits <port-error>. ポートから読み込み中の I/O エラー。<port-error> を継承しています。

 -- Class: <io-write-error>
 -- Condition Type: &io-write-error
     [SRFI-36] An I/O error during writing to a port.  Inherits <port-error>. ポートへの書き出し中の I/O エラー。<port-error> を継承しています。

 -- Class: <io-closed-error>
 -- Condition Type: &io-closed-error
     [SRFI-36] An I/O error when read/write is attempted on a closed port. Inherits <port-error>. クローズされたポートで読み込み/書き出しをしようしたときの I/O エラー。 <port-error> を継承しています。

 -- Class: <io-unit-error>
     An I/O error when the read/write is requested with a unit that is not supported by the port (e.g. a binary I/O is requested on a character-only port).   Inherits <port-error>. 対象となるポートでサポートされていない単位での読み/書き要求 (たとえば、キャラクタ専用ポートでのバイナリ I/O 要求)の際の I/O エラー。 <port-error> を継承しています。

Condition API
.............

コンディションAPI
..........

 -- Macro: define-condition-type name supertype predicate field-spec ...
     [SRFI-35+] Defines a new condition type.  In Gauche, a condition type is a class, whose metaclass is <condition-meta>. 新しいコンディションタイプを定義します。Gaucheでは、コンディションタイプはクラスであり、そのメタクラスは <condition-meta> です。

     NAME becomes the name of the new type, and also the variable of that name is bound to the created condition type. SUPERTYPE is the name of the supertype (direct superclass) of this condition type.  A condition type must inherit from <condition> or its descendants. (Multiple inheritance can't be specified by this form, and generally should be avoided in condition type hierarchy.  Instead, you can use compound conditions, which don't introduce multiple inheritance.) NAME が新しいタイプの名前になり、この名前の変数が作成されたコンディションタイプに束縛されます。SUPERTYPE はこのコンディションタイプのスーパータイプ(直接のスーパークラス)の名前です。コンディションタイプは <condition> を継承するか、その子孫を継承しなければなりません。(この形式では、多重継承を指定することはできません。一般的にいって、コンディションタイプの階層の中では多重継承は避けるべきです。そのかわりに、合成コンディションを使えます。合成コンディションは多重継承を使いません。)

     A variable PREDICATE is bound to a predicate procedure for this condition type. 変数 PREDICATE はこのコンディションタイプ用の述語手続きに束縛されます。

     Each field-spec is a form of (field-name accessor-name), and the condition will have fields named by FIELD-NAME, and a variable ACCESSOR-NAME will be bound to a procedure that accesses the field.   In Gauche, each field becomes a slot of the created class.

     Gauche extends srfi-35 to allow PREDICATE and/or accessor-name to be #f, or accessor-name to be omitted, if you don't need to them to be defined. 各 field-spec は (field-name accessor-name) の形式でこのコンディションは、フィールド名は FIELD-NAME で決まります。変数 ACCESSOR-NAME はそのフィールドにアクセスする手続きに束縛されます。Gauche では、それぞれのフィールドは生成されたクラスのスロットとなります。

     Gaucheはsrfi-35を拡張して、PREDICATEやACCESSOR-NAMEを定義する必要が無い場合はその位置に#fを指定できるようにしています。 ACCESSOR-NAMEが必要無い場合はそれを省略することもできます。

     When define-condition-type is expanded into a class definition, each slot gets a :init-keyword slot option with the keyword whose name is the same as the slot name. define-condition-typeがクラス定義に展開される際に、各スロットは:init-keywordスロットオプションにスロット名と同名のキーワードを取るように定義されます。

 -- Function: condition-type? obj
     [SRFI-35] Returns #t iff OBJ is a condition type.  In Gauche, it means (is-a? obj <condition-meta>). OBJがコンディションタイプである場合で、その場合にかぎり、 #t を返します。Gauche では (is-a? obj <condition-meta>) と同じです。

 -- Function: make-condition-type name parent field-names
     [SRFI-35] A procedural version to create a new condition type. 新しいコンディションタイプを生成する手続き版です。

 -- Function: make-condition type field-name value ...
     [SRFI-35] Creates a new condition of condition-type TYPE, and initializes its fields as specified by field-name and value pairs. コンディションタイプ TYPE のコンディションを生成し、 field-name および value のペアで指定されたようにフィールドを初期化します。

 -- Function: condition? obj
     [SRFI-35] Returns #t iff OBJ is a condition.  In Gauche, it means (is-a? obj <condition>). OBJ がコンディションである場合で、その場合にかぎり、 #t を返します。Gauche では (is-a? obj <condition>) と同じです。

 -- Function: condition-has-type? obj type
     [SRFI-35] Returns #t iff OBJ belongs to a condition type TYPE. Because of compound conditions, this is not equivalent to is-a?. OBJ がコンディションタイプ TYPE に属している場合で、その場合にかぎり、#t を返します。合成コンディションがあるので、これは、is-a? と同じではありません

 -- Function: condition-ref condition field-name
     [SRFI-35] Retrieves the value of field FIELD-NAME of CONDITION. If CONDITION is a compound condition, you can access to the field of its original conditions; if more than one original condition have FIELD-NAME, the first one passed to make-compound-condition has precedence. CONDITION のフィールド FIELD-NAME の値を検索します。 CONDITION が合成コンディションであれば、元のコンディションのフィールドにアクセスできます。もし、複数の元のコンディションが、 FIELD-NAME を持つ場合には、最初に make-compound-condition に渡されたものが優先されます。

     You can use slot-ref and/or ref to access to the field of conditions; compound conditions define a slot-missing method so that slot-ref behaves as if the compound conditions have all the slots of the original conditions.  Using condition-ref increases portability, though. コンディションのフィールドにアクセスするには、slot-ref および ref の両方あるいはどちらかを使えます。合成コンディションでは、 slot-missing メソッドが定義されますので、slot-ref はあたかも、合成コンディションが元になったコンディションの全てのスロットをもつかのように振舞います。しかしながら、condition-ref を使う方が可搬性が増します。

 -- Function: condition-message condition :optional fallback
     This is a convenience procedure to retrieve a message if CONDITION has a type <message-condition>, and returns FALLBACK otherwise.  If FALLBACK is omitted, #f is assumed.

     Often, in a generic routine you want to intercept a raised condition and retrieve a message for logging or user feedback. Since any object can be raised in Scheme, an exception may not contain the message slot, and you need to check the type of the condition.  We've written such code enough so that we add this procedure. CONDITIONが<message-condition>を持っていればそのmessageスロットを、そうでなければFALLBACKを返す手続きです。 FALLBACKが省略された場合は#fが指定されたとみなします。

     投げられたコンディションを一度捕まえてメッセージを記録したりユーザに見せたりする一般的なコードはよくあります。Schemeでは任意のオブジェクトをraiseできるため、捕まえたコンディションがメッセージスロットを持っているとは限りません。従ってそういったコードはいちいちコンディションの型を検査して分岐することになります。そのパターンは充分によくあるので、この手続きが追加されました。

 -- Function: make-compound-condition condition0 condition1 ...
     [SRFI-35] Returns a compound condition that has all CONDITION0 CONDITION1 ....  The returned condition's fields are the union of all the fields of given conditions; if any conditions have the same name of fields, the first one takes precedence.   The returned condition also has condition-type of all the types of given conditions. (This is not a multiple inheritance.  See <compound-condition> above.) CONDITION0 CONDITION1 ... のすべてを持つ合成コンディションを返します。返されたコンディションのフィールドは、与えられたコンディションのすべてのフィールドの和集合になります。同じ名前のフィールドを持つコンディションがある場合には最初に与えられものが優先されます。返されたコンディションは元になったコンディションのすべてのタイプのコンディションタイプをもつことになります。 (これは多重継承ではありません。上の <compound-condition> を参照)

 -- Function: extract-condition condition condition-type
     [SRFI-35] CONDITION must be a condition and have type CONDITION-TYPE. This procedure returns a condition of CONDITION-TYPE, with field values extracted from CONDITION. CONDITION はコンディションで、CONDITION-TYPEタイプでなければなりません。この手続きは CONDITION-TYPE のコンディションを返し、CONDITION からとりだされた値のフィールドを持ちます。

 -- Macro: condition type-field-binding ...
     [SRFI-35] A convenience macro to create a (possibly compound) condition. TYPE-FIELD-BINDING is a form of (CONDITION-TYPE (FIELD-NAME VALUE-EXPR) ...). コンディションを生成するのに便利なマクロ。合成されたコンディションも生成できます。 TYPE-FIELD-BINDING は、 (CONDITION-TYPE (FIELD-NAME VALUE-EXPR) ...) という形式になります。

          (condition
            (type0 (field00 value00) ...)
            (type1 (field10 value10) ...)
            ...)
           ==
          (make-compound-condition
            (make-condition type0 'field00 value00 ...)
            (make-condition type1 'field10 value10 ...)
            ...)

Eval and repl
=============

 -- Function: eval expr env
     [R7RS eval] Evaluate EXPR under the environment ENV. In Gauche, ENV is just a <module> object. EXPRを環境ENV内で評価します。 Gaucheにおいて、ENVは単なる<module>オブジェクトです。

R5RS and R7RS provide a portable way to obtain environment. R5RS way is described below.  R7RS way is described in R7RS eval. R5RSとR7RSは、環境ENVを得るポータブルな方法を定義しています。 R5RSの方法を以下に示します。R7RSの方法はR7RS evalを参照してください。

 -- Function: null-environment version
 -- Function: scheme-report-environment version
 -- Function: interaction-environment
     [R5RS] Returns an environment specifier which can be used as the second argument of eval.   Right now an environment specifier is just a module.  (null-environment 5) returns a null module, which contains just the syntactic bindings specified in R5RS, (scheme-report-environment 5) returns a scheme module, which contains syntactic and procedure bindings in R5RS, and (interaction-environment) returns a user module that contains all the Gauche built-ins plus whatever the user defined. It is possible that the Gauche adopts a first-class environment object in future, so do not rely on the fact that the environment specifier is just a module. evalの第2引数として使われる環境識別子を返します。現時点では、環境識別子は単にモジュールです。 (null-environment 5)は、R5RSで規定されている単なる構文的な束縛を含むnullモジュールを返します。 (scheme-report-environment 5)は、R5RSで規定されている構文的な束縛と手続きの束縛を含むschemeモジュールを返します。 (interaction-environment)は、全てのGaucheのビルトインとユーザ定義の全てを含んだuserモジュールを返します。将来、Gaucheがファーストクラスの環境オブジェクトを採用する可能性があるので、環境識別子が単なるモジュールであることを当てにしないで下さい。

     An error is signaled if a value other than 5 is passed as VERSION argument. 引数VERSIONに5以外の値を渡すとエラーが通知されます。

 -- Function: read-eval-print-loop :optional reader evaluator printer prompter
     This exports Gosh's default read-eval-print loop to applications. Each argument can be #f, which indicates it to use Gauche's default procedure(s), or a procedure that satisfies the following conditions. goshのデフォルトのread-eval-printループをアプリケーションにエクスポートします。それぞれの引数は、Gaucheのデフォルトの手続きを使うことを示す#fであっても良いですし、以下の条件を満たす手続きであっても構いません。

     reader
          A procedure that takes no arguments.  It is supposed to read an expression and returns it. 引数を取らない手続きです。式を読み込んでそれを返すことを期待されます。

     evaluator
          A procedure that takes two arguments, an expression and an environment specifier.  It is supposed to evaluate the expression and returns zero or more value(s). 式と環境識別子を2引数として取る手続きです。式を評価して、0個以上の値を返すことを期待されます。

     printer
          A procedure that takes zero or more arguments.   It is supposed to
          print out these values.   The result of this procedure is discarded.
          0個以上の引数を取る手続きです。それらの値を出力することを期待されます。
          この手続きの戻り値は無視されます。

     prompter
          A procedure that takes no arguments.  It is supposed to print out the prompt.   The result of this procedure is discarded. 引数を取らない手続きです。プロンプトを出力することを期待されます。この手続きの戻り値は無視されます。

     Given those procedures, read-eval-print-loop runs as follows: これらの手続きが与えられると、read-eval-print-loopは以下のように動作します。

      1. Prints the prompt by calling PROMPTER. PROMPTERを呼んでプロンプトを出力します。

      2. Reads an expression by calling READER.  If it returns EOF, exits the loop and returns from read-eval-print-loop. READERを呼んで式を読み込みます。EOFが返されたら、ループを終了し read-eval-print-loopから戻ります。

      3. Evaluates an expression by calling EVALUATOR EVALUATORを呼んで式を評価します。

      4. Prints the result by calling PRINTER, then repeats from 1. PRINTERを呼んで結果を出力し、その後、1から繰り返します。

     When an error is signaled from one of those procedures, it is captured and reported by the default escape handler, then the loop restarts from 1. これらの手続きのうちの1つからエラーが通知されると、そのエラーはデフォルトのエスケープハンドラにより捕捉・報告され、その後、ループが1から再開します。

     It is OK to capture a continuation within those procedures and re-invoke them afterwards. これらの手続きの内部で継続を捕捉し、後で再起動することは許されています。

Input and Output
================

Ports
-----

 -- Builtin Class: <port>
     A port class.   A port is Scheme's way of abstraction of I/O channel. Gauche extends a port in number of ways so that it can be used in wide range of applications. Portは、Schemeにおいて抽象化された入出力のインタフェースを提供します。 Gaucheはportにいくつかの拡張を行い、いろいろなアプリケーションに対応できるようにしました。

     Textual and binary I/O
          R7RS defines textual and binary ports.  In Gauche, most ports can mix both text I/O and binary I/O.  It is cleaner to think the two is distinct, for they are sources/sinks of different types of objects and you don't need to mix textual and binary I/O.

          In practice, however, a port is often a tap to an untyped pool of bytes and you may want to decide interpret it later.  One example is the standard I/O; in Unix-like environment, it's up to the program to use pre-opened ports for textual or binary I/O.  R7RS defines the initial ports for current-input-port etc. are textual ports; in Gauche, you can use either way.

     テキストとバイナリI/O
          R7RSはテキストポートとバイナリポートを定義しています。 Gaucheでは、ほとんどのポートはテキストI/OとバイナリI/Oを混ぜて使えます。概念的には、異なる型のオブジェクトのソース/シンクは別物と考える方が綺麗ですし、ひとつのポートでテキストI/OとバイナリI/Oを混在して使うことは滅多にありません。

          しかし現実には、ポートを型の無いデータの集まりにつながったものとして、データをどう解釈するかは後から決めたい、という場合があります。例えば標準入出力です。Unix的な環境では、あらかじめオープンされている標準入出力に対してテキストI/Oを行うかバイナリI/Oを行うかはプログラムに任されています。 R7RSでは、current-input-port等の初期値はテキストポートであると規定しています。Gaucheではどちらにも使うことができます。

     Conversion
          Some ports can be used to convert a data stream from one format to another; one of such applications is character code conversion ports, provided by gauche.charconv module (see Character code conversion, for details).

     変換
          ポートはまた、データストリームを変換するのにも使えます。例えばgauche.charconv モジュールでは、文字コード間の変換を行うポートを提供しています (詳しくはCharacter code conversionを参照)。

     Extra features
          There are also a ports with special functionality. A coding-aware port (see Coding-aware ports) recognizes a special "magic comment" in the file to know which character encoding the file is written. Virtual ports (see Virtual ports) allows you to program the behavior of the port in Scheme.

     追加機能
          また、特殊な機能を実現するポートもあります。コーディング認識ポート(Coding-aware ports参照)はファイル中の特殊なコメントを認識して、そのファイルがどの文字エンコーディングで書かれているかを検出します。仮想ポート(Virtual ports参照)はSchemeでふるまいをプログラムできるポートを提供します。

Port and threads
----------------

When Gauche is compiled with thread support, the builtin port operations locks the port, so that port access from multiple threads will be serialized. (It is required by SRFI-18, BTW). Here, "builtin port operations" are the port access functions that takes a port and does some I/O or query on it, such as read/write, read-char/write-char, port->string, etc. Note that call-with-* and with-* procedures do not lock the port during calling the given procedures, since the procedure may pass the reference of the port to the other thread, and Gauche wouldn't know if that's the case. GaucheがスレッドサポートをONにしてコンパイルされている場合、組み込みのポート操作関数はポートをロックして、複数のスレッドからの同一のポートへのアクセスがポートの内部状態を壊さないようにしています。 (SRFI-18によって要求されている動作です)。ここで「組み込みのポート操作関数」はGaucheにより提供される、ポートを引数に取り何らかのI/O動作や問い合わせを行う手続きで、 read/write、read-char/write-char、 port->string等を含みます。但し、call-with-*やwith-*系関数は、与えられた手続きを呼ぶ際にはポートをロックしません。その手続きが別のスレッドにポートを渡すかもしれず、Gaucheにはそれを知ることができないからです。

This means you don't need to be too paranoia to worry about ports under multithreaded environment.  However, keep it in mind that this locking mechanism is meant to be a safety net from breaking the port's internal state, and not to be a general mutex mechanism.  It assumes port accesses rarely conflict, and uses spin lock to reduce the overhead of majority cases.  If you know there will be more than one thread accessing the same port, you should use explicit mutex to avoid conflicts. 従って、マルチスレッド環境でポートへのアクセス競合によりポートの内部状態を壊してしまうんじゃないか、などとあまり神経質になる必要はありません。但し、このロック機構はあくまで予想外のアクセス競合によってポートがおかしな状態になってしまうことを防ぐための安全ネットであって、一般的な排他制御機構として使われることは想定していないのに注意して下さい。このロックの実装は、ポートへのアクセス競合は例外的な場合のみであると仮定し、通常のアクセスにおけるオーバヘッドを避けるために、スピンロックを使用します。もし、意図的にポートアクセスが競合するようなコードを書く場合は、明示的に排他制御をしてください。

 -- Function: with-port-locking port thunk
     Executes THUNK, while making the calling thread hold the exclusive lock of PORT during the dynamic extent of THUNK.

     Calls of the builtin port functions during the lock is held would bypass mutex operations and yield better performance.

     Note that the lock is held during the dynamic extent of THUNK; so, if THUNK invokes a continuation captured outside of with-port-locking, the lock is released.  If the continuation captured within THUNK is invoked afterwards, the lock is re-acquired.

     With-port-locking may be nested.  The lock is valid during the outermost call of with-port-locking.

     Note that this procedure uses the port's built-in lock mechanism which uses busy wait when port access conflicts.  It should be used only for avoiding fine-grain lock overhead; use explicit mutex if you know there will be conflicts. PORTをロックし、THUNKを実行します。ロックはTHUNKのダイナミックエクステントの期間有効です。

     PORTがロックされている期間での組み込みのポートアクセス関数の呼び出しは排他制御をバイパスするため、性能向上が見込まれます。

     ロックの有効期間はTHUNKのダイナミックエクステントなので、 THUNK内からwith-port-lockingの外で捕捉された継続を呼んだ場合、ロックは解放されます。その後、THUNK内で捕捉された継続が呼ばれた場合、再びロックが獲得されます。

     with-port-lockingはネスト可能です。ロックは最も外側の with-port-lockingの期間中有効となります。

     この手続きはポート組込みのロック機構を利用します。つまり、ポートアクセスが競合した場合はbusy waitになるということです。この手続きはあくまで頻繁なロックによるオーバヘッドを回避するためのものです。もし本当に競合が予測される場合は明示的に排他制御を行ってください。

Common port operations
----------------------

 -- Function: port? obj
 -- Function: input-port? obj
 -- Function: output-port? obj
     [R7RS base] Returns true if OBJ is a port, an input port and an output port, respectively.  Port? is not listed in the R5RS standard procedures, but mentioned in the "Disjointness of Types" section. OBJ がそれぞれポート、入力ポート、出力ポートなら真を返します。 port?はR5RSの"Standard Procedures"の項には載っていませんが、"Disjointness of Types"の項に挙げられています。

 -- Function: port-closed? port
     Returns true if OBJ is a port and it is already closed. A closed port can't be reopened. OBJがポートであり、既に閉じられていた場合に真を返します。一度閉じたポートは再び開くことはできません。

 -- Parameter: current-input-port
 -- Parameter: current-output-port
 -- Parameter: current-error-port
     [R7RS base] Returns the current input, output and error output port, respectively.

     R7RS defines that the initial values of these ports are textual ports. In Gauche, initial ports can handle both textual and binary I/O. 現在の入力ポート、出力ポート、エラー出力ポートをそれぞれ返します。

     R7RSではこれらのポートの初期値はテキストポートであると規定されています。 Gaucheでは、これらのポートの初期値はテキスト入出力もバイナリ入出力も扱えます。

     Values of the current ports can be temporarily changed by parameterize (see Parameters), though you might want the convenience procedures such as with-output-to-string or with-input-from-file in typical cases. 現在のポートの値はparameterizeを使って一時的に変更できます (Parameters参照)。もっとも、典型的な場合にはより簡単なwith-output-to-stringやwith-input-from-fileなどの手続きが使えるでしょう。

          (use gauche.parameter)
          (let1 os (open-output-string)
            (parameterize ((current-output-port os))
              (display "foo"))
            (get-output-string os))
           => "foo"

 -- Parameter: current-trace-port
     A paremeter that holds an output port which debug trace goes to. The initial value is the same as the initial value of current-error-port. デバッグトレース出力に使われる出力ポートを保持するパラメータです。初期値はcurrent-error-portの初期値と同じです。

     The debug-print feature (see Debugging aid) and the macro trace feature (see Tracing macro expansion) uses this port. debug-print機能(Debugging aid参照)と、マクロトレース機能(Tracing macro expansion参照)がこのポートを使っています。

 -- Parameter: standard-input-port
 -- Parameter: standard-output-port
 -- Parameter: standard-error-port
     Returns standard i/o ports at the time the program started. These ports are the default values of current-input-port, current-output-port and current-error-port, respectively.

     You can also change value of these procedures by parameterize, but note that (1) current-*-ports are initialized before the program execution, so changing values of standard-*-port won't affect them, and (2) changing values these procedures only affect Scheme-world, and does not change system-level stdio file descriptors low-level libraries referring. プログラム開始時点の標準入出力ポートを返します。これらの値が current-input-port、current-output-port、 current-error-portのデフォルトとなります。

     これらの手続きの値もparameterizeで変えることができますが、 (1) current-*-portはプログラム実行前に初期化されるので、プログラム中でstandard-*-portを変更しても影響は及ばない、 (2) これらの手続きの値の変更はScheme世界だけのことで、低レベルライブラリが参照しているシステムのstdioファイルディスクリプタは変更されない、という点に注意してください。

 -- Function: with-input-from-port port thunk
 -- Function: with-output-to-port port thunk
 -- Function: with-error-to-port port thunk
     Calls THUNK.  During evaluation of thunk, the current input port, current output port and current error port are set to PORT, respectively. Note that PORT won't be closed after thunk is executed. それぞれ入力、出力、エラーポートをPORTにセットした状態でTHUNKを呼び出します。 portはTHUNK実行後にも閉じられないことに注意してください。

 -- Function: with-ports iport oport eport thunk
     Does the above three functions at once. Calls THUNK while the current input, output, and error ports are set to IPORT, OPORT, and EPORT, respectively. You may pass #f to any port argument(s) if you don't need to alter the port(s).

     Note that PORT won't be closed after thunk is executed. (Unfortunately, recent Scheme standards added a similar named procedure, call-with-port, which does close the port.  See below.) 上の3つの動作を同時に行う手続きです。入力、出力、エラーの各ポートをそれぞれIPORT, OPORT, EPORTにセットしてTHUNKを呼び出します。変更する必要がないポートの引数には #fを渡すことができます。

     portはTHUNK実行後にも閉じられないことに注意してください (最近のScheme標準は良く似た名前の手続きcall-with-portを追加しましたが、生憎そちらはポートを閉じる仕様になっています。call-with-portについては下で説明します。)

 -- Function: close-port port
 -- Function: close-input-port port
 -- Function: close-output-port port
     [R7RS base] Closes the port.  Close-port works both input and output ports, while close-input-port and close-output-port work only for the respective ports and throws an error if another type of port is passed.

     Theoretically, only close-port would suffice; having those three is merely for historical reason. R5RS has close-input-port and close-output-port; R6RS and R7RS support all three. ポートを閉じます。close-portは入力ポートも出力ポートも閉じられますが、 close-input-portとclose-output-portはそれぞれ対応するポートのみに使え、異なる種類のポートが渡されたらエラーを通知します。

     理屈の上では、close-portだけあれば十分です。3つ手続きがあるのは歴史的理由です。 R5RSにはclose-input-port and close-output-portだけがありました。 R6RSとR7RSは3つ全てをサポートしています。

 -- Function: call-with-port port proc
     [R7RS base] Calls PROC with one argument, PORT.  After PROC returns, or it throws an uncaptured error, PORT is closed.  Value(s) returned from PROC will be the return value(s) of call-with-port.

     PROCを、PORTを引数として呼び出します。PROCからリターンするか、エラーが投げられた場合はPORTがクロースざれます。 PROCが返す値がそのままcall-with-portの返り値となります。

 -- Function: port-type port
     Returns the type of PORT in one of the symbols file, string or proc. PORTのタイプを、シンボルfile、string、procのいずれかで返します。

 -- Function: port-name port
     Returns the name of PORT.  If the port is associated to a file, it is the name of the file.   Otherwise, it is some description of the port. PORTの名前を返します。ポートがファイルに関連付けられている場合は、ポートの名前はファイル名です。そうでない場合、ポートを説明する文字列が返されます。

 -- Function: port-buffering port
 -- Function: (setter port-buffering) port buffering-mode
     If PORT is type of file port (i.e. (port-type PORT) returns file), these procedures gets and sets the port's buffering mode.  For input ports, the port buffering mode may be either one of :full, :modest or :none. For output ports, port-buffering, it may be one of :full, :line or :none. See File ports, for explanation of those modes.

     If port-buffering is applied to ports other than file ports, it returns #f.  If the setter of port-buffering is applied to ports other than file ports, it signals an error. ファイルポート((port-type PORT)がfileを返すもの) に対して、そのバッファリングモードを読みだし、もしくは変更します。入力ポートではバッファリングモードは :full、 :modest、:noneのいずれかです。出力ポートでは :full、 :line、:noneのいずれかです。バッファリングモードの詳細な説明は、File ports を参照してください。

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

 -- Function: port-current-line port
     Returns the current line count of PORT.  This information is only available on file-based port, and as long as you're doing sequential character I/O on it.  Otherwise, this returns -1. PORTの現在の行番号を返します。行番号は、ファイルに関連付けられたポートでかつシーケンシャルなキャラクタI/Oを行っている場合のみ有効です。それ以外の場合は -1を返します。

 -- Function: port-file-number port :optional dup?
     Returns an integer file descriptor, if the PORT is associated to the system file I/O.  Returns #f otherwise.

     If a true value is passed to DUP?, the procedure calls dup(2) and returns a duplicated file descriptor.  In such case, the returned file descriptor can be closed independently with the port, and it is caller's responsibility to close it (by sys-close) once it's done. PORTがファイルに関連付けられている場合、そのファイルディスクリプタ番号を返します。それ以外の場合は#fを返します。

     DUP?引数に真の値が与えられると、この手続きはdup(2)を呼んで複製したファイルディスクリプタを返します。この場合、返されたファイルディスクリプタは呼び出し側が責任を持って閉じなければなりません (sys-closeが使えます)。

 -- Function: port-position port
     [SRFI-192] Returns the current position of PORT.  For the input port, the current position is where the next data will be read from, and for the output port, it is where the next data will be written to. (Note that peek-char/peek-byte won't move the current position).

     If PORT is a simple file port or a string port, the position is represented as an integer byte offset from the top of the stream. If it is more complicated ports, such as the one doing the character encoding conversion, the port position may not be available, or returned object may not correspond to the byte offset. If PORT is a procedural (virtual) port (see Virtual ports), the returned value can be an arbitrary Scheme object, it can only be valid to be used for set-port-position!.

     An error is thrown if PORT doesn't support port positions. You can use port-has-port-position? to check if the port supports port positions.

     For portable code: srfi-192 defines the following conditions.

       * Return value is an arbitrary Scheme object and you should treat it as an opaque object.  In general, it is only safe to pass it to the set-port-position! on the same port.

       * If the port is a binary port and the returned position is a nonnegative exact integer, it represents the byte offset of the position.

     PORTの現在の位置を返します。現在の位置とは、入力ポートでは次の読み込みでデータが読まれる位置、出力ポートでは次の書き込みでデータが書かれる位置です。 (peek-char/peek-byteでは現在の位置は動きません)。

     PORTが単純なファイルポートや文字列ポートなら、ポートの位置はストリームの先頭からのバイトオフセットを表す正確な整数です。より複雑なポート、例えば文字エンコーディング変換ポートでは、ポート位置を取ることはできないか、取れた場合でもその値はバイトオフセットに対応するとは限りません。仮想ポート(Virtual ports参照)では、現在位置は任意のSchemeオブジェクトで、 set-port-position!に渡す以外に使うことはできません。

     PORTがポート位置をサポートしていなければエラーが投げられます。ポート位置をサポートしているかどうかはport-has-port-position?で調べられます。

     ポータブルなコードを書くときは、以下のsrfi-192の条件に気をつけてください。

       * ポート位置は任意のSchemeオブジェクトであり、同じポートに対してset-port-position!するのにだけ使うことができます。

       * ただし、ポートがバイナリポートで、位置が正確な非負整数の場合は、それはバイトオフセットを表しています。

 -- Function: port-has-port-position? port
     [SRFI-192] Returns #t iff the port supports port-position procedure. ポートがport-position手続きをサポートしていれば#tを、そうでなければ#fを返します。

 -- Function: set-port-position! port pos
     [SRFI-192] Sets the current position of PORT to POS.  For the input port, the current position is where the next data will be read from, and for the output port, it is where the next data will be written to.

     Interpretation of POS is up to the PORT, and generally it  must be an object returned previously by port-position on the same port.  If PORT is a simple file port (a port opened on file, without CES conversion) or an input string port, you may pass a nonnegative exact integer as the byte offset.

     An error is signaled if the position is not settable, or POS is not acceptable as a position for PORT.  You can check if position of PORT is settable by port-has-set-port-position!?. POSをPORTの現在の位置としてセットします。現在の位置とは、入力ポートでは次の読み込みでデータが読まれる位置、出力ポートでは次の書き込みでデータが書かれる位置です。

     POSの解釈はPORTに依存します。一般的には、 PORTに対するport-positionで以前返されたオブジェクトしか渡せません。ただし、PORTが単純なファイルポート(ファイルに対してオープンされ、文字コード変換などを行っていないポート)や入力文字列ポートならば、非負の正確な整数をバイトオフセットとして渡すことができます。

     ポートが位置のセットを許さない場合や、POSが位置として不正な場合はエラーが投げられます。PORTに位置がセットできるかどうかは port-has-set-port-position!?で検査できます。

 -- Function: port-has-set-port-position!? port
     [SRFI-192] Returns #t iff the port supports set-port-position! procedure. ポートがset-port-position!手続きをサポートしていれば#tを、そうでなければ#fを返します。

 -- Function: port-seek port offset :optional whence
     (This procedure is deprecated.  Use port-position and set-port-position! for the new code. (この手続きは非推奨です。新しいコードにはport-positionおよび set-port-position!を使ってください)。

     If the given PORT allows random access, this procedure sets the read/write pointer of the PORT according to the given OFFSET and WHENCE, then returns the updated offset (number of bytes from the beginning of the data).  If PORT is not random-accessible, #f is returned.  In the current version, file ports and input string ports are fully random-accessible.  You can only query the current byte offset of output string ports. PORTがランダムアクセス可能なポートの場合、この手続きはPORTのread/writeポインタをOFFSETとWHENCEの値によって設定し、新たなread/writeポインタの値(データの先頭からのバイトオフセット)を返します。PORTがランダムアクセス可能でない場合は#fが返されます。現在のバージョンでは、ファイルポートおよび入力文字列ポートがランダムアクセス可能です。出力文字列ポートは現在のポインタの値を問い合わせる動作だけが可能です。

     Note that port position is represented by byte count, not character count. ポートのポインタはバイト数で表現され、文字数とは異なることに注意して下さい。

     It is allowed to seek after the data if PORT is an output file port.  See POSIX lseek(2) document for details of the behavior. For input file port and input string port, you can't seek after the data. PORTが出力ファイルポートの場合は、データの終端を超えた位置までseek することが可能です。その場合の動作はPOSIXのlseek(2)に準じます。入力ファイルポートや入力文字列ポートではデータの終端以降にseekすることはできません。

     The WHENCE argument must be a small integer that represents from where OFFSET should be counted.   The following constant values are defined. WHENCE引数は、OFFSETの基準を指定する小さな整数です。以下の定数が定義されています。

     SEEK_SET
          OFFSET represents the byte count from the beginning of the data. This is the default behavior when WHENCE is omitted. OFFSETはデータ先頭からのバイト数を指定します。 WHENCEが省略された場合のデフォルトの動作です。

     SEEK_CUR
          OFFSET represents the byte count relative to the current read/write pointer.  If you pass 0 to OFFSET, you can get the current port position without changing it. OFFSETは現在のread/writeポインタからの相対バイト数を指定します。 OFFSETが0であれば、ポインタを動かさずに現在のポート位置を知ることができます。

     SEEK_END
          OFFSET represents the byte count relative to the end of the data. OFFSETはデータの終端からの相対バイト数を指定します。

 -- Function: port-tell port
     Returns the current read/write pointer of PORT in byte count, if PORT is random-accessible.   Returns #f otherwise. This is equivalent to the following call: PORTの現在のread/writeポインタの値をバイト数で返します。 PORTがランダムアクセス可能でない場合は#fが返されます。これは以下の呼び出しと等価です。

          (port-seek PORT 0 SEEK_CUR)

Note on the names:  Port-seek is called seek, file-position or input-port-position/ output-port-position on some implementations. Port-tell is called tell, ftell or set-file-position!.   Some implementations have port-position for different functionality. CommonLisp has file-position, but it is not suitable for us since PORT need not be a file port.  Seek and tell reflects POSIX name, and with Gauche naming convention we could use sys-seek and sys-tell; however, PORT deals with higher level of abstraction than system calls, so I dropped those names, and adopted new names. 名前に関するメモ: port-seekは他の処理系で seek、file-position、input-port-position/ output-port-position等と呼ばれています。 port-tellはtell、ftell、set-file-position!等と呼ばれています。いくつかの処理系はport-positionという手続きを持っていますが、port-seekとは別の機能を実現しています。 file-positionはCommonLisp由来の名前ですが、 fileポート以外のものも扱うため採用しませんでした。また、seekとtellはPOSIXの名前由来であり、 Gaucheの名前付け規則を使ってsys-seekとsys-tellとしてもよさそうですが、portの操作はシステムコールレベルよりも抽象度が高いためこれも採用しませんでした。結局、新しい名前を採用することにしました。

 -- Function: copy-port src dst :key (unit 0) (size #f)
     Copies data from an input port SRC to an output port DST, until eof is read from SRC. SRCからEOFまでデータを読みだし、DSTへ書き出します。

     The keyword argument UNIT may be zero, a positive exact integer, a symbol byte or a symbol char, to specify the unit of copying.  If it is an integer, a buffer of the size (in case of zero, a system default size) is used to copy, using block I/O.  Generally it is the fastest if you copy between normal files.   If UNIT is a symbol byte, the copying is done byte by byte, using C-version of read-byte and write-byte.  If UNIT is a symbol char, the copying is done character by character, using C-version of read-char and write-char. キーワード引数UNITは0以上の整数か、シンボルbyteもしくはchar でなければなりません。これはデータをコピーする単位を指定します。整数ならば、その大きさ(0の場合はシステム規定の大きさ)のバッファが確保され、ブロックI/Oを使って転送が行われます。通常のファイルをコピーする場合などはこれが速いでしょう。もしUNITがシンボルbyteであれば、バイト毎に読みだし／書き込みが行われます。UNITがシンボルcharであれば、キャラクタ毎に読みだし／書き込みが行われます。

     If nonnegative integer is given to the keyword argument SIZE, it specifies the maximum amount of data to be copied.  If UNIT is a symbol char, SIZE specifies the number of characters. Otherwise, SIZE specifies the number of bytes. キーワード引数SIZEに非負の整数が与えられた場合、それはコピーされるデータの最大量を指定します。UNITがシンボルcharの場合はSIZEはコピーされる文字数を、そうでない場合はバイト数を指定します。

     Returns number of characters copied when UNIT is a symbol char.  Otherwise, returns number of bytes copied. UNITがシンボルcharの場合はコピーされた文字数を返し、そうでない場合はコピーされたバイト数を返します。

File ports
----------

 -- Function: open-input-file filename :key if-does-not-exist buffering element-type encoding conversion-buffer-size conversion-illegal-output
 -- Function: open-output-file filename :key if-does-not-exist if-exists buffering element-type encoding conversion-buffer-size conversion-illegal-output
     [R7RS+] Opens a file FILENAME for input or output, and returns an input or output port associated with it, respectively.

     The keyword arguments specify precise behavior. ファイルFILENAMEを入力または出力用にオープンし、入力ポートまたは出力ポートを作成して返します。

     キーワード引数により、動作を細かく指定できます。

     :if-exists
          This keyword argument can be specified only for open-output-file, and specifies the action when the FILENAME already exists. One of the following value can be given. このキーワード引数はopen-output-fileのみに指定でき、 FILENAMEが既に存在した場合の動作を指定します。次の値のいずれかを与えることができます。

          :supersede
               The existing file is truncated.  This is the default behavior. 既存のファイルが長さ0に縮められます。これが既定の動作です。

          :append
               The output data will be appended to the existing file. 既存のファイルにこれから書き出す内容が追加されます。

          :overwrite
               The output data will overwrite the existing content. If the output data is shorter than the existing file, the rest of existing file remains. 既存のファイルにこれから書き出す内容が上書きされます。書き出されるデータが既存のファイルのデータよりも短い場合、残りの部分はそのまま残されます。

          :error
               An error is signaled. エラーが報告されます。

          #f
               No action is taken, and the function returns #f. 何もせず、#fを返します。

     :if-does-not-exist
          This keyword argument specifies the action when FILENAME does not exist. このキーワード引数はFILENAMEが存在しない場合の動作を指定します。

          :error
               An error is signaled.  This is the default behavior of open-input-file. エラーを報告します。これがopen-input-fileの既定の動作です。

          :create
               A file is created.  This is the default behavior of open-output-file. The check of file existence and creation is done atomically; you can exclusively create the file by specifying :error or #f to IF-EXISTS, along this option. You can't specify this value for open-input-file. ファイルが作成されます。これがopen-output-fileの既定の動作です。ファイルの存在のチェックと作成はアトミックに行われます。このオプションに加え、IF-EXISTSオプションに:errorか#fを指定することで、排他的にファイルを作成することができます。 open-input-fileに対してはこの値を指定することはできません。

          #f
               No action is taken, and the function returns #f. 何もせず、#fを返します。

     :buffering
          This argument specifies the buffering mode.  The following values are allowed. The port's buffering mode can be get/set by port-buffering. (see Common port operations). この引数はバッファリングモードを指定します。以下の値が設定できます。ポートのバッファリングモードは手続きport-buffering (Common port operations参照)によって読みだし/変更可能です。

          :full
               Buffer the data as much as possible.  This is the default mode. 出来る限りデータをバッファリングします。これがデフォルトのモードです。

          :none
               No buffering is done.  Every time the data is written (to an output port) or read (from an input port), the underlying system call is used. Process's standard error port is opened in this mode by default. バッファリングを行いません。出力ポートにデータが書き出されるか、入力ポートからデータが読み込まれる度に、下位にあるシステムコールが呼ばれます。プロセスの標準エラーポートはこのモードでオープンされています。

          :line
               This is valid only for output ports.  The written data is buffered, but the buffer is flushed whenever a newline character is written. This is suitable for interactive output port.  Process's standard output port is opened in this mode by default. (Note that this differs from the line buffering mode of C stdio, which flushes the buffer as well when input is requested from the same file descriptor.) このモードは出力ポートにのみ有効です。書き出されたデータはバッファに貯められますが、改行文字が書かれたらフラッシュされます。このモードは対話的な出力ポートなどに便利です。プロセスの標準出力ポートはこのモードでオープンされています。 (これは、Cのstdioライブラリの「ラインバッファリング」とちょっと違うことに注意してください。stdioでは同じファイルディスクリプタから入力が行われる時もバッファはフラッシュされますが、Gaucheではそうはなりません)。

          :modest
               This is valid only for input ports.  This is almost the same as the mode :full, except that read-uvector may return less data than requested if the requested amount of data is not immediately available. (In the :full mode, read-uvector waits the entire data to be read).   This is suitable for the port connected to a pipe or network. このモードは入力ポートにのみ有効です。ほとんど:fullバッファリングモードと同じですが、read-uvectorはポートに要求されたデータより少ないデータしか無かった場合、要求された量がたまるまで待つのではなく、今あるデータだけを返します(:fullの場合はread-uvectorはすべてのデータが到着するまで待ちます)。このモードはポートがパイプやネットワークに接続されている場合に便利です。

     :element-type
          This argument specifies the type of the file. この引数はファイルのタイプを指定します。

          :binary
               The file is opened in "binary" mode. (This is the default) ファイルはバイナリモードでオープンされます。(これがデフォルトです。)

          :character
               The file is opened in "character" (or "text") mode. ファイルはキャラクタモード(テキストモード)でオープンされます。

          Note: This flag makes difference only on Windows-native platforms, and only affect the treatment of line terminators.  In character mode, writing #\newline on the output causes CR + LF characters to be written, instead of just LF.  And reading CR + LF sequence returns just #\newline.

          On Unix, both mode are the same.

          Note that Gauche doesn't distinguish character (textual) port and binary port.  So this flag really matters only on Windows line terminators. 註: このフラグで違いが出るのはWindowsネイティブ版のみです。キャラクタモードでは、#\newline文字をを出力するとCR + LFが書き出され、またCR + LFシーケンスは単一の#\newlineとして読まれます。

          Unixでは両者に違いはありません。

          なお、Gaucheにはテキストポートとバイナリポートの区別はありません。したがってこのフラグはWindowsの行終端文字の扱いのみのためにあります。

     :encoding
          This argument specifies character encoding of the file.   The argument is a string or a symbol that names a character encoding scheme (CES).

          For open-input-file, it can be a wildcard CES (e.g. *jp) to guess the file's encoding heuristically (see Autodetecting the encoding scheme), or #t, in which case we assume the input file itself has magic encoding comment and use open-coding-aware-port (see Coding-aware ports).

          If this argument is given, Gauche automatically loads gauche.charconv module and converts the input/output characters as you read to or write from the port. See Supported character encoding schemes, for the details of character encoding schemes. この引数はファイルの文字エンコーディングを指定します。引数は文字列かシンボルで、文字エンコーディングスキーム(CES)の名前を渡します。

          open-input-fileでは、ここにワイルドカードCES (例: *jp) を渡して、入力ファイルのエンコーディングを推測させることもできます (Autodetecting the encoding scheme参照)。また、ここに#tを渡すと、入力ポートはCoding aware portでラップされます (Coding-aware ports参照)。入力ファイルがエンコーディング指定のマジックコメントを持っていることが期待できる場合に便利です。

          この引数が与えられた場合、Gaucheは自動的にgauche.charconvモジュールをロードし、ポートの入出力時に文字コード変換を行います。 CESについて詳しくはSupported character encoding schemesを参照してください。

     :conversion-buffer-size
          This argument may be used with the ENCODING argument to specify the buffer size of character encoding conversion.  It is passed as a BUFFER-SIZE argument of the conversion port constructors (see Conversion ports).

          Usually you don't need to give this argument; but if you need to guess the input file encoding, larger buffer size may work better since guessing routine can have more data before deciding the encoding. この引数は、文字エンコーディング変換に使うバッファサイズを指定するために ENCODING引数と共に使うことができます。渡された値はそのまま文字コード変換ポートのコンストラクタのBUFFER-SIZE引数に渡されます (Conversion ports参照)。

          この引数を指定する必要は滅多にありませんが、入力ファイルの文字エンコーディングを推測しなければならない場合、大きめのバッファサイズの方が精度が上がります。推測ルーチンがより多くのデータを見て文字エンコーディングを決定できるからです。

     :conversion-illegal-output
          This argument may be used with the ENCODING argument to specify the behavior when the source character can't be mapped to the destination character.  It must be either a symbol raise or a symbol replace, and is passed as ILLEGAL-OUTPUT argument to the conversion port.  See Conversion ports, for the details. この引数はENCODE引数と一緒に使うことで、文字エンコーディング変換において、元の文字に対応する文字が変換先に無い場合の振る舞いを指定できます。値はシンボルraiseかreplaceでなければならず、それはそのまま変換ポートのILLEGAL-OUTPUT引数に渡されます。詳しくはConversion portsを参照してください。

     By combination of IF-EXISTS and IF-DOES-NOT-EXIST flags, you can implement various actions:

          (open-output-file "foo" :if-exists :error)
           => ;opens "foo" exclusively, or error

          (open-output-file "foo" :if-exists #f)
           => ;opens "foo" exclusively, or returns #f

          (open-output-file "foo" :if-exists :append
                                  :if-does-not-exist :error)
           => ;opens "foo" for append only if it already exists

     IF-EXISTSとIF-DOES-NOT-EXISTフラグの組合せにより、色々な動作を実現できます。

          (open-output-file "foo" :if-exists :error)
           => ;"foo"を排他的にオープンするかエラーを報告する

          (open-output-file "foo" :if-exists #f)
           => ;"foo"を排他的にオープンするか#fを返す

          (open-output-file "foo" :if-exists :append
                                  :if-does-not-exist :error)
           => ;"foo"が既に存在する場合に限り、それを追加モードでオープン

     To check the existence of a file without opening it, use sys-access or file-exists? (see File stats). ファイルをオープンせずにその存在をチェックするには、 sys-accessかfile-exists?を使って下さい (File stats参照)。

     Note for portability: Some Scheme implementations (e.g. STk) allows you to specify a command to FILENAME and reads from, or writes to, the subprocess standard input/output.  Some other scripting languages (e.g. Perl) have similar features.  In Gauche, open-input-file and open-output-file strictly operates on files (what the underlying OS thinks as files). However, you can use ``process ports'' to invoke other command in a subprocess and to communicate it. See Process ports, for details. 移植性に関する註：Schemeシステムによっては、FILENAMEのところにシェルコマンドを指定して、サブプロセスの標準入出力と通信できるようにするものがあります。他のスクリプティング言語(例：Perl)にも同様の機能があります。 Gaucheでは、open-input-fileとopen-output-fileはあくまでファイル (OSがファイルとして扱うもの) のみに対して使えます。サブプロセスと通信するためには、「プロセスポート」という機能が提供されています。 Process portsを参照して下さい。

 -- Function: call-with-input-file string proc :key if-does-not-exist buffering element-type encoding conversion-buffer-size
 -- Function: call-with-output-file string proc :key if-does-not-exist if-exists buffering element-type encoding conversion-buffer-size
     [R7RS+] Opens a file specified by STRING for input/output, and call PROC with one argument, the file port.  When PROC returns, or an error is signaled from PROC that is not captured within PROC, the file is closed. STRINGで示されるファイルを入力または出力用にオープンし、作成されたポートを引数として手続きPROCを呼び出します。 PROCが正常終了するか、PROC内で捕捉されないエラーが起きた場合にファイルはクローズされます。

     The keyword arguments have the same meanings of open-input-file and open-output-file's.  Note that if you specify #f to IF-EXISTS and/or IF-DOES-NOT-EXIST, PROC may receive #f instead of a port object when the file is not opened. キーワード引数は open-input-file及びopen-output-fileのものと同じ意味を持ちます。 IF-EXISTSやIF-DOES-NOT-EXISTに#fを指定した場合、ファイルがオープンされなかった場合はPROCにポートではなく#fが渡されることに注意して下さい。

     Returns the value(s) proc returned. PROCが返す値を返します。

 -- Function: with-input-from-file string thunk :key if-does-not-exist buffering element-type encoding conversion-buffer-size
 -- Function: with-output-to-file string thunk :key if-does-not-exist if-exists buffering element-type encoding conversion-buffer-size
     [R7RS file] Opens a file specified by STRING for input or output and makes the opened port as the current input or output port, then calls THUNK.  The file is closed when THUNK returns or an error is signaled from THUNK that is not captured within THUNK.

     Returns the value(s) thunk returns.

     The keyword arguments have the same meanings of open-input-file and open-output-file's, except that when #f is given to IF-EXISTS and IF-DOES-NOT-EXIST and the opening port is failed, THUNK isn't called at all and #f is returned as the result of with-input-from-file and with-output-to-file. STRINGで示されるファイルを入力または出力用にオープンし、オープンされたポートを現在の入力または出力ポートに設定して、THUNKを呼び出します。 THUNKが戻るか、THUNK内で捕捉されないエラーが生じた際にファイルは閉じられます。

     THUNKが返す値を返します。

     キーワード引数は open-input-file及びopen-output-fileのものと同じ意味を持ちます。但しIF-EXISTSやIF-DOES-NOT-EXISTに#fが指定され、ファイルがオープンできなかった場合は、THUNKは呼ばれずに直ちに#fが返されます。

Notes on semantics of closing file ports: R7RS states, in the description of call-with-port et al., that "If proc does not return, then the port will not be closed automatically unless it is possible to prove that the port will never again be used for read or write operation." ポートを閉じるセマンティクスについて: R7RSはcall-with-port等の説明において、次のように述べています。「procが戻って来なかった場合、今後ポートが読み書きに一切使われないことが証明できない限りは、ポートは自動的には閉じられない」。

Gauche's implementation slightly misses this criteria; the mere fact that an uncaptured error is thrown in PROC does not prove the port will never be used.  Nevertheless, it is very difficult to think the situation that you can do meaningful operation on the port after such an error is signaled; you'd have no idea what kind of state the port is in.  In practical programs, you should capture error explicitly inside PROC if you still want to do some meaningful operation with the port. Gaucheの実装は若干この条件には反しています。捕捉されないエラーがPROCから発せられたというだけでは、そのポートが今後一切使われないかどうかはわかりません。しかし実際には、そのようなエラーが発せられた後でポートに対して意味のある操作をするのは非現実的です。ポートがどのような状態にあるかわからないわけですから。現実的なプログラムでは、ポートに対して意味のある操作をしつづけたいのなら、 PROCの中で明示的にエラーをハンドルすべきでしょう。

Note that if a continuation captured outside call-with-input-file et al. is invoked inside PROC, the port is not closed. It is possible that the control returns later into the PROC, if a continuation is captured in it (e.g. coroutines). The low-level exceptions (see Handling exceptions) also doesn't ensure closing the port. call-with-input-fileの外で捕捉された継続をPROC内で呼んだ場合にはポートは閉じられないことに注意して下さい。後でPROCへと制御が戻ってくるかもしれないからです (コルーチン等)。また、低レベルの例外メカニズム(Handling exceptions 参照)を利用した場合、エラー時にポートを閉じるのはプログラマの責任になります。

 -- Function: open-input-fd-port fd :key buffering name owner?
 -- Function: open-output-fd-port fd :key buffering name owner?
     Creates and returns an input or output port on top of the given file descriptor.  BUFFERING specifies the buffering mode as described in open-input-file entry above; the default is :full.  NAME is used for the created port's name and returned by port-name.

     A boolean flag owner? specifies whether FD should be closed when the port is closed.  If it is #f, closing port doesn't close FD.  If it s #t, closing port automatically closes fd.  It can also be a symbol dup, in which case fd is duplicated (by dup(2) system call) and the resulting port owns the new fd which will be closed automatically--but FD itself remains open, and can be closed independently. 与えられたファイルディスクリプタにアクセスする入力または出力ポートを作成して返します。BUFFERING はopen-input-file の項で説明されたポートのバッファリングモードを指定します。デフォルトは:fullです。 NAMEはport-nameによって返されるポートの名前を指定します。

     OWNER? は、このポートを閉じた時にFDもクローズすべきかどうかを指定します。#fならポートを閉じてもFDはそのままです。 #tならポートを閉じた時にFDも自動的に閉じられます。また、シンボルdupを渡すこともできて、その場合は内部でFDが dup(2)システムコールによって複製され、新しいfdをポートが所有します。新たなfdはポートが閉じると自動的に閉じられますが、FD自体は閉じられません。また、FDをポートとは独立して閉じることができます。

 -- Function: port-fd-dup! toport fromport
     Interface to the system call dup2(2). Atomically closes the file descriptor associated to TOPORT, creates a copy of the file descriptor associated to FROMPORT, and sets the new file descriptor to TOPORT. Both TOPORT and FROMPORT must be file ports. Before the original file descriptor of TOPORT is closed, any buffered output (when TOPORT is an output port) is flushed, and any buffered input (when TOPORT is an input port) is discarded.

     `Copy' means that, even the two file descriptors differ in their values, they both point to the same system's open file table entry.  For example they share the current file position; after PORT-FD-DUP!, if you call port-seek on FROMPORT, the change is also visible from TOPORT, and vice versa.  Note that this 'sharing' is in the system-level; if either TOPORT or FROMPORT is buffered, the buffered contents are not shared.

     This procedure is mainly intended for programs that needs to control open file descriptors explicitly; e.g. a daemon process would want to redirect its I/O to a harmless device such as /dev/null, and a shell process would want to set up file descriptors before executing the child process. システムのdup2(2)のインタフェースです。アトミックにTOPORTのファイルディスクリプタをクローズし、FROMPORTのファイルディスクリプタを複製したものをTOPORTに設定します。 TOPORT、FROMPORTはいずれもファイルポートでなければなりません。

     ファイルディスクリプタが「複製」されると、ふたつのディスクリプタ番号が異なっていてもそれらはシステムのオープンファイルテーブルの同じエントリを指します。例えば、現在の(システムレベルでの)ファイル上の読み書き位置は共有されます。 port-fd-dup!の後で、port-seekをFROMPORTに対して呼び出せば、その変更はTOPORTの読み書き位置にも影響を与えるでしょうし、その逆もまたあります。ただし、共有されるのはシステムレベルの情報のみで、 TOPORTやFROMPORTがバッファリングされている場合、バッファの内容は共有されません。

     この手続きは、主にファイルディスクリプタを明示的に制御する必要のあるプログラムのために用意されています。例えばデーモンプロセスがその入出力を/dev/nullなどの無難なデバイスに切り替えたり、シェルプロセスが子プロセスをexecする前にそのファイルディスクリプタをセットアップしたりするような場合です。

String ports
------------

String ports are the ports that you can read from or write to memory. 文字列ポートは、メモリ上のデータと関連付けられたポートです。

 -- Function: open-input-string string :key name
     [R7RS base][SRFI-6] Creates an input string port that has the content STRING. This is a more efficient way to access a string in order rather than using string-ref with incremental index.

          (define p (open-input-string "foo x"))
          (read p) => foo
          (read-char p) => #\space
          (read-char p) => #\x
          (read-char p) => #<eof>
          (read-char p) => #<eof>

     STRINGを内容とする入力文字列ポートを作って返します。文字列に逐次的にアクセスする場合、インデックスをインクリメントしながら string-refを呼び出すより効率の良い方法です。

          (define p (open-input-string "文字 列"))
          (read p) => 文字
          (read-char p) => #\space
          (read-char p) => #\列
          (read-char p) => #<eof>
          (read-char p) => #<eof>

     The NAME keyword argument is a Gauche extension. By default, the created port is named as (input string port). It is mainly used for debugging.  You can specify alternative name with this argument. As Gauche's convention, file ports has the source file path as its name, so port names for debugging information should be parenthesized not to be taken as pathnames. NAMEキーワード引数はGaucheの拡張です。デフォルトでは、作られるポートの名前は(input string port)になります。ポートの名前は主にデバッグのために使われます。この引数で代わりの名前を指定できます。 Gaucheの慣習として、ファイルポートは元ファイルのパス名を名前に持つので、ポート名にデバッグ用途の情報を載せる場合はパス名と区別しやすいよう括弧に入れるのが良いでしょう。

          gosh> (open-input-string "")
          #<iport (input string port) 0x215c0c0>
          gosh> (open-input-string "" :name "(user input)")
          #<iport (user input) 0x22a4e40>

 -- Function: get-remaining-input-string port
     PORT must be an input string port. Returns the remaining content of the input port. The internal pointer of PORT isn't moved, so the subsequent read from PORT isn't affected. If PORT has already reached to EOF, a null string is returned. PORTは入力文字列ポートでなければなりません。入力ポートに残っている文字列を返します。 PORTの内部ポインタは動かされないので、PORTに対するreadは影響を受けません。PORTが既にEOFに達していた場合は、空文字列が返されます。

          (define p (open-input-string "abc\ndef"))
          (read-line p)                  => "abc"
          (get-remaining-input-string p) => "def"
          (read-char p)                  => #\d
          (read-line p)                  => "ef"
          (get-remaining-input-string p) => ""

 -- Function: open-output-string :key name
     [R7RS base][SRFI-6] Creates an output string port.   Anything written to the port is accumulated in the buffer, and can be obtained as a string by get-output-string. This is a far more efficient way to construct a string sequentially than pre-allocate a string and fill it with string-set!. 出力文字列ポートを作成して返します。このポートに書き出された文字列は内部のバッファにたくわえられ、get-output-string で取り出すことができます。これは、順番に文字列を構成する方法として、あらかじめ文字列をアロケートして string-set!で埋めて行くよりもずっと効率の良い方法です。

     The NAME keyword argument is a Gauche extension. By default, the created port is named as (output string port). It is mainly used for debugging.  You can specify alternative name with this argument. As Gauche's convention, file ports has the source file path as its name, so port names for debugging information should be parenthesized not to be taken as pathnames. NAMEキーワード引数はGaucheの拡張です。デフォルトでは、作られるポートの名前は(output string port)になります。ポートの名前は主にデバッグのために使われます。この引数で代わりの名前を指定できます。 Gaucheの慣習として、ファイルポートは元ファイルのパス名を名前に持つので、ポート名にデバッグ用途の情報を載せる場合はパス名と区別しやすいよう括弧に入れるのが良いでしょう。

          gosh> (open-output-string)
          #<oport (output string port) 0x22a4c00>
          gosh> (open-output-string :name "(temporary output)")
          #<oport (temporary output) 0x22a49c0>

 -- Function: get-output-string port
     [R7RS base][SRFI-6] Takes an output string port port and returns a string that has been accumulated to port so far. If a byte data has been written to the port, this function re-scans the buffer to see if it can consist a complete string; if not, an incomplete string is returned. 出力文字列ポートportを取り、それまでそのポートに蓄積された文字列を返します。バイトデータがそのポートに書き出されていた場合、この手続きはまず内部バッファをスキャンし、結果が完全な文字列で表現できるかどうかを調べます。もし表現できなければ、不完全な文字列が返されます。

     This doesn't affect the PORT's operation, so you can keep accumulating content to PORT after calling get-output-string. これはPORTの操作には影響をあたえません。get-output-stringを呼んだ後でも、PORTに内容を蓄積しつづけることができます。

 -- Function: call-with-input-string string proc
 -- Function: call-with-output-string proc
 -- Function: with-input-from-string string thunk
 -- Function: with-output-to-string thunk
     These utility functions are trivially defined as follows. The interface is parallel to the file port version. これらのユーティリティ関数は次に定義されるような動作をします。インタフェースはファイルポートを扱う類似の関数と揃えてあります。

          (define (call-with-output-string proc)
            (let ((out (open-output-string)))
              (proc out)
              (get-output-string out)))

          (define (call-with-input-string str proc)
            (let ((in (open-input-string str)))
              (proc in)))

          (define (with-output-to-string thunk)
            (let ((out (open-output-string)))
              (with-output-to-port out thunk)
              (get-output-string out)))

          (define (with-input-from-string str thunk)
            (with-input-from-port (open-input-string str) thunk))

 -- Function: call-with-string-io str proc
 -- Function: with-string-io str thunk

          (define (call-with-string-io str proc)
            (let ((out (open-output-string))
                  (in  (open-input-string str)))
              (proc in out)
              (get-output-string out)))

          (define (with-string-io str thunk)
            (with-output-to-string
              (lambda ()
                (with-input-from-string str
                  thunk))))

 -- Function: write-to-string obj :optional writer
 -- Function: read-from-string string :optional start end
     These convenience functions cover common idioms using string ports.

          (write-to-string obj writer)
            ==
            (with-output-to-string (lambda () (writer obj)))

          (read-from-string string)
            ==
            (with-input-from-string string read)

     The default value of WRITER is the procedure write. The default values of START and END is 0 and the length of STRING.

     Portability note: Common Lisp has these functions, with different optional arguments. STk has read-from-string without optional argument. 文字列ポートを使う定型句をユーティリティ関数にしました。

          (write-to-string obj writer)
            ==
            (with-output-to-string (lambda () (writer obj)))

          (read-from-string string)
            ==
            (with-input-from-string string read)

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

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

Coding-aware ports
------------------

A coding-aware port is a special type of procedural input port that is used by load to read a program source.  The port recognizes the magic comment to specify the character encoding of the program source, such as ;; -*- coding: utf-8 -*-, and makes an appropriate character encoding conversion. See Multibyte scripts for the details of coding magic comment. コーディング認識ポートは特殊な手続的入力ポートで、loadがプログラムソースコードを読む際に使われています。このポートは ;; -*- coding: utf-8 -*-のような、プログラムソースの文字エンコーディングを指定する特殊なコメントを認識し、適切な文字エンコーディング変換を行います。特殊なコメントでソースの文字エンコーディングを指定することについては、 Multibyte scriptsを参照して下さい。

 -- Function: open-coding-aware-port iport
     Takes an input port and returns an input coding aware port, which basically just pass through the data from IPORT to its reader.  However, if a magic comment appears within the first two lines of data from IPORT, the coding aware port applies the necessary character encoding conversion to the rest of the data as they are read. 入力ポートを引数としてとりコーディング認識入力ポートを返します。基本的には IPORT からの入力データをリーダにわたしているだけです。しかし、IPORT からの入力データの最初の2行以内に、特別な呪文コメントが現れた場合、コーディング認識ポートは、その後に読み込まれるデータについて必要な文字エンコーディング変換を行います。

     The passed port, IPORT, is "owned" by the created coding-aware port.  That is, when the coding-aware port is closed, IPORT is also closed.  The content read from IPORT is buffered in the coding-aware port, so other code shouldn't read from IPORT. 引数として渡されたポート、IPORT は生成されたコーディング認識ポートによって所有されます。つまり、コーディング認識ポートがクローズされると、IPORT もクローズされます。IPORT から読み込まれた内容はコーディング認識ポート内でバッファリングさます、したがって、別のコードで IPORT から読み出しを行うべきではありません。

     By default, Gauche's load uses a coding aware port to read the program source, so that the coding magic comment works for the Gauche source programs (see Loading Scheme file). However, since the mechanism itself is independent from load, you can use this port for other purposes; it is particularly useful to write a function that processes Scheme source programs which may have the coding magic comment. デフォルトでは、Gauche の load はプログラムソースを読むのにコーディング認識ポートを使います。したがって、文字エンコーディングを示す特別な呪文コメントは、Gauche のソースプログラムでは有効になります (Loading Scheme file参照)。ただし、この機構自身は load とは独立しており、このポートを別の目的で利用できます。特にコーディングの呪文コメントがある Scheme のソースプログラムを処理する関数を書くときに便利です。

Input
-----

For the input-related procedures, the optional IPORT argument must be an input port, and when omitted, the current input port is assumed. 入力に関する手続きで、省略可能な引数IPORTは入力ポートでなければなりません。省略された場合が現在の入力ポートが使われます。

Reading data
............

 -- Function: read :optional iport
     [R7RS base] Reads an S-expression from IPORT and returns it. Gauche recognizes the lexical structure specified in R7RS, and some additional lexical structures listed in Lexical structure.

     If IPORT has already reached to the end of file, an eof object is returned.

     The procedure reads up to the last character that consists the S-expression, and leaves the rest in the port.  It's not like CommonLisp's read, which consumes whitespaces after S-expression by default. IPORTからS式をひとつ読み込んで返します。 GaucheはR7RSに定義されている構文要素に加え、Lexical structureに定義されている拡張構文要素を認識します。

     IPORTが既にEOFに達していた場合は、EOFオブジェクトが返されます。

     この手続きはS式を構成する最後の文字までを読み、その後の文字はポートに残します。これは、S式に続く空白文字も読み込むCommonLispのreadの振る舞いとは異なります。

 -- Function: read-with-shared-structure :optional iport
 -- Function: read/ss :optional iport
     [SRFI-38] These procedures are defined in srfi-38 to recognize shared substructure notation (#n=, #n#).   Gauche's builtin read recognizes the srfi-38 notation, so these are just synonyms to read; these are only provided for srfi-38 compatibility. これらの手続きは、SRFI-38 で定義されていて、共有構造を表す記法 (#n=, #n#)を認識できます。Gauche の組み込み read はこの SRFI-38 の記法を認識します。それゆえ、これらの手続きは、read と同じで、SRFI-38 との互換性のために用意されています。

 -- Function: read-char :optional iport
     [R7RS base] Reads one character from IPORT and returns it. If IPORT has already reached to the end, returns an eof object. If the byte stream in IPORT doesn't consist a valid character, the behavior is undefined.  (In future, a port will have a option to deal with invalid characters). IPORTから1文字読み込んで返します。 IPORTが既にEOFに達していた場合はeofオブジェクトを返します。 IPORTにあるバイトストリームが正しい文字を構成しない場合、ふるまいは未定義です。(将来はポート側に、不正な文字に対する対応を決めるオプションを設ける予定です)。

 -- Function: peek-char :optional iport
     [R7RS base] Reads one character in IPORT and returns it, keeping the character in the PORT. If the byte stream in IPORT doesn't consist a valid character, the behavior is undefined.  (In future, a port will have a option to deal with invalid characters). IPORTから1文字読み込んで返します。文字はそのままIPORTに留まります。 IPORTが既にEOFに達していた場合はeofオブジェクトを返します。 IPORTにあるバイトストリームが正しい文字を構成しない場合、ふるまいは未定義です。(将来はポート側に、不正な文字に対する対応を決めるオプションを設ける予定です)。

 -- Function: read-byte :optional iport
 -- Function: read-u8 :optional iport
     [R7RS base] Reads one byte from an input port IPORT, and returns it as an integer in the range between 0 and 255. If IPORT has already reached EOF, an eof object is returned.

     This is traditionally called read-byte, and R7RS calls it read-u8.  You can use either. 入力ポートIPORTから1バイト読み込み、0から255までの整数値として返します。 IPORTが既にEOFに達していた場合はeofオブジェクトを返します。

     これは伝統的にread-byteと呼ばれてきましたが、 R7RSではread-u8と名づけています。どちらも使えます。

 -- Function: peek-byte :optional iport
 -- Function: peek-u8 :optional iport
     [R7RS base] Peeks one byte at the head of an input port IPORT, and returns it as an integer in the range between 0 and 255. If IPORT has already reached EOF, an eof object is returned.

     This is traditionally called peek-byte, and R7RS calls it peek-u8.  You can use either. 入力ポートIPORTの先頭の1バイトを見て、それを0から255までの整数値として返します。 IPORTが既にEOFに達していた場合はeofオブジェクトを返します。

     これは伝統的にpeek-byteと呼ばれてきましたが、 R7RSではpeek-u8と名づけています。どちらも使えます。

 -- Function: read-line :optional iport allow-byte-string?
     [R7RS base] Reads one line (a sequence of characters terminated by newline or EOF) and returns a string.  The terminating newline is not included. This function recognizes popular line terminators (LF only, CRLF, and CR only). If IPORT has already reached EOF, an eof object is returned. 入力ポートから、行末もしくはEOFまで読み込んで文字列として返します。よく使われる行末 (LF only, CRLF, and CR only) を認識します。戻り値にはこれらの行末文字は含まれません。 IPORTが既にEOFに達していた場合はeofオブジェクトを返します。

     If a byte sequence is read from IPORT which doesn't constitute a valid character in the native encoding, read-line signals an error by default.  However, if a true value is given to the argument ALLOW-BYTE-STRING?, read-line returns a byte string (incomplete string) in such case, without reporting an error. It is particularly useful if you read from a source whose character encoding is not yet known; for example, to read XML document, you need to check the first line to see if there is a charset parameter so that you can then use an appropriate character conversion port. This optional argument is Gauche's extension to R7RS. IPORTから、内部文字エンコーディングでは文字を構成し得ないバイトシーケンスが読まれた場合、デフォルトではread-lineはエラーを通知します。しかし、省略可能な引数ALLOW-BYTE-STRING?に真の値が与えられた場合は、 read-lineはエラーを通知せず、かわりにバイト文字列 (不完全な文字列) を返します。この動作は、特に文字エンコーディングが不明なソースから読み込む際に便利です。例えばXMLドキュメントを読み込む際、最初の行のcharsetパラメータをチェックしてから適切な文字エンコーディング変換ポートを使うといった用途などです。この動作はGauche独自の拡張です。

 -- Function: read-string nchars :optional iport
     [R7RS base] Read NCHARS characters, or as many characters as available before EOF, and returns a string that consists of those characters. If the input has already reached EOF, an eof object is returned. NCHARS文字を読み込み、もしくはそれ以前にEOFに達したら読めただけの文字を使って文字列を作って返します。もし入力が既にEOFに達していた場合は EOFを返します。

 -- Function: read-block nbytes :optional iport
     This procedure is deprecated - use read-uvector instead (see Uvector block I/O). この手続きは非推奨になりました。read-uvectorを使ってください (Uvector block I/O参照)。

     Reads NBYTES bytes from IPORT, and returns an incomplete string consisted by those bytes.  The size of returned string may shorter than NBYTES when IPORT doesn't have enough bytes to fill. If NBYTES is zero, a null string is always returned.

     If IPORT has already reached EOF, an eof object is returned. NBYTESバイトのデータをIPORTから読み込み、不完全な文字列として返します。IPORTに十分なデータが無い場合、返される文字列はNBYTESより短いかもしれません。 NBYTESが0の場合は、常に空文字列が返されます。

     IPORTが既にEOFに達していた場合はEOFオブジェクトが返されます。

     If IPORT is a file port, the behavior of read-block differs by the buffering mode of the port (see File ports, for the detail explanation of buffering modes). IPORTがファイルポートだった場合、read-blockはポートのバッファリングモードによってふるまいが異なります (バッファリングモードの詳細についてはFile portsを参照して下さい)。

       * If the buffering mode is :full, read-block waits until NBYTES data is read, except it reads EOF. バッファリングモードが:fullの場合、read-blockは EOFを読まない限り、NBYTESのデータが読まれるまで待ちます。

       * If the buffering mode is :modest or :none, read-block returns shorter string than NBYTES even if it doesn't reach EOF, but the entire data is not available immediately. バッファリングモードが:modestか:noneである場合、 read-blockはEOFが読まれなくても、すぐに読めるデータがNBYTESよりも少ない場合はそのデータだけを返します。

     If you want to write a chunk of bytes to a port, you can use either display if the data is in string, or write-uvector in gauche.uvector (see Uvector block I/O) if the data is in uniform vector. データブロックをポートに書き出すには、データが文字列で表現されている場合は単純にdisplayが使えます。データがuniform vectorで表現されている場合はgauche.uvectorモジュールのwrite-uvectorが使えます (Uvector block I/O参照)。

 -- Function: eof-object
     [R7RS base] Returns an EOF object. EOFオブジェクトを返します。

 -- Function: eof-object? obj
     [R7RS base] Returns true if OBJ is an EOF object. OBJがEOFオブジェクトなら#tを返します。

 -- Function: char-ready? :optional port
     [R7RS base] If a character is ready to be read from PORT, returns #t.

     For now, this procedure actually checks only if next byte is immediately available from PORT.   If the next byte is a part of a multibyte character, the attempt to read the whole character may block, even if char-ready? returns #t on the port. (It is unlikely to happen in usual situation, but theoretically it can. If you concern, use read-uvector to read the input as a byte sequence, then use input string port to read characters.) PORTから文字が読み出せる状態ならば#tを返します。

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

 -- Function: byte-ready? :optional port
 -- Function: u8-ready? :optional port
     [R7RS base] If one byte (octet) is ready to be read from PORT, returns #t.

     This is traditionally called byte-ready?, and R7RS calls it u8-ready?.  You can use either. PORTから1バイトをすぐに読み込める状態なら#tを返します。

     これは伝統的にbyte-ready?と呼ばれてきましたが、 R7RSではu8-ready?と名づけています。どちらも使えます。

Reader lexical mode
...................

 -- Parameter: reader-lexical-mode
     Get/set the reader lexical mode.  Changing this parameter switches behavior of the reader concerning some corner cases of the lexical syntax, where legacy Gauche syntax and R7RS syntax aren't compatible. 現在のリーダ字句モードを表すパラメータです。このパラメータの値を変えることにより、旧来のGaucheとR7RSで非互換となるコーナーケースの字句構文についての解釈を変更できます。

     In general, you don't need to change this parameter directly. The lexical syntax matters at the read-time, while changing this parameter happens at the execution-time; unless you know the exact timing when each phase occurs, you might not get what you want. 一般的には、このパラメータを直接変える必要のある場合は少ないでしょう。字句構文は読み込み時に問題となりますが、パラメータの変更は実行時に起こります。いつ、何が起きるかを正確に把握しているのでない限り、意図したとおりの効果は得られないかもしれません。

     The hash-bang directive #!gauche-legacy and #!r7rs indirectly affects this parameter; the first one sets the reader mode to legacy, and the second one to strict-r7. hash-bang指示子 #!gauche-legacy および #!r7rs は間接的にこのパラメータに影響を与えます。#!gauche-legacyはリーダモードをlegacyに、#!r7rsはstrict-r7に変更します。

     The command-line argument -fwarn-legacy sets the default reader mode to warn-legacy. コマンドライン引数の-fwarn-legacyはデフォルトのリーダモードを warn-legacyにセットします。

     Change to this parameter during load is delimited within that load; once load is done, the value of this parameter is reset to the value when load is started. load中にこのパラメータを変更した場合、その効果はloadの期間中に留まります。そのloadが終了した時点で、 load開始時のリーダモードが復元されます。

     The parameter takes one of the following symbols as a value. このパラメータは値として次のシンボルのうちいずれかを取ります。

     permissive
          This is the default mode.  It tries to find a reasonable compromise between two syntax. これがデフォルトのモードです。二つの構文の、ほどほどの妥協点を見つけようとします。

          In string literals, hex escape sequence is first interpreted as R7RS lexical syntax.  If the syntax doesn't conform R7RS hex escape, it is interpreted as legacy Gauche hex escape syntax.  For example, "\x30;a" is read as "0a", for the hex escape sequence including the terminating semicolon is read as R7RS hex escape sequence.  It also reads "\x30a" as "0a", for the legacy Gauche hex escape always takes two hexadecimal digits without the terminator.  With this mode, you can use R7RS hex escape syntax for the new code, and yet almost all legacy Gauche code can be read without a problem. However, if the legacy code has a semicolon followed by hex escape, it is interpreted as R7RS syntax and the incompatibility arises. 文字列リテラル中の16進数エスケープシーケンスは、まず R7RSの字句構文で解釈されます。もしそれがR7RSの16進数エスケープシーケンスの構文に沿っていなかった場合は、旧来のGaucheの構文で解釈されます。例えば、"\x30;a" は、セミコロンがR7RSのエスケープシーケンスの終端とみなされ、"0a" と読まれます。一方で "\x30a" も "0a" と読まれます。終端のセミコロンが無く、有効なR7RSの構文でないため、旧来のGaucheのエスケープシーケンスとして2桁固定で解釈されるからです。このモードでは、新たなコードでR7RSエスケープシーケンスを利用できるうえ、ほとんどの既存のGaucheコードはそのまま走ります。しかし、もし既存のGaucheコードで、たまたま2桁の16進数エスケープの直後にセミコロンがあった場合、それはR7RSとして読まれ、非互換性が生じます。

     strict-r7
          Strict R7RS compatible mode. When the reader encounters the hash-bang directive #!r7rs, the rest of file is read with this mode. 厳密にR7RS互換なモード。リーダが、hash-bang指示子#!r7rsに出会うと、ファイルの残りの部分はこのモードで読まれます。

          In this mode, Gauche's extended lexical syntax will raise an error.

          Use this mode to ensure the code can be read on other R7RS implementations. このモードでは、Gaucheの拡張字句構文はエラーとなります。

          他のR7RS実装でも読めるコードであることを確認したい場合に使ってください。

     legacy
          The reader works as the legacy Gauche (version 0.9.3.3 and before). When the reader encounters the hash-bang directive #!gauche-legacy, the rest of file is read with this mode.

          This only matters when you want to read two-digit hex escape followed by semicolon as a character plus a semicolon, e.g. "\x30;a" as "0;a" instead of "0a". We expect such a sequence rarely appears in the code, but if you dump a data in a string literal format, you may have such sequence (especially in incomplete string literals). リーダは以前の(0.9.3.3及びそれ以前の)Gaucheと同じように動作します。リーダがhash-bang指示子#!gauche-legacyに出会うと、ファイルの残りの部分はこのモードで読まれます。

          このモードが必要になるのは、2桁の16進数エスケープの直後にセミコロンが来ているリテラルを、文字＋セミコロンと読みたい場合だけです。例えば "\x30;a"を"0a"でなく"0;a"と読みたい、等。こういうケースはコードではほとんど無いと思いますが、データを文字列リテラルとしてダンプしてある場合、それも不完全な文字列としてダンプしてある場合に、こういった並びが出現しているかもしれません。

     warn-legacy
          The reader works as the permissive mode, but warns if it reads legacy hex-escape syntax. This mode is default when -fwarn-legacy command-line argument is given to gosh.

          This is useful to check if you have any incompatible escape sequence in your code. リーダはpermissiveモードと同様に動作しますが、旧来の16進数エスケープに出会うと警告を発します。 goshに-fwarn-legacyコマンドライン引数が与えられた場合はこれがデフォルトのモードになります。

          コードの中に非互換なエスケープシーケンスが無いかどうか調べるのに役立ちます。

Read-time constructor
.....................

Read-time constructor, defined in SRFI-10, provides an easy way to create an external representation of user-defined structures. SRFI-10で定義されている読み込み時コンストラクタは、ユーザ定義の構造の外部表現を作るための簡単な方法を提供します。

 -- Reader Syntax: #,(TAG ARG ...)
     [SRFI-10] Gauche maintains a global table that associates a TAG (symbol) to a constructor procedure. GaucheはTAG (シンボル)をコンストラクタ手続きに関連付けるグローバルなテーブルを管理しています。

     When the reader encounters this syntax, it reads ARG ..., finds a reader constructor associated with TAG, and calls the constructor with ARG ... as arguments, then inserts the value returned by the constructor as the result of reading the syntax. リーダーがこの構文に出会ったとき、ARG ...を読み込み、 TAGに関連付けられた読み込みコンストラクタを探し、 ARG ...を引数としてそのコンストラクタを呼び出し、その構文を読み込んだ結果としてそのコンストラクタが返した値を挿入します。

     Note that this syntax is processed inside the reader---the evaluator doesn't see any of ARGs, but only sees the object the reader returns. この構文はリーダー内部で処理されることに注意して下さい。評価器は ARGを見ず、リーダーが返したオブジェクトしか見ません。

 -- Function: define-reader-ctor TAG PROCEDURE
     [SRFI-10] Associates a reader constructor PROCEDURE with TAG.

     Examples: [SRFI-10] 読み込みコンストラクタPROCEDUREをTAGに関連付けます。

     例:

          (define-reader-ctor 'pi (lambda () (* (atan 1) 4)))

          #,(pi) => 3.141592653589793

          '(#,(pi)) => (3.141592653589793)

          (define-reader-ctor 'hash
            (lambda (type . pairs)
              (let ((tab (make-hash-table type)))
                (for-each (lambda (pair)
                            (hash-table-put! tab (car pair) (cdr pair)))
                          pairs)
                tab)))

          (define table
           #,(hash eq? (foo . bar) (duh . dah) (bum . bom)))

          table => #<hash-table eq? 0x80f9398>
          (hash-table-get table 'duh) => dah

     Combined with write-object method (see Output), it is easy to make a user-defined class written in the form it can be read back: write-objectメソッド(Output参照)と組み合わせて、読み戻ることが可能なフォームで書かれたユーザ定義のクラスを作ることが簡単になります。

          (define-class <point> ()
            ((x :init-value 0 :init-keyword :x)
             (y :init-value 0 :init-keyword :y)))

          (define-method write-object ((p <point>) out)
            (format out "#,(<point> ~s ~s)" (ref p 'x) (ref p 'y)))

          (define-reader-ctor '<point>
            (lambda (x y) (make <point> :x x :y y)))

NOTE: The extent of the effect of define-reader-ctor is not specified in SRFI-10, and might pose a compatibility problem among implementations that support SRFI-10. (In fact, the very existence of define-reader-ctor is up to an implementation choice.) 注意: define-reader-ctorの効果の範囲はSRFI-10には規定されておらず、SRFI-10をサポートする実装においても互換性の問題を起こすことがあるかもしれません。 (実際に、define-reader-ctorの存在そのものが実装の選択に任されています。)

In Gauche, at least for the time being, define-reader-ctor take effects as soon as the form is compiled and evaluated.  Since Gauche compiles and evaluates each toplevel form in order, TAG specified in define-reader-ctor can be used immediately after that. However, it doesn't work if the call of define-reader-ctor and the use of TAG is enclosed in a begin form, for the entire begin form is compiled at once before being evaluated. Gaucheでは、現時点においては、define-reader-ctorはそのフォームがコンパイルされ評価された時点で効力を持ちます。 Gaucheはトップレベルのフォームを順番にコンパイル・評価するので、 define-reader-ctorで指定されたTAGは、その指定の直後から使えます。しかし、define-reader-ctorの呼び出しとTAGの使用が beginフォームで囲まれている場合は、beginフォーム全体は評価される前に一度にコンパイルされるため、うまく動作しません。

Other implementations may require to read the entire file before making its define-reader-ctor call effective.  If so, it effectively prevents one from using define-reader-ctor and the defined TAG in the same file.   It is desirable to separate the call of define-reader-ctor and the use of TAG in the different files if possible. 他の実装では、define-reader-ctorの呼び出しが効力を持つようにする前にファイル全体を読み込むことを要求するかも知れません。その場合は、define-reader-ctorと定義されたTAGの使用を同じファイルに置く事は実質的に不可能です。可能ならば、define-reader-ctorの呼び出しと、TAGの使用は異なるファイルに分離されることが望まれます。

Another issue about the current define-reader-ctor is that it modifies the global table of Gauche system, hence it is not modular. The code written by different people might use the same tags, and yield an unexpected result.   In future versions, Gauche may have some way to encapsulate the scope of TAG, although the author doesn't have clear idea yet. 現在のdefine-reader-ctorに関するもう1つの問題は、それが Gaucheシステムのグローバルテーブルを変更してしまうことで、それゆえにモジュール性が良くありません。複数人によって書かれたコードは同じタグを使っているかも知れず、期待されない結果を引き起こすかも知れません。作者にはまだ明確なアイデアがありませんが、将来のバージョンでは、 GaucheにはTAGのスコープをカプセル化する方法が導入されるかもしれません。

Input utility functions
.......................

 -- Function: port->string port
 -- Function: port->list reader port
 -- Function: port->string-list port
 -- Function: port->sexp-list port
     Generally useful input procedures.  The API is taken from scsh and STk. 便利な入力手続きです。APIはScshとSTkから取りました。

     port->string reads PORT until EOF and returns the accumulated data as a string. port->stringはPORTをEOFまで読み込み、読んだものを文字列として返します。

     port->list applies READER on PORT repeatedly, until READER returns an EOF, then returns the list of objects READER returned. Note that PORT isn't closed. port->listは手続きREADERをPORTに繰り返し適用し、結果をリストに蓄積します。READERがEOFを返したら蓄積されたリストを返します。 PORT自体はクローズされないことに注意してください。

     port->string-list is a port->list specialized by read-line, and port->sexp-list is a port->list specialized by read. port->string-listはport->listを read-lineで特定化したもので、 port->sexp-listはport->listを readで特定化したものです。

     If the input contains an octet sequence that's not form a valid character in the Gauche's native character encoding, port->string and port->string-list may return incomplete string(s). If you want to deal with binary data, consider using port->uvector in gauche.uvector (see Uvector block I/O). もし入力にGaucheの内部エンコーディングにおいて有効な文字をつくらないバイト列が含まれていた場合、port->stringとport->string-list の返り値には不完全な文字列が含まれている可能性があります。入力をバイナリデータとして扱いたい場合は、 gauche.uvectorのport->uvectorを使って下さい (Uvector block I/O参照)。

 -- Function: port-fold fn knil reader
 -- Function: port-fold-right fn knil reader
 -- Function: port-for-each fn reader
 -- Function: port-map fn reader
     Convenient iterators over the input read by READER.

     Since these procedures are not really about ports, they are superseded by generator-fold, generator-fold-right, generator-for-each and generator-map, respectively.  See Folding generated values, for the details.

     We provide these only for the backward compatibility. READERによって読まれる入力に対する便利な繰り返し手続きです。

     実際にはこれらの手続きはポートからの入力以外にも使えるため、それぞれ generator-fold, generator-fold-right, generator-for-each, generator-mapによって置き換えられました。詳しくはFolding generated valuesを参照してください。

     これらの手続きは後方互換性のためだけに提供されています。

Output
------

Layers of output routines
.........................

Gauche has quite a few output procedures which may confuse newcomers. The following table will help to understand how to use those procedures: Gaucheにはたくさんの出力手続きがあり、慣れないうちはどれを使えばよいか迷ってしまうかもしれません。次の表は様々な出力手続きを分類するものです。

Object writers
     Procedures that write out Scheme objects. Although there exist more low-level procedures, these are regarded as a basic layer of output routines, since it works on a generic Scheme object as a single unit. They come in two flavors:

       * Write-family procedures: write, write-shared, write-simple--these are to produce external representation of Scheme objects, which can be generally read back by read without losing information as much as possible (In a sense, this is somewhat similar to what is called ``serialization'' or ``marshalling'' in other programming language; you can write out a generic Scheme object on disk or to wire, and read it to get an object equivalent to the original one.  In Lisp-family languages, this is called read/write invariance and is a built-in feature. Note that some objects do not have this invariance in nature, so sometimes you need to make your own serializer/marshaller.). The external representation of most Scheme objects are the ones you write literal data in program, so this is the default way of writing Scheme objects out.

       * Display-family procedures: display, print, newline. These are to produce plain-text output suitable for human readers.

オブジェクトの出力
     Schemeオブジェクトを出力する手続きです。もっと低レベルの手続きもありますが、一般にはこの層が出力ルーチンの基本であるとみなされています。Schemeのオブジェクト単位で操作をするからです。この手続き群はさらに次の二つのグループに分かれます。

       * Write族手続き: write, write-shared, write-simple---これらは、Schemeオブジェクトの外部表現を出力します。出力されたものは一般に、 readを使って、可能な限り情報を失わずに読み戻すことができます (ある意味、これは他のプログラミング言語でシリアライズやマーシャライズと呼ばれている操作に似ています。一般のSchemeオブジェクトをディスクやネットワークにwriteして、それをreadすれば、元のオブジェクトと等価なオブジェクトが得られるわけです。 Lisp族言語では、これはread/write invarianceと呼ばれ、組み込みの機能となっています。但しオブジェクトによってはこの性質を持たないものもあり、そういうオブジェクトを扱う時は専用のシリアライザを書く必要があります。)。 Schemeオブジェクトの外部表現は、リテラルデータをプログラム中に記述するのと同じ書き方なので、これがSchemeオブジェクトを出力する際のデフォルトの表現になっています。

       * Display族手続き: display, print, newline. これらは人間に読みやすいプレーンテキストな出力を生成します。

High-level formatting output
     To produce output in specific width, alignment, etc: format. This corresponds to C's printf.

高レベル整形出力
     出力を指定の桁数に揃えたり、どちらかに寄せたり、といった書式を指定できる手続きが formatです。Cのprintfのようなものです。

Low-level type-specific output
     Procedures that deal with raw data.

       * To output a character or a byte: write-char, write-byte.

       * To output a string or an array of binary data: write-string, write-uvector.

       * To flush the output buffer: flush, flush-all-ports.

低レベル、特定の型用の出力
     「生」のデータを扱う手続きです。

       * 文字毎やバイト毎の出力: write-char, write-byte

       * 文字列やバイナリデータの配列の出力: write-string, write-uvector

       * 出力バッファのフラッシュ: flush, flush-all-ports

Output controls
...............

 -- Class: <write-controls>
     You can control several aspects of Lisp structure output via <write-controls> object.  The object output routines (e.g. write, display) and the high-level output routines (e.g. format) can take optional write-controls. Lisp構造の出力形式は、 <write-controls>オブジェクトによって制御することができます。 Lispオブジェクトを出力するルーチン(write, display等)や、高レベル出力手続き(format等)は出力制御オブジェクトを取ることができます。

     The following example may give you some ideas on what write controls can do: 以下の例で、出力制御の様子がわかると思います。

          (write '(1 10 100 1000)
                 (make-write-controls :base 16 :radix #t))
           prints (#x1 #xa #x64 #x3e8)

          (write (iota 100)
                 (make-write-controls :length 5))
           prints (0 1 2 3 4 ...)

     The make-write-controls procedure returns a write-controls object, which has the following slots (those slot names are taken from Common Lisp's print control variables): make-write-controls手続きは出力制御オブジェクトを作って返します。出力制御オブジェクトは以下のスロットを持ちます (これらのスロット名はCommon Lispの対応するプリント制御変数から取られました)。

      -- Instance Variable of <write-controls>: length
          If this slot has a nonnegative integer, it determines the maximum number of items displayed for lists and vectors (including uniform vectors). If the sequence has more elements than the limit, ... is printed in place.  If this slot is #f (default), sequence will be written out fully. このスロットが非負整数の場合、それはリストとベクタ(ユニフォームベクタを含む)の要素が表示される最大数を指定します。もしリストやベクタがその最大数より多くの要素を持っている場合、残りの要素は表示されず、代わりに ...が表示されます。このスロットが#f(デフォルト)であれば、すべての要素が表示されます。

      -- Instance Variable of <write-controls>: level
          If this slot has a nonnegative integer, it determines the maximum depth of the structure (lists and vectors) to be displayed.  If the structure has deeper node, it will be printed as #. If this slot is #f (default), no depth limit is enforced. このスロットが非負整数の場合、それは構造体(リストとベクタ)が表示される最大の深さを指定します。もし構造体がより深いノードを持っている場合、そのノードの代わりに#が表示されます。このスロットが#f(デフォルト)であれば、すべての要素が表示されます。

      -- Instance Variable of <write-controls>: base
          This slot must have an integer between 2 and 36, inclusive, and specifies the radix used to print exact numbers.  The default value is 10. このスロットは2以上36以下の整数でなければならず、正確な整数を印字する基数を指定します。デフォルトは10です。

      -- Instance Variable of <write-controls>: radix
          This slot must have a boolean value.  If it is true, radix prefix is always printed before exact numbers.  The default value is #f. このスロットは真偽値を持ちます。真であれば、正確な整数の前に常に基数プレフィクスが表示されます。デフォルトは#fです。

      -- Instance Variable of <write-controls>: pretty
          If this slot has true value, pretty printing is used, that is, newlines and indentations are inserted to show nested data structures fit in the specified width of columns. このスロットが真の値の場合、指定されたカラム幅内で、改行やインデントを適宜挿入してネストした構造を見やすく表示する、プリティプリント機能を使います。

      -- Instance Variable of <write-controls>: width
          If this slot has a nonnegative integer, it specifies the display column width used for pretty printing. このスロットが非負整数の場合、プリティプリントで使われる表示幅を指定します。

     A write-controls object is immutable.  If you need a controls object with a slight variation of an existing controls object, use write-controls-copy. 出力制御オブジェクトは変更不可です。もし既に存在する制御オブジェクトを少し変えたものが欲しければ、write-controls-copyが使えます。

     Note: When we introduced <write-controls> object in 0.9.5, we used slot names as print-length, print-pretty etc., mirroring Common Lisp's special variables.  However, the print- part is redundant, as it is a part of a class dedicated to print control.  So we changed the slot names as of 0.9.6. The procedures make-write-controls and write-controls-copy accepts both old and new names for the backward compatibility.  The old code that directly refers to the slots needs to be rewritten (we think there're a not a lot).  We'll drop the old name support in 1.0 release. 註: 0.9.5で<write-controls>オブジェクトを導入した際には、 Common Lispのスペシャル変数の名前をそのまま反映した print-length、print-pretty等をスロット名としていました。しかし出力制御オブジェクトの一部であることがわかっている以上、print-の部分は冗長です。そこで0.9.6からスロット名を変えました。互換性のために、make-write-controlsとwrite-controls-copyは古いスロット名でのキーワード引数も認識します。スロットを直接指定してアクセスしているコードは修正の必要があります。 1.0リリース時に古いスロット名のサポートを落とす予定です。

 -- Function: make-write-controls :key length level base radix pretty width
     Creates and returns a write-controls object. 出力制御オブジェクトを作って返します。

 -- Function: write-controls-copy controls :key length level base radix pretty width
     Returns a copy of another write-controls object CONTROLS. If keyword arguments are given, those values override the original values. 出力制御オブジェクトCONTROLSのコピーを返します。もしキーワード引数が与えられれば、その要素が置き換えられます。

Note: The high-level output procedures can be recursively called via write-object method.  In that case, the write controls of the root output call will be automatically inherited to the recursive output calls to the same port. 高レベル出力手続きはwrite-objectメソッドを経由して再帰的に呼ばれる可能性があります。その場合、大元の出力手続き呼び出しに渡された出力制御オブジェクトが、同じポートに対して出力する再帰的に呼ばれる出力手続きへと自動的に引き継がれます。

Object output
.............

For the following procedures, the optional PORT argument must be an output port, and when omitted, the current output port is assumed. 以下の手続きで、省略可能な引数PORTは出力ポートでなければなりません。省略された場合が現在の出力ポートが使われます。

Some procedures take PORT/CONTROLS argument, which can be either an output port or <write-controls> object.  For example, write takes up to two such optional arguments; that is, you can call it as (write obj), (write obj port), (write obj controls), (write obj port controls) or (write obj controls port).  When omitted, the port is assumed to be the current output port, and the controls is assumed to be the default controls. いくつかの手続きはPORT/CONTROLS引数を取ります。これは、出力ポートもしくは<write-controls>オブジェクトでなければなりません。例えば writeは二つまでそういった引数を取ります。すなわち、writeは以下のいずれの形式でも呼び出すことができます: (write obj)、(write obj port)、 (write obj controls)、(write obj port controls)、 (write obj controls port)。省略された場合、ポートは現在の出力ポート、出力制御についてはデフォルトの出力制御が使われます。

 -- Function: write obj :optional port/controls1 port/controls2
 -- Function: write-shared obj :optional port/controls1 port/controls2
 -- Function: write-simple obj :optional port/controls1 port/controls2
     [R7RS+ write] The write-family procedures are used to write an external representation of Scheme object, which can be read back by read procedure.  The three procedures differ in a way to handle shared or circular structures. write族の手続きは、Schemeオブジェクトの外部表現を出力します。外部表現は一般に、read手続きによって読み戻せば、元のオブジェクトと同等のオブジェクトとなります。この3つの手続きの違いは、共有構造および循環構造の扱いにあります。

     Write is circular-safe; that is, it uses datum label notation (#n= and #n#) to show cycles.  It does not use datum label notation for non-circular structures that are merely shared (see the second example). writeは循環構造に対して安全です。データに循環がある場合はデータラベル記法(#n=と#n#)を用いてそれを表現します。循環の無い、単に共有されているだけの構造についてはデータラベル記法を使いません (二番目の例参照)。

          (let1 x (list 1)
            (set-cdr! x x)   ; create a cycle
            (write x))
           => shows #0=(1 . #0#)

          (let1 x (list 1)
            (write (list x x)))
           => shows ((1) (1))

     Write-shared is also circular-safe, and it also shows shared structures using datum labels.  Use this if you need to preserve topology of a graph structure. write-sharedも循環構造に対して安全で、さらに共有構造もデータラベル記法で表示します。グラフ構造のトポロジーを維持する必要がある場合はこの手続きを使ってください。

          (let1 x (list 1)
            (write-shared (list x x)))
           => shows (#0=(1) #0#)

     Finally, write-simple writes out the object recursively without taking account of shared or circular structures.  This is fast, for it doesn't need to scan the structure before actually writing out. However, it won't stop when a circular structure is passed. 最後に、write-simpleはオブジェクトを、共有構造や循環構造を考慮せずに再帰的に表示します。これは出力前に共有構造の検出パスを走らせる必要がないので高速です。しかし、渡されたデータに循環があった場合は出力が止まらなくなります。

     When these procedures encounter an object of a user-defined class, they call the generic function write-object. これらの手続きが表示中にユーザ定義クラスのオブジェクトに出会った場合は、ジェネリックファンクションwrite-objectを呼び出します。

     Historical context: Write has been in Scheme standards, but handling of circular structures hasn't been specified until R7RS. In fact, until Gauche 0.9.4, write diverged for circular structures. SRFI-38 introduced the datum-label notation and write-with-shared-structure and write/ss procedures to produce such notation, and Gauche supported it. R7RS clarified this issue, and Gauche 0.9.4 followed. 歴史的経緯: writeは以前のScheme標準にもありましたが、循環構造があった場合の振る舞いはR7RSになるまで規定されていませんでした。実際、Gauche 0.9.4より前のwriteは、循環構造を渡されると停止しません。 SRFI-38はデータラベル記法および、それを表示するための write-with-shared-structureとwrite/ss手続きを導入し、 Gaucheもそれをサポートしていました。 R7RSでこの問題は明確にされ、Gaucheも0.9.4からそれに沿っています。

 -- Function: write-with-shared-structure obj :optional port
 -- Function: write/ss obj :optional port
 -- Function: write* obj :optional port
     [SRFI-38] These are aliases of write-shared above. これらは上記のwrite-sharedの別名です。

     Gauche has been used the name write* for long, which is taken from STklos.  SRFI-38 defines write-with-shared-structure and write/ss.  These names are kept for the backward compatibility. New code should use write-shared. Gaucheは、STklosから取ったwrite*という名前を長く使ってきましたが、 srfi-38によってwrite-with-shared-structureとwrite/ssが定義されました。これらの名前は互換性のためだけに残してあります。新たなコードにはwrite-sharedを使ってください。

 -- Function: display obj :optional port/controls1 port/controls2
     [R7RS write] Produces a human-friendly representation of an object OBJ to the output port.

     If OBJ contains cycles, display uses datum-label notation.

     When display encounters an object of a user-defined class, it calls the generic function write-object. オブジェクトOBJの人に読みやすい表現を、出力ポートに書き出します。

     OBJが循環構造を含んでいる場合は、データラベル記法を使って出力します。

     displayが表示中にユーザ定義クラスのオブジェクトに出会った場合は、ジェネリックファンクションwrite-objectを呼び出します。

          (display "\"Mahalo\", he said.")
           => shows "Mahalo", he said.

          (let ((x (list "imua")))
            (set-cdr! x x)
            (display x))
           => shows #0=(imua . #0#)

 -- Function: print expr ...
     Displays EXPRs (using display) to the current output port, then writes a newline. EXPR ... をdisplayを使って現在の出力ポートに表示し、最後に改行を書き出します。

 -- Function: pprint obj :key port controls width length level newline
     Pretty prints OBJ to PORT, which is defaulted to the current output port.  The same effect is achieved by passing the write procedure a write control with pretty slot setting to #t (in fact, it is how pprint is implemented), but this procedure provides more convenient interface when you want to play with the pretty printer.

     By default, pprint prints a newline after writing OBJ. You can suppress this newline by passing #f to NEWLINE keyword argument.

     To customize pretty printing, you can pass a write control object to the CONTROLS keyword argument (the pretty slot of CONTROLS is ignored; it'll always printed prettily). Furthermore, you can override width, length and level slots of CONTROLS.  If you omit CONTROLS, a reasonable default value is assumed. See Output controls, for the detail of write controls. OBJをPORTに整形出力(prettyprint)します。 PORTが省略された場合は現在の出力ポートが使われます。この手続きと同じ効果は、write手続きにprettyスロットを#tにした出力制御オブジェクトを渡すことでも得られます (実際、内部的にはpprintはそうやってwriteを呼び出しているだけです) が、手軽に整形出力を試してみたい場合にこの手続きは便利です。

     デフォルトでは、pprintはOBJを出力した後に改行します。この動作を抑制するにはNEWLINEに#fを渡してください。

     出力の整形をカスタマイズするには、CONTROLSキーワード引数に出力制御オブジェクトを渡します(渡された制御オブジェクトのprettyスロットは無視されます; 常に出力は整形されます)。さらに、出力制御オブジェクトの width、length、levelスロットを、それぞれのキーワード引数でオーバライドできます。 CONTROLSを省略した場合は適切なデフォルト値が使われます。出力制御の詳細についてはOutput controlsを参照してください。

          (pprint (make-list 6 '(gauche droite)))
           => prints
            ((gauche droite) (gauche droite) (gauche droite) (gauche droite)
             (gauche droite) (gauche droite))

          (pprint (make-list 6 '(gauche droite)) :width 20)
           => prints
            ((gauche droite)
             (gauche droite)
             (gauche droite)
             (gauche droite)
             (gauche droite)
             (gauche droite))

          (pprint (make-list 6 '(gauche droite)) :length 3)
           => prints
            ((gauche droite) (gauche droite) (gauche droite) ....)

          (pprint (make-list 6 '(gauche droite)) :level 1)
           => prints
            (# # # # # #)

 -- Method: write-object (obj <object>) port
     You can customize how the object is printed out by this method. このメソッドをつかって、オブジェクトをどのように印字するかをカスタマイズできます。

 -- Function: newline :optional port
     [R7RS base] Writes a newline character to PORT. This is equivalent to (write-char #\newline port), (display "\n" port).  It is kept for a historical reason. PORTに改行文字を書き出します。(write-char #\newline port)や (display "\n" port)と書いても同じことですが、歴史的な理由から残されています。

Formatting output
.................

 -- Function: format dest controls string arg ...
 -- Function: format controls dest string arg ...
 -- Function: format dest string arg ...
 -- Function: format controls string arg ...
 -- Function: format string arg ...
     [SRFI-28+] Format ARG ... according to STRING. This function is a subset of CommonLisp's format function, with a bit of extension.  It is also a superset of SRFI-28, Basic format strings (https://srfi.schemers.org/srfi-28/srfi-28.html). STRING の指示に従い、ARG ...をフォーマットします。この手続きはCommonLispのformatのサブセットに、Gauche独自の拡張を加えたものです。また、これはSRFI-28 "Basic format strings" のスーパーセットになっています (https://srfi.schemers.org/srfi-28/srfi-28.html)。

     The DEST argument specifies the destination; if it is an output port, the formatted result is written to it; if it is #t, the result is written to the current output port; if it is #f, the formatted result is returned as a string. DEST can be omitted, as SRFI-28 format; it has the same effects as giving #f to the DEST. DEST引数は出力先を指定します。それが出力ポートであれば、フォーマットされた結果はそのポートに書き出されます。PORTが#tであれば、結果は現在の出力ポートに書き出されます。PORTが#fであれば、結果は文字列としてformatから返されます。 DESTは省略することもできます。その場合は、destに#f を指定したのと同じ動作をします(SRFI-28のformat)。

     The CONTROLS argument is <write-controls> object (see Output controls), which affects the output of ~s and ~a.  This is Gauche's extension. CONTROLS引数は<write-controls>オブジェクトで、 ~sと~aの出力に影響を与えます (Output controls参照)。これはGauche独自の拡張です。

     (The unusual function signature of format is for the convenience; both DEST and CONTROLS are optional and they can appear in either order.) (formatの関数シグネチャはちょっと変わっていますが、これは便利さを優先したためです。PORTとCONTROLSはどちらも省略可能で、またどの順序でも指定できます。)

     STRING is a string that contains format directives. A format directive is a character sequence begins with tilde, `~', and ends with some specific characters.  A format directive takes the corresponding ARG and formats it.  The rest of string is copied to the output as is. STRINGはフォーマット指示子を含んだ文字列です。フォーマット指示子はチルダ`~'から始まり、特定の文字で終了する文字の並びで、それぞれのフォーマット指示子が対応するARGを取りフォーマットします。 STRING内のフォーマット指示子以外の文字列はそのまま出力されます。

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

     The format directive can take one or more PARAMETERS, separated by comma characters.  A parameter may be an integer or a character; if it is a character, it should be preceded by a quote character. Parameter can be omitted, in such case the system default value is used.  The interpretation of the parameters depends on the format directive. フォーマット指示子は一つ以上のコンマで区切られたパラメータを取ることもできます。パラメータは整数か文字です。文字の場合、クオート文字に続けてその文字を置きます。パラメータが省略された場合は既定値が使われます。パラメータの意味はフォーマット指示子毎に異なります。

     Furthermore, a format directive can take two additional flags: atmark `@' and colon `:'.  One or both of them may modify the behavior of the format directive. Those flags must be placed immediately before the directive character. さらに、フォーマット指示子は2種類のフラグ、`@' と `:' を取ることができます。これらの組合せでフォーマットの動作が変わります。フラグは (もしあれば)パラメータの後、指示子の文字の直前に置かれなければなりません。

     If a character `v' or `V' is in the place of the parameter, the value of the parameter is taken from the format's argument.  The argument must be either an integer, a character, or #f (indicating that the parameter is effectively omitted). パラメータの位置に文字 `v' か `V' を置くこともできます。その場合、パラメータの値が引数リストから取られます。対応する引数は整数か文字、または#fでなければなりません。#fの場合はそのパラメータが省略されたのと同じになります。

     Some examples:

     ~10,2s
          A format directive ~s, with two parameters, 10 and 2.

     ~12,,,'*A
          A format directive ~a, with 12 for the first parameter and a character `*' for the fourth parameter.  The second and third parameters are omitted.

     ~10@d
          A format directive ~d, with 10 for the first parameter and `@' flag.

     ~v,vx
          A format directive ~x, whose first and second parameter will be taken from the arguments.

     いくつかの例です。

     ~10,2s
          パラメータ10と2を伴う、フォーマット指示子~s。

     ~12,,,'*A
          第1パラメータに数値12、第4パラメータに文字`*'を取るフォーマット指示子~a。第2と第3のパラメータは省略されています。

     ~10@d
          フォーマット指示子~d。パラメータ10と`@'フラグがついています。

     ~v,vx
          フォーマット指示子~x。第1パラメータと第2パラメータは引数リストから取られます。

     The following is a complete list of the supported format directives. Either upper case or lower case character can be used for the format directive; usually they have no distinction, except noted. 以下にサポートされているフォーマット指示子を示します。フォーマット指示子の文字自体は大文字であっても小文字であっても構いません。特に断りのない限り両者は同じ動作をします。

     ~A
          Parameters: MINCOL,COLINC,MINPAD,PADCHAR,MAXCOL

          Ascii output.  The corresponding argument is printed by display. If an integer MINCOL is given, it specifies the minimum number of characters to be output; if the formatted result is shorter than MINCOL, a whitespace is padded to the right (i.e. the result is left justified). パラメータ: MINCOL,COLINC,MINPAD,PADCHAR,MAXCOL

          ASCII出力。対応する引数がdisplayを使ってフォーマットされます。整数がMINCOLに与えられた場合、それは出力される最小の文字数を指定します。引数のフォーマット結果がMINCOLより短ければ、空白が右に追加されます(つまり、左詰めになります)。

          The COLINC, MINPAD and PADCHAR parameters control, if given, further padding.  A character PADCHAR replaces the padding character for the whitespace.  If an integer MINPAD is given and greater than 0, at least MINPAD padding character is used, regardless of the resulting width.  If an integer COLINC is given, the padding character is added (after MINPAD) in chunk of COLINC characters, until the entire width exceeds MINCOL. COLINC、MINPAD、そしてPADCHARは更に細かいパディング方法を指定します。PADCHARに文字が与えられた場合、それが空白文字の代わりにパディング文字として使われます。MINPADに0以上の整数が与えられた場合、少なくともその数だけのパディング文字が追加されます。COLINCが指定された場合、追加されるパディング文字の数がCOLINCの倍数に調整されます。

          If atmark-flag is given, the format result is right justified, i.e. padding is added to the left. アトマーク `@' フラグが与えられた場合、結果は右詰めになります。

          The MAXCOL parameter, if given, limits the maximum number of characters to be written.  If the length of formatted string exceeds MAXCOL, only MAXCOL characters are written. If colon-flag is given as well and the length of formatted string exceeds MAXCOL, MAXCOL - 4 characters are written and a string `` ...'' is attached after it. MAXCOLパラメータは与えられていれば書かれる文字数の上限を指定します。フォーマット後の文字列の長さがMAXCOLを超えた場合、MAXCOL文字だけが書かれます。コロン `:' フラグが同時に与えられていれば、 MAXCOL - 4 文字が書かれた後、文字列`` ...''が書かれます。

               (format #f "|~a|" "oops")
                 => "|oops|"
               (format #f "|~10a|" "oops")
                 => "|oops      |"
               (format #f "|~10@a|" "oops")
                 => "|      oops|"
               (format #f "|~10,,,'*@a|" "oops")
                 => "|******oops|"
               (format #f "|~10,,,'☆a|" "oops")
                 => "|oops☆☆☆☆☆☆|"

               (format #f "|~,,,,10a|" '(abc def ghi jkl))
                 => "|(abc def gh|"
               (format #f "|~,,,,10:a|" '(abc def ghi jkl))
                 => "|(abc de ...|"

     ~S
          Parameters: MINCOL,COLINC,MINPAD,PADCHAR,MAXCOL

          S-expression output.  The corresponding argument is printed by write.  The semantics of parameters and flags are the same as ~A directive. パラメータ: MINCOL,COLINC,MINPAD,PADCHAR,MAXCOL

          S式出力。対応する引数がwriteを使ってフォーマットされます。パラメータの意味は~A指示子と同じです。

               (format #f "|~s|" "oops")
                 => "|\"oops\"|"
               (format #f "|~10s|" "oops")
                 => "|\"oops\"    |"
               (format #f "|~10@s|" "oops")
                 => "|    \"oops\"|"
               (format #f "|~10,,,'*@s|" "oops")
                 => "|****\"oops\"|"
               (format #f "|~10,,,'★s|" "oops")
                 => "|\"oops\"★★★★|"

     ~C
          Parameters: None

          Character output.  The argument must be a character, or an error is signaled.  If no flags are given, the character is printed with display. If atmark-flag is given, the character is printed with write. パラメータ: なし

          文字出力。対応する引数は文字でなければなりません(そうでなければエラーが報告されます)。フラグが無ければ文字はdisplayで表示されます。アトマークフラグが与えられた場合はwriteで表示されます。

     ~D
          Parameters: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          Decimal output.  The argument is formatted as an decimal integer. If the argument is not an integer, all parameters are ignored (after processing `v' parameters) and it is formatted by ~A directive. パラメータ: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          10進出力。対応する引数が10進数表記でフォーマットされます。もし引数が数値でなければ、全てのパラメータは(`v'パラメータの処理後に)無視され、引数は~Aでフォーマットされます。

          If an integer parameter MINCOL is given, it specifies minimum width of the formatted result; if the result is shorter than it, PADCHAR is padded on the left (i.e. the result is right justified).  The default of PADCHAR is a whitespace. もしMINCOLに整数が与えられたら、それが最小の文字数を指定します。結果の文字数がそれより少なければ、文字PADCHARが左に追加されます(右詰めになります)。 PADCHARが省略された場合は空白文字が使われます。

               (format #f "|~d|" 12345)
                 => "|12345|"
               (format #f "|~10d|" 12345)
                 => "|     12345|"
               (format #f "|~10,'0d|" 12345)
                 => "|0000012345|"

          If atmark-flag is given, the sign `+' is printed for the positive argument. アトマーク `@' フラグが与えられた場合、正の引数に対して `+' が先頭につけられます。

          If colon-flag is given, every INTERVAL-th digit of the result is grouped and COMMACHAR is inserted between them. The default of COMMACHAR is `,', and the default of INTERVAL is 3. コロンフラグ `:' が与えられた場合、結果の文字はINTERVAL文字毎にまとめられ、間に文字COMMACHARが挿入されます。デフォルトでは3文字毎にコンマが挿入されます。

               (format #f "|~:d|" 12345)
                 => "|12,345|"
               (format #f "|~,,'_,4:d|" -12345678)
                 => "|-1234_5678|"

     ~B
          Parameters: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          Binary output.  The argument is formatted as a binary integer. The semantics of parameters and flags are the same as the ~D directive. パラメータ: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          2進出力。対応する引数が2進数の整数としてフォーマットされます。パラメータの意味は~Dと同じです。

     ~O
          Parameters: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          Octal output.  The argument is formatted as an octal integer. The semantics of parameters and flags are the same as the ~D directive. パラメータ: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          8進出力。対応する引数が8進数の整数としてフォーマットされます。パラメータの意味は~Dと同じです。

     ~X
     ~x
          Parameters: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          Hexadecimal output. The argument is formatted as a hexadecimal integer. If `X' is used, upper case alphabets are used for the digits larger than 10.  If `x' is used, lower case alphabets are used. The semantics of parameters and flags are the same as the ~D directive. パラメータ: MINCOL,PADCHAR,COMMACHAR,INTERVAL

          16進出力。対応する引数が16進数の整数としてフォーマットされます。フォーマット指示文字に `X' が与えられた場合は `ABCDEF' が桁文字として使われ、 `x' が与えられた場合は `abcdef' が桁文字として使われます。パラメータの意味は~Dと同じです。

               (format #f "~8,'0x" 259847592)
                 => "0f7cf5a8"
               (format #f "~8,'0X" 259847592)
                 => "0F7CF5A8"

     ~F
          Parameters: WIDTH,DIGIS,SCALE,OVFCHAR,PADCHAR

          Floating-number output. If the argument is a real number, it is formatted as a decimal floating number. The WIDTH parameter defines the width of the field; the number is written out right-justified, with the left room padded with PADCHAR, whose default is #\space.  When the formatted output can't fit in WIDTH, OVFCHAR is output WIDTH times if it is given, or the entire output is shown if OVFCHAR is omitted. パラメータ: WIDTH,DIGIS,SCALE,OVFCHAR,PADCHAR

          浮動小数点数出力。引数が実数ならば、その十進小数表現が出力されます。 WIDTHパラメータは出力幅を指定します。もしフォーマット結果がその幅に足りなければ、左側にPADCHARが詰められます。PADCHARのデフォルトは#\spaceです。フォーマット結果がWIDTHを越える場合、OVFCHARが指定されていれば、 WIDTH個のOVFCHARが出力され、指定されていなければWIDTHを無視して必要なだけの桁数が出力されます。

               (format "~6f" 3.14)          => "  3.14"
               (format "~6f" 3.141592)      => "3.141592"
               (format "~6,,,'#f" 3.141592) => "######"
               (format "~6,,,,'*f" 3.14)    => "**3.14"

          The DIGITS parameter specifies number of digits shown below the decimal point.  Must be nonnegative integer.  When omitted, enough digits to identify the flonum uniquely is generated (same as using write and display---when you read back the number, you'll get exactly the same flonum.) DIGITSパラメータは小数点以下に表示される桁数を指定します。非負整数でなければなりません。省略された場合は、引数の浮動小数点数を一意に同定できる最小の精度で出力されます (writeやdisplayで出力した場合と同じです。その文字列をreadすれば、全く同じ浮動小数点数が得られます)。

               (format "~6,3f" 3.141592)    => " 3.142"
               (format "~6,0f" 3.141592)    => "    3."
               (format "~10,4f" 355/113)    => "    3.1416"
               (format "~10,4f" 3)          => "    3.0000"

          If the SCALE parameter is given, the argument is multiplied by (expt 10 scale) before printing. SCALEパラメータが与えられた場合、引数が表示前に(expt 10 scale)倍されます。

          If the @ flag is given, plus sign is printed before the non-negative number. @フラグが与えられると、引数が非負の場合にプラス記号が出力されます。

               (format "~8,3@f" 3.141592)   => "  +3.142"

          When DIGITS is smaller than the digits required to represent the flonum unambiguously, we round at DIGITS+1 position.  By default, it is done based on the value the flonum represents---that is, we choose the rounded value closer to the actual value of the flonum. It can sometimes lead to unintuitive results, however.  Suppose you want to round 1.15 at 100ths (that is, round to nearest 10ths).  Unlike elementary math class, it gives you 1.1.  That's because the flonum represented by 1.15 is actually tiny bit smaller than 1.15, so it's closer to 1.1 than 1.2.  We show it as 1.15 since no other flonums are closer to 1.15. DIGITSが浮動小数点数を一意に同定するための桁数に足りない場合は、小数点以下DIGITS桁に丸められます。デフォルトでは、この丸めは浮動小数点数の真の値に基づいて行われます。つまり、真の値に近い方の表現が選ばれます。これはたまに、非直感的な結果になることがあります。例えば1.15を1/100の位で丸めて(1/10単位にして)みると、小学校でやる算数と異なり、1.1が出力されます。この理由は、1.15と表記される浮動小数点数が実際には1.15よりわずかに小さく、従って 1.1により近いからです。本当は1.15でないものを1.15と表示しているのは、 1.15により近い浮動小数点数が他に無く、1.15が該当する浮動小数点数を一意に同定する最も短い表現だからです。

          But in casual applications, users may perplexed with this behavior. So we support another rounding mode, which we call notational rounding. It is based on the notation used for the flonum.  In that mode, rounding 1.15 to nearest 10ths yields 1.2.  You can get it by adding : flag. しかし日常的なアプリケーションでこういう振る舞いがあると、ユーザが混乱してしまうかもしれません。そこでもう一つ、表示に基づいた丸め(notational rounding)モードを用意しました。このモードでは、浮動小数点数の表示に基づいた丸めを行います。従って 1.15を1/100の位で丸めると1.2になります。このモードは:フラグで指定できます。

               (format "~6,1f" 1.15)  => "   1.1"
               (format "~6,1:f" 1.15) => "   1.2"

     ~$
          Parameters: DIGITS,IDIGITS,WIDTH,PADCHAR

          Floating-point formatting suitable for currency display.  The DIGITS parameter specifies the number of digits after the decimal point (default 2). The IDIGITS parameter specifies the minimum number of digits before the decimal point (default 1).  The WIDTH parameter specifies the mininum number of characters for the entire display, and if the number of printed characters are smaller than it, PADCHAR is displayed on the left to fill the blank.  The default of WIDTH is 0, and the default of PADCHAR is #\space.

          If @ flag is given and the argument is nonnegative, + is displayed.

          If : flag is given, the sign is displayed first, before any padding characters.

          If the argument isn't a real number, the object is formatted as if ~wD directive is given (where W is WIDTH).

          Gauche specific: The number is rounded with notational rounding (see the description of ~F above for the rounding mode). パラメータ: DIGITS,IDIGITS,WIDTH,PADCHAR

          通貨の表示に適した浮動小数点数フォーマット。 DIGITSは小数点以下に表示される桁数で、デフォルトは2です。 IDIGITSは小数点より前に表示される最小の桁数で、デフォルトは1です。 WIDTHパラメータは全体の最少文字数を指定し、表示すべき文字がそれより少ない場合は PADCHARが左側に足されます。WIDTHのデフォルトは0、 PADCHARのデフォルトは#\spaceです。

          @フラグが与えられた場合、非負の値に+符号が表示されます。

          :フラグが与えられた場合、符号があればそれはパディングより前に表示されます。

          引数が実数でない場合は、あたかも~wD (wはWIDTH) が指定されたかのように表示されます。

          Gauche特有の機能として、数値は表示に基づいた丸め(notational rounding)で丸められます。表示に基づいた丸めについては上の~Fの項の説明を参照してください。

               (map (cut format "~$" <>) '(1.23 4.5 6))
                 => '("1.23" "4.50" "6.00")

     ~?
          Recursive formatting.  The argument for this directive must be a string which is interpreted as a format string.  The arguments for the given directive should be given in the next argument, as a list.

               (format "~s~?~s" '< "~s ~s" '(a b) '>)
                 => "<a b>"

          If @ flag is given, the arguments for the given directive is taken from the following arguments.

               (format "~s~@?~s" '< "~s ~s" 'a 'b '>)
                 => "<a b>"

          再帰的フォーマッティング。この指示子はまず文字列を引数に取り、それをフォーマット文字列と解釈します。そしてさらに次の引数(それはリストでなければなりません)を、そのフォーマット文字列への引数と解釈します。

               (format "~s~?~s" '< "~s ~s" '(a b) '>)
                 => "<a b>"

          @フラグが与えられた場合は、最初の引数をフォーマット文字列と解釈した後で、続く引数を必要なだけそのフォーマット文字列の引数として使います。

               (format "~s~@?~s" '< "~s ~s" 'a 'b '>)
                 => "<a b>"

     ~*
          Parameter: COUNT

          Moves the argument counter COUNT times forward, effectively skips next COUNT arguments.  The default value of COUNT is 1, hence skip the next argument.  If a colon-flag is given, moves the argument counter backwards, e.g. ~:* makes the next directive to process last argument again.  If an atmark-flag is given, COUNT specifies absolute position of the arguments, starting from 0. パラメータ: COUNT

          引数のカウンタをCOUNTだけ後方にずらします。つまり、COUNT個の引数が無視されることになります。COUNTのデフォルト値は1です。コロンフラグが与えられた場合は引数カウンタを前方に動かします。例えば~:*は次のディレクティブが直前に使った引数を再び使うようにします。アトマークフラグが与えられた場合は、COUNTが引数の絶対位置を示します。 0が最初の引数です。

     ~~
     ~%
     ~t
     ~|
          Parameter: COUNT

          Output a #\~, #\newline, #\tab and #\page, respectively.    If COUNT is given, output the specified number of characters. パラメータ: COUNT

          それぞれ、文字#\~、#\newline、#\tab、#\pageをひとつ出力します。COUNTが与えられた場合はその個数出力します。

Low-level output
................

 -- Function: write-char char :optional port
     [R7RS base] Write a single character CHAR to the output port PORT. 文字CHARをポートに出力します。

 -- Function: write-byte byte :optional port
 -- Function: write-u8 byte :optional port
     [R7RS base] Write a byte BYTE to the port. BYTE must be an exact integer in range between 0 and 255.

     This is traditionally called write-byte, and R7RS calls it write-u8.  You can use either. 出力ポートに1バイトのデータBYTEを書き出します。 BYTEは0から255の間の正確な整数でなければなりません。

     これは伝統的にwrite-byteと呼ばれてきましたが、 R7RSではwrite-u8と名づけています。どちらも使えます。

 -- Function: write-string string :optional oport start end
     [R7RS base] If the optional START and END arguments are omitted, it is the same as (display string oport).  The optional arguments restricts the range of STRING to be written. STARTとEND引数が省略された場合は(display string oport)と同じです。それらが与えられた場合は、STRING中の指定範囲のみが出力されます。

 -- Function: flush :optional port
 -- Function: flush-all-ports
     Output the buffered data in PORT, or all ports, respectively.

     The function "flush" is called in variety of ways on the various Scheme implementations: force-output (Scsh, SCM), flush-output (Gambit), or flush-output-port (Bigloo). The name flush is taken from STk and STklos. R7RS calls this flush-output-port それぞれ、PORT、および全てのポートにバッファされているデータを全て書き出します。

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

Loading Programs
================

Loading Scheme file
-------------------

 -- Function: load file :key paths (error-if-not-found #t) environment ignore-coding
     [R7RS+] Loads FILE, that is, read Scheme expressions in FILE and evaluates them. An extension ``.scm'' may be omitted from FILE.

     If FILE doesn't begin with ``/'' or ``./'' or ``../'', it is searched from the system file search list, stored in a variable *load-path*. Or you can explicitly specify the search path by passing a list of directory names to the keyword argument PATHS.

     On success, load returns #t. If the specified file is not found, an error is signaled unless the keyword argument ERROR-IF-NOT-FOUND is #f, in which case load returns #f.

     By default, load uses a coding-aware port (see Coding-aware ports) so that the "coding:" magic comment at the beginning of the source file is effective. (See Multibyte scripts, for the details of the coding magic comment).  If a true value is given to the keyword argument IGNORE-CODING, load doesn't create the coding-aware port and directly reads from the file port.

     If a module is given to the keyword argument ENVIRONMENT, load works as if the given module is selected at the beginning of the loaded file.

     The current module is preserved; even select-module is called in FILE, the module in which load is called is restored afterwards.

     Gauche's load is upper-compatible to R5RS load, but R7RS load differs in optional arguments; see R7RS load.

     If you want to load a library file, it's better to use `use' (see Defining and selecting modules), or `require' described below. See Compilation, for difference between load and require. FILEをロードします。すなわち、FILEに書かれたScheme式を順次読み込んで評価します。FILEの拡張子 (``.scm'') は省略できます。

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

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

     デフォルトでは、loadはコーディング認識ポート(Coding-aware ports参照)を使ってソースファイルを読み込むので、ファイル先頭の"coding:" コメントによる文字エンコーディング指定が有効になります。 (codingコメントについてはMultibyte scriptsを参照)。但し、キーワード引数IGNORE-CODINGに真の値が渡された場合、 loadはcoding-aware portを作成せず、直接ファイルポートからソースを読み込みます。

     キーワード引数ENVIRONMENTにモジュールが渡された場合は、あたかもそのモジュールがファイルの先頭でselectされたかのように loadされます。

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

     GaucheのloadはR5RSのloadの上位互換ですが、 R7RSのloadは省略可能引数が異なります。R7RS load参照。

     ライブラリファイルをロードする場合は、`use' (Defining and selecting modules参照) を使うか、下に説明する`require' を使う方が良いでしょう。 loadとrequireの違いについてはCompilationを参照してください。

 -- Variable: *load-path*
     Keeps a list of directories that are searched by load and require.

     If you want to add other directories to the search path, do not modify this variable directly; use add-load-path, described below, instead. loadとrequireがファイルを探すディレクトリのリストを保持しています。

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

 -- Special Form: add-load-path path flag ...
     Adds a path PATH to the library load path list. PATH must be a literal string, for load paths must be known at compilation time. If PATH is a relative path, it is resolved relative to the current working directory, unless :relative flag is given. パスPATHをライブラリロードパスのリストに加えます。ロードパスはコンパイル時に確定している必要があるので、 PATHはリテラル文字列でなければなりません。 PATHが相対パスの場合、:relativeフラグが与えられていなければ、プロセスの現在のワーキングディレクトリからの相対と解釈されます。

     PATH doesn't need to exist; nonexisting paths in load path list are simply ignored.  However, if PATH does exist, add-load-path searches for architecture-dependent paths; see below. PATHは存在する必要はありません。ロードパスに存在しないディレクトリが含まれていても単に無視されるだけです。ただ、PATHが存在する場合、add-load-pathはアーキテクチャ依存パスも探します。後で詳しく説明します。

     Each FLAG argument may be one of the followings. 以下の値がFLAG引数として認識されます。

     :after
          Append PATH to the end of the current list of load paths. By default, PATH is added in front of the load path list. PATHを現在のロードパスリストの末尾に加えます。デフォルトでは、PATHはロードパスリストの先頭に加えられます。

     #t
          The same as :after.  This is for the backward compatibility. :afterと同じです。互換性のために認識されます。

     :relative
          Interpret PATH as a relative path to the directory of the current file, instead of the current working directory. If the current file can't be determined (e.g. evaluated in REPL, or the expression is read from a socket), this flag is ignored. PATHを、(カレントワーキングディレクトリではなく) 現在ロード中のファイルのあるディレクトリからの相対パスとして解釈します。現在ロード中のファイルが不明な場合 (REPLから評価されたり、ソケットから読まれたりしている場合) は、このフラグは無視されます。

     Use this form instead of changing *load-path* directly. This form is a special form and recognized by the compiler; if you change *load-path*, it is in effect at run time, and that may be too late for ``use'' or ``require''. ロードパスを変更したい場合、*load-path*を直接替えずにこのフォームを使って下さい。このフォームはコンパイル時に解釈されるのに対し、*load-path*を書き換えるコードは実行時に解釈されます。``use'' や ``require'' はコンパイル時のロードパスを使うので、*load-path*への変更は反映されないかもしれません。

     Furthermore, add-load-path looks for the architecture dependent directories under the specified path and if it exists, sets up the internal path list for dynamic loading correctly.   Suppose you have your Scheme module in /home/yours/lib, and that requires a dynamic loadable library.  You can put the library under /home/yours/lib/ARCH/, where ARCH is the value (gauche-architecture) returns (see Environment inquiry). Then you can have compiled libraries for multiple platforms and Gauche can still find the right library. 更に、add-load-pathはPATHの下にアーキテクチャ依存のディレクトリがないかどうかを探し、あればそれを内部の共有ライブラリサーチパスに追加します。例えばあなたが自分のSchemeモジュールを/home/yours/libに入れていて、それが共有ライブラリを必要としていたとします。手続きgauche-architecture (Environment inquiry参照)が返す値をARCHとして、共有ライブラリを/home/yours/lib/ARCH/に置いておくと、共有ライブラリはそこからロードされます。この方法を取ると、複数のプラットフォーム用に別々にコンパイルされた共有ライブラリを管理することができます。

 -- Function: load-from-port port
     Reads Scheme expressions from an input port PORT and evaluates them, until EOF is read.

     Note that unless you pass a coding-aware port to PORT, the "coding:" magic comment won't be handled. 入力ポートPORTから、EOFを読むまで繰り返しScheme式を読み込み評価します。

     PORTにコーディング認識ポートを渡さない限り、"coding:"コメントによる文字コード変換は行われないことに注意して下さい。

 -- Function: current-load-port
 -- Function: current-load-path
 -- Function: current-load-history
 -- Function: current-load-next
     These procedures allows you to query the current context of loading. They returns the following values when called inside a file being loaded:

     current-load-port
          Returns the port object from which this form is being loaded.

     current-load-path
          Returns the pathname of the file from which this form is being loaded. Note that this may return #f if the source of load is not a file.

     current-load-history
          Returns a list of pairs of a port and a line number (integer), representing the nesting of loads.  Suppose you load foo.scm, and from its line 7 it loads bar.scm, and from its line 18 it loads baz.scm.   If you call current-load-history in the file baz.scm, you'll get

               ((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))

     current-load-next
          Returns a list of remaining directories to be searched at the time this file is found.   Suppose the *load-path* is ("." "../lib" "/home/gauche/lib" "/share/gauche/lib") and you load foo.scm, which happens to be in ../lib/. Then, inside foo.scm, current-load-next returns:

               ("/home/gauche/lib" "/share/gauche/lib")

     When called outside of load, these procedures returns #f, #f, () and (), respectively. これらの手続きによって、現在のロードのコンテクストを知ることができます。ロードされているファイルの中でこれらの手続きを呼ぶと、次のような値が返されます。

     current-load-port
          現在のフォームがロードされている入力ポート。

     current-load-path
          現在のフォームがロードされているファイル。ロードのソースがファイルでない場合、この値は#f。

     current-load-history
          入力ポートと行番号のペアのリストで、ロードのネスティングを示したもの。例えばあなたがfoo.scmをロードし、そのファイルの7行目で bar.scmがロードされ、そのファイルの18行目でbaz.scmがロードされたとします。current-load-historyをbaz.scm中で呼ぶと、それは次のような値を返します。

               ((#<port "foo.scm"> . 7) (#<port "bar.scm"> . 18))

     current-load-next
          現在のファイルがロードされた時点での、ファイルサーチパスの残りを返します。例えば *load-path* が ("." "../lib" "/home/gauche/lib" "/share/gauche/lib")で、あなたがfoo.scmをロードしたところ、それが../lib/中に見つかったとしましょう。このとき、foo.scm中でcurrent-load-nextを呼べば

               ("/home/gauche/lib" "/share/gauche/lib")

          が返されます。

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

Load dynamic library
--------------------

 -- Function: dynamic-load file :key init-function
     Loads and links a dynamic loadable library (shared library) FILE. FILE shouldn't contain the suffix (``.so'' on most systems); dynamic-load adds it, for it may differ among platforms.

     The keyword argument INIT-FUNCTION specifies the initialization function name of the library in a string.  By default, if the file basename (without extension) is ``foo'', the initialization function name is ``Scm_Init_foo''.

     Usually a dynamic loadable library is provided with wrapping Scheme module, so the user doesn't have to call this function directly.

     There's no way to unload the loaded libraries. ダイナミックローダブルライブラリ(共有ライブラリ)FILEをロードしてリンクします。 FILEにはサフィックス(``.so'' 等) を含めないで下さい。システムによってサフィックスは異なるため、dynamic-loadがそれを追加します。

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

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

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

Require and provide
-------------------

Require and provide are a traditional Lisp way to ensure loading a library file only once.  If you require a feature for the first time, a library file that provides it is loaded and the fact that the feature is provided is memorized. Subsequent request of the same feature doesn't need to load the file. requireとprovideは、Lispでライブラリファイルを一度だけ読み込むことを保証するための伝統的な方法です。あるfeatureを最初にrequireすると、その機能を提供するライブラリファイルがロードされ、その機能が提供されたということが記憶されます。 2回め以降のそのfeatureのリクエストではファイルはロードされません。

In Gauche, the use syntax (see Using modules) hides the require mechanism under the hood so you hardly need to see these forms.  These are provided just in case if you want to do some non-trivial management of libraries and thus want to bypass Gauche's standard mechanism. Gaucheではuse構文 (Using modules参照) が requireのメカニズムをボンネットの下に隠してくれるので、これらの式を直接目にする必要はほとんどありません。もしあなたがちょっと変わった方式でライブラリを構成したくて、したがって Gaucheの標準的なメカニズムをバイパスしたい場合に限り、使うようにしてください。

 -- Special Form: require feature
     If FEATURE is not loaded, load it.  FEATURE must be a string, and it is taken as a file name (without suffix) to be loaded. This loading takes place at compile time.

     If you load SLIB module, require is extended.  see SLIB for details. FEATUREがまだロードされていなければロードします。FEATUREは文字列でなければなりません。それがそのまま(サフィックスを除く)ファイル名としてロードパスから探されます。requireの解釈はコンパイル時に行われます。

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

     If the loaded file does not contain provide form at all, the FEATURE is automatically provided, as if (provide FEATURE) is called at the end of the loaded file.  We call this autoprovide feature. もしロードされたファイルがprovideフォームを含んでいなかった場合、あたかもファイルの最後に(provide FEATURE)があったかのように、 FEATUREが自動的にprovideされます。これを autoprovide機能と呼んでいます。

     Note that require first sets the current module to an immutable module called gauche.require-base and then load the file.  The files loaded by require usually have define-module/select-module or define-library for the first thing, so you rarely notice the gauche.require-base module.  However, if the loaded file has toplevel defines or imports (use's) without specifying a module, you'll get an error like the following: requireは、ファイルをロードする前に現在のモジュールを gauche.require-baseという変更不可なモジュールにセットします。 requireされるファイルは通常、最初にdefine-module/select-module かdefine-libraryフォームを持つので、このgauche.require-baseモジュールを目にすることはほとんど無いでしょう。ただ、もしロードされたファイルがモジュールを指定すること無くトップレベルの変数を定義したり他のモジュールをimport(use)しようとした場合、次のようなエラーとなります。

          *** ERROR: Attempted to create a binding (a) in a sealed
          module: #<module gauche.require-base>

     Rationale: Generally it's difficult to guarantee when the specified file is loaded by require (because some other module may already have required it).  If we just used the caller's current module, there would be a couple of issues: The form define-module or define-library may not be visible from the current module, and you can't guarantee if the toplevel defines without specifying modules in the loaded file inserts the caller's current module, since they may have been loaded into a different module. It is just a bad idea to insert toplevel definitions or to import other modules without specifying which module you put them in.  So we made them an error. 理由: requireされているファイルがどのタイミングで読まれるかを正確にコントロールするのは難しいです(他のモジュールが既にrequireしているかもしれないので)。もし呼び出し側の現在のモジュールをそのまま使った場合、二つの問題が生じ得ます。(1)呼び出し側の現在のモジュールから、 define-moduleやdefine-libraryが見えているとは限りません。 (2)モジュールを指定しないトップレベル定義が呼び出し側の現在のモジュールに定義を追加することは保証されません(既に別のモジュールへと読みこまれているかもしれません)。モジュールを指定しないトップレベル定義やimportを持つファイルをrequireすることは、単に悪いアイディアです。したがってそういう事例はエラーとすることにしました。

 -- Function: provide feature
     Adds FEATURE to the system's provided feature list, so that the subsequent require won't load the same file again. FEATUREをシステムのprovideされたフィーチャーリストに加えます。以降、FEATUREがrequireされてもファイルはふたたびロードされません。

     Because of the autoproviding, i.e. require automatically provides the required feature, you hardly need to use a provide form explicitly.   There are a couple of scenarios that you may want to use a provide form: requireが要求された機能を自動的にprovideされたかのように扱うAutoprovide機能があるために、provideを明示的に呼ぶ必要はほとんど無いでしょう。PROVIDEを使いたいシチュエーションとしては次のようなものが考えられます。

       * To provide a feature (or features) that is/are different from the one that caused loading the file.

          Suppose feature X supersedes feature Y and providing compatible APIs of Y but with different implementation. Once X.scm is loaded, you don't want Y.scm to be loaded; so you want to tell the user that X.scm also provides the feature Y. Adding (provide "X") and (provide "Y") at the end of X.scm accomplish that.  (Note: If you add a provide form, require no longer autoprovides the feature, so you need to specify (provide "X") in X.scm explicitly to provide X as well.)

          Of course, this doesn't prevent users from loading Y.scm by specifying (require "Y") before (require "X"). It should be considered just as a workaround in a production where other solutions are costly, instead of a permanent solution. そのファイルをロードすることになったfeatureとは異なるfeature (複数可) を provideしたい場合。

          例えばfeature Xがfeature Yを置き換えるものだとします。 XはYのAPIを全て提供しますが、実装は異なります。この場合、 X.scmが一度ロードされたら、Y.scmをロードしてほしくないと思うでしょう。 X.scmに (provide "X") と (provide "Y") の両方を書いておくことで、X.scmがfeature Yもprovideすると明示すれば、それが実現できます。 (注：provideが呼ばれると、requireのautoprovide機能は抑制されるため、X.scm中で(provide "X")も指定する必要があります。)

          もちろんの方法では、ユーザが (require "Y") を (require "X") より先に書いてしまったらY.scmはロードされてしまいます。この方法は、現場において、永久的な解決が高コストになるような場合のとりあえずの回避処置と考えるべきでしょう。

       * To provide no features at all.  Passing #f as FEATURE prevents autoproviding by require without providing any feature.

          This should also be a temporary solution.  One possible scenario is that you are changing X.scm very frequently during development and you want (require "X") always causes loading the file.  Don't forget to remove (provide #f) when you release the file, though.  Besides, for interactive reloading, consider using gauche.reload (see Reloading modules) instead. featureを全くprovideしない。 FEATURE引数に#fを渡すことで、何のfeatureもprovideすることなく requireによるautoprovidingを抑制できます。

          これもまた、何らかの一時的な解決と考えるべきです。たとえば開発中に、 X.scmを頻繁に変更するために(require "X")が常にそのファイルをロードするようにさせたい、といった場合が考えられます。 X.scmのリリースの前に (provide #f) を消しておくことを忘れないように。また、インタラクティブにリロードしたいならば gauche.reload (Reloading modules参照) を使うことをおすすめします。

 -- Function: provided? feature
     Returns #t if FEATURE is already provided. FEATUREが既にprovideされていれば#tを返します。

Autoload
--------

 -- Macro: autoload file/module item ...
     Sets up ITEM ... to be autoloaded. That is, when an ITEM is referenced for the first time, FILE/MODULE is loaded before the ITEM is evaluated. This delays the loading of FILE/MODULE until it is needed. ITEM ... がオートロードされるように設定します。すなわち、次にITEMが参照された時、それが実際に評価される前にFILE/MODULEがロードされるようにします。これによって、必要とされる時までFILE/MODULEのロードを遅らせることができます。

     You can specify either a string file name or a symbol module name to FILE/MODULE.  If it is a string, the named file is loaded.  If it is a symbol, the named module is loaded (using the same rule as of use), then the binding of ITEM in the FILE/MODULE is imported to the module used the autoload (see Defining and selecting modules, for details of use). 引数FILE/MODULEには、文字列かシンボルを指定できます。文字列の場合はそのファイルがロードされます。シンボルの場合、その名のモジュールが(useと同じルールで)ロードされ、ITEMがFILE/MODULEからオートロードを呼び出したモジュールへとインポートされます。 (モジュールのuseの詳細についてはDefining and selecting modulesを参照して下さい)。

     ITEM can be either a variable name (symbol), or a form (:macro SYMBOL).  If it is a variable, the named file/module is loaded when the variable is about to be evaluated.  If it is the latter form, the named file/module is loaded when a form (SYMBOL arg ...) is about to be compiled, which enables autoloading macros. ITEMは変数名(シンボル)か、(:macro SYMBOL)というフォームでなければなりません。変数名の場合は、その変数が評価されようとした時に指定のファイル／モジュールがロードされます。後者のフォームの場合は、 (SYMBOL arg ...) というフォームがコンパイルされようとした時に指定のファイル／モジュールがロードされます。後者はマクロのオートロードになります。

     FILE/MODULE must define SYMBOL in it, or an error is signaled when FILE/MODULE is autoloaded. SYMBOLはFILE/MODULEの中で定義されなければなりません。そうでなければロード時にエラーが報告されます。

     The following is an example of autoloading procedures. 手続きのオートロードの例を示します。

          (autoload "foo" foo0 foo1)
          (autoload "bar" bar0 bar1)

          (define (foobar x)
            (if (list? x)
                (map bar0 x)
                (foo0)))

          (foobar '(1 2)) ; "bar" is loaded at this moment

          (foobar #f)     ; "foo" is loaded at this moment
          (foobar '(1 2)) ; この時点で "bar" がロードされる

          (foobar #f)     ; この時点で "foo" がロードされる

     Note that if you set to autoload macro, the file/module is loaded immediately when such form that uses the macro is compiled, regardless of the piece of the code is executed or not. マクロのオートロードを設定した場合、指定のファイルまたはモジュールは、そのマクロを使っているフォームが実行されるされないにかかわらず、コンパイラがそのフォームを見た時点でロードされることに注意してください。

Operations on libraries
-----------------------

There are several procedures you can use to check if certain libraries and/or modules are installed in the system.

In the following descriptions, PATTERN is either a symbol or a string.  If it is a symbol, it specifies a module name (e.g. foo.bar).  If it is a string, it specifies a partial pathname of the library (e.g. "foo/bar"), which will be searched under library search paths. You can also use glob-like metacharacters * and ? in PATTERN. ある特定のライブラリおよび/あるいはモジュールがシステムにインストールされているかどうかをチェックするための手続きがいくつかあります。

以下の説明の中では、PATTERNはシンボルまたは文字列です。シンボルである場合にはモジュール名(たとえば、foo.bar)を指定します。文字列である場合にはライブラリの部分パス(たとえば、"foo/bar")を指定します。これはライブラリサーチパス以下で検索されます。 PATTERNにはglobのメタ文字と同じ意味で * と ? を使うこともできます。

 -- Function: library-fold pattern proc seed :key paths strict? allow-duplicates?
     A basic iterator for library/module files. This procedure searches Scheme program files which matches PATTERN, under directories listed in PATHS (the default is the standard file load paths, *load-path*). For each matched file, it calls PROC with three arguments: the matched module or library name, the full path of the program file, and the state value.  SEED is used as the initial state value, and the value PROC returns is used as the state value for the next call of PROC.  The value returned from the last PROC becomes the return value of library-fold. ライブラリ/モジュールファイルに対する基本イテレータ。この手続きは PATTERN にマッチする Scheme のプログラムファイルを検索します。検索は PATHS (デフォルトは標準のファイルロードパス、 *load-path*)にリストされたディレクトリ以下でおこなわれます。マッチしたファイル毎に、PROC が、そのマッチしたモジュール名あるいはライブラリ名、そのプログラムファイルのフルパス、状態値、の3つの引数をともなって呼びだされます。SEEDは、初期状態値として使われ、 PROC が返す値は次の PROC の呼出し時に状態値として使われます。最後の PROC から返された値は library-fold の値として返ります。

     If PATTERN is a symbol and the keyword argument STRICT? is #t (which is the default), this procedure calls library-has-module? on the files whose name seems to match the given pattern of module name, in order to find out the file really implements the module.  It can be a time consuming process if you try to match large number of modules; you can pass #f to STRICT? to avoid the extra check. If PATTERN is a string, matching is done only for file names so STRICT? is ignored. PATTERN がシンボルでかつ、キーワード引数 STRICT? が #t (デフォルト値)であれば、この手続きはあたえられたモジュール名のパターンにマッチするようにみえるファイル名にたいして library-has-module? を適用して、本当にそのモジュールを実装しているファイルを見付けます。大量のモジュールにマッチさせようとすると、時間がかる可能性があります。 #f を STRICT? に渡すことで、余分なチェックを回避できます。 PATTERN が文字列だった場合、照合はファイル名に対してのみ行われ、 STRICT?は無視されます。

     By default, if there are more than one files that have the same name that matches PATTERN in PATHS, only the first one appears in PATHS is taken.  This gives you the file you'll get if you use require or use for that library.  If you want to iterate all of matching files, pass #t to the ALLOW-DUPLICATES? keyword argument.

     Here are some examples (the result may differ in your environment). デフォルトでは、PATH 中の PATTERN にマッチする同じ名前をもつ 2つ以上のファイルがあるばあい、PATH に最初に出現したものだけが採用されます。そのライブラリに対して、require あるいは use を用いたをつかった場合に得られるのはこのファイルです。すべてのマッチしたファイルについて反復したければ、ALLOW-DUPLICATES? キーワード引数に #t を渡します。

          (library-fold 'srfi-1 acons '())
           => ((srfi-1 . "../lib/srfi-1.scm"))

          (library-fold "srfi-1" acons '())
           => (("srfi-1" . "../lib/srfi-1.scm"))

          ;; Note the returned list is in a reverse order of
          ;; how acons is called.
          (library-fold 'srfi-1 acons '() :allow-duplicates? #t)
           => ((srfi-1 . "/usr/share/gauche/0.7.1/lib/srfi-1.scm")
             (srfi-1 . "../lib/srfi-1.scm"))

          ;; In the following cases, the module name doesn't match,
          ;; but the filename does.
          (library-fold 'srfi-19.* acons '())
           => ()

          (library-fold "srfi-19/*" acons '())
           => (("srfi-19/read-tai" . "../lib/srfi-19/read-tai.scm")
             ("srfi-19/format" . "../lib/srfi-19/format.scm"))

          ;; Finds available dbm implementations
          (library-fold 'dbm.* acons '())
           => ((dbm.cdb . "/usr/share/gauche/0.7.1/lib/dbm/cdb.scm")
             (dbm.gdbm . "../lib/dbm/gdbm.scm")
             (dbm.ndbm . "../lib/dbm/ndbm.scm")
             (dbm.odbm . "../lib/dbm/odbm.scm"))

          (library-fold 'srfi-1 acons '())
           => ((srfi-1 . "../lib/srfi-1.scm"))

          (library-fold "srfi-1" acons '())
           => (("srfi-1" . "../lib/srfi-1.scm"))

          ;; acons が呼ばれるのとは逆順のリストが
          ;; 返ることに注意してください
          (library-fold 'srfi-1 acons '() :allow-duplicates? #t)
           => ((srfi-1 . "/usr/share/gauche/0.7.1/lib/srfi-1.scm")
             (srfi-1 . "../lib/srfi-1.scm"))

          ;; 以下の場合は、モジュール名ではマッチしませんが、
          ;; ファイル名ではマッチします
          (library-fold 'srfi-19.* acons '())
           => ()

          (library-fold "srfi-19/*" acons '())
           => (("srfi-19/read-tai" . "../lib/srfi-19/read-tai.scm")
             ("srfi-19/format" . "../lib/srfi-19/format.scm"))

          ;; 利用可能な dbm の実装を見付けます
          (library-fold 'dbm.* acons '())
           => ((dbm.cdb . "/usr/share/gauche/0.7.4.2/lib/dbm/cdb.scm")
             (dbm.gdbm . "../lib/dbm/gdbm.scm")
             (dbm.ndbm . "../lib/dbm/ndbm.scm")
             (dbm.odbm . "../lib/dbm/odbm.scm"))

 -- Function: library-map pattern proc :key paths allow-duplicates? strict?
 -- Function: library-for-each pattern proc :key paths allow-duplicates? strict?
     Map and for-each version of iterator over matched libraries/modules.  See library-fold above for detailed operation of matching and the meanings of keyword arguments.

     PROC receives two arguments, the matched module/library name and full path of the file.  Library-map returns a list of results of PROC.  Library-for-each discards the results. マッチしたライブラリ/モジュール上のイテレータの map版および for-each版。照合操作とキーワード引数の詳細については上述の library-foldを参照してください。

     PROCは、マッチしたモジュール/ファイル名と、そのファイルのフルパスの 2 つの引数をうけとります。library-for-each は結果を捨てます。

          (library-map 'srfi-4 list :allow-duplicates? #t)
           => ((srfi-4 "../lib/srfi-4.scm")
                      (srfi-4 "/usr/share/gauche/0.7.1/lib/srfi-4.scm"))

          (library-map 'dbm.* (lambda (m p) m))
           => (dbm.odbm dbm.ndbm dbm.gdbm dbm.cdb)

 -- Function: library-exists? mod/path :key paths force-search? strict?
     Search a library or a module specified by MOD/PATH, and returns a true value if it finds one.  PATHS and STRICT? keyword arguments have the same meaning as library-fold.

     Unlike the iterator procedures above, this procedure first checks loaded libraries and modules in the calling process, and returns true if it finds MOD/PATH in it, without looking into the filesystem.   Passing #t to FORCE-SEARCH? keyword arguments skips the checking of loaded libraries and modules. MOD/PATH で指定されたライブラリあるいはモジュールを検索し、もしあれば、真値を返します。キーワード引数 PATHS および STRICT? は library-fold のそれと同じ意味です。

     上述のイテレータ手続きとはちがい、この手続きは呼び出しの過程で最初に既にロードされているライブラリおよびモジュールをチェックします。もしそのときに MOD/PATH を見つけたら、真値を返し、ファイルシステムを見にいくことはありません。キーワード引数 FORCE-SEARCH? に #t を渡せば、すでにロードされいるライブラリおよびモジュールのチェックはスキップされます。

 -- Function: library-has-module? path module
     Returns #t iff a file specified by PATH exists and appears to implement a module named by module.  PATH must be an actual filename. PATH で指定したファイルが存在し、かつ、module で名指しされたモジュールが実装されている場合でその場合に限り、#t を返します。 PATH は実際のファイル名でなければなりません。

          (library-has-module? "./test/foo/bar.scm" 'foo.bar)
           => #t ;; if ./test/foo/bar.scm implements module foo.bar.

     This procedure assumes a typical layout of the source code to determine if the given file implements the module, i.e., it reads the first form of the code and see if it is a define-module form that is defining the given module. この手続きは典型的なソースコードの配置を仮定して、与えられたファイルがそのモジュールを実装しているかどうかを決定します。すなわち、まずそのコードのフォームを読み、与えられたモジュールを定義している define-module フォームかどうかを見ます。

Sorting and merging
===================

The interface of sorting and merging API complies SRFI-95, with the following extensions: ソートとマージのインタフェースはSRFI-95に準拠し、さらに次の点で拡張されています。

  * You can sort not only lists, vectors and strings, but any sequence (an instance of <sequence>). リスト、ベクタ、文字列だけでなく、あらゆるシーケンス (<sequence>のインスタンス)をソートできます。

  * You can use both comparison procedures and comparators (see Basic comparators) to specify the order. 順序を指定するのに、比較関数も比較器(Basic comparators参照)も使うことができます。

  * You can omit comparison procedure; in that case, elements are compared with default-comparator. 比較関数を省略できます。省略された場合、要素同士はdefault-comparatorを使って比較されます。

 -- Function: sort seq :optional cmp keyfn
 -- Function: sort! seq :optional cmp keyfn
     [SRFI-95+] Sorts elements in a sequence SEQ in ascending order and returns the sorted sequence. sort! destructively reuses the original sequence.

     You can pass an instance of any <sequence> as SEQ; the same type of sequence will be returned.  For sort, the sequence type must have builder interface so that sort can build a new sequence of the same type (See Fundamental iterator creators, for the builder interface). For sort!, SEQ must be mutable.

     The sorting order is specified by cmp.  It must be either a procedure or a comparator. If it is a procedure, it must take two elements of SEQ, and returns #t if the first argument strictly precedes the second. If it is a comparator, it must have the comparison procedure. If omitted, default-comparator is used.

     If the optional argument KEYFN is given, the elements are first passed to it and the results are used for comparison. It is guaranteed that KEYFN is called at most once per element. シーケンスSEQの要素を昇順にソートし、ソートされたシーケンスを返します。 sort!は、オリジナルのシーケンスを破壊的に再利用します。

     SEQには<sequence>クラスのインスタンスを渡すことができます。同じ型のシーケンスが返されます。sortの場合、 SEQと同じ型のシーケンスを新たに作る必要があるので、 SEQの型はビルダーインタフェースを実装していなければなりません (ビルダーインタフェースについてはFundamental iterator creatorsを参照)。 sort!の場合、SEQは変更可能でなければなりません。

     ソート順はcmpで指定されます。これは手続きか比較器でなければなりません。手続きの場合は、SEQのふたつの要素を引数に取り、最初の要素が厳密に2番目の要素より先行する場合に #tを返します。比較器の場合は、比較手続きを持つものでなければなりません。省略された場合はdefault-comparatorが使われます。

     省略可能な手続き引数KEYFNが与えられた場合、要素はまずKEYFNに渡され、その結果が比較に使われます。 KEYFNは各要素に対してたかだか1回しか呼ばれないことが保証されます。

          (sort '(("Chopin" "Frederic")
                  ("Liszt" "Franz")
                  ("Alkan" "Charles-Valentin"))
                string<?
                car)
            => (("Alkan" "Charles-Valentin")
                ("Chopin" "Frederic")
                ("Liszt" "Franz"))

     In the current implementation, quicksort and heapsort algorithm is used when both CMP and KEYFN is omitted, and merge sort algorithm is used otherwise.  That is, the sort is stable if you pass at least CMP (note that to guarantee stability, CMP must return #f when given identical arguments.) SRFI-95 requires stability, but also requires CMP argument, so those procedures are upper-compatible to SRFI-95. 現在の実装では、CMPが省略された場合はクィックソートとヒープソートを使い、 CMPが与えられた場合はマージソートを使っています。すなわち、少なくともCMPを指定すれば、ソートは安定であることが保証されます (ただし、安定であるためには CMPは等しい引数が与えられた時に必ず#fを返さなければなりません)。 SRFI-95は安定性を要求しますが、同時にCMPが与えられることも要求するので、これらの手続きはSRFI-95の上位互換です。

     If you want to keep a sorted set of objects to which you add objects one at at time, you can also use treemaps (see Treemaps).  If you only need to find out a few maximum or minimum elements instead of sorting all the elements, heaps can be used (see Heap). なお、オブジェクトをひとつづつ集合に追加しつつ、常にソートされた状態に保ちたい場合は、treemapの使用を考えても良いでしょう (Treemaps参照)。また、最大または最小から数要素だけを必要とする場合は、全ての要素をソートするかわりにヒープが使えます (Heap参照)。

 -- Function: sorted? seq :optional cmp keyfn
     [SRFI-95+] Returns #t iff elements in SEQ are in sorted order. You can pass any sequence to SEQ. The optional argument CMP and KEYFN are the same as sort.

     In SRFI-95, CMP can't be omitted. SEQの要素がソートされている時に限り#tを返します。 SEQにはどんなシーケンスを渡すこともできます。省略可能引数CMPとKEYFNの意味はsortと同じです。

     SRFI-95ではCMPは必須になっています。

 -- Function: merge a b :optional cmp keyfn
 -- Function: merge! a b :optional cmp keyfn
     [SRFI-95+] Arguments A and B are lists, and their elements are sorted using a compare function or a comparator CMP.  These procedures merges two list and returns a list, whose elements are sorted using CMP.  The destructive version merge! reuses cells in A and B; the returned list is eq? to either A or B.

     In SRFI-95, CMP can't be omitted. 引数AとBはリストで、比較関数または比較器CMPによって既にソートされているものとします。これらの手続きは二つのソート済みリストをマージして、ソートされた一つのリストにします。merge!は破壊的バージョンで、 AとBのセルを再利用します。戻り値はAかBに対してeq?となります。

     SRFI-95ではCMPは必須になっています。

The following procedures are for the backward compatibility.  Their features are already covered by extended sort and sort!. 以下の手続きは後方互換性のために残されていますが、その機能は拡張されたsortおよびsort!によってカバーされています。

 -- Function: stable-sort seq :optional cmp keyfn
 -- Function: stable-sort! seq :optional cmp keyfn
     Sort a sequence SEQ, using stable sort algorithm. Arguments CMP and KEYFN are the same as sort and sort!.

     In fact, sort and sort! now uses stable algorithm when CMP is provided, so these procedures are redundant, unless you want to omit CMP and yet guarantee stable sort. 安定ソートアルゴリズムを使って、シーケンス SEQをソートします。 CMPFNとKEYFN引数はsortおよびsort!と同じです。

     実のところ、現在ではSORTとSORT!はCMPが与えられれば安定ソートアルゴリズムを使うので、これらの手続きはどうしてもCMPを省略しつつ安定ソートしたい、という場合でなければ使う必要はありません。

 -- Function: sort-by seq keyfn :optional cmp
 -- Function: sort-by! seq keyfn :optional cmp
 -- Function: stable-sort-by seq keyfn :optional cmp
 -- Function: stable-sort-by! seq keyfn :optional cmp
     Variations of sort procedures that takes a key extracting function. These are redundant now, for sort etc. takes optional KEYFN. 比較のためのキーを取り出す関数を取る、ソート手続きの別バージョンです。 sort等の手続きが省略可能なKEYFNを取るようになったので、現在ではこれらの関数は冗長です。

System interface
================

Gauche supports most of POSIX.1 functions and other system functions popular among Unix variants as built-in procedures. GaucheはPOSIX.1の多くの関数と、さまざまなUnixで共通して使われているシステム関数へのインタフェースを組込み手続きとして提供しています。

Lots of Scheme implementations provide some sort of system interface under various APIs.  Some are just called by different names (e.g, delete-file or remove-file or unlink to delete a file), some do more abstraction introducing new Scheme objects. Instead of just picking one of such interfaces, I decided to implement Gauche's system interface API in two layers; the lower level layer, described in this section, follows the operating system's API as close as possible.  On top of that, the higher-level APIs are provided, with considering compatibility to the existing systems. 多くのScheme実装はいろいろな形で何らかのシステムインタフェースを提供しています。名前だけが違うもの(例：delete-file、remove-file 、unlink) もあれば、新しいSchemeオブジェクトを導入して抽象化を行っているものもあります。Gaucheでは、既存のAPIのどれかをそのまま真似るのではなく、2つのレイヤを提供することにしました。この章で述べられる低レベルレイヤは、OSのインタフェースに似せたものを実装します。その上に、既存のシステムと互換性のある高レベルのインタフェースが実装されます。

The low level system interface has the name sys-NAME and usually correspond to the system call NAME. I tried to keep the interface similar whenever reasonable. sys-NAMEという名前を持つ手続きは、多くの場合、システムコールNAMEに対応しています。可能な限り、インタフェースが似るようにしました。

Gauche restarts a system call after it is interrupted by a signal by default. See Signal for the details. なお、システムコールがシグナルによって割り込まれた場合、そのシステムコールは原則としてリスタートされます。詳しくはSignalを参照して下さい。

If you are familiar with system programming in C, see also C to Scheme mapping, which shows correspondence between C standard library functions and Gauche procedures. Cによるシステムプログラミングに慣れている方は、 C to Scheme mappingも参考にして下さい。 Cの標準ライブラリとGaucheの手続きとの対応が示してあります。

Program termination
-------------------

Gauche has a few ways to terminate itself (other than returning from main).  The exit procedure is a graceful way with all proper cleanups.  sys-exit and sys-abort may be used in emergency where proper cleanup is impossible. Gaucheは(mainから返る以外に)自分自身を終了させる方法をいくつか提供しています。exit手続きが、正しいクリーンアップを行って優雅に終了する方法です。一方、正しいクリーンアップが不可能な非常事態には sys-exitかsys-abortを使います。

 -- Function: exit :optional (code 0) (fmtstr #f) args ...
     [R7RS+] Terminates the current process with the exit code CODE. CODE must be zero or positive exact integer. When a string is given to FMTSTR, it is passed to format (see Output), with the rest arguments ARGS, to produce a message to the standard error port (not the current error port; see Common port operations). 現在のプロセスを終了し、CODEを終了コードにします。 CODEはゼロもしくは正の正確な整数でなければなりません。 FMTSTR文字列が与えられた場合、それは残りの引数ARGSとともにformatに渡され、standard error portにメッセージとして印字されます (current-error-portではありません。 Common port operations参照。また、formatについては Output参照。)

     In fact, the exiting procedure is a bit more complicated. The precise steps of exiting is as follow. 実のところ、プロセス終了の手続きはもう少し複雑です。正確な段階を次に説明します。

      1. The value of parameter exit-handler is checked. If it is not #f, the value is called as a procedure with three arguments: CODE, FMTSTR, and a list of rest arguments.  It is the default procedure of exit-handler that prints out the message to the standard error port. If an error occurs within exit handler, it is captured and discarded.  Other exceptions are not caught. パラメータexit-handlerの値がチェックされます。もしそれが#fでなければ、それは3引数の手続きとみなされ、 CODE、FMTSTR、そして残りの引数のリストを引数として呼び出されます。実はメッセージを標準エラー出力に出しているのはデフォルトのexit-handlerです。終了ハンドラの中でエラーが起きた場合、そのエラーは捕捉され捨てられます。エラー以外の例外は捕捉されません。

      2. The AFTER thunks of the active dynamic winds are invoked. Any exceptions raised in AFTER thunks are captured and discarded. アクティブなdynamic-windのAFTERサンクが順に呼び出されます。 AFTERサンク中で発生した例外は捕捉され捨てられます。

      3. The clean-up handlers registered via C API Scm_AddCleanupHandler are invoked.  These are usually responsible for under-the-hood cleanup jobs for each application that embeds Gauche.  From the Scheme world there's not much to care. C APIのScm_AddCleanupHandlerで登録されたクリーンアップハンドラが呼ばれます。このハンドラは通常、Gaucheを内蔵しているアプリケーション特有のクリーンアップをするために使われます。Schemeの世界からはあまり気にする必要はないでしょう。

      4. The unclosed output buffered ports are flushed. まだ閉じられていない出力ポートのバッファが掃き出されます。

      5. The process exits with CODE as an exit code, via exit(3). exit(3)を呼び、プロセスはCODEを終了コードとして終了します。

     The exit-handler mechanism allows the application to hook its exit operation.   Note that it is not for simple cleanup jobs; dynamic-wind, guard or unwind-protect are more appropriate. exit-handler is for more specific use just upon application exit. For example, GUI applications may want to post a dialog instead of printing to stderr.

     For this reason, the library code shouldn't change exit-handler; only the application knows what to do when it exits.

     Another useful case is when you want to call a third-party code which calls exit inside.  In that case you may swap the exit-handler for the one that raises a non-error exception while calling the third-party code. Non-error exception isn't caught in exit, effectively interrupts the steps explained above.   (Yet the AFTER thunks of dynamic handlers are processed just like normal exception handling case.) Your application code can then capture the exception. You can use parameterize to swap exit-handler dynamically and thread-safely (see Parameters). exit-handlerのメカニズムはアプリケーションが終了処理をフックすることを可能にします。ただし、単純なクリーンアップ処理のためのものではありません (クリーンアップ処理には dynamic-wind, guardあるいはunwind-protectを使う方が適切です。) exit-handlerはもっと「アプリケーションの終了」という特定の事態に対して何か処理を行いたい場合に使います。例えばGUIアプリケーションはメッセージを標準エラー出力ではなくダイアログとして表示する、というようなことです。

     従って、ライブラリコードはexit-handlerに触るべきではありません。アプリケーションの終了時に何をすべきかを知っているのはアプリケーション自身なのですから。

     別の使いどころとしては、サードパーティ製のコードで中でexitが呼ばれる可能性のあるものを安全に呼び出したいという場合があります。そのコードを呼び出している間だけ、exit-handlerをエラーではない例外を発生させる手続きへと差し替えます。エラーではない例外はexitでは捕捉されないので、実質的に上で説明したような終了処理のステップは中断されることになります (但し、ダイナミックハンドラのAFTERサンクは通常の例外発生時と同じように処理されます)。アプリケーションコードの方でその例外を捕捉してやればよいのです。 parameterizeを使えばexit-handlerを動的に、かつスレッドセーフに差し替えることが容易になります (Parameters参照)。

          (guard (e [(eq? e 'exit-called) (handle-exit-as-desired)])
            (parameterize ((exit-handler (lambda (c f a) (raise 'exit-called))))
              (call-third-party-library)))

     Generally, calling exit while other threads are running should be avoided, since it only rewinds the dynamic handlers active in the calling threads, and other threads will be killed abruptly. If you have to do so for some reason, you may be able to use exit-handler to tell to other threads that the application is exiting.  (There's no general way, and Gauche doesn't even have a list of all running threads; it's application's responsibility). 一般的に、他のスレッドが走っている時にexitを呼ぶことは推奨されません。 exit手続きは該当スレッド上でアクティブなダイナミックハンドラしか巻き戻さないので、他のスレッドはいきなり終了させられてしまいます。しかしexitを呼ばざるを得ない場合には、 exit-handlerを使って他のスレッドにアプリケーションが終了しつつあることを伝えられるかもしれません (但しGauche自身は走っているスレッドのリストといった情報は持っていないので、アプリケーションごとに固有のロジックを実装する必要があります。)

     Note on design: Some languages integrates exit handling into exception handling, treating exit as a kind of exception. It is a tempting idea, so much that we've tried it.  It didn't work out well in Gauche; a big annoyance was that when an AFTER thunk raised an exception during rewinding dynamic-winds, it shadowed the original exit exception. 設計に関する覚書: 終了を一種の例外とすることで、終了処理を例外処理と統合している言語もあります。良いアイディアに思えたので我々もそのような実装を試してみましたが、 Gaucheではうまくいきませんでした。大きな理由のひとつは、 dynamic-windの巻き戻し中にAFTERで例外が発生すると、その例外がもともとの「終了」例外を隠してしまうことでした。

 -- Function: exit-handler :optional new-handler
     When called without argument, returns the value of the current exit handler.  When called with an argument, sets NEW-HANDLER as the value of the exit handler, and returns the previous value of the exit handler.    NEW-HANDLER must be a procedure that takes three arguments, or #f.

     The value of exit handler is thread-specific, and the default value is inherited from the value of the current exit handler of the parent thread.  exit-handler can be used as if it's a parameter in the parameterize macro (see Parameters). 引数なしで呼ばれた場合、現在のexit handlerの値を返します。引数つきで呼ばれた場合は、NEW-HANDLERを現在のexit handlerの値とし、以前の値を返します。NEW-HANDLERは3つの引数をとる手続きか、#fでなければなりません。

     exit handlerの値はスレッドごとに固有で、デフォルト値はスレッドが作られた時点の親スレッドのexit handlerの値から引き継がれます。 exit-handlerはあたかもパラメータのようにparameterizeマクロで使うことができます (Parameters参照)。

 -- Function: sys-exit code
     [POSIX] Terminates the current process with the exit code CODE. CODE must be zero or positive exact integer. This procedure calls _exit(2) directly. No cleanup is done.  Unflushed file output is discarded. 現在のプロセスを終了し、CODEを終了コードにします。 CODEはゼロもしくは正の正確な整数でなければなりません。この手続きは_exit(2)を直接コールします。クリーンアップは一切行われません。フラッシュされてないファイルバッファの内容は捨てられます。

 -- Function: sys-abort
     [POSIX] Calls POSIX abort().  This usually terminates the running process and dumps core.  No cleanup is done. POSIXのabort()を呼びます。通常、現在のプロセスは終了され、コアダンプされます。クリーンアップは一切行われません。

Command-line arguments
----------------------

The recommended way to get command-line arguments passed to a Scheme script is the argument to the main procedure (see Writing Scheme scripts).  For the convenience, there are a few ways to access to the command-line arguments globally. Schemeスクリプトに渡されたコマンドライン引数を受け取るには、 MAIN関数の引数を使うのが推奨される方法です (see Writing Scheme scripts)。ただ、簡便のために、どこからでもコマンドライン引数にアクセスできるインターフェースもいくつか用意してあります。

Note that a Scheme code may not always be called with a command-line argument---for example, an application-embedded Scheme scriptlet may not have the concept of command-line at all.  That's why the main argument is preferred, since it is an explicit interface; if main is called, the caller is responsible to pass in something. Schemeコードが実行される時、常にコマンドライン引数が存在するわけではないことに注意してください。例えばアプリケーションに埋め込まれたSchemeコード片にとっては、コマンドライン引数は意味を持ちません。なるべくmain関数の引数を使うべき、というのはそのためです。main関数の引数は明示的だからです。 mainが呼ばれたなら、呼び出す側は意識してコマンドライン引数を渡しているわけですから。

That said, here are how to access the command-line arguments: この注意を念頭に置いておいてください。以下にコマンドライン引数にアクセスする方法を示します。

 -- Parameter: command-line
     [R7RS+][SRFI-193] When called without arguments, it returns a list of command-line arguments, including the program name in the first element, as a list of strings. 引数なしで呼ばれた場合は、コマンドライン引数のリストを文字列のリストとして返します。最初の要素はプログラム名です。

     When Gauche is used as an embedded language, it is application's discretion to set up this parameter.  If the application does nothing, this parameter will have an empty list.  When you use this parameter in the library you have to deal with that situation. Gaucheが埋め込み言語として使われた場合、このパラメータの値はアプリケーションの設定に依存します。アプリケーションが何もしていなければ、このパラメータの値は空リストとなります。ライブラリ中でこのパラメータの値を使う場合は、その可能性を念頭に置いてください。

     When called with one argument, a list of string, it will become the new value of the parameter.  You can use parameterize to switch the value of command-line dynamically (see Parameters).  Note that R7RS only defines zero-argument command-line. 一つの引数で呼び出すこともできます。その場合、引数は文字列のリストでなければなりません。渡された引数が、新たなパラメータの値となります。 parameterizeを使ってcommand-lineの値を動的に変えることができます (Parameters参照)。 R7RSは、ゼロ引数のcommand-lineのみ定義しています。

 -- Parameter: script-file
     [SRFI-193] While a Scheme program is run as a script, this parameter holds the absolute path of the Scheme source file being run.  Run as a script means either it is passed as the script file to gosh, or the file is directly loaded from the toplevel REPL.

     If this function is called from the context outside of script execution, #f is returned. Schemeプログラムがスクリプトとして実行されている期間中、このパラメータはそのスクリプトの絶対パスを保持しています。スクリプトとして実行とは、goshにスクリプトファイルとして渡されるか、トップレベルREPLから直接loadされる場合です。

     この関数がスクリプト実行期間中以外に呼ばれた場合は#fが返ります。

 -- Variable: *program-name*
 -- Variable: *argv*
     These variables are bound to the program name and the list of command-line arguments, respectively.  In Gauche scripts that are invoked by gosh command, *program-name* is usually the name of the script, as given to gosh.  When gosh is invoked interactively, *program-name* is gosh itself.

     These variables exist in user module.

     They are mainly kept for the backward compatibility. These names are compatible to STk, but other Scheme implementation uses different conventions.  The command-line parameter above is preferred.

     When Gauche is used as an embedded language, it's the host application's discretion to set up these variables.  Generally, you can't count on those variables to exist.  That's another reason you should avoid using them. これらの変数はそれぞれ、プログラム名および、コマンドライン引数のリストに束縛されます。 goshを使ってGaucheスクリプトを実行しているなら、*program-name*は (goshに与えられたとおりの) スクリプト名になっています。goshがインタラクティブREPLとして起動された場合は*program-name*はgosh自身です。

     これらの変数はuserモジュールにあります。

     これは主として互換性のためだけに残されています。STkと互換な名前ですが、他のScheme実装へはポータブルではありません。上のcommand-lineパラメータの方がお勧めです。

     Gaucheが埋め込み言語として使われている場合、これらの変数を設定するかどうかはホストアプリケーションに任されます。一般には、これらの変数が必ず存在しているとは限りません。これもまた、他の方法を使うべき理由です。

Environment inquiry
-------------------

 -- Function: sys-getenv name
     [POSIX] Returns the value of the environment variable NAME as a string, or #f if the environment variable is not defined.

     For the portable code, you may want to use SRFI-98's get-environment-variable (see Accessing environment variables), which is also in R7RS.

     Note: Most systems doesn't guarantee thread-safety of getenv while environment is being modified; however, Gauche mutexes environment accessing/mutating APIs internally, so you don't need to worry about the race condition as far as you use Gauche procedures. 環境変数NAMEの値を文字列で返します。もしNAMEが定義されていなければ、 #fが返ります。

     ポータブルなコードでは、SRFI-98およびR7RSのget-environment-variableを使うのが良いでしょう(Accessing environment variables参照)。

     註: 多くのシステムでは、環境が変更されている最中のgetenvのスレッド安全性を保証していませんが、Gaucheは内部的に環境へのアクセスと変更のAPIを排他制御しているので、 Gaucheの手続きを使っている限りにおいてはスレッド安全です。

 -- Function: sys-environ
     Returns the current environment as a list of strings.  Each string is a form of NAME=VALUE, where NAME is the name of the environment variable and VALUE is its value.  NAME never contains a character #\=.  This is useful when you want to obtain the all environment variables of the current process. Use sys-getenv if you want to query a specific environment variable. 現在の環境を文字列のリストとして返します。それぞれの文字列は NAME=VALUEというフォーマットになっています。ここでNAMEは環境変数名、VALUEはその値です。NAMEが文字#\=を含むことはありません。この手続きは現在のプロセスの環境変数をすべて取得したい場合に便利です。特定の環境変数の値が欲しい場合には sys-getenvを使ってください。

 -- Function: sys-environ->alist :optional envlist
     A convenience procedure for sys-environ.  When the list of environment strings (like what sys-environ returns) is given to ENVLIST, this procedure splits name and value of each environment variable and returns an assoc list. sys-environの便利版。環境リスト(sys-environが返すような形式のもの)をENVLISTとして与えると、この手続きは各環境変数を名前と値に分けて連想リストにして返します。

     When ENVLIST is omitted, this procedure calls sys-environ to get the current environment variables. ENVLISTを省略すると、この手続きはsys-environを呼んで現在の環境変数を取得します。

     For the portable code, you may want to use SRFI-98's get-environment-variables (see Accessing environment variables), which is also in R7RS. ポータブルなコードでは、SRFI-98およびR7RSの get-environment-variables (Accessing environment variables参照), を使うのが良いでしょう。

          (sys-environ->alist '("A=B" "C=D=E"))
            => (("A" . "B") ("C" . "D=E"))

 -- Function: sys-setenv name value :optional overwrite
 -- Function: sys-putenv name=value
     SYS-SETENV inserts an environment variable NAME with the value VALUE. Both NAME and VALUE must be a string. If the optional argument OVERWRITE is #f (default), the environment is untouched if a variable with NAME already exists.   If OVERWRITE is true, the variable is overwritten. SYS-SETENVは環境変数NAMEとその値VALUEをプロセスの実行環境に挿入します。ただし、省略可能引数OVERWRITEが#f(デフォルト値)の場合、 NAMEが既に存在したら実行環境は変更されません。 OVERWRITEが真の値であれば、環境変数は上書きされます。

     For sys-putenv, you have to give a single string with the form of NAME=VALUE, that is, concatenating NAME and VALUE with #\=.  If the environment variable with the same name exists, it will be overwritten. sys-putenvでは、環境変数を名前と値を#\=でつないだ NAME=VALUEという形式で指定します。同名の環境変数が既に存在する場合は常に上書きされます。

     These API reflects POSIX setenv(3) and putenv(3). However, unlike putenv(3), modifying the string passed to sys-putenv afterwards won't affect the environment. これらのAPIはPOSIXのsetenv(3)とputenv(3)のインタフェースを反映しています。しかし、putenv(3)と違って sys-putenvに渡した文字列はコピーされるので、後でその文字列を破壊的変更してもプロセスの実行環境に影響はありません。

     These procedures are only available when a feature identifier gauche.sys.setenv exists.  Use cond-expand (see Feature conditional) to check their availability. これらの手続きは機能識別子gauche.sys.setenvがある場合のみ使えます。下の例のようにcond-expandで使えるかどうかチェックしてください (Feature conditional参照)。

          (cond-expand
           [gauche.sys.setenv
             ... use sys-setenv or sys-putenv ... ]
           [else
             ... fallback code ...])

     These procedures are thread-safe as far as you access and modify the environment through Gauche API. これらの手続きは、他の方法で環境変数を変更しない限り、スレッドセーフです。

 -- Function: sys-unsetenv name
 -- Function: sys-clearenv
     Remove the environment variable with NAME (sys-unsetenv), or all environment variables.  sys-clearenv is handy when you need to run subprocess, but you cannot trust the inherited environment.

     These procedures are only available when a feature identifier gauche.sys.unsetenv exists.  Use cond-expand (see Feature conditional) to check their availability. sys-unsetenvは環境変数NAMEを、また sys-clearenvは全ての環境変数をプロセスの実行環境から取り除きます。 sys-clearenvは、子プロセスを走らせる際に予期せぬ環境変数を注入されないようにするのに便利です。

     これらの手続きは機能識別子gauche.sys.unsetenvがある場合のみ使えます。下の例のようにcond-expandで使えるかどうかチェックしてください (Feature conditional参照)。

          (cond-expand
           [gauche.sys.unsetenv
             ... use sys-unsetenv or sys-clearenv ... ]
           [else
             ... fallback code ...])

SRFI-98 (see Accessing environment variables) also defines a subset of above procedures to access to the environment variables. Portable programs may want to use them instead. SRFI-98 (Accessing environment variables参照) にも、環境変数を読み出すための、上記の手続きのサブセットにあたるものが定義されています。ポータブルなコードにしたければそちらも見てみてください。

 -- Function: gauche-version
 -- Function: gauche-architecture
 -- Function: gauche-library-directory
 -- Function: gauche-architecture-directory
 -- Function: gauche-site-library-directory
 -- Function: gauche-site-architecture-directory
     These functions returns a string that tells information about Gauche runtime itself. これらの手続きはGaucheランタイムの情報を文字列で返します。

 -- Function: version-alist
     [SRFI-176] Returns an alist of various runtime information. The information is the same as what displayed with gosh -V. 様々なランタイムの情報をalistで返します。 gosh -Vで表示される情報と同じです。

 -- Function: sys-available-processors
     Returns the number of available processors on the running platform. Return value is always a positive exact integer.  If Gauche can't get the information, 1 is returned.

     However, If an environment variable GAUCHE_AVAILABLE_PROCESSORS is defined and its value can be interpreted as a positive integer, then the value is returned regardless of what the hardware/OS tells. 現在Gaucheが走っているプラットフォームで使えるプロセッサの個数を返します。戻り値は常に正の正確な整数です。Gaucheがこの情報を入手できなかった場合は 1が返ります。

     但し、もし環境変数GAUCHE_AVAILABLE_PROCESSORSが定義されていて、その値が正の整数と解釈できるものだった場合、ハードウェア/OSがどう言おうと環境変数の値が返されます。

Filesystems
-----------

System calls that deal with filesystems. See also Filesystem utilities, which defines high-level APIs on top of the procedures described here. ファイルシステムに関するシステムコール群です。ここで述べる手続きの上に、より高レベルなAPIがモジュールfile.utilとして実装されています。Filesystem utilitiesを参照して下さい。

Directories
...........

See also Directory utilities for high-level API. 高レベルAPIに関してはDirectory utilitiesも参照して下さい。

 -- Function: sys-readdir path
     PATH must be a string that denotes valid pathname of an existing directory.  This function returns a list of strings of the directory entries.  The returned list is not sorted.  An error is signaled if PATH doesn't exists or is not a directory. PATHは存在するディレクトリを示すパス名でなければなりません。この手続きはディレクトリの全エントリを文字列のリストとして返します。リストはソートされません。PATHが存在しなかったり、ディレクトリでなかった場合はエラーとなります。

 -- Function: glob pattern :key separator folder sorter
 -- Function: sys-glob pattern :key separator folder sorter
     Provides a traditional Unix glob(3) functionality; returns a list of pathnames that matches the given PATTERN. 伝統的なUnixのglob(3)の機能を提供します。この手続きはPATTERNとマッチするパス名のリストを返します。

     This feature used to be a wrapper of system-provided glob function, hence it was named sys-glob.  However, as of Gauche version 0.8.12, it was reimplemented in Scheme on top of other system calls, to overcome incompatibilities between platforms and for the opportunity to put more functionalities.  So we renamed it glob. The old name sys-glob is kept for compatibility, but new programs should use glob. この機能は、かつてはプラットフォームが提供するglob関数をラップするもので、sys-globという名前でした。しかし、プラットフォーム間の非互換性を解消し機能の追加を容易にするために、Gauche 0.8.12以降、システムコールの上にSchemeで再実装されています。そのため、globと改名してあります。古い方の名前sys-globは互換性のために残してありますが、新たにプログラムを書くときはglobを使ってください。

     The PATTERN argument may be a single glob pattern, or a list of glob patterns.  If a list is given, pathnames that matches any one of the pattern are returned.  If you're a unix user, you already know how it works. 引数PATTERNは単一のグロブパターンもしくは、グロブパターンのリストです。リストが渡されたときには、最低1つのパターンにマッチするパス名がすべて返されます。 Unixのユーザならglobの動作は馴染み深いものでしょう。

          gosh> (glob "*.scm")
          ("ext.scm" "test.scm")
          gosh> (glob "src/*.[ch]")
          ("src/ext.c" "src/ext.h")
          gosh> (glob '("*.scm" "src/*.c"))
          ("ext.scm" "src/ext.c" "test.scm")

     Unlike shell's glob, if there's no matching pathnames, () is returned. シェルのグロブとはちがって、マッチするパス名がないときは、()が返ります。

     By default, the result is sorted using built-in sort procedure (see Sorting and merging).  You can pass alternative procedure to SORTER argument; it should be a procedure that takes single list, and returns a sorted list.  It can also be #f, in which case the result isn't sorted at all. デフォルトでは、結果は組み込みのsort手続きによりソートされて返されます (Sorting and merging参照)。SORTERキーワード引数で代わりのソート手続きを指定できます。SORTER手続きはひとつのリストを受け取り、それをソートして返します。また、SORTER引数に#fを渡すと、結果はソートされずに返されます。

     In fact, globbing is a very useful tool to search hierarchical data structure in general, not limited to the filesystems. So the glob function is implemented separately from the filesystem.  Using keyword arguments, you can glob from any kind of tree data structure. It is just that their default values are set to look at the filesystems. グロブはファイルシステムに限らず階層的なデータ構造を検索するのに非常に便利なツールです。したがって、glob関数はファイルシステムからは切り離して実装されています。キーワード引数を使うことで、どのようなツリー状のデータ構造からでもグロブできます。デフォルト値がファイルシステム用に設定されているにすぎません。

     The SEPARATOR argument should be a char-set, and used to split the PATTERN into components.  Its default is #[/].  It is not used to the actual pathnames to match. 引数SEPARATORは文字の集合を与えます。これを使ってPATTERNをコンポーネントに分割します。デフォルトは#[/]です。実際のパス名をマッチさせるのには使われません。

     The FOLDER is a procedure that walks through the data structure.  It is called with five arguments: FOLDERはデータ構造をトラバースするための手続きです。この手続きは引数を5つとります。

          (folder PROC SEED PARENT REGEXP NON-LEAF?)

     PROC is a procedure that takes two arguments.  The FOLDER should call PROC with every node in the PARENT whose component name matches REGEXP, passing around the seed value just like fold.  It should return the final value returned by PROC.  For example, if cons is given to PROC and () is given to SEED, the return value of the folder is a list of nodes that matches the REGEXP. PROCは引数を2つ取る手続きです。FOLDERは、PARENT内でコンポーネントとなる名前がREGEXPとマッチする各ノードと、 foldと同様に順に渡されるシード値とで、PROCを呼びます。 FOLDERはPROCが最後に返した値を返します。たとえば、 consがPROCとして、()がSEEDとして渡されれば、 folder手続きが返す値はREGEXPとマッチするノードのリストになります。

     The representation of a node is up to the implementation of FOLDER.  It can be a pathname, or some sort of objects, or anything.  The glob procedure does not care what it is; the glob procedure merely passes the node to subsequent call to folder as PARENT argument, or returns a list of nodes as the result. ノードの表現がどうなるかはFOLDERの実装によります。パス名であったり、オブジェクトであったりするかもしれません。 glob手続きはノードの表現については感知しません。 glob手続きがやることはノードを次に呼ぶ folderにPARENT引数として渡して、その結果のノードリストを返すだけです。

     The PARENT argument is basically a node, and FOLDER traverses its children to find the match. The exception is the initial call of FOLDER--- at the beginning glob knows nothing about each node. When glob needs to match an absolute path, it passes #t, and when glob needs to match a relative path, it passes #f, as the initial PARENT value. PARENT引数は基本的にはノードで、FOLDERはその子ノードを対象にマッチするものを探索します。例外は最初にFOLDERが呼ばれる時です。その時点ではglobはノードについて何も知らないので、絶対パスでマッチをかける場合は#tを、相対パスでマッチをかける場合は#fを最初のPARENTの値として渡します。

     The REGEXP argument is used to filter the child nodes. It should be matched against the component name of the child, not including its directory names.  As a special case, it can be a symbol dir; if that's the case, the folder should return NODE itself, but it may indicate NODE as a directory; e.g. if NODE is represented as a pathname, the folder returns a pathname with trailing directory separator. As special cases, if NODE is a boolean value and REGEXP is dir, the folder should return the node representing root node or current node, respectively; e.g. if NODE is represented as a pathname, the folder may return "/" and "./" for those cases. REGEXP引数は子ノードをフィルターするのに使い、ディレクトリ名を含まない、子のコンポーネントである名前に対して照合されるものです。特別な場合として、シンボルdirにすることができます。この場合は、folder はNODEそのものを返し、NODEはディレクトリと見なされます。すなわち、NODEがパス名を表わす場合には、folderはディレクトリ区切り子が最後に付いたパス名を返します。特別な場合として、NODEがブール値でかつ REGEXPがdirである場合、folderはルートノードをあらわすノードあるいはカレントノードを返すことになっています。すなわち、NODE はパス名を表す場合、folderは"/"または"./"を返します。

     The NON-LEAF argument is a boolean flag.  If it is true, the filter should omit the leaf nodes from the result (e.g. only include the directories). NON-LEAF引数はブール値フラッグです。真なら、フィルタは結果からリーフノードをのぞきます(すなわち、ディレクトリだけが含まれるようになります)。

     Now, here's the precise spec of glob pattern matching. ここからはグロブパターンマッチングの細かい仕様をみていきます。

     Each glob pattern is a string to match pathname-like strings. 各グロブパターンはパス名様式文字列にマッチする文字列です。

     A pathname-like string is a string consists of one or more components, separated by separators. The default separator is #[/]; you can change it with SEPARATOR keyword argument. A component cannot contain separators, and cannot be a null string.  Consecutive separators are regarded as a single separator.  A pathname-like string optionally begins with, and/or ends with a separator character. パス名様式文字列は1つ以上のセパレータで区切られたコンポーネントから構成される文字列です。デフォルトのセパレータは#[/]です。キーワード引数SEPARATOR を使うとこれを変更できます。コンポーネントにはセパレータを含められません。また空文字列にすることもできません。連続したセパレータは単一のセパレータとみなされます。パス名様式の文字列は状況に応じてセパレータから始めたり、セパレータで終端したりできます(両方をやるのも可)。

     A glob pattern also consists of components and separator characters.  In a component, following characters/syntax have special meanings. グロブパターンもコンポーネントとセパレータ文字から構成されます。コンポーネントにおいては、以下の文字、構文は特別な意味を持ちます。

     *
          When it appears at the beginning of a component, it matches zero or more characters except a period (.).  And it won't match if the component of the input string begins with a period.

          Otherwise, it matches zero or more sequence of any characters. これがコンポーネントの先頭に表われた場合、0個以上のピリオド(.) を除く文字にマッチします。入力文字列のコンポーネントがピリオドではじまるような文字列の場合にはマッチしません。

          先頭以外の場所では、0個以上の文字の列にマッチします。

     **
          If a component is just **, it matches zero or more number of components that match *.  For example, src/**/*.h matches all of the following patterns. コンポーネントが**だけの場合、これは*にマッチする0個以上のコンポーネントにマッチします。例えばsrc/**/*.hは次のようなパターン全てにマッチします。

               src/*.h
               src/*/*.h
               src/*/*/*.h
               src/*/*/*/*.h
               ...

     ?
          When it appears at the beginning of a component, it matches a character except a period (.).  Otherwise, it matches any single character. コンポーネントの先頭にあらわれた場合、ピリオド(.)以外の一文字にマッチします。先頭以外の場所では任意の一文字にマッチします。

     [chars]
          Specifies a character set.  Matches any one of the set. The syntax of chars is the same as Gauche's character set syntax (see Character sets).  For the compatibility of the traditional glob, the ! character can be used to complement the character set, e.g. [!abc] is the same as [^abc]. 文字の集合を指定します。その集合に含まれる文字のどれかにマッチします。 charsの構文はGaucheの文字集合を表す構文と同じです (Character sets参照)。伝統的なグロブとの互換性のために、! 文字をつかって、補集合で文字集合を表わすこともできるようになっています。すなわち、[!abc]は[^abc]と同じです。

 -- Function: glob-fold pattern proc seed :key separator folder sorter
     This is actually a low-level construct of the glob function. Actually, GLOB is simply written like this: これはグロブ関数の低レベル版です。実際GLOBは以下のように書いたのと同じです。

          (define (glob patterns . opts)
            (apply glob-fold patterns cons '() opts))

     The meaning of PATTERN, SEPARATOR, FOLDER and SORTER is the same as explained above. PATTERN、SEPARATOR、FOLDERおよびSORTERの意味を前述のものと同じです。

     For each pathname that matches PATTERN, glob-fold calls PROC with the pathname and a seed value.  The initial seed value is SEED, and the value PROC returns becomes the next seed value.  The result of the last call to PROC becomes the result of glob-fold.  If there's no matching pathnames, PROC is never called and SEED is returned. PATTERNにパス名ごとにglob-foldはPROCをパス名とシード値で呼びます。最初のシード値はSEEDで、PROCが返す値は次のシード値になります。最後のPROCの呼び出し結果はglob-foldの結果となります。マッチするパス名が存在しないときは、PROCは呼ばれずに、SEEDが返ります。

 -- Function: make-glob-fs-fold :key root-path current-path
     This is a utility function to generate a procedure suitable to pass the FOLDER keyword argument of glob-fold and glob. Without arguments, this returns the same procedure which is used in glob-fold and glob by default. これはglob-foldやglobのFOLDERキーワード引数に渡せる形の手続きを作るユーティリティ手続きです。引数を渡さなければ、glob-foldやglobがデフォルトで使うのと同じ手続きが返ります。

     The keyword arguments ROOT-PATH and CURRENT-PATH specify the paths where glob-fold starts to search. キーワード引数ROOT-PATHおよびCURRENT-PATHはそれぞれ、 glob-foldが探索を開始するディレクトリを指定します。

          gosh> (glob "/tmp/*.scm")
          ("/tmp/x.scm" "/tmp/y.scm")
          gosh> (glob "/*.scm"
                      :folder (make-glob-fs-fold :root-path "/tmp"))
          ("/tmp/x.scm" "/tmp/y.scm")
          gosh> (glob "*.scm"
                      :folder (make-glob-fs-fold :current-path "/tmp"))
          ("/tmp/x.scm" "/tmp/y.scm")

See File stats, to check if a path is actually a directory. パスがディレクトリかどうかチェックする方法は、File statsを参照してください。

Directory manipulation
......................

 -- Function: sys-remove filename
     [POSIX] If FILENAME is a file it is removed. On some systems this may also work on an empty directory, but portable scripts shouldn't depend on it. FILENAMEがファイルであればそれを消去します。システムによってはFILENAMEが空のディレクトリであっても動作しますが、移植性を気にする場合はその動作に依存しない方が良いでしょう。

 -- Function: sys-rename old new
     [POSIX] Renames a file OLD to NEW.  The new name can be in different directory from the old name, but both paths must be on the same device. ファイルOLDをNEWにリネームします。新しい名前は古い名前と異なるディレクトリにあってもかまいませんが、両者は同じデバイス上になければなりません。

 -- Function: sys-tmpnam
     [POSIX] Creates a file name which is supposedly unique, and returns it. This is in POSIX, but its use is discouraged because of potential security risk.  Use sys-mkstemp below if possible. ユニークなファイル名を作成して返します。この関数はPOSIXに含まれていますが、セキュリティ上の問題が指摘されており、使わない方が良いとされています。可能なら下にあげるsys-mkstempを使って下さい。

 -- Function: sys-mkstemp template
     Creates and opens a file that has unique name, and returns two values; opened port and the created filename.  The file is created exclusively, avoiding race conditions.   TEMPLATE is used as the prefix of the file.  Unlike Unix's mkstemp, you don't need padding characters. The file is opened for writing, and its permission is set to 600. ユニークな名前を持つファイルを作成してオープンし、オープンされたポートとファイル名の二つの値を返します。ファイルは排他的に作成されるため、レースコンディションは起こりません。 TEMPLATEはファイル名のプレフィックスに使われます。Unixのmkstempと違って、パディングキャラクタをつける必要はありません。ファイルは書き込み用としてオープンされ、パーミッションは600にセットされます。

 -- Function: sys-mkdtemp template
     Creates a directory that has unique name, and returns the name. TEMPLATE is used as the prefix of the directory.  Unlike Unix's mkdtemp, you don't need padding characters.  The directory's permission is set to 700. ユニークな名前を持つディレクトリを作成し、その名前を返します。 TEMPLATEはディレクトリ名のプレフィックスに使われます。 Unixのmkdtempと違って、パディングキャラクタをつける必要はありません。ディレクトリのパーミッションは700にセットされます。

 -- Function: sys-link existing new
     [POSIX] Creates a hard link named NEW to the existing file EXISTING. 既存のファイルEXISTINGに対し、NEWという名のハードリンクを作成します。

 -- Function: sys-unlink pathname
     [POSIX] Removes PATHNAME.  It can't be a directory. Returns #t if it is successfully removed, or #f if PATHNAME doesn't exist. An error is signaled otherwise. PATHNAMEで示されるファイルを消去します。 PATHNAMEはディレクトリであってはなりません。もし消去に成功したら#tが、PATHNAMEが存在しなければ#fが返されます。他の場合はエラーが通知されます。

     There are similar procedures, delete-file/remove-file in file.util module, while they raises an error when the named pathname doesn't exist (see File operations). file.utilモジュールに似た手続きdelete-file/remove-fileがありますが、そちらはファイルが存在しない場合にエラーを投げます (File operations参照)。

     R7RS defines delete-file, which you may want to use in portable programs. R7RSはdelete-fileを定義しています。ポータブルなプログラムではそちらを使うのが良いでしょう。

 -- Function: sys-symlink existing new
     Creates a symbolic link named NEW to the pathname EXISTING. On systems that doesn't support symbolic links, this function is unbound. EXISTINGを指すNEWという名のシンボリックを作成します。シンボリックリンクをサポートしないシステムでは、この手続きは定義されません。

 -- Function: sys-readlink path
     If a file specified by PATH is a symbolic link, its content is returned.  If PATH doesn't exist or is not a symbolic link, an error is signaled. On systems that don't support symbolic links, this function is unbound. PATHで示されるファイルがシンボリックリンクならば、それが指すパスを返します。もしPATHが存在しなかったり、シンボリックリンクでなければ、エラーが通知されます。シンボリックリンクをサポートしないシステムでは、この手続きは定義されません。

 -- Function: sys-mkdir pathname mode
     [POSIX] Makes a directory PATHNAME with mode MODE. (Note that MODE is masked by the current umask; see sys-umask below). The parent directory of PATHNAME must exist and be writable by the process.  To create intermediate directories at once, use make-directory* in file.util (Directory utilities). ディレクトリPATHNAMEをモードMODEで作成します。 (MODEはさらにumaskでマスクされることに注意して下さい；下のsys-umask 参照)。 PATHNAMEの親ディレクトリは存在して、プロセスが書き込めるようになっていなければなりません。中間のディレクトリも一度に作成するには、 file.utilのmake-directory*が使えます (Directory utilities)。

 -- Function: sys-rmdir pathname
     [POSIX] Removes a directory PATHNAME.  The directory must be empty. To remove a directory with its contents, use remove-directory* in file.util (Directory utilities). ディレクトリPATHNAMEを消去します。ディレクトリは空でなければなりません。ディレクトリの内容も一緒に消去するには、file.utilのremove-directory* が使えます(Directory utilities)。

 -- Function: sys-umask :optional mode
     [POSIX] Sets umask setting to MODE.  Returns previous umask setting. If MODE is omitted or #f, just returns the current umask without changing it. See man umask for more details. umaskをMODEにセットします。変更される前のumaskを返します。 MODEが省略されるか#fが渡された場合、現在のumaskを変更せずにその値を返します。 umaskについてはman umaskを参照してください。

Pathnames
.........

See also Pathname utilities, for high-level APIs. 高レベルのAPIに関してはPathname utilitiesも参照して下さい。

 -- Function: sys-normalize-pathname pathname :key absolute expand canonicalize
     Converts PATHNAME according to the way specified by keyword arguments. More than one keyword argument can be specified. 与えられたキーワード引数によってPATHNAMEを以下のように変換します。キーワード引数は同時に複数指定できます。

     absolute
          If this keyword argument is given and true, and PATHNAME is not an absolute pathname, it is converted to an absolute pathname by appending the current working directory in front of PATHNAME. このキーワード引数に真の値が与えられて、PATHNAMEが絶対パスでない場合、 PATHNAMEの前にプロセスのワーキングディレクトリを足して絶対パスにします。

     expand
          If this keyword argument is given and true, and PATHNAME begins with `~', it is expanded as follows: このキーワード引数に真の値が与えられて、PATHNAMEが`~' で始まっていた場合、以下のように展開されます。

            * If PATHNAME is consisted entirely by ``~'', or begins with ``~/'', then the character ``~'' is replaced for the pathname of the current user's home directory. PATHNAMEが``~''のみであるか、または``~/''で始まっている場合、文字``~''が現在のプロセスのユーザのホームディレクトリに置き換えられます。

            * Otherwise, characters following `~' until either `/' or the end of PATHNAME are taken as a user name, and the user's home directory is replaced in place of it.  If there's no such user, an error is signaled. 上記以外の場合、`~'以降、`/'かPATHNAMEの終端までの文字列がユーザ名とみなされ、そのユーザのホームディレクトリに置換されます。もし該当するユーザがいなければエラーとなります。

     canonicalize
          Tries to remove pathname components ``.'' and ``..''. The pathname interpretation is done purely in textural level, i.e. it doesn't access filesystem to see the conversion reflects the real files.  It may be a problem if there's a symbolic links to other directory in the path. パス名から ``.'' や ``..'' を除き、単純化します。この操作は実際のファイルシステムを参照せずに行われます。元のパス名がディレクトリへのシンボリックリンクを含んでいた場合、単純化されたパス名は正しくないかもしれません。

 -- Function: sys-basename pathname
 -- Function: sys-dirname pathname
     sys-basename returns a basename, that is the last component of PATHNAME.  sys-dirname returns the components of PATHNAME but the last one.   If PATHNAME has a trailing `/', it is simply ignored. sys-basenameは与えられたパスのベース名、すなわち最後のコンポーネントを返します。 sys-dirnameは与えられたパスのディレクトリ名、すなわち最後のコンポーネント以外のコンポーネントを返します。PATHNAMEの末尾が`/'である場合、その文字は無視されます。

          (sys-basename "foo/bar/bar.z") => "bar.z"
          (sys-basename "coo.scm") => "coo.scm"
          (sys-basename "x/y/") => "y"
          (sys-dirname "foo/bar/bar.z") => "foo/bar"
          (sys-dirname "coo.scm") => "."
          (sys-dirname "x/y/") => "x"

     These functions doesn't check if PATHNAME really exists. この手続きはPATHNAMEが存在するかどうかはチェックしません。

     Some boundary cases: 特殊なケース：

          (sys-basename "") => ""
          (sys-dirname "") => "."

          (sys-basename "/") => ""
          (sys-dirname "/") => "/"

     Note: The above behavior is the same as Perl's basename and dirname.   On some systems, the command basename may return "/" for the argument "/", and "." for the argument ".". 註：このふるまいはPerlのbasenameおよびdirnameと同様です。システムによっては、コマンドのbasenameは"/"に対して"/"を、 "."に対して"."を返すものがあります。

 -- Function: sys-realpath pathname
     sys-realpath returns an absolute pathname of PATHNAME that does not include ``.'', ``..'' or symbolic links. If PATHNAME does not exist, it includes a dangling symbolic link, or the caller doesn't have enough permission to access to the path, an error is signaled. sys-realpathは``.'', ``..''およびシンボリックリンクを含まないPATHNAMEの絶対パスを返します。PATHNAME自体が存在しなかったり、存在しないパスを指すシンボリックリンクが含まれていたり、関連するパスへのアクセス権限が不足している場合はエラーが通知されます。

     Note: the POSIX realpath(3) function is known to be unsafe, so Gauche avoids using it and implements sys-realpath in its own. 注：POSIXのrealpath(3)は安全でない場合があるので、 Gaucheは内部でCランタイムのrealpathを呼ばずに、独自にsys-realpathの機能を実装しています。

 -- Function: sys-tmpdir
     Returns the default directory name suitable to put temporary files.

     On Unix-like systems, the environment variable TMPDIR and TMP are first checked, then falls back to /tmp.

     On Windows-native systems, it uses GetTempPath Windows API. It checks environment variables TMP, TEMP, and USERPROFILE in this order, and falls back to Windows system directory.

     On both platforms, the returned pathname may not exist, or may not be writable by the calling process.

     In general, user programs and libraries are recommended to use temporary-directory (see Directory utilities) instead; sys-tmpdir should be used only if you now the raw value the platform provides. 一時ファイルを置くためのデフォルトのディレクトリ名を返します。

     Unix系システムでは、環境変数TMPDIRとTMPがこの順でチェックされ、フォールバックとして/tmpが返されます。

     Windowsネイティブの環境では、GetTempPath Windows APIを呼びます。これは環境変数TMP、TEMP、USERPROFILEを順に調べ、いずれも定義されていなければWindowsシステムディレクトリを返します。

     いずれのプラットフォームでも、返されたパス名は存在しないかもしれず、また書き込み可能ではないかもしれないことに注意してください。

     一般的に、ユーザプログラムやライブラリはtemporary-directory (Directory utilities参照) の方を利用するのが良いでしょう。 sys-tmpdirはプラットフォームが推奨する生の値を知りたい場合に限り使ってください。

File stats
..........

See also File attribute utilities, for high-level APIs. 高レベルのAPIに関してはFile attribute utilitiesも参照して下さい。

 -- Function: file-exists? path
     [R7RS file] Returns true if PATH exists. PATHが存在していれば#tを返します。

 -- Function: file-is-regular? path
 -- Function: file-is-directory? path
     Returns true if PATH is a regular file, or is a directory, respectively.   They return false if PATH doesn't exist at all. それぞれ、PATHが存在するか、存在してそれがレギュラーファイルであるか、存在してそれがディレクトリであれば#tを返します。

 -- Builtin Class: <sys-stat>
     An object that represents struct stat, attributes of an entry in the filesystem.   It has the following read-only slots. ファイルシステム内のエントリの属性を表す、struct statのラッパーオブジェクトです。以下に示す読みだし専用のスロットを持ちます。

      -- Instance Variable of <sys-stat>: type
          A symbol represents the type of the file. ファイルのタイプを示すシンボルです。

          regular   a regular file
          directory   a directory
          character   a character device
          block   a block device
          fifo   a fifo
          symlink   a symbolic link
          socket   a socket

          regular   通常のファイル
          directory   ディレクトリ
          character   キャラクタデバイス
          block   ブロックデバイス
          fifo   FIFO
          symlink   シンボリックリンク
          socket   ソケット

          If the file type is none of the above, #f is returned. 以上のどれにも当てはまらない場合は#fが返されます。

          Note: Some operating systems don't have the socket file type and returns fifo for socket files.   Portable programs should check both possibilities to see if the given file is a socket. 注：いくつかのオペレーティングシステムではsocketファイルタイプを fifoと区別せず、どちらに対してもfifoを返します。ポータブルなプログラムを書くときは注意して下さい。

      -- Instance Variable of <sys-stat>: perm
          An exact integer for permission bits of struct stat. It is the same as lower 9-bits of "mode" slot; provided for the convenience. パーミッションビットマスク。"mode"スロットの下位9ビットと同じですが、便利なので独立したスロットとして提供されます。

      -- Instance Variable of <sys-stat>: mode
      -- Instance Variable of <sys-stat>: ino
      -- Instance Variable of <sys-stat>: dev
      -- Instance Variable of <sys-stat>: rdev
      -- Instance Variable of <sys-stat>: nlink
      -- Instance Variable of <sys-stat>: uid
      -- Instance Variable of <sys-stat>: gid
      -- Instance Variable of <sys-stat>: size
          An exact integer for those information of struct stat. struct statの該当するフィールドの値。正確な整数です。

      -- Instance Variable of <sys-stat>: atime
      -- Instance Variable of <sys-stat>: mtime
      -- Instance Variable of <sys-stat>: ctime
          A number of seconds since Unix Epoch for those information of struct stat. struct statの該当するフィールドの値を、Unix Epochからの秒数で。

      -- Instance Variable of <sys-stat>: atim
      -- Instance Variable of <sys-stat>: mtim
      -- Instance Variable of <sys-stat>: ctim
          Timestamps represented in <time> object (see Time). If the system supports it, this allows up to nanosecond precision. <time>オブジェクトで表されたタイムスタンプ (Time参照)。システムがサポートしていれば、ナノ秒単位のタイムスタンプを得ることができます。

 -- Function: sys-stat path
 -- Function: sys-fstat port-or-fd
     [POSIX] Returns a <sys-stat> object of PATH, or the underlying file of PORT-OR-FD, which may be a port or a positive exact integer file descriptor, respectively.

     If PATH is a symbolic link, a stat of the file the link points to is returned from sys-stat.

     If PORT-OR-FD is not associated to a file, sys-fstat returns #f. 与えられたパス名PATH、またはポートかファイルディスクリプタ PORT-OR-FDで示されるファイルの情報を<sys-stat>オブジェクトで返します。

     sys-statは、PATHがシンボリックリンクであった場合はリンクの指す先のファイルに関する情報を返します。

     sys-fstatは、PORT-OR-FDがファイルに関係ないポートであった場合は#fを返します。

 -- Function: sys-lstat path
     Like sys-stat, but it returns a stat of a symbolic link if PATH is a symbolic link. sys-statと同じですが、PATHがシンボリックリンクであった場合はリンクそのものの情報を返します。

     gosh> (describe (sys-stat "gauche.h"))
     #<<sys-stat> 0x815af70> is an instance of class <sys-stat>
     slots:
       type      : regular
       perm      : 420
       mode      : 33188
       ino       : 845140
       dev       : 774
       rdev      : 0
       nlink     : 1
       uid       : 400
       gid       : 100
       size      : 79549
       atime     : 1020155914
       mtime     : 1020152005
       ctime     : 1020152005

 -- Function: sys-stat->mode stat
 -- Function: sys-stat->ino stat
 -- Function: sys-stat->dev stat
 -- Function: sys-stat->rdev stat
 -- Function: sys-stat->nlink stat
 -- Function: sys-stat->size stat
 -- Function: sys-stat->uid stat
 -- Function: sys-stat->gid stat
 -- Function: sys-stat->atime stat
 -- Function: sys-stat->mtime stat
 -- Function: sys-stat->ctime stat
 -- Function: sys-stat->file-type stat
     Deprecated. Use slot-ref to access information of <sys-stat> object. <sys-stat>オブジェクトの情報にアクセスするにはslot-refを使って下さい。

 -- Function: sys-access pathname amode
     [POSIX] Returns a boolean value of indicating whether access of PATHNAME is allowed in AMODE.   This procedure signals an error if used in a suid/sgid program (see the note below). AMODE can be a combinations (logical or) of following predefined flags. PATHNAMEへのアクセスが MODEに示されるモードで許可されているかどうかを示す真偽値を返します。この手続きは、suid/sgidプログラムで使われるとエラーとなります(下記註参照)。 MODEは以下に示す定数のコンビネーション(logical or)です。

     R_OK
          Checks whether PATHNAME is readable by the current user. PATHNAMEをカレントユーザが読み出し可能かどうか

     W_OK
          Checks whether PATHNAME is writable by the current user. PATHNAMEへカレントユーザが書き込み可能かどうか

     X_OK
          Checks whether PATHNAME is executable (or searchable in case PATHNAME is a directory) by the current user. PATHNAMEをカレントユーザが実行可能かどうか(PATHNAMEがディレクトリの場合はサーチ可能かどうか)

     F_OK
          Checks whether PATHNAME exists or not, regardless of the access permissions of PATHNAME.  (But you need to have access permissions of the directories containing PATHNAME). PATHNAMEのパーミッションフラグにかかわらず、PATHNAMEが存在するかどうか (但しPATHNAMEがあるディレクトリの読みだし許可は必要)。

     Note: Access(2) is known to be a security hole if used in suid/sgid program to check the real user's privilege of accessing the file. 註: access(2)は、suid/sgidプログラム中で実ユーザの権限を確かめるために使われた場合、セキュリティホールとなります。

 -- Function: sys-chmod path mode
 -- Function: sys-fchmod port-or-fd mode
     Change the mode of the file named PATH or an opened file specified by PORT-OR-FD to MODE. MODE must be a small positive integer whose lower 9 bits specifies POSIX style permission. 名前PATHを持つ、もしくはPORT-OR-FDで指定されるファイルのパーミッションビットをMODEに変更します。 MODEは小さな正の正確な整数で、POSIXスタイルのパーミッションビットマスクでなければなりません。

 -- Function: sys-chown path owner-id group-id
     Change the owner and/or group of the file named PATH to OWNER-ID and GROUP-ID respectively. OWNER-ID and GROUP-ID must be an exact integer. If either of them is -1, the corresponding ownership is not changed. ファイルPATHのオーナーとグループをOWNER-IDとGROUP-ID で示されるものに変更します。OWNER-IDとGROUP-IDは正確な整数でなければなりません。どちらかに-1が渡された場合は、対応する情報は変更されません。

 -- Function: sys-utime path :optional atime mtime
     Change the file's access time and modification time to ATIME and MTIME, respectively.   The arguments can be either #f (indicating the current time), #t (do not change), a real numebr (number of seconds from Epoch), or <time> object (see Time).

     See also touch-file (see File operations). ファイルのアクセスタイムと変更タイムをATIMEとMTIMEが示す値にセットします。ATIME/MTIME引数に許されるのは、 #f (現在の時刻)、#t (変更なし)、実数 (Epochからの秒数)、あるいは<time>インスタンスです (Time参照)。

     File operationsのtouch-fileも参照して下さい。

Other file operations
.....................

 -- Function: sys-chdir dir
     [POSIX] An interface to chdir(2). See also current-directory (see Directory utilities). chdir(2)へのインタフェースです。 current-directory(Directory utilities)も参照して下さい。

 -- Function: sys-pipe :key (buffering :line)
     [POSIX] Creates a pipe, and returns two ports. The first returned port is an input port and the second is an output port. The data put to the output port can be read from the input port. [POSIX] パイプを作り、ポートを2つ返します。最初に返されるポートは入力ポートで、2番目に返されるポートは出力ポートです。出力ポートへ書き出したデータは、入力ポートから読み込めます。

     BUFFERING can be :full, :line or :none, and specifies the buffering mode of the ports opened on the pipe. See File ports, for details of the buffering mode. The default mode is sufficient for typical cases. BUFFERINGは:full、:line、:noneのいずれかで、パイプ上に開かれたポートのバッファリングモードを指定します。バッファリングモードの詳細については、File portsを参照して下さい。通常のケースでは、デフォルトのモードで間に合うでしょう。

          (receive (in out) (sys-pipe)
            (display "abc\n" out)
            (flush out)
            (read-line in)) => "abc"

     Note: the returned value is changed from version 0.3.15, in which sys-pipe returned a list of two ports. 注意: 戻り値はバージョン0.3.15から変更されています。それまでは、 sys-pipeは2つのポートのリストを返します。

 -- Function: sys-mkfifo path mode
     [POSIX] creates a fifo (named pipe) with a name PATH and mode MODE.  MODE must be a positive exact integer to represent the file mode. [POSIX] 名前がPATHでモードがMODEのFIFO(名前付きパイプ)を作ります。MODEはファイルのモードを表す正の正確整数でなければなりません。

 -- Function: sys-isatty port-or-fd
     [POSIX] PORT-OR-FD may be a port or an integer file descriptor. Returns #t if the port is connected to the console, #f otherwise. [POSIX] PORT-OR-FDはポートか整数のファイルディスクリプタです。ポートがコンソールに接続されていれば#tを、そうでなければ#fを返します。

 -- Function: sys-ttyname port-or-fd
     [POSIX] PORT-OR-FD may be a port or an integer file descriptor. Returns the name of the terminal connected to the port, or #f if the port is not connected to a terminal. [POSIX] PORT-OR-FDはポートか整数のファイルディスクリプタです。ポートに接続された端末の名前か、ポートが端末に接続されていなければ #fを返します。

 -- Function: sys-truncate path length
 -- Function: sys-ftruncate port-or-fd length
     [POSIX] Truncates a regular file named by PATH or referenced by PORT-OR-FD to a size of LENGTH bytes. If the file is larger than LENGTH bytes, the extra data is discarded. If the file is smaller than that, zero is padded. PATHあるいはPORT-OR-FDによって指定される通常ファイルの長さを LENGTHにします。ファイルがLENGTHより長かった場合、余分なデータは捨てられます。ファイルがLENGTHより短かった場合、残りの部分にはゼロが詰められます。

Unix groups and users
---------------------

Unix groups
...........

 -- Builtin Class: <sys-group>
     Unix group information.  Has following slots. Unixのグループの情報です。以下のスロットを持ちます。

      -- Instance Variable of <sys-group>: name
          Group name. グループ名。

      -- Instance Variable of <sys-group>: gid
          Group id. グループID

      -- Instance Variable of <sys-group>: passwd
          Group password. グループパスワード。

      -- Instance Variable of <sys-group>: mem
          List of user names who are in this group. このグループに属するユーザ名のリスト。

 -- Function: sys-getgrgid gid
 -- Function: sys-getgrnam name
     [POSIX] Returns <sys-group> object from an integer group id GID or a group name NAME, respectively. If the specified group doesn't exist, #f is returned. グループIDGIDもしくはグループ名NAMEで示されるグループの情報を <sys-group>で返します。該当するグループが存在しない場合は #fが返されます。

 -- Function: sys-gid->group-name gid
 -- Function: sys-group-name->gid name
     Convenience function to convert between group id and group name. グループIDとグループ名を相互変換する便利な手続きです。

Unix users
..........

 -- Builtin Class: <sys-passwd>
     Unix user information.  Has following slots. Unixのユーザの情報です。以下のスロットを持ちます。

      -- Instance Variable of <sys-passwd>: name
          User name. ユーザ名。

      -- Instance Variable of <sys-passwd>: uid
          User ID. ユーザID

      -- Instance Variable of <sys-passwd>: gid
          User's primary group id. ユーザのプライマリグループID。

      -- Instance Variable of <sys-passwd>: passwd
          User's (encrypted) password.  If the system uses the shadow password file, you just get obscure string like "x". ユーザの(暗号化された)パスワード。システムがシャドウパスワードファイルを使っている場合は、 "x" のような無意味な文字列が入っています。

      -- Instance Variable of <sys-passwd>: gecos
          Gecos field. Gecosフィールド。

      -- Instance Variable of <sys-passwd>: dir
          User's home directory. ユーザのホームディレクトリ。

      -- Instance Variable of <sys-passwd>: shell
          User's login shell. ユーザのログインシェル。

      -- Instance Variable of <sys-passwd>: class
          User's class (only available on some systems). ユーザのクラス。(特定のシステムでのみ有効)。

 -- Function: sys-getpwuid uid
 -- Function: sys-getpwnam name
     [POSIX] Returns <sys-passwd> object from an integer user id UID or a user name NAME, respectively. If the specified user doesn't exist, #f is returned. ユーザIDUIDもしくはユーザ名NAMEで示されるユーザの情報を <sys-passwd>で返します。該当するユーザが存在しない場合は #fが返されます。

 -- Function: sys-uid->user-name uid
 -- Function: sys-user-name->uid name
     Convenience functions to convert between user id and user name. ユーザIDとユーザ名を相互変換する便利な手続きです。

Password encryption
...................

 -- Function: sys-crypt key salt
     This is the interface to crypt(3).   KEY and SALT must be a string, and an encrypted string is returned. On systems where crypt(3) is not available, call to this function signals an error.

     This routine is only for the code that needs to check password against the system's password database. If you are building user database on your own, you must use crypt.bcrypt module (see Password hashing) instead of this routine. これは、crypt(3)へのインターフェースです。KEYとSALTは文字列でなければならず、暗号化された文字列が返されます。 crypt(3)が利用できないシステムでこの関数を呼ぶとエラーが通知されます。

     このルーチンは、システムのパスワードデータベースを使ってパスワードチェックをしなければならない時以外に使うべきではありません。独自のパスワードデータベースを新たに作る場合は、crypt.bcryptモジュール(Password hashing)を使ってください。

Locale
------

 -- Function: sys-setlocale category locale
     [POSIX] Sets the locale of the category CATEGORY to the locale LOCALE. CATEGORY must be an exact integer; the following pre-defined variables are available.  LOCALE must be a string locale name. Returns the locale name on success, or #f if the system couldn't change the locale. カテゴリーCATEGORYのロケールをLOCALEにセットします。 CATEGORYは整数でなければなりません；以下の変数がCATEGORYのために定義されています。LOCALEはロケールを表す文字列です。成功した場合は新しいロケール名を、ロケールが変更できなかった場合は#fを返します。

 -- Variable: LC_ALL
 -- Variable: LC_COLLATE
 -- Variable: LC_CTYPE
 -- Variable: LC_MONETARY
 -- Variable: LC_NUMERIC
 -- Variable: LC_TIME
     Predefined variables for possible CATEGORY value of sys-setlocale. sys-setlocaleのCATEGORYに渡せる数値を定義しています。

 -- Function: sys-localeconv
     [POSIX] Returns an assoc list of various information for formatting numbers in the current locale. 現在のロケールで数値をフォーマットする際に必要な様々な情報をassoc listにして返します。

An example session.  It may differ on your system settings. 例を示します。あなたのシステム設定によっては異なる結果になるかもしれません。

     (sys-localeconv)
      =>
        ((decimal_point . ".") (thousands_sep . "")
         (grouping . "") (int_curr_symbol . "")
         (currency_symbol . "") (mon_decimal_point . "")
         (mon_thousands_sep . "") (mon_grouping . "")
         (positive_sign . "") (negative_sign . "")
         (int_frac_digits . 127) (frac_digits . 127)
         (p_cs_precedes . #t) (p_sep_by_space . #t)
         (n_cs_precedes . #t) (n_sep_by_space . #t)
         (p_sign_posn . 127) (n_sign_posn . 127))

     (sys-setlocale LC_ALL "fr_FR")
      => "fr_FR"

     (sys-localeconv)
      =>
       ((decimal_point . ",") (thousands_sep . "")
        (grouping . "") (int_curr_symbol . "FRF ")
        (currency_symbol . "F") (mon_decimal_point . ",")
        (mon_thousands_sep . " ") (mon_grouping . "\x03\x03")
        (positive_sign . "") (negative_sign . "-")
        (int_frac_digits . 2) (frac_digits . 2)
        (p_cs_precedes . #f) (p_sep_by_space . #t)
        (n_cs_precedes . #f) (n_sep_by_space . #t)
        (p_sign_posn . 1) (n_sign_posn . 1))

Signal
------

Gauche can send out operating system's signals to the other processes (including itself) and can handle the incoming signals. Gaucheでは、OSのシグナルを自分自身や他のプロセスに送ったり、送られたシグナルを処理することができます。

In multithread environment, all threads share the signal handlers, and each thread has its own signal mask. See Signals and threads, for details. マルチスレッド環境では、全てのスレッドがシグナルハンドラを共有し、各スレッドが独自のシグナルマスクを持ちます。詳しくはSignals and threadsを参照して下さい。

When a system call is interrupted by a signal, and a programmer defines a handler for the signal that doesn't transfer control to other context, the system call is restarted after the handler returns by default. システムコールがシグナルによって割り込まれ、プログラマがシグナルハンドラをセットしており、そのハンドラが別コンテキストに制御を移さずに戻った場合、そのシステムコールは原則としてハンドラからの復帰後にリスタートされます。

Here are some calls that are not simply restarted by signal interruption. シグナル割り込みによって単純にリスタートされないものは次の通りです。

close
     This may be called through sys-close, close-port, or even implicitly when the underlying file is closed.   When a signal interrupts this call, the passed fd is no longer in use.  Simply restarting it can be a race if another thread just grabs the fd. これはsys-closeやclose-port、さらには低層のファイルが自動的にクローズされる場合に呼ばれます。シグナルがこのシステムコールを中断してEINTRが返った時点で、渡されたファイルディスクリプタは無効になっており、もし他のスレッドがそのディスクリプタを直後に再利用していたら、リスタートするのは競合を引き起こします。

dup2
     This is called via port-fd-dup!.  When dup2 returns EINTR, the NEWFD is no longer in use and some other thread may grab it before restarting it. このコールはport-fd-dup!から呼ばれます。dup2がEINTRを返した時、NEWFDは使われない状態になっており、他のスレッドが直後にそれを使う可能性があるのでリスタートは危険です。

sleep
nanosleep
     These calls tells the remaining time when they are interrupted. We restart them with that remaining time, not the original argument, so that the total sleep time would be close to what was given originally. これらのコールは中断された場合に残りの時間を教えてくれます。 Gaucheではリスタート時に元の引数でなく残りの時間を渡すので、スリープする全体の時間はおおよそ最初に与えられた時間となります。

On Windows native platforms, signals don't work except some limited support of sys-kill. Windowsネイティブ環境では、sys-killの限定的なサポートを除いてシグナルは動作しません。

Signals and signal sets
.......................

Each signal is referred by its signal number (a small integer) defined on the underlying operating system. Variables are pre-defined to the system's signal number. System's signal numbers may be architecture dependent, so you should use those variables rather than using literal integers. シグナルはオペレーティングシステムで定義された小さな整数値で表現されます。システムのシグナル番号に束縛された変数が定義されています。システムのシグナル番号はアーキテクチャによって異なるので、なるべく変数を利用するようにして下さい。

 -- Variable: SIGABRT
 -- Variable: SIGALRM
 -- Variable: SIGCHLD
 -- Variable: SIGCONT
 -- Variable: SIGFPE
 -- Variable: SIGHUP
 -- Variable: SIGILL
 -- Variable: SIGINT
 -- Variable: SIGKILL
 -- Variable: SIGPIPE
 -- Variable: SIGQUIT
 -- Variable: SIGSEGV
 -- Variable: SIGSTOP
 -- Variable: SIGTERM
 -- Variable: SIGTSTP
 -- Variable: SIGTTIN
 -- Variable: SIGTTOU
 -- Variable: SIGUSR1
 -- Variable: SIGUSR2
     These variables are bound to the signal numbers of POSIX signals. これらの変数はPOSIXで定義された対応するシグナルの番号に束縛されています。

 -- Variable: SIGTRAP
 -- Variable: SIGIOT
 -- Variable: SIGBUS
 -- Variable: SIGSTKFLT
 -- Variable: SIGURG
 -- Variable: SIGXCPU
 -- Variable: SIGXFSZ
 -- Variable: SIGVTALRM
 -- Variable: SIGPROF
 -- Variable: SIGWINCH
 -- Variable: SIGPOLL
 -- Variable: SIGIO
 -- Variable: SIGPWR
     These variables are bound to the signal numbers of system-dependent signals.  Not all of them may be defined on some systems. これらの変数はシステム依存のシグナル番号に束縛されています。全てのシステムで全てのシグナルがサポートされているわけではありません。

Besides each signal numbers, you can refer to a set of signals using a <sys-sigset> object. It can be used to manipulate the signal mask, and to install a signal handler to a set of signals at once. それぞれのシグナル番号の他に、<sys-sigset>オブジェクトを使ってシグナルの集合を扱うことができます。シグナルの集合はシグナルマスクを操作したり、ひとつのシグナルハンドラを多数のシグナルに同時に設定したりする際に使えます。

 -- Class: <sys-sigset>
     A set of signals.   An empty sigset can be created by シグナルの集合を表します。空のシグナルの集合は次の式で作成できます：

          (make <sys-sigset>) => #<sys-sigset []>

 -- Function: sys-sigset signal ...
     Creates and returns an instance of <sys-sigset> with members SIGNAL ....  Each SIGNAL may be either a signal number, another <sys-sigset> object, or #t for all available signals. SIGNAL ...をメンバーとする<sys-sigset>のインスタンスを作成して返します。各SIGNALにはシグナル番号、他の<sys-sigset>オブジェクト、あるいは #tを渡すことができます。#tを渡した場合は全てのシグナルが対象となります。

          (sys-sigset SIGHUP SIGINT) => #<sys-sigset [HUP|INT]>

 -- Function: sys-sigset-add! sigset signal ...
 -- Function: sys-sigset-delete! sigset signal ...
     SIGSET must be a <sys-sigset> object. Those procedures adds and removes the specified signals from SIGSET respectively, and returns the result.  SIGSET itself is also modified.

     SIGNAL may be either a signal number, another <sys-sigset> object, or #t for all available signals. SIGSETは<sys-sigset>オブジェクトでなければなりません。これらの手続きはSIGSETに指定されたシグナルを追加、もしくはSIGSETから指定されたシグナルを削除します。変更されたSIGSETが返されます。

     SIGNALにはシグナル番号、他の<sys-sigset>オブジェクト、あるいは #tを渡すことができます。#tを渡した場合は全てのシグナルが対象となります。

 -- Function: sys-sigset-fill! sigset
 -- Function: sys-sigset-empty! sigset
     Fills SIGSET by all available signals, or empties SIGSET. システムで定義された全てのシグナルをSIGSETにセット、もしくはSIGSETを空にします。

 -- Function: sys-signal-name signal
     Returns the human-readable name of the given signal number. (Note that signal numbers are system-dependent.) シグナル番号の名前を返します。(シグナル番号はシステムに依存します)。

          (sys-signal-name 2) => "SIGINT"

Sending signals
...............

To send a signal, you can use sys-kill which works like kill(2). シグナルを送るには、sys-killを使うことができます。これはシステムのkill(2)のように動作します。

 -- Function: sys-kill pid sig
     [POSIX] Sends a signal SIG to the specified process(es).  SIG must be a positive exact integer.  PID is an exact integer and specifies the target process(es): シグナルSIGを指定されたプロセス(群)に送ります。 SIGは正確な正整数でなければなりません。PIDは正確な整数でなければならず、次のルールで対象となるプロセスを指定します。

       * If PID is positive, it is the target process id. PIDが正ならば、それがそのまま対象となるプロセスIDです。

       * If PID is zero, the signal is sent to every process in the process group of the current process. PIDがゼロならば、シグナルは現在のプロセスのプロセスグループ内の全てのプロセスに送られます。

       * If PID is less than -1, the signal is sent to every process in the process group -PID. PIDが-1より小さければ、シグナルはプロセスグループIDが-PIDである全てのプロセスに送られます。

     On Windows native platforms, sys-kill may take positive integer or a process handle (<win:handle> instance) as PID. Only SIGKILL, SIGINT and SIGABRT are allowed as SIG; Gauche uses TerminateProcess to terminate the target process for SIGKILL, and sends the target process CTRL_C_EVENT and CTRL_BREAK_EVENT for SIGINT and SIGABRT, respectively. Windowsネイティブ環境では、sys-killはPIDに正整数かプロセスハンドル(<win:handle>のインスタンス)を取ります。 SIGがサポートするのはSIGKILL、SIGINT、SIGABRT のみです。SIGKILLに対してはTerminateProcessを使って対象プロセスを終了させます。SIGINTとSIGABRTに対しては対象プロセスにそれぞれCTRL_C_EVENTとCTRL_BREAK_EVENTを送ります。

There's no Scheme equivalence for raise(), but you can use (sys-kill (sys-getpid) SIG). POSIXのraise()に対応するScheme関数はありませんが、 (sys-kill (sys-getpid) SIG) で同じことができます。

Handling signals
................

You can register signal handling procedures in Scheme. (In multithread environment, signal handlers are shared by all threads; see Signals and threads for details). Schemeでシグナルを処理する手続きを登録できます。 (マルチスレッド環境では、シグナルハンドラの設定は全てのスレッドで共有されます。 Signals and threadsを参照して下さい)。

When a signal is delivered to the Scheme process, the VM just records it and processes it later at a 'safe point' where the state of VM is consistent. We call the signal is pending when it is registered by the VM but not processed yet. シグナルがSchemeプロセスに送られると、VMはそれを記録し、 VMの状態が一貫している「安全なポイント」に達した時に処理します。シグナルがVMに記録され、しかしまだ処理されていない状態を、シグナルが保留されていると呼ぶことにします。

(Note that this makes handling of some signals such as SIGILL useless, for the process can't continue sensible execution after recording the signal). (このメカニズムのため、SIGILLのようなシグナルはSchemeレベルでは処理できません。そのシグナルを記録した後でプロセスが意味のある処理を続行できないからです)。

If the same signal is delivered more than once before VM processes the first one, the second one and later have no effect.  (This is consistent to the traditional Unix signal model.)  In other words, for each VM loop a signal handler can be invoked at most once per each signal. VMがシグナルを処理する前に同じシグナルが到着した場合、後に到着した方のシグナルは無効になります。(これは伝統的なUnixのシグナル処理と同様です)。言い替えれば、各VM loop毎に、シグナルハンドラは各シグナルについてたかだか1回しか呼ばれません。

When too many signals of the same kind are pending, Gauche assumes something has gone wrong (e.g. infinite loop inside C-routine) and aborts the process.  The default of this limit is set rather low (3), to allow unresponsive interactive script to be terminated by typing Ctrl-C three times.  Note that the counter is individual for each signal; Gauche won't abort if one SIGHUP and two SIGINTs are pending, for example.  You can change this limit by set-signal-pending-limit described below. 同じシグナルがたくさん保留された状態になった場合、 Gaucheは異常事態が起きたとみなし (例えばCルーチンで無限ループに入った等)、プロセスをabortします。デフォルトではこの限界はかなり低い値(3)に設定されています。これは、インタラクティブスクリプトが反応しなくなった場合にCtrl-Cを3回打てば強制終了できる、という場合を想定しているためです。この限界を調べるカウンタはシグナル毎にあるので、例えばSIGHUPがひとつ、SIGINTがふたつ保留になった、といった場合はabortしません。この限界は下で述べるset-signal-pending-limit で変更することができます。

When you're using the gosh interpreter, the default behavior for each signal is as in the following table. goshインタプリタを使っている場合、デフォルトでのシグナルの処理は次のように設定されています。

SIGABRT, SIGILL, SIGKILL, SIGSTOP, SIGSEGV, SIGBUS
     Cannot be handled in Scheme.  Gosh follows the system's default behavior. Schemeでは処理できません。goshではこれらのシグナルを受けるとシステムのデフォルトの動作をします。

SIGCHLD, SIGTSTP, SIGTTIN, SIGTTOU, SIGWINCH
     No signal handles are installed for these signals by gosh, so the process follows the system's default behavior. A Scheme programs can install its own signal handler if necessary. goshは初期状態ではこれらのシグナルのハンドラを設定せず、システムのデフォルトの振るまいに任せます。Schemeプログラムは必要ならばこれらのシグナルのハンドラを設定できます。

SIGCONT
     If gosh is running with input editing mode, a signal handler is installed to restore terminal status.  Otherwise, no signal handler is installed by default, and a Scheme program can install its own signal handler if necessary. goshが入力編集モードで起動している場合は、端末状態を回復するシグナルハンドラが設定されています。それ以外の場合はシグナルハンドラは設定されず、Schemeプログラムは必要ならば独自のハンドラを設定できます。

SIGHUP, SIGQUIT, SIGTERM
     Gosh installs a signal handler for these signals that exits from the application with code 0. goshはこれらのシグナルに対して、終了コード0でアプリケーションを終了するシグナルハンドラをセットします。

SIGPIPE
     Gosh installs a signal handler that does nothing---that is, this signal is effectively ignored by default.

     It is a design choice.  Since Gauche delays actual handling of signals, SIGPIPE would be handled after the system call that tries to write to a broken pipe returns with EPIPE. That makes the signal a lot less useful, for we can handle the situation with error handlers for <system-error> with EPIPE.

     The default Unix behavior of SIGPIPE is to terminate the process.  It is useful for the traditional command-line tools that are often piped together---if one of downstream commands fails, the upstream process receives SIGPIPE and the entire command chain is shut down without a fuss.  The signal is, however, rather an annoyance for other types of output such as sockets.

     Gauche does support this ``exit when pipe gets stuck'' convention by ports.   A port can be configured as sigpipe sensitive; if writing to that port caused EPIPE, it terminates the process.  By default, standard output and standard error output are configured in that way. Goshは何もしないシグナルハンドラを設定します。つまり、事実上このシグナルはデフォルトで無視されます。

     この設計の意図は次のとおりです。Gaucheはシグナルの処理を安全なポイントまで遅延するため、SIGPIPEはそれを発生させたシステムコールがEPIPEを返した後で処理されることになります。この事実によって、SIGPIPEを処理する必要性は大きく低下します。書き出した先のパイプが壊れていた場合にはEPIPEの<system-error> をハンドルすれば良いからです。

     UnixのデフォルトのSIGPIPE処理は、プロセスを終了させます。これは伝統的な、パイプでつないでゆくコマンドラインツールにとっては便利な振る舞いです。下流のコマンドが失敗した場合、上流のコマンドは SIGPIPEを受け取るので、つながれたすべてのコマンドが静かに終了するからです。けれども、ソケットなど他の種類の出力に対しては、このシグナルはしばしば邪魔になります。

     Gaucheは、この「パイプが詰まったら終了する」という慣習を、ポートによってサポートします。ポートを「SIGPIPEを感知する」モードにセットすることができます。そのようなポートへの書き込みが EPIPEを発生させる状況になったら、プロセスが終了します。デフォルトでは、標準出力および標準エラー出力のポートがこのモードになっています。

SIGPWR, SIGXCPU, SIGUSR1, SIGUSR2
     On Linux platforms with thread support, these signals are used by the system and not available for Scheme.  On other systems, these signals behaves the same as described below. Linuxプラットフォームでスレッドを使用している場合は、これらのシグナルはシステムで使用されるため、Schemeからは使用できません。他のシステムではこれらのシグナルは下記の「他のシグナル」と同じ動作となります。

other signals
     Gosh installs the default signal handler, which raises <unhandled-signal-error> condition (see Conditions). Scheme programs can override it by its own signal handler.

他のシグナル
     goshはデフォルトのシグナルハンドラを設定します。デフォルトのシグナルハンドラは<unhandled-signal-error>コンディションを通知します(Conditions参照)。 Schemeプログラムはシグナル毎に独自のハンドラを設定することが可能です。

If you're using Gauche embedded in some other application, it may redefine the default behavior. goshでなく、他のアプリケーションに埋め込まれたGaucheを使っている場合、 Schemeレベルでのシグナルの使用をアプリケーションが制限している場合があります。

Use the following procedures to get/set signal handlers from Scheme. Schemeからシグナルハンドラを設定するには以下の手続きを使って下さい。

 -- Function: set-signal-handler! signals handler :optional sigmask
     SIGNALS may be a single signal number or a <sys-sigset> object, and HANDLER should be either #t, #f, #<undef>, or a procedure that takes one argument. If HANDLER is a procedure, it will be called when the process receives one of specified signal(s), with the received signal number as an argument.

     By default, the signals in SIGNALS are blocked (in addition to the signal mask in effect at that time) during HANDLER is executed, so that HANDLER won't be reentered by the same signal(s).  You can provide a <sys-sigset> object to the SIGMASK arg to specify the signals to be blocked explicitly. Note that the signal mask is per-thread; if more than one thread unblocks a signal, the handler may still be invoked during execution of the handler (in other thread) even if you specify SIGMASK.  You have to set the threads' signal mask properly to avoid such situation.

     It is safe to do anything in HANDLER, including throwing an error or invoking continuation captured elsewhere.  (However, continuations captured inside HANDLER will be invalid once you return from HANDLER). SIGNALSはシグナル番号か<sys-sigset>オブジェクト、 HANDLERは#t、#f、#<undef>、一つの引数を取る手続きのいずれかでなければなりません。 HANDLERが手続きの場合、プロセスが指定されたシグナル(のうちのいずれか)を受けた時に、そのシグナル番号を引数としてHANDLERが呼ばれます。

     デフォルトでは、HANDLERは、SIGNALSに含まれるシグナルが(その時点で有効なシグナルマスクに加えて)ブロックされた状態で実行されます。オプショナルなSIGMASK引数に <sys-sigset>オブジェクトを渡すことで、ブロックすべきシグナルを明示することもできます。ただ、シグナルマスクはスレッド毎であることに注意して下さい。もし複数のスレッドがあるシグナルをブロックしていない場合、例えSIGMASK を指定していたとしても、ひとつのスレッドでHANDLERを実行中に別のスレッドで並行してHANDLERが呼ばれる可能性はあります。各スレッドのシグナルマスクを適切に設定することでそのようなケースを避けるようにして下さい。

     HANDLERの中でできる操作にはほとんど制限がありません。 HANDLERからエラーを投げたり、他の場所で補捉された継続を呼ぶこともできます。但し、HANDLER内で補捉した継続はHANDLERから戻った時点で無効になります。

     If HANDLER is #t, the operating system's default behavior is set to the specified signal(s).  If HANDLER is #f, the specified signals(s) will be ignored. HANDLERが#tの場合、指定されたシグナルにはオペレーティングシステムのデフォルトの振るまいが設定されます。 HANDLERが#fの場合、指定されたシグナルは無視されます。

     If HANDLER is #<undef> (see Undefined values), it indicates Gauche to leave the current OS's signal handler as it is. This value isn't as much use in set-signal-handler! as in get-signal-handler: If #<undef> is passed to set-signal-handler!, it immediately returns without modifying anything.   However, if you get #<undef> from get-signal-handler, you can know that the signal handler behavior hasn't been modified by Gauche. (Note that once Gauche ever installs a signal handler, there is no way to revert back to make get-signal-handler return #<undef>). HANDLERが#<undef> (Undefined values参照) であった場合は、 Gaucheはその時点のOSレベルのシグナルハンドラを変更しません。この引数はset-signal-handler!に対してはあまり意味を持ちません; 何もせずに返るだけだからです。しかし、get-signal-handlerで#<undef>が返った場合、Gaucheがそのシグナルハンドラを一度もいじっていないことを示します。 (一度でもGaucheがシグナルハンドラをインストールした場合、 get-signal-handlerが#<undef>を再び返すことはありません。)

     Note that signal handler setting is shared among threads in multithread environment.  The handler is called from the thread which is received the signal.  See Signals and threads for details. マルチスレッドプログラムでは、シグナルハンドラの設定はスレッド間で共有されることに注意して下さい。ハンドラはシグナルを受けたスレッドで実行されます。詳しくはSignals and threadsを参照して下さい。

 -- Function: get-signal-handler signum
 -- Function: get-signal-handler-mask signum
     Returns the handler setting, or signal mask setting, of a signal SIGNUM, respectively.  See set-signal-handler! for the meaning of the return value of get-signal-handler. シグナルSIGNUMに設定されたハンドラもしくはシグナルマスクをそれぞれ返します。get-signal-handlerが返す値の意味については set-signal-handler!を参照してください。

 -- Function: get-signal-handlers
     Returns an associative list of all signal handler settings. Car of each element of returned list is a <sys-sigset> object, and cdr of it is the handler (a procedure or a boolean value) of the signals in the set. 現在の全てのシグナルハンドラの設定を連想リストにして返します。返されるリストの各要素のcarには<sys-sigset>オブジェクトが、 cdrにはそれらのシグナルに対応するハンドラ(手続きもしくはブール値)がセットされています。

 -- Function: get-signal-pending-limit
 -- Function: set-signal-pending-limit limit
     Gets/sets the maximum number of pending signals per each signal type. If the number of pending signals exceeds this limit, Gauche aborts the process.  See the explanation at the beginning of this section for the details.  LIMIT must be a nonnegative exact integer. In the current implementation the maximum number of LIMIT is 255. Setting limit to zero makes the number of pending signals unlimited. それぞれ、同一のシグナルをいくつまで保留することを許すかの現在の限界値を読み出し、また設定します。同一のシグナルが限界値を越える回数、処理されないまま保留された場合、 Gaucheはプロセスを強制終了します。本節の冒頭の説明を参照してください。 LIMITは非負の正確な整数でなければなりません。現在の実装では、LIMITに設定できる最大値は255です。また、LIMITに0を設定すると、無制限にシグナルを保留できるようになります。

 -- Macro: with-signal-handlers (handler-clause ...) thunk
     A convenience macro to install signal handlers temporarily during execution of THUNK. (Note: though this is convenient, this has certain dangerous properties described below.  Use with caution.) THUNKの実行中だけシグナルハンドラを一時的に設定する便利なマクロです (このマクロは便利ですが下に述べるような多少危険な性質もあるので、注意して使って下さい)。

     Each HANDLER-CLAUSE may be one of the following forms.

     (SIGNALS EXPR ...)
          SIGNALS must be an expression that will yield either a signal, a list of signals, or a <sys-sigset> object. Installs a signal handler for SIGNALS that evaluates EXPR ... when one of the signals in SIGNALS is delivered.

     (SIGNALS => HANDLER)
          This form sets the handler of SIGNALS to HANDLER, where HANDLER should be either #t, #f or a procedure that takes one argument.

          If HANDLER is a procedure, it will be called when the process receives one of specified signal(s), with the received signal number as an argument. If HANDLER is #t, the operating system's default behavior is set to the specified signal(s).  If HANDLER is #f, the specified signals(s) will be ignored.

     HANDLER-CLAUSEは以下のいずれかの形式です

     (SIGNALS EXPR ...)
          SIGNALSは、評価された時に単独のシグナル番号、シグナル番号のリスト、あるいは<sys-sigset>オブジェクトを生成する式でなければなりません。 SIGNALSに含まれるシグナルを受け取った時に、EXPR ...を評価するようなハンドラを設定します。

     (SIGNALS => HANDLER)
          SIGNALSは上と同じです。SIGNALSに含まれるシグナルに対して、処理HANDLERを設定します。

          HANDLERは#t、#f、一つの引数を取る手続きのいずれかでなければなりません。 HANDLERが手続きの場合、プロセスが指定されたシグナル(のうちのいずれか)を受けた時に、そのシグナル番号を引数としてHANDLERが呼ばれます。 HANDLERが#tの場合、指定されたシグナルにはオペレーティングシステムのデフォルトの振るまいが設定されます。 HANDLERが#fの場合、指定されたシグナルは無視されます。

     When the control exits from THUNK, the signal handler setting before with-signal-handlers are recovered. THUNKから制御が抜けた時に、with-signal-handlersが呼ばれた時点でのシグナルハンドラが再設定されます。

     CAVEAT: If you're setting more than one signal handlers, they are installed in serial.  If a signal is delivered before all the handlers are installed, the signal handler state may be left inconsistent.  Also note that the handler setting is a global state; you can't set "thread local" handler by with-signal-handlers, although the form may be misleading. 注意： このフォームで一つ以上のシグナルハンドラを設定する場合、それらは順にシステムに設定されます。全てのハンドラの設定が終る前にシグナルが届いた場合、シグナルハンドラの設定や再設定が不完全なままになるかもしれません。また、シグナルハンドラはグローバルな設定であり、「スレッドローカル」なハンドラを設定することはできませんが、 with-signal-handlersの形式はそれを誤解させるかもしれません。

Masking and waiting signals
...........................

A Scheme program can set a signal mask, which is a set of signals to be blocked from delivery.   If a signal is delivered which is completely blocked in the process, the signal becomes "pending".  The pending signal may be delivered once the signal mask is changed not to block the specified signal. (However, it depends on the operating system whether the pending signals are queued or not.) Schemeプログラムで、送出がブロックされるシグナルの集合であるシグナルマスクをセットできます。プロセスで完全にブロックされるシグナルが送出されると、そのシグナルは``保留''となります。保留されたシグナルは、指定されたシグナルをブロックしないようにシグナルマスクが変更されると送出されるかもしれません。 (しかし、保留されたシグナルがキューに入れられるかどうかはオペレーティングシステムに依存します。)

In multithread environment, each thread has its own signal mask. マルチスレッドの環境では、スレッド毎に独自のシグナルマスクを持ちます。

 -- Function: sys-sigmask how mask
     Modifies the current thread's signal mask, and returns the previous signal mask.   MASK should be a <sys-sigset> object to specify the new mask, or #f if you just want to query the current mask without modifying one.

     If you give <sys-sigset> object to MASK, HOW argument should be one of the following integer constants: 現在のスレッドのシグナルマスクを変更し、以前のシグナルマスクを返します。 MASKには新しいマスクを指定する<sys-sigset>オブジェクトか、あるいはマスクを変更せず現在のマスクを得るだけなら#fを渡します。

     MASKに<sys-sigset>オブジェクトを渡した場合、引数HOWは以下の整数定数のうちの1つでなければなりません。

     SIG_SETMASK
          Sets MASK as the thread's signal mask. MASKをそのスレッドのシグナルマスクとしてセットします。

     SIG_BLOCK
          Adds signals in MASK to the thread's signal mask. そのスレッドのシグナルマスクにMASKにあるシグナルを追加します。

     SIG_UNBLOCK
          Removes signals in MASK from the thread's signal mask. そのスレッドのシグナルマスクからMASKにあるシグナルを削除します。

 -- Function: sys-sigsuspend mask
     Atomically sets thread's signal mask to MASK and suspends the calling thread.  When a signal that is not blocked and has a signal handler installed is delivered, the associated handler is called, then sys-sigsuspend returns. アトミックに、スレッドのシグナルマスクをMASKにセットし、呼び出しているスレッドを一時停止します。ブロックされておらずシグナルハンドラがインストールされているシグナルが送出されると、関連付けられたハンドラが呼ばれ、sys-sigsuspendは戻ります。

 -- Function: sys-sigwait mask
     [POSIX] MASK must be a <sys-sigset> object. If any of signals in MASK is/are pending in the OS, atomically clears one of them and returns the signal number of the cleared one.   If there's no signal in MASK pending, sys-sigwait blocks until any of the signals in MASK arrives.

     You have to block all signals in MASK in all threads before calling sys-sigwait.  If there's a thread that doesn't block the signals, the behavior of sys-sigwait is undefined.

     Note: Sys-sigwait uses system's sigwait function, whose behavior is not defined if there's a signal handler on the signals it waits.  To avoid complication, sys-sigwait resets the handlers set to the signals included in MASK before calling sigwait to SIG_DFL, and restores them after sigwait returns.  If another thread changes signal handlers while sys-sigwait is waiting, the behavior is undefined; you shouldn't do that. MASKは<sys-sigset>オブジェクトでなければなりません。アトミックに、保留されたシグナルからMASKにあるシグナルの1つをクリアし、クリアしたシグナルの番号を返します。MASKにあるシグナルが1つも保留されていなければ、sys-sigwaitはシグナルが届くまでブロックします。

     sys-sigwaitを呼ぶ前に、MASKにある全てのシグナルを、全スレッドからブロックしておく必要があります。シグナルをブロックしていないスレッドがある場合、sys-sigwaitの動作は未定義です。

     註：sys-sigwaitはシステムのsigwait関数を呼び出しますが、この関数は待つべきシグナルにシグナルハンドラが設定されていた場合の振る舞いが未定義となっています。困ったことになるのを避けるために、 sys-sigwaitはまずMASKに含まれるシグナルにハンドラが設定されていたらそれをSIG_DFLにリセットしてから sigwaitを呼び出し、それが戻った後でハンドラを元に戻します。 sys-sigwaitが待っている間に他のスレッドでシグナルハンドラを変更してはいけません。そうした場合の動作は不定です。

Signals and threads
...................

The semantics of signals looks a bit complicated in the multithread environment.   Nevertheless, it is pretty comprehensible once you remember a small number of rules.  Besides, Gauche sets up the default behavior easy to use, while allowing programmers to do tricky stuff. シグナルのセマンティクスはマルチスレッド環境では少々複雑に見えます。しかし、いくつかのルールを覚えてしまえば、とても理解しやすいものでもあります。さらにGaucheでは、プログラマの簡単に使えるようにデフォルトの振る舞いをセットアップしています。

If you don't want to be bothered by the details, just remember one thing, with one sidenote. By default, signals are handled by the primordial (main) thread.  However, if the main thread is suspended on mutex or condition variable, the signal may not be handled at all, so be careful. 細かいことは知りたくないという場合は、次の1つのことだけを覚えておいて下さい。デフォルトでは、シグナルはメインスレッドで処理されます。しかし、メインスレッドがmutexや条件変数で一時停止している場合は、シグナルは全く処理されないので注意が必要です。

Now, if you are curious about the details, here are the rules: 詳細に興味がある場合は、ここにルールがあります。

  * The signal handler setting is shared by all threads. シグナルハンドラのセッティングは、全てのスレッドで共有されます。

  * The signal mask is thread-specific. シグナルマスクはスレッド固有です。

  * If a process receives an asynchronous signal (think it as a signal delivered from other processes), one thread is chosen, out of threads which don't block that signal. プロセスが非同期のシグナルを受け取ったら(他のプロセスからシグナルが送出されたと考えて下さい)、そのシグナルをブロックしていないスレッドのうちから任意の1つのスレッドが選ばれます。

  * The signal handler is run on the chosen thread. However, if the chosen thread is waiting for acquiring a mutex lock or a condition variable, the handling of signal will be delayed until the thread is restarted.   Signal delivery itself doesn't restart the thread. シグナルハンドラは選択されたスレッドにおいて実行されます。しかし、選択されたスレッドがmutexのロックの獲得や条件変数を待っている場合は、シグナルの処理はそのスレッドが再開するまで遅延されます。シグナルの送出自体はスレッドを再開しません。

Now, these rules have several implications. これらのルールにはいくつかの暗黙の了解があります。

If there are more than one thread that don't block a particular signal, you can't know which thread receives the signal. Such a situation is much less useful in Gauche than C programs because of the fact that the signal handling can be delayed indefinitely if the receiver thread is waiting on mutex or condition variable. So, it is recommended to make sure, for each signal, there is only one thread that can receive it. 特定のシグナルをブロックしないスレッドが1つ以上ある場合、どのスレッドがそのシグナルを受け取るかを知る術はありません。そのような状況は、GaucheにおいてはCプログラムよりもさらに不便です。なぜなら、受信側のスレッドがmutexや条件変数で待機している場合、シグナル処理は無期限に遅延されうるからです。したがって、それぞれのシグナルについて、それを受け取ることのできるスレッドが常にただの1つしかないようにすることを推奨します。

In Gauche, all threads created by make-thread (see Thread procedures) blocks all the signals by default (except the reserved ones).   This lets all the signals to be directed to the primordial (main) thread. Gaucheでは、make-thread(Thread procedures参照) で作られた全てのスレッドは、デフォルトで全てのシグナル(予約済みを除く) をブロックします。これは、全てのシグナルがメインスレッドへ送られるということです。

Another strategy is to create a thread dedicated for handling signals.  To do so, you have to block the signals in the primordial thread, then create the signal-handling thread, and within that thread you unblock all the signals. Such a thread can just loop on sys-pause. もう1つの戦略は、シグナル処理のみを行うスレッドを作る方法です。

もしシステムがsys-sigwaitをサポートしていれば、ハンドルしたい全てのシグナルを全てのスレッドでブロックしておき、シグナル処理専用のスレッドでsys-sigwaitを呼び出してシグナルの受信を待つことができます。sys-sigwaitの返り値がシグナル番号なので、その値でディスパッチしてください。この方法ではシグナルハンドラが呼び出されることはありません。

sys-sigwaitを使わないのであれば、メインスレッドでシグナルをブロックして、シグナル処理専用スレッドを作り、そのスレッドで全てのシグナルを受け付けることができます。そのようなスレッドはsys-pause で単にループしていれば良いでしょう。sys-pauseがシグナルで中断されると、シグナルハンドラがシグナル処理専用スレッドで呼び出されます。

     (thread-start!
       (make-thread
         (lambda ()
           (sys-sigmask SIG_SETMASK (make <sys-sigset>)) ;;empty mask
           (let loop () (sys-pause) (loop)))))

Complicated application may want to control per-thread signal handling precisely.   You can do so, just make sure that at any moment only the designated thread unblocks the desired signal. 複雑なアプリケーションでは、正確にスレッド毎のシグナル処理を制御したいかもしれません。それは、いつでも、指定されたスレッドのみが望むシグナルをブロックしないようにすれば、可能です。

System inquiry
--------------

 -- Function: sys-uname
     [POSIX] Returns a list of five elements, (SYSNAME NODENAME RELEASE VERSION MACHINE). [POSIX] 次の5要素のリストを返します。 (SYSNAME NODENAME RELEASE VERSION MACHINE)。

 -- Function: sys-gethostname
     Returns the host name.  If the system doesn't have gethostname(), the second element of the list returned by sys-uname is used. ホスト名を返します。システムでgethostname()が使えない場合、 sys-unameが返すリストの2番目の要素が使われます。

 -- Function: sys-getdomainname
     Returns the domain name.  If the system doesn't have getdomainname(), "localdomain" is returned. ドメイン名を返します。システムでgetdomainname()が使えない場合、 "localdomain"が返されます。

 -- Function: sys-getcwd
     [POSIX] Returns the current working directory by a string. If the current working directory couldn't be obtained from the system, an error is signaled.   See also sys-chdir (see Other file operations), current-directory (see Directory utilities). [POSIX] 現在の作業ディレクトリを文字列で返します。システムから現在の作業ディレクトリが得られない場合は、エラーが通知されます。 sys-chdir(Other file operations参照)、current-directory (Directory utilities参照)も参照して下さい。

 -- Function: sys-getgid
 -- Function: sys-getegid
     [POSIX] Returns integer value of real and effective group id of the current process, respectively. Use sys-gid->group-name or sys-getgrgid to obtain the group's name and other information associated to the returned group id (see Unix groups and users). [POSIX] 現在のプロセスの実グループIDと実効グループIDをそれぞれ整数で返します。返されたグループIDからグループ名その他の情報を得るには sys-gid->group-nameやsys-getgrgidを使って下さい (Unix groups and users参照)。

 -- Function: sys-setgid gid
     [POSIX] Sets the effective group id of the current process. [POSIX] 現在のプロセスの実効グループIDをセットします。

 -- Function: sys-getuid
 -- Function: sys-geteuid
     [POSIX] Returns integer value of real and effective user id of the current process, respectively. Use sys-uid->user-name or sys-getpwuid to obtain the user's name and other information associated to the returned user id (see Unix groups and users). 現在のプロセスの実ユーザIDと実効ユーザIDをそれぞれ整数で返します。返されたユーザIDからユーザ名その他の情報を得るには sys-uid->user-nameやsys-getpwuidを使って下さい (Unix groups and users参照)。

 -- Function: sys-setuid uid
     [POSIX] Sets the effective user id of the current process. 現在のプロセスの実効ユーザIDをセットします。

 -- Function: sys-setugid?
     Returns true iff the process is running with suid/sgid-ed (that is, the program's suid and/or sgid bit is set.)

     Note: If the platform has issetugid() call, we use it. Otherwise, we remember the if real (user|group) id and effective (user|group) id differ or not at the initialization time. (In the latter case, we can't detect the case that the process changes [e]uid/[e]gid before initializing Gauche; keep it in mind if libgauche is used as an embedded Scheme engine). プロセスがsuid/sgidされていたら#tを、そうでなければ#fを返します。

     註：プラットフォームがissetugid()を持っていればそれを呼びます。そうでない場合は、初期化時にリアルuid/gidと実効uid/gidが異なるかどうかを記憶しています。(後者の場合、Gaucheが組み込みSchemeエンジンとして使われていて、プロセスがGauche初期化前に[e]uid/[e]gidを変更していたケースは検出できないことに留意してください)。

 -- Function: sys-getgroups
     [POSIX] Returns a list of integer ids of supplementary groups. [POSIX] 補助的なグループのIDの整数のリストを返します。

 -- Function: sys-setgroups gids
     Sets the current process's groups to the given list of integer group ids. The caller must have the appropriate privilege.

     This procedure is only available when the feature id gauche.sys.setgroups exists.  Use cond-expand for the portable program: 現在のプロセスのグループIDのリストを、引数GIDSで与えたグループIDのリストに置き換えます。呼び出すプロセスは適切な特権を持っていなければなりません。

     この手続きは、機能識別子gauche.sys.setgroupsがあるときのみ使えます。ポータブルなコードではcond-expandを用いてください。

          (cond-expand
            [gauche.sys.setgroups (sys-setgroups '(0 1))]
            [else])

 -- Function: sys-getlogin
     [POSIX] Returns a string of the name of the user logged in on the controlling terminal of the current process. If the system can't determine the information, #f is returned. [POSIX] 現在のプロセスの制御端末にログインしているユーザの名前を文字列で返します。システムがその情報を決定できない場合、#fが返されます。

 -- Function: sys-getpgrp
     [POSIX] Returns a process group id of the current process. [POSIX] 現在のプロセスのプロセスグループIDを返します。

 -- Function: sys-getpgid pid
     Returns a process group id of the process specified by PID. If PID is zero, the current process is used. PIDで指定されたプロセスのプロセスグループIDを返します。 PIDが0の場合、現在のプロセスが使われます。

     Note that getpgid() call is not in POSIX.  If the system doesn't have getpgid(), sys-getpgid still works if PID is zero (it just calls sys-getpgrp), but signals an error if PID is not zero. getpgid()はPOSIXではないことに注意して下さい。システムにgetpgid()がない場合、PIDが0ならば sys-getpgidがまだ動作しますが(それは単にsys-getpgrpを呼びます) 、PIDが0でない場合はエラーが通知されます。

 -- Function: sys-setpgid pid pgid
     [POSIX] Sets the process group id of the process PID to PGID. If PID is zero, the process ID of the current process is used.  If PGID is zero, the process ID of the process specified by pid is used.  (Hence sys-setpgid(0, 0) sets the process group id of the current process to the current process id). [POSIX] プロセスPIDのプロセスグループIDをPGIDにセットします。 PIDが0ならば、現在のプロセスのプロセスIDが使われます。 PGIDが0ならば、pidで指定されたプロセスのプロセスIDが使われます。 (したがって、sys-getpgid(0, 0)は、現在のプロセスのプロセスグループIDを現在のプロセスIDにセットします。)

 -- Function: sys-setsid
     [POSIX] Creates a new session if the calling process is not a process group leader. [POSIX] 呼んでいるプロセスがプロセスグループリーダでなければ、新しいセッションを作ります。

 -- Function: sys-getpid
 -- Function: sys-getppid
     [POSIX] Returns the current process id and the parent process id, respectively. [POSIX] 現在のプロセスIDと親プロセスのIDをそれぞれ返します。

 -- Function: sys-times
     [POSIX]

 -- Function: sys-ctermid
     [POSIX]  Returns the name of the controlling terminal of the process. This may be just a "/dev/tty".   See also sys-ttyname. [POSIX] プロセスの制御端末の名前を返します。これは単に``/dev/tty''かもしれません。sys-ttynameも参照して下さい。

 -- Function: sys-getrlimit resource
 -- Function: sys-setrlimit resource current :optional maximum
     [POSIX] Get and set resource limits respectively. RESOURCE is an integer constant to specify the resource of concern.  The following constants are defined. (The constants marked as bsd and/or linux indicates that they are not defined in POSIX but defined in BSD and/or Linux. Other systems may or may not have them.  Consult getrlimit manpage of your system for the details.) プロセスのリソースリミットを取得あるいは設定します。 RESOURCEはリソースの種類を指定する整数値です。以下にリストする定数が定義されています。 (bsd、linuxとマークされている値は、POSIXでは定義されていないけれどBSDもしくはLinuxで定義されていることを示します。他のプラットフォームでそれらが定義されているかどうかは、該当システムのgetrlimitのマニュアルを参照してください。)

          RLIMIT_AS                      RLIMIT_CORE
          RLIMIT_CPU                     RLIMIT_DATA
          RLIMIT_FSIZE                   RLIMIT_LOCKS
          RLIMIT_MEMLOCK (bsd/linux)     RLIMIT_MSGQUEUE (linux)
          RLIMIT_NICE (linux)            RLIMIT_NOFILE
          RLIMIT_NPROC (bsd/linux)       RLIMIT_RSS (bsd/linux)
          RLIMIT_RTPRIO (linux)          RLIMIT_SIGPENDING (linux)
          RLIMIT_SBSIZE                  RLIMIT_STACK
          RLIMIT_OFILE

 -- Function: sys-nice inc
     [POSIX] Adds INC, which must be an exact integer, to the current process's nice value.  Only the root user can specify negative INC value. Returns the new nice value. 現在のプロセスのnice値にINCを加算します。INCは正確な整数でなければなりません。ルートユーザのみがINCに負の値を指定できます。新たなnice値を返します。

 -- Function: sys-strerror errno
     ERRNO must be an exact nonnegative integer representing a system error number.  This function returns a string describing the error. ERRNOはシステムエラー番号を表現する非負正確整数でなければなりません。この関数はエラーを説明する文字列を返します。

     To represent ERRNO, the following constants are defined. Each constant is bound to an exact integer representing the system's error number.  Note that the actual value may differ among systems, and some of these constants may not be defined on some systems. ERRNOを表現するのに、以下の定義済み定数が使えます。各定数はシステムエラーを表現する非負正確整数に束縛されています。実際の値はシステムごとに違い、またシステムによっては定義されていない定数があるということに注意してください。

          E2BIG             EHOSTDOWN         ENETDOWN          ENXIO
          EACCES            EHOSTUNREACH      ENETRESET         EOPNOTSUPP
          EADDRINUSE        EIDRM             ENETUNREACH       EOVERFLOW
          EADDRNOTAVAIL     EILSEQ            ENFILE            EPERM
          EADV              EINPROGRESS       ENOANO            EPFNOSUPPORT
          EAFNOSUPPORT      EINTR             ENOBUFS           EPIPE
          EAGAIN            EINVAL            ENOCSI            EPROTO
          EALREADY          EIO               ENODATA           EPROTONOSUPPORT
          EBADE             EISCONN           ENODEV            EPROTOTYPE
          EBADF             EISDIR            ENOENT            ERANGE
          EBADFD            EISNAM            ENOEXEC           EREMCHG
          EBADMSG           EKEYEXPIRED       ENOKEY            EREMOTE
          EBADR             EKEYREJECTED      ENOLCK            EREMOTEIO
          EBADRQC           EKEYREVOKED       ENOLINK           ERESTART
          EBADSLT           EL2HLT            ENOMEDIUM         EROFS
          EBFONT            EL2NSYNC          ENOMEM            ESHUTDOWN
          EBUSY             EL3HLT            ENOMSG            ESOCKTNOSUPPORT
          ECANCELED         EL3RST            ENONET            ESPIPE
          ECHILD            ELIBACC           ENOPKG            ESRCH
          ECHRNG            ELIBBAD           ENOPROTOOPT       ESRMNT
          ECOMM             ELIBEXEC          ENOSPC            ESTALE
          ECONNABORTED      ELIBMAX           ENOSR             ESTRPIPE
          ECONNREFUSED      ELIBSCN           ENOSTR            ETIME
          ECONNRESET        ELNRNG            ENOSYS            ETIMEDOUT
          EDEADLK           ELOOP             ENOTBLK           ETOOMANYREFS
          EDEADLOCK         EMEDIUMTYPE       ENOTCONN          ETXTBSY
          EDESTADDRREQ      EMFILE            ENOTDIR           EUCLEAN
          EDOM              EMLINK            ENOTEMPTY         EUNATCH
          EDOTDOT           EMSGSIZE          ENOTNAM           EUSERS
          EDQUOT            EMULTIHOP         ENOTSOCK          EWOULDBLOCK
          EEXIST            ENAMETOOLONG      ENOTTY            EXDEV
          EFAULT            ENAVAIL           ENOTUNIQ          EXFULL
          EFBIG

 -- Function: sys-errno->symbol k
 -- Function: sys-symbol->errno symbol
     These procedures convert between integer error number and the symbol of its unix name (e.g. EINTR).

     If the given error number or name isn't available on the running platform, those procedures return #f.  See sys-strerror above for potentially available error names.

     Valid error names and their actual values differ among platforms. These procedures make it easy to write portable meta-code that deal with system errors.

     これらの手続きは、整数のエラー番号と、Unixでのエラー名を表すシンボル(例:EINTR)とを相互に変換します。

     与えられたエラー番号もしくはエラー名が実行中のプラットフォームで有効でない場合は #fが返されます。使えるかもしれないエラー名については上のsys-strerror の項を参照してください。

     有効なエラー名およびその整数値はプラットフォーム毎に異なります。これらの手続きは、システムエラーを扱うメタなコードをポータブルに書く時に役立つでしょう。

Time
----

Gauche has two representations of time, one is compatible to POSIX API, and the other is compatible to SRFI-18, SRFI-19 and SRFI-21. Most procedures accept both representations; if not, the representation the procedure accepts is indicated as either 'POSIX time' or 'SRFI time'. Gaucheでは時間は2種類の表現を持ちます。ひとつはPOSIX APIとコンパチブルな表現で、もう一つはSRFI-18、SRFI-19、SRFI-21とコンパチブルな表現です。多くの手続きはどちらの表現も理解しますが、そうでない場合は適用可能な表現を'POSIX time'または'SRFI time'と表記します。

POSIX time is represented by a real number which is a number of seconds since Unix Epoch (Jan 1, 1970, 0:00:00GMT). Procedure sys-time, which corresponds to POSIX time(2), returns this time representation. POSIX timeは実数で、Unix Epoch(Jan 1, 1970, 0:00:00GMT)からの秒数で表現されます。POSIXのtime(2)に対応するsys-time手続きはこの表現を返します。

SRFI-compatible time is represented by an object of <time> class, which keeps seconds and nanoseconds, as well as the type of the time (UTC, TAI, duration, process time, etc). Current-time returns this representation. SRFI互換の時間は<time>クラスのインスタンスとして表現され、秒、およびナノ秒のスロットを持ちます。また、時間の種別(UTC、TAI、期間、プロセス時間、他)も保持しています。 Current-timeはこの表現を返します。

POSIX time
..........

 -- Function: sys-time
     [POSIX] Returns the current time in POSIX time (the time since Epoch (00:00:00 UTC, January 1, 1970), measured in seconds).  It may be a non-integral number, depending on the architecture.

     Note that POSIX's definition of ``seconds since the Epoch'' doesn't take leap seconds into account. [POSIX] 現在の時間を POSIX 時間(エポック(00:00:00 UTC, January 1, 1970) からの秒数)で返します。マシンのアーキテクチャによっては、不正確数であるかもしれません。

 -- Function: sys-gettimeofday
     Returns two values.  The first value is a number of seconds, and the second value is a fraction in a number of microseconds, since 1970/1/1 0:00:00 UTC.   If the system doesn't have gettimeofday call, this function calls time(); in that case, microseconds portion is always zero. 2つの値を返します。1970/1/1 0:00:00 UTC を基準として、 1つ目の値は秒数、2つ目の値は端数をマイクロ秒で表したものです。システムが gettimeofday 呼び出しをサポートしていない場合、この手続きは time() を呼び出し、その場合はマイクロ秒の部分はいつも 0 です。

 -- Builtin Class: <sys-tm>
     Represents struct tm, a calendar date.  It has the following slots. カレンダーである、struct tm を表します。以下のスロットを持ちます。
      -- Instance Variable of <sys-tm>: sec
          Seconds. 0-61. 秒。0-61。

      -- Instance Variable of <sys-tm>: min
          Minutes. 0-59. 分。0-59。

      -- Instance Variable of <sys-tm>: hour
          Hours.  0-23. 時。0-23。

      -- Instance Variable of <sys-tm>: mday
          Day of the month, counting from 1.  1-31. 月の日。1 から数える。1-31。

      -- Instance Variable of <sys-tm>: mon
          Month, counting from 0.  0-11. 月。0 から数える。0-11。

      -- Instance Variable of <sys-tm>: year
          Years since 1900, e.g. 102 for the year 2002. 1900年からの年数。例えば、102 なら 2002年。

      -- Instance Variable of <sys-tm>: wday
          Day of the week.  Sunday = 0 .. Saturday = 6. 曜日。日曜は 0 .. 土曜は 6。

      -- Instance Variable of <sys-tm>: yday
          Day of the year.  January 1 = 0 .. December 31 = 364 or 365. 1年の中での日数。1月1日は 0 .. 12月31日は 364 か 365。

      -- Instance Variable of <sys-tm>: isdst
          A flag that indicates if the daylight saving time is in effect. Positive if DST is in effect, zero if not, or negative if unknown. 夏時間が有効であるかどうかを指定するフラグ。有効なら正の数、無効なら 0、分からなければ負の数。

 -- Function: sys-gmtime time
 -- Function: sys-localtime time
     [POSIX] Converts TIME to <sys-tm> object, represented in GMT or local timezone, respectively.   TIME can be either POSIX-time or SRFI-time. [POSIX] TIME を <sys-tm> オブジェクトに変換します。標準時での表現かローカルタイムゾーンでの表現かで使い分けます。 TIME は POSIX 時間か SRFI 時間です。

 -- Function: sys-ctime time
     [POSIX] Converts TIME to it string representation, using POSIX ctime(). TIME can be either POSIX-time or SRFI-time. [POSIX] TIME を POSIX の ctime() を使って文字列表現に変換します。 TIME は POSIX 時間か SRFI 時間です。

 -- Function: sys-difftime time1 time0
     [POSIX] Returns the difference of two times in the real number of seconds. TIME0 and TIME1 can be either POSIX-time or SRFI-time. [POSIX] 2つの時間の差を、秒の実数で返します。TIME0 とTIME1 は POSIX 時間か SRFI 時間です。

 -- Function: sys-asctime tm
     [POSIX] Converts <sys-tm> object TM to a string representation. [POSIX] <sys-tm> オブジェクトである TM を文字列表現に変換します。

 -- Function: sys-strftime format tm
     [POSIX] Converts <sys-tm> object TM to a string representation, according to a format string FORMAT. [POSIX] <sys-tm> オブジェクトである TM を、フォーマット文字列 FORMAT に従って文字列表現に変換します。

 -- Function: sys-mktime tm
     [POSIX] Converts <sys-tm> object TM, expressed as local time, to the POSIX-time (number of seconds since Epoch). [POSIX] ローカルタイムとして表現された <sys-tm> オブジェクトである TM を POSIX 時間(エポックからの秒数)に変換します。

 -- Function: sys-tm->alist tm
     (Deprecated function)

SRFI time
.........

 -- Builtin Class: <time>
     The <time> object also represents a point of time. ある時刻を表す<time>オブジェクトです。

      -- Instance Variable of <time>: type
          Indicates time type.  time-utc is the default, and that represents the number of seconds since Unix Epoch. SRFI-19 (see Time data types and procedures) adds more types. timeの型を表します。デフォルトはtime-utcで、Unixエポックからの秒数を表します。SRFI-19(Time data types and procedures参照) ではさらに型が追加されています。

      -- Instance Variable of <time>: second
          Second part of the time. timeの秒の部分です。

      -- Instance Variable of <time>: nanosecond
          Nanosecond part of the time. timeのナノ秒の部分です。

 -- Function: current-time
     [SRFI-18][SRFI-21] Returns the <time> object representing the current time in time-utc.   See Time data types and procedures, for it redefines current-time to allow optional argument to specify time type. [SRFI-18][SRFI-21] 現在の時間をtime-utcで表す<time>オブジェクトを返します。 Time data types and proceduresでは、current-timeが再定義され、 timeの型を指定するオプショナル引数を受け付けるようにされています。

 -- Function: time? obj
     [SRFI-18][SRFI-19][SRFI-21] Returns #t if OBJ is a time object. [SRFI-18][SRFI-19][SRFI-21] OBJがtimeオブジェクトなら#tを返します。

 -- Function: time->seconds time
 -- Function: seconds->time seconds
     [SRFI-18][SRFI-21] Converts between time object and the number of seconds (POSIX-time). TIME argument of time->seconds has to be a <time> object. [SRFI-18][SRFI-21] timeオブジェクトと秒数(POSIX時間)を変換します。 time->secondsの引数TIMEは、<time>オブジェクトでなければなりません。

Process management
------------------

The following procedures provide pretty raw, direct interface to the system calls. See also High-level process interface, which provides more convenient process handling on top of these primitives. 以下の手続きは、システムコールに対する直接的なインタフェースを提供します。 High-level process interfaceも合わせて参照して下さい。より高レベルの便利な手続きが定義されています。

Fork and exec
.............

 -- Function: sys-system command
     [POSIX] Runs COMMAND in a subprocess.   COMMAND is usually passed to sh, so the shell metacharacters are interpreted. [POSIX] サブプロセスでCOMMANDを実行します。COMMANDは通常、 shへ渡されるので、シェルのメタキャラクタは解釈されます。

     This function returns an integer value system() returned. Since POSIX doesn't define what system() returns, you can't interpret the returned value in a portable way. この関数は、system()が返した整数値を返します。 POSIXはsystem()が何を返すかを定義していないので、戻り値をポータブルな方法で解釈することができません。

     On Windows native platforms this will pass the argument to cmd.exe. Windowsネイティブな環境では、引数はcmd.exeに渡されます。

 -- Function: sys-fork
     [POSIX] Fork the current process.  Returns 0 if you're in the child process, and a child process' pid if you're in the parent process. All the opened file descriptors are shared between the parent and the child.  See fork(2) of your system for details. [POSIX] 現在のプロセスをフォークします。子プロセスにいるならば0が返り、親プロセスにいるならば子プロセスのプロセスIDが返ります。全ての開かれているファイルディスクリプタは、親プロセスと子プロセスで共有されます。詳細は、システムのfork(2)を参照して下さい。

     If the child process runs some Scheme code and exits instead of calling sys-exec, it should call sys-exit instead of exit to terminate itself. Normal exit call tries to flush the file buffers, and on some OS it messes up the parent's file buffers. 子プロセスがsys-execを呼ぶ代わりにSchemeコードを実行して終了する場合は、exitではなくsys-exitを呼ぶ必要があります。通常のexitの呼び出しはファイルバッファのフラッシュを試み、 OSによっては親のファイルバッファを混乱させるでしょう。

     It should be noted that sys-fork is not safe when multiple threads are running.  Because fork(2) copies the process' memory image which includes any mutex state, a mutex which is locked by another thread at the time of sys-fork remains locked in the child process, nevertheless the child process doesn't have the thread that unlock it! (This applies to the internal mutexes as well, so even you don't use Scheme mutex explicitly, this situation can always happen.)

     If what you want is to spawn another program in a multi-threaded application, use sys-fork-and-exec explained below. If you absolutely need to run Scheme code in the child process, a typical technique is that you fork a manager process at the beginning of application, and whenever you need a new process you ask the manager process to fork one for you. sys-forkは複数のスレッドが走っている時には安全ではないことに注意してください。fork(2)システムコールはプロセスのメモリイメージを複製しますが、それには他のスレッドでロックされているmutexも含まれます。もしsys-forkの瞬間に他のスレッドが何かをロックしていたとすれば、子プロセスでもその資源はロックされたままになりますが、その時子プロセスはもはやその資源をアンロックするスレッドを持っていません。 (これは内部で使っているmutexにも起こり得るため、Schemeレベルでmutexを全く使っていないとしても防ぐことはできません)。

     やりたいことが、マルチスレッドアプリケーションで別プログラムをspawnすることであるなら、下に説明するsys-fork-and-execを使ってください。どうしても別プロセスでSchemeコードを走らせたいのなら、よくある方法は、アプリケーションの起動後すぐにマネージャプロセスとなる子プロセスをfork しておき、新たなプロセスが欲しくなったらそのマネージャプロセスに forkを依頼するという方法です。

     This procedure is not available on Windows native platforms. Windowsネイティブな環境ではこの手続きは使えません。

 -- Function: sys-exec command args :key directory iomap sigmask
     [POSIX+] Execute COMMAND with ARGS, a list of arguments. The current process image is replaced by COMMAND, so this function never returns. [POSIX+] COMMANDを引数のリストであるARGSを伴って実行します。現在のプロセスイメージはCOMMANDに置き換えられるので、この関数は戻りません。

     All elements of ARGS must be strings.  The first element of ARGS is used as argv[0], i.e. the program name. ARGSの全ての要素は文字列でなければなりません。 ARGSの最初の要素は、argv[0]、すなわちプログラム名として使われます。

     The keyword argument DIRECTORY must be a string of a directory name or #f. If it is a string, sys-exec change current working directory there before executing the program. キーワード引数DIRECTORYは文字列によるディレクトリ名か#fでなければなりません。文字列だった場合、sys-execはプログラムを実行する前にカレントワーキングディレクトリを指定ディレクトリに移動します。

     The IOMAP keyword argument, when provided, specifies how the open file descriptors are treated.  It must be the following format: キーワード引数のIOMAPは、与えられた場合は、開かれているファイルディスクリプタがどのように扱われるかを指定します。この引数は以下のフォーマットでなければなりません。

          ((to-fd . from-port-or-fd) ...)

     To-fd must be an integer, and from-port-or-fd must be an integer file descriptor or a port. Each element of the list makes the file descriptor of from-port-or-fd of the current process be mapped to the file descriptor to-fd in the executed process. to-fdは整数でなければならず、from-port-or-fdは整数のファイルディスクリプタかポートでなければなりません。リストのそれぞれの要素は、現在のプロセスのfrom-port-or-fdのファイルディスクリプタを、実行されているプロセスのファイルディスクリプタ to-fdにマップさせます。

     If IOMAP is provided, any file descriptors other than specified in the iomap list will be closed before exec().  Otherwise, all file descriptors in the current process remain open. IOMAPが与えられると、iomapリストで指定されていないいかなるファイルディスクリプタもexec()の前に閉じられます。さもなければ、現在のプロセスの全てのファイルディスクリプタは開かれたままになります。

          (sys-exec "ls" '("ls" "-l")) => ;; ls is executed.

          (let ((out (open-output-file "ls.out")))
            (sys-exec "ls" '("ls" "-l") :iomap `((2 . 1) (1 . ,out)))
             =>
            ;; ls is executed, with its stderr redirected
            ;; to the current process's stdout, and its
            ;; stdout redirected to the file "ls.out".

     The SIGMASK keyword argument can be an instance of <sys-sigset> or #f (see Signal, for the details of signal masks). If it is an instance of <sys-sigset>, the signal mask of calling thread is replaced by it just before exec(2) is called. It is useful, for example, to run an external program from a thread where all signals are blocked (which is the default; see Signals and threads). Without setting SIGMASK, the execed process inherits calling thread's signal mask and become a process that blocks all signals, which is not very convenient in most cases. SIGMASKキーワード引数には、<sys-sigset>のインスタンスか #fを渡すことができます (シグナルマスクについてはSignalを参照して下さい)。<sys-sigset>のインスタンスを渡した場合、この関数を呼び出したスレッドのシグナルマスクが、exec(2)を呼ぶ直前にそれによって置き換えられます。これは、全てのシグナルをブロックしているスレッドから外部プログラムを走らせるような場合に便利です (Signals and threadsで述べるように、新たなスレッドは全てのシグナルをデフォルトでブロックします)。このような場合にSIGMASKを設定しないと、execされたプロセスはスレッドのシグナルマスクを継承し、ほとんどのシグナルを受け付けないプロセスとなってしまうからです。通常、それはあまり便利ではありません。

     When sys-exec encounters an error, most of the time it raises an error condition. Once the file descriptors are permuted, however, it would be impractical to handle errors in reasonable way (you don't even know stderr is still available!), so Gauche simply exits on the error. sys-execがエラーに遭遇すると、たいていの場合エラー条件を投げます。しかし一旦ファイルディスクリプタの順番が変えられると、合理的な方法でエラーを処理することは実行不可能です(標準エラーがまだ有効かどうかさえ知る術がありません)。したがって、その場合はGaucheはエラー時には単に終了するだけです。

     On Windows native platforms, only redirections of stdin, stdout and stderr are handled.   Singal mask is ignored, for Windows doesn't have signals as the means of interprocess communication. Windowsネイティブ環境では、標準入力、標準出力、標準エラー出力に関するリダイレクションのみが処理されます。Windowsはプロセス間通信としてのシグナルをサポートしないので、シグナルマスクは無視されます。

 -- Function: sys-fork-and-exec command args :key directory iomap sigmask detached
     Like sys-exec, but executes fork(2) just before remapping I/O, altering signal mask and call execvp(2). Returns child's process id.  The meanings of arguments are the same as sys-exec.

     It is strongly recommended to use this procedure instead of sys-fork and sys-exec combination when you need to spawn another program while other threads are running. No memory allocation nor lock acquisition is done between fork(2) and execvp(2), so it's pretty safe in the multithreaded environment. sys-execと同じですが、ファイルディスクリプタとシグナルマスクを変更して execvp(2)を実行する直前に、fork(2)を実行します。子プロセスのプロセスidを返します。引数の意味はsys-execと同じです。

     他のスレッドが走っている環境下で別プログラムをspawnしたい場合は、 sys-forkとsys-execを別々に使うのではなく、この手続きを使ってください。この手続き中では、fork(2)とexecvp(2)の間でメモリアロケーションもロックの獲得も行われないため、マルチスレッド環境で実行しても安全になっています。

     On Windows native platforms, this procedure returns a Windows handle object (<win:handle>) of the created process instead of an integer process ID.  See below for Windows process handle specific API.

     Like sys-exec, only redirections of stdin, stdout and stderr are handled on Windows native platforms. Windowsネイティブ環境では、この手続きはプロセスIDではなく作られたプロセスに対するWindowsのハンドルオブジェクト (<win:handle>) を返します。Windowsプロセスハンドル特有の手続きについては後に述べます。

     また、sys-exec同様、Windowsネイティブ環境では、標準入力、標準出力、標準エラー出力に関するリダイレクションのみが処理されます。

     When a true value is given to the DETACHED keyword argument, the executed process is detached from the current process group and belongs to its own group. That is, it won't be affected to the signal sent to the process group the caller process currently belongs to. It is a part of the common idioms to start a daemon process.

     On Unix platforms, besides the executed process gets its own session by setsid(2), it performs extra fork(2) to make its parent be the init process (pid=1). (Note: It means the running process is actually a grandchild of the calling process, although that relationship isn't preserved. The returned pid is the running process's one, not the intermediate process that exits immediately.)

     On Windows native platforms, this flag causes the new process to be created with the CREATE_NEW_PROCESS_GROUP creation flag. DETACHEDキーワード引数に真の値が与えられた場合、実行されるプロセスは現在のプロセスグループからは切り離されます。つまり、現在のプロセスグループに送られるシグナルを、新しいプロセスは受け取りません。この動作はデーモンプロセスを作る際の標準的な手順のひとつです。

     Unixでは、実行されるプロセスがsetsid(2)を呼んで独自のセッションを作るだけでなく、余分なfork(2) を実行することで親をinitプロセス (pid=1) に切り替えます。 (つまり、実行されるプロセスは実は呼び出すプロセスの孫にあたります。親子関係はなくなりますが。返されるpidは実際に走っているこのプロセスのもので、すぐに終了する中間プロセスのものではありません。)

     Windowsネイティブ環境では、このフラグがあるとプロセス作成時にCREATE_NEW_PROCESS_GROUPフラグが使われます。

Wait
....

 -- Function: sys-wait
     [POSIX] Calls system's wait(2).  The process suspends its execution until one of the child terminates.  Returns two exact integer values, the first one is the child's process id, and the second is a status code. The status code can be interpreted by the following functions. [POSIX] システムのwait(2)を呼びます。プロセスは、子プロセスの1つが終了するまでその実行を一時停止します。2つの正確整数、1つ目は子プロセスのID、 2つ目はステータスコードを返します。ステータスコードは以下の関数によって解釈できます。

 -- Function: sys-waitpid pid :key nohang untraced
     [POSIX] This is an interface to waitpid(3), an extended version of wait. [POSIX] これは、waitの拡張バージョンである、waitpid(3)へのインターフェースです。

     PID is an exact integer specifying which child(ren) to be waited. If it is a positive integer, it waits for that specific child.  If it is zero, it waits for any member of this process group.  If it is -1, it waits for any child process. If it is less than -1, it waits for any child process whose process group id is equal to the absolute value of PID. PIDは、待つべき子プロセスを指定する正確な整数です。正の整数ならば、特定の子プロセスを待ちます。0ならば、このプロセスグループのいずれかのメンバを待ちます。-1ならば、いずれかの子プロセスを待ちます。 -1よりも小さければ、プロセスグループIDがPIDの絶対値と等しいいずれかの子プロセスを待ちます。

     If there's no child process to wait, or a specific PID is given but it's not a child process of the current process, an error (<system-error>, ECHILD) is signaled. 待つべき子プロセスが存在しない場合や、PIDに具体的なプロセスIDが与えられたがそれが現在のプロセスの子プロセスでない場合はエラー(<system-error>, ECHILD)となります。

     The calling process suspends until one of those child process is terminated, unless true is specified to the keyword argument NOHANG. キーワード引数NOHANGに真値が指定されていなければ、呼んでいるプロセスは、それらの子プロセスのうちの1つが終了するまで一時停止します。

     If true is specified to the keyword argument UNTRACED, the status of stopped child process can be also returned. キーワード引数UNTRACEDに真値が指定されていれば、停止した子プロセスのステータスも返ります。

     The return values are two exact integers, the first one is the child process id, and the second is a status code.  If NOHANG is true and no child process status is available, the first value is zero. 戻り値は2つの正確整数で、1つ目は子プロセスのID、2つ目はステータスコードです。 NOHANGが真で子プロセスのステータスが利用できない場合は、1つ目の値は0です。

     On Windows native platforms, this procedure may also accept a Windows process handle (<win:handle>) object as PID to wait the specific process.  You can pass -1 as PID to wait for any children, but you cannot wait for a specific process group. Windowsネイティブ環境では、この関数はPIDにWindowsプロセスハンドル (<win:handle>)オブジェクトを受け取ることもできます。その場合はそのハンドルの指すプロセスの終了を待ちます。また、-1を渡していずれかの子プロセスの終了を待つこともできますが、特定のプロセスグループの中の子プロセスを待つことはできません。

 -- Function: sys-wait-exited? status
 -- Function: sys-wait-exit-status status
     [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-exited? returns #t if the child process is terminated normally.   sys-wait-exit-status returns the exit code the child process passed to exit(2), or the return value of main(). [POSIX] 引数はsys-waitかsys-waitpidの2番目の値として返される終了ステータスです。子プロセスが正常終了したら、sys-wait-exited?は #tを返します。sys-wait-exit-statusは、子プロセスが exit(2)に渡した終了コードか、main()の戻り値を返します。

 -- Function: sys-wait-signaled? status
 -- Function: sys-wait-termsig status
     [POSIX] The argument is an exit status returned as a second value from sys-wait or sys-waitpid. sys-wait-signaled? returns #t if the child process is terminated by an uncaught signal. sys-wait-termsig returns the signal number that terminated the child. [POSIX] 引数は、sys-waitかsys-waitpidの2つ目の戻り値である終了ステータスです。子プロセスが捕捉されないシグナルで終了した場合は、sys-wait-signaled?は #tを返します。 sys-wait-termsigは、子プロセスを終了したシグナルの番号を返します。

 -- Function: sys-wait-stopped? status
 -- Function: sys-wait-stopsig status
     [POSIX] The argument is an exit status returned as a second value from sys-waitpid. sys-wait-stopped? returns #t if the child process is stopped.   This status can be caught only by sys-waitpid with true UNTRACED argument.  sys-wait-stopsig returns the signum number that stopped the child. [POSIX] 引数は、sys-waitpidの2つ目の戻り値である終了ステータスです。子プロセスが停止されれば、sys-wait-stopped?は#tを返します。このステータスは、sys-waitpidがUNTRACED引数に真値を持っている場合にのみ捕捉されます。sys-wait-stopsigは子プロセスを停止させたシグナルの番号を返します。

On Windows native platforms, exit code is not structured as on Unix. You cannot distinguish a process being exited voluntarily or by forced termination.  Gauche uses exit code #xff09 to terminate other process with sys-kill, and the above sys-wait-* procedures are adjusted accordingly, so that sys-wait-signaled? can likely to be used to check whether if the child process is terminated by Gauche. (see Signal, for the details of signal support on Windows.) Sys-wait-stopped? never returns true on Windows native platforms (yet). Windowsネイティブ環境では、終了コードはUnixのように構造化されておらず、プロセスが自発的に終了したか強制的に終了させられたかを判断する一般的な方法はありません。Gauche自身は他のプロセスをsys-killで終了させる場合に終了コード#xff09を送り、上のsys-wait-* 手続きもそれに合わせてあります。従ってGaucheによって終了させられたプロセスでは sys-wait-signaled?でそのことを検出できる可能性が高いでしょう。 (Windows上のシグナルのサポートについてはSignalを参照してください。) Windowsネイティブ環境では、sys-wait-stopped?が真を返すことは (今のところ)ありません。

Windows specific utilities
..........................

Windows特有のユーティリティ
.................

The following procedures are to access Windows process handle. They are only available on Windows native platforms. 以下の手続きはWindowsのプロセスハンドルにアクセスするものです。 Windowsネイティブ環境でのみ提供されます。

 -- Function: sys-win-process? obj
     [Windows] Returns #t iff OBJ is a Windows process handle object. OBJがWindowsプロセスハンドルの場合に#tを、それ以外では#fを返します。

 -- Function: sys-win-process-pid handle
     [Windows] Returns an integer PID of the process represented by a Windows process handle HANDLE.  An error is signaled if HANDLE is not a valid Windows process handle.

     Note that the API to get a pid from a process handle is only provided on or after Windows XP SP1.  If you call this procedure on Windows version before that, -1 will be returned. WindowsプロセスハンドルHANDLEが示すプロセスの、整数のpid値を返します。HANDLEが有効なWindowsプロセスハンドルでない場合はエラーが通知されっす。

     プロセスハンドルからプロセスIDを得るAPIはWindows XP SP1から提供されるようになりました。それ以前のWindowsでこの手続きを呼ぶと-1が返されます。

I/O multiplexing
----------------

The interface functions for select(2). The higher level interface is provided on top of these primitives; see Simple dispatcher. select(2)へのインターフェース関数です。これらのプリミティブの上に構築された高次元のインターフェースが提供されています。Simple dispatcherを参照して下さい。

 -- Builtin Class: <sys-fdset>
     Represents fd_set, a set of file descriptors.  You can make an empty file descriptor set by make method: ファイルディスクリプタの集合であるfd_setを表します。 makeメソッドによって、空のファイルディスクリプタの集合を作れます。

          (make <sys-fdset>)

 -- Function: sys-fdset elt ...
     Creates a new <sys-fdset> instance with file descriptors specified by ELT ....  Each ELT can be an integer file descriptor, a port, or a <sys-fdset> instance. In the last case, the descriptors in the given fdset is copied to the new fdset. ELT ...で指定されたファイルディスクリプタを持つ新たな<sys-fdset>のインスタンスを作成して返します。各ELTは、ファイルディスクリプタを指定する整数、ポート、もしくは<sys-fdset>のインスタンスでなければなりません。最後の場合は、与えられたfdsetに含まれるディスクリプタが新たなfdsetにコピーされます。

 -- Function: sys-fdset-ref fdset port-or-fd
 -- Function: sys-fdset-set! fdset port-or-fd flag
     Gets and sets specific file descriptor bit of FDSET. PORT-OR-FD may be a port or an integer file descriptor. If PORT-OR-FD is a port that doesn't have associated file descriptor, sys-fdset-ref returns #f, and sys-fdset-set! doesn't modify FDSET.  FLAG must be a boolean value. FDSETの特定のファイルディスクリプタビットを取得・セットできます。 PORT-OR-FDは関連付けられたファイルディスクリプタを持っていないポートで、 sys-fdset-refは#fを返し、sys-fdset-set!はFDSETを変更しません。FLAGは真偽値でなければなりません。

     You can use generic setter of sys-fdset-ref as this: 下記のように、sys-fdset-refのジェネリックなセッタが使えます。

          (set! (sys-fdset-ref fdset port-or-fd) flag)
            == (sys-fdset-set! fdset port-or-fd flag)

 -- Function: sys-fdset-copy! dest-fdset src-fdset
     Copies the content of SRC-FDSET into DEST-FDSET. Returns DEST-FDSET. SRC-FDSETの内容をDEST-FDSETにコピーします。 DEST-FDSETを返します。

 -- Function: sys-fdset-clear! fdset
     Empties and returns FDSET. FDSETの内容をクリアし、それ自身を返します。

 -- Function: sys-fdset->list fdset
 -- Function: list->sys-fdset fds
     Converts an fdset to a list of integer file descriptors and vice versa. In fact, list->sys-fdset works just like (lambda (fds) (apply sys-fdset fds)), so it accepts ports and other fdsets as well as integer file descriptors. fdsetを整数のファイルディスクリプタのリストに変換し、またその逆を行います。実際は、list->sys-fdsetは (lambda (fds) (apply sys-fdset fds)) のように動作するため、整数のファイルディスクリプタ以外にポートや他のfdsetを与えることもできます。

 -- Function: sys-fdset-max-fd fdset
     Returns the maximum file descriptor number in FDSET. FDSETにある最大のファイルディスクリプタ番号を返します。

 -- Function: sys-select readfds writefds exceptfds :optional timeout
 -- Function: sys-select! readfds writefds exceptfds :optional timeout
     Waits for a set of file descriptors to change status. READFDS, WRITEFDS, and EXCEPTFDS are <fdset> objects to represent a set of file descriptors to watch. File descriptors in READFDS are watched to see if characters are ready to be read.   File descriptors in WRITEFDS are watched if writing to them is ok.  File descriptors in EXCEPTFDS are watched for exceptions.  You can pass #f to one or more of those arguments if you don't care about watching the condition. ステータスを変更するためにファイルディスクリプタの集合を待ちます。 READFDS、WRITEFDS、EXCEPTFDSは、注目するファイルディスクリプタの集合を表す<fdset>オブジェクトです。 READFDSにあるファイルディスクリプタは、文字を読み込む準備が出来たかどうかを検査するために監視されています。 WRITEFDSにあるファイルディスクリプタはそこへ書き込むことができるようになったか監視されています。EXCEPTFDSにあるファイルディスクリプタは例外のために監視されています。条件を監視する必要がない場合は、これらの引数の 1つ以上に#fを渡すことができます。

     TIMEOUT specifies maximum time sys-select waits for the condition change.  It can be a real number, for number of microseconds, or a list of two integers, the first is the number of seconds and the second is the number of microseconds.  If you pass #f, sys-select waits indefinitely. TIMEOUTはsys-selectが条件の変更を待つ最大の時間を指定します。それは、マイクロ秒を表す実数か、1つ目が秒数で2つ目がマイクロ秒である 2つの整数からなるリストです。#fを渡すと、sys-selectは永久に待ちます。

     sys-select returns four values.  The first value is a number of descriptors it detected status change.  It may be zero if timeout expired.  The second, third and fourth values are <fdset> object that contains a set of descriptors that changed status for reading, writing, and exception, respectively. If you passed #f to one or more of READFDS, WRITEFDS and EXCEPTFDS, the corresponding return value is #f. sys-selectは4つの値を返します。1つ目の値は、ステータスの変更を検知したディスクリプタの数です。timeoutが経過したら0になるでしょう。 2、3、4番目の値は、それぞれ読み込み、書き出し、例外のステータスを変更するディスクリプタの集合を含む<fdset>オブジェクトです。 READFDS、WRITEFDS、EXCEPTFDSのうちの1つ以上に#fを渡すと、対応する戻り値は#fになります。

     sys-select! variant works the same as sys-select, except it modifies the passed <fdset> arguments. sys-select creates new <fdset> objects and doesn't modify its arguments. sys-select!の仲間は、それが渡された引数<fdset>を変更することを除けば、sys-selectと同じように動作します。 sys-selectは、新しい<fdset>オブジェクトを作り、その引数を変更しません。

Garbage collection
------------------

The garbage collector runs implicitly whenever it is necessary, and you don't usually need to worry about it.  However, in case if you do need to worry, here are a few procedures you can use. ガベージコレクタは必要になった時に自動的に走るので、普段気にする必要はないでしょう。けれどももし気にする必要が出てきた時は、いくつか使える手続きがあります。

 -- Function: gc
     Trigger a full GC.  It may be useful if you want to reduce interference of GC in certain parts of code by calling this immediately before that. フルGCを起動します。GCの影響をなるべく排除したいコードがある場合、その直前にこの手続きを呼ぶことで影響を減らせるかもしれません。

 -- Function: gc-stat
     Returns a list of lists, each inner list contains a keyword and related statistics. Current statistics include :total-heap-size, :free-bytes, :bytes-since-gc and :total-bytes. GCに関する統計情報を返します。返り値はリストのリストで、内側のリストはキーワードと対応する数値からなります。現在、返されるキーワードは :total-heap-size、 :free-bytes、:bytes-since-gc、:total-bytesです。

Miscellaneous system calls
--------------------------

 -- Function: sys-pause
     [POSIX] Suspends the process until it receives a signal whose action is to either execute a signal-catching function or to terminate the process.  This function only returns when the signal-catching function returns.  The returned value is undefined. [POSIX] シグナルキャッチ関数の実行かプロセスの終了を指示するシグナルを受け取るまでプロセスを一時停止します。この関数は、シグナルキャッチ関数が戻ったときにのみ戻ります。戻り値は未定義です。

     Note that just calling pause() doesn't suffice the above semantics in Scheme-level.  Internally this procedure calls sigsuspend() with the current signal mask. Schemeレベルでは、pause()を呼ぶだけでは上記のセマンティクスを満足しません。内部的にこの手続きは現在のシグナルマスクを伴って、 sigsuspend()を呼びます。

 -- Function: sys-alarm seconds
     [POSIX] Arranges a SIGALRM signal to be delivered after SECONDS. The previous settings of the alarm clock is canceled.  Passing zero to SECONDS doesn't schedule new alarm. Returns the number of seconds remaining until previously scheduled alarm was due to be delivered (or zero if no alarm is active). [POSIX] SIGALRMシグナルがSECONDS秒後に送出されるように準備します。以前のアラームクロックのセッティングはキャンセルされます。 SECONDSに0を渡すと、新しいアラームをスケジューリングしません。以前にスケジューリングされていたアラームが送出されるまでの残り時間を秒数で返します(アラームがアクティブでない場合は0を返します)。

 -- Function: sys-sleep seconds :optional (no-retry #f)
     [POSIX] Suspends the calling thread until the specified number of seconds elapses.

     Note that libc's sleep(3) could return before the specified interval if the calling thread receives a signal; in that case, sys-sleep automatically restarts sleep(3) again with remaining time interval (after invoking Scheme signal handlers if there's any) by default. So you can count on the thread does sleep at least the specified amount of time.

     If you do want sys-sleep to return prematurely upon receiving a signal, you can give a true value to an optional argument NO-RETRY.

     The reason that we retries by default is that Gauche's GC may use signals to synchronize between threads.   If GC is invoked by one thread While another thread is sleeping on sleep(3), it may return prematurely.  It could happen often if other threads allocate a lot, which could make sys-sleep unreliable.

     Returns zero if it sleeps well (which is always the case if NO-RETRY is false), or the number of unslept seconds if it is woke up by a signal. 指定された秒数が経過するまで、呼び出したスレッドを一時停止します。

     libcのsleep(3)は、シグナルを受けると指定時間経過前であっても戻ってきます。その場合sys-sleepはデフォルトで、(Schemeのシグナルハンドラがあればそれを呼び出した後)残り時間を引数にして再びsleep(3)を呼び出します。従ってsys-sleepを呼び出したスレッドは、少なくとも指定した時間、眠れることが保証されます。

     もしsys-sleepがシグナルを受けた場合にすぐ戻ってきてほしければ、省略可能引数no-retryに真の値を渡してください。

     デフォルトでsleep(3)を再呼び出しする理由は、GaucheのGCがスレッド間同期にシグナルを使う場合があるからです。もし一つのスレッドがsys-sleepで待っている間にもうひとつのスレッドが GCをトリガすると、sys-sleepが時間経過前に戻ってくる可能性があります。他のスレッドがたくさんアロケートする場合、sys-sleepはすぐに戻ってきてしまい、信頼できなくなるかもしれません。

     指定時間が満了した場合(NO-RETRYが偽であれば常にそうです)、 sys-sleepは0を返し、シグナルによって一時停止が解除された場合は、満了までの秒数を返します。

     To be portable across POSIX implementation, keep SECONDS less than 65536. POSIX実装間でポータブルにするためには、SECONDSを65536より小さく保って下さい。

     Some systems may be using alarm(2) to implement sleep(3), so you shouldn't mix sys-sleep and sys-alarm. システムによってはsleep(3)の実装にalarm(2)を用いている可能性があるので、 sys-sleepとsys-alarmを混ぜて使うことはおすすめしません。

 -- Function: sys-nanosleep nanoseconds :optional (no-retry #f)
     [POSIX] Suspends the calling thread until the specified number of nanoseconds elapses. The argument NANOSECONDS can be a <time> object (see Time), or a real number.

     The system's nanosleep(2) could return before the specified interval if the calling thread receives a signal; in that case, sys-nanosleep automatically restarts nanosleep(2) again with remaining time interval (after invoking Scheme signal handlers if there's any) by default. So you can count on the thread does sleep at least the specified amount of time.

     The reason that we retries by default is that Gauche's GC may use signals to synchronize between threads.   If GC is invoked by one thread while another thread is sleeping on nanosleep(2), it may return prematurely.  It could happen often if other threads allocate a lot, which could make sys-nanosleep unreliable.

     Returns #f if NANOSECONDS elapsed (which is always the case if no-retry is #f), or a <time> object that indicates the remaining time if sys-nanosleep is interrupted by a signal. 指定されたナノ秒が経過するまで、呼び出したスレッドを一時停止します。引数NANOSECONDSは<time>オブジェクト(Time参照)か実数です。

     システムのnanosleep(2)は、シグナルを受けると指定時間経過前であっても戻ってきますが、sys-nanosleepはデフォルトで、(Schemeのシグナルハンドラがあればそれを呼び出した後)残り時間を引数にして再びnanosleep(2)を呼び出します。従ってsys-nanosleepを呼び出したスレッドは、少なくとも指定した時間、眠れることが保証されます。

     もしsys-nanosleepがシグナルを受けた場合にすぐ戻ってきてほしければ、省略可能引数no-retryに真の値を渡してください。

     デフォルトでnanosleep(2)を再呼び出しする理由は、GaucheのGCがスレッド間同期にシグナルを使う場合があるからです。もし一つのスレッドがsys-nanosleepで待っている間にもうひとつのスレッドが GCをトリガすると、sys-nanosleepが時間経過前に戻ってくる可能性があります。他のスレッドがたくさんアロケートする場合、sys-nanosleepはすぐに戻ってきてしまい、信頼できなくなるかもしれません。

     NANOSECONDSが経過した場合の返り値は#fです。 no-retryが偽であれば常にそうなります。 sys-nanosleepがシグナルによって割り込まれた場合は、残りの時間を表す<time>オブジェクトを返します。

          ;wait for 0.5 sec
          (sys-nanosleep 500000000)

          ;wait for 1.3 sec
          (sys-nanosleep (make <time> :second 1 :nanosecond 300000000))

     Note: On Windows native platforms, this function is emulated using Sleep.  The argument is rounded up to millisecond resolution, and it won't be interrupted by a signal. Windowsネイティブ環境では、この関数はSleepによってエミュレートされます。引数はミリ秒の単位に切り上げられます。またシグナルによって中断されることはありません。

 -- Function: sys-random
 -- Function: sys-srandom seed
     A pseudo random number generator. sys-random returns a random number between 0 and a positive integer RAND_MAX, inclusive.  This is a straightforward interface to random(3).  If the underlying system doesn't have random(3), lrand48(3) is used. 擬似的な乱数ジェネレータです。 sys-randomは0からRAND_MAX(それ自体を含む)までの間で乱数を返します。これはrandom(3)への直接的なインターフェースです。システムにrandom(3)がない場合、lrand48(3)が使われます。

     sys-srandom sets the seed of the random number generator. It uses either srandom(3) or srand48(3), depending on the system. sys-srandomは乱数ジェネレータの種をセットします。システムによって、srandom(3)かsrand48(3)を使います。

     The intention of these functions are to provide an off-the-stock handy random number generator (RNG) for applications that doesn't sensitive to the quality and/or speed of RNG.  For serious statistics analysis, use Mersenne Twister RNG in math.mt-random module (see Mersenne-Twister random number generator). これらの関数の意図は、乱数ジェネレータ(RNG; random number generator)の品質や速度を気にしないアプリケーションに、簡便なRNGを提供することです。本格的な統計分析には、math.mt-randomモジュールのMersenne Twister RNGを使って下さい(Mersenne-Twister random number generator参照)。

 -- Variable: RAND_MAX
     Bound to a positive integer that sys-random may return. sys-randomが返す正の整数に束縛されます。

 -- Function: sys-get-osfhandle port-or-fd
     [Windows] This procedure is only available on Windows native platforms. Returns a Windows file handle associated to the given port or integer file descriptor.   Throws an error if the given argument does not have associated file handle. この手続きはWindowsネイティブ版だけにあります。与えられたポートまたは整数のファイルディスクリプタに対応する Windowsファイルハンドルを返します。引数がファイルハンドルに対応していなかった場合はエラーが投げられます。

Development helper API
======================

Gauche has some basic built-in APIs to help developers to analyze the program. Gauche には開発者がプログラムを解析するための基本的な組込みAPIがあります。

Debugging aid
-------------

 -- Macro: debug-print expr
     This macro prints EXPR in a source form, then evaluates it, then prints out the result(s), and returns them. このマクロはEXPRをそのフォームのまま印字してから、その式を評価し、評価の結果を印字し、その値を返します。

     The output goes to the current trace port (see Common port operations). 出力は現在のトレース出力ポート (current-trace-port) に行きます (Common port operations参照)。

     The special reader syntax #?=EXPR is expanded into (debug-print EXPR).  See Debugging, for the details. 特殊リーダー構文 #?=EXPR は (debug-print EXPR) に展開されます。詳細については Debugging を参照してください。

 -- Parameter: debug-print-width
     This parameter specifies the maximum width of information to be printed by debug-print.  If the information takes more columns than the value of this parameter, it is truncated. このパラメータはdebug-printが印字する情報の最大幅を指定するものです。このパラメータが保持する値よりも大きいカラム数の情報は丸められます。

     To show all the information, set #f to this parameter. すべての情報を表示したければ、このパラメータに#fを設定してください。

 -- Macro: debug-funcall (proc arg ...)
     This macro prints the value of ARGs right before calling PROC and the result(s) of the call afterwards. このマクロはPROCを呼び出す直前に全てのARGの価を表示し、そしてPROCの呼び出し後に全ての戻り価を表示します。

     The output goes to the current trace port (see Common port operations). 出力は現在のトレース出力ポート (current-trace-port) に行きます (Common port operations参照)。

     The special reader syntax #?,EXPR is expanded into (debug-funcall EXPR).  See Debugging, for the details. 特別なリーダ構文 #?,EXPR は (debug-funcall EXPR) に展開されます。詳しくは Debugging を参照してください。

 -- Function: debug-source-info obj
     Retrieves source information attached to OBJ. The source information is returned as a list of source file name and an integer line number.  If no source information is available in OBJ, #f is returned. OBJに付加されているソースコード情報を検索します。ソースコード情報とはソースコードファイル名と行番号のリストです。OBJにソースコード情報が付加されていなければ、#fが返されます。

 -- Function: source-code closure
     Returns the source code of CLOSURE, if available. Otherwise, #f is returned.

     Currently, only the code that's directly read from Scheme source is available; if the Scheme code is precompiled, the source code isn't saved.   It may be changed in future. CLOSUREのソースコードが取り出せればそれを返します。そうでなければ #fを返します。

     現在、Schemeソースから直接読み込まれた場合のみ、ソースコードが取り出せます。プリコンパイルされたSchemeコードではソースコードは保存されません。将来は変更されるかもしれません。

 -- Function: source-location closure
     Returns the location (a list of filename and line number) where CLOSURE is defined, if available.  Otherwise, #f is returned. CLOSUREが定義された場所(ファイル名と行番号)がわかればそれをリストにして返します。わからなければ#fが返ります。

          gosh> (use rfc.http)
          gosh> (source-location http-get)
          ("/usr/share/gauche-0.9/0.9.5/lib/rfc/http.scm" 443)

 -- Function: disasm closure
     Disassemble the compiled body of CLOSURE and print it. It may not be very useful unless you're tracking a compiler bug, or trying to tune the program to its limit. コンパイル済のCLOSUREの本体部分をディスアセンブルして印字します。これはコンパイラのバグをなんとかしようという場合か、限界までチューンしようとしないかぎりは役には立たないでしょう。

     If you're reading the disassembler output, keep in mind that the compiled code vector may have some dead code; they are produced by the jump optimization, but the compiler doesn't bother to eliminate them. このディスアセンブラの出力結果を読む場合には、コンパイルされたコードにはデッドコードが含まれている可能性があることを心してください。デッドコードはジャンプ最適化によって生成されるのですが、コンパイラはこれをわざわざ除去することはしていません。

 -- Function: debug-label obj
     This returns a string that is quasi-unique to an object OBJ. ``Quasi-unique'' means the label is unique to the OBJ--- the same (eq?) objs returns the same string, and if two objs return different string they aren't eq? to each other--- until next GC occurs.

     This is mostly for printing out anonymous objects that doesn't have any other good way to distinguish each other. Note that uniqueness isn't guaranteed across GCs, you shouldn't use the returned value as the key to identify the objects. この手続きは、OBJについてほぼユニークな文字列を返します。「ほぼ」ユニークというのは、次のGCが起きるまでは、オブジェクトが同じ文字列を返したらeq?であり、またeq?でないオブジェクト同士は異なる文字列を返すということです。

     この文字列は、他に区別の手段がないような無名オブジェクトを印字する時に使われることを想定しています。GCをまたいだ唯一性は保証されないので、この手続きが返す文字列をオブジェクトを同定するキーとして使ってはいけません。

Profiler API
------------

These are the functions to control Gauche's built-in profiler. See Using profiler for the explanation of the profiler. ここに挙げている関数は、Gauche の組込みプロファイラを制御するためのものです。プロファイラの説明については Using profiler を参照してください。

Note that the profiler isn't guaranteed to work correctly yet in multi-threaded program, since the interaction between setitimer and threads are platform-dependent. 注意：現時点ではプロファイラはマルチスレッドプログラムでは正しく動作する保証はありません。setitimerとスレッドの相互作用がプラットフォーム依存だからです。

 -- Function: profiler-start
     Starts the sampling profiler.   If the profiler is already started, nothing is done. 標本化プロファイラを始動します。プロファイラが既に始動しいる場合には何もしません。

 -- Function: profiler-stop
     Stop the sampling profiler, and save the sampled data into the internal structure.   If there are already saved sampled data, the newly obtained data is added to it. If the profiler isn't running, nothing is done. 標本化プロファイラを停止し、標本データを内部データ構造に保存します。既に標本データが保存されていた場合には、新しく収集された標本データがその後に追加されます。もしプロファイラが動いていなかった場合には何もしません。

 -- Function: profiler-reset
     Stop the profiler if it is running.  Then discard the saved sampled data. もしプロファイラが動いていればそれを停止し、保存されていた標本データを破棄します。

 -- Function: profiler-show :key sort-by max-rows
     Show the saved sampled data. 格納されている標本データを表示します。

     The keyword argument SORT-BY may be one of the symbols time, count, or time-per-call, to specify how the result should be sorted.  The default is time. キーワード引数 SORT-BY は指定する場合は、time、 count または time-per-call のどれかひとつです。これで結果の整列順を指定します。デフォルトでは timeです。

     The keyword argument MAX-ROWS specifies the max number of rows to be shown.  If it is #f, all the data is shown. キーワード引数 MAX-ROWS では結果を表示する最大行数を指定します。この値が #f であればすべてのデータが表示されます。

 -- Function: with-profiler thunk
     A convenience procedure. Call THUNK with the sampling profiler running, and show the result to the current output port afterwards. Returns value(s) thunk yields. The profiler is reset after the result is shown.

     You can't nest this construct; the innermost with-profiler will reset the profiler, invalidates any outer with-profiler. 手軽にプロファイリングするための手続きです。プロファイラをonにしてTHUNKを呼び出し、結果をcurrent output port に出力します。THUNKの戻り値が式の戻り値となります。結果表示後、プロファイラはリセットされます。

     この手続きをネストすることはできません。最も内側のwith-profilerが結果をリセットしてしまうので、外側のwith-profilerに全ての情報が渡らないからです。