For Gauche 0.9.15Search (procedure/syntax/module):

Previous: , Up: ライブラリモジュール - R7RS標準ライブラリ   [Contents][Index]

10.3 R7RS large

R7RS largeはまだ策定途上ですが、既に決定したライブラリについては 徐々にGaucheに追加してゆきます。

現在、R7RS-largeには2つのエディション (RedとTangerine) が 制定されており、Gaucheでもこれらをサポートしています。


10.3.1 scheme.list - R7RSリスト

Module: scheme.list

このモジュールは、豊富なリスト操作手続きのコレクションです (srfi.1と同じです)。

Gaucheはscheme.listの手続きの多くを組み込みで提供しています。 以下に挙げる手続きはscheme.listモジュールをロードしなくても使えます。 これらの手続きの説明は、ペアとリストを参照してください。

null-list? cons* last member
take drop take-right drop-right take! drop-right!
delete delete! delete-duplicates delete-duplicates!
assoc alist-copy alist-delete alist-delete!
any every filter filter! fold fold-right find find-tail
split-at split-at! iota

List constructors

Function: xcons cd ca

[R7RS list] {scheme.list} (cons ca cd) と同等です。高階手続きへ渡すのに便利です。

Function: list-tabulate n init-proc

[R7RS list] {scheme.list} n個の要素をもつリストを構築し、それぞれの要素を (init-proc i) で生成します。

(list-tabulate 4 values) ⇒ (0 1 2 3)
Function: circular-list elt1 elt2 …

[R7RS list] {scheme.list} 指定した要素をもつ循環リストを構築します。

(circular-list 'z 'q) ⇒ (z q z q z q …)

List predicates

Function: not-pair? x

[R7RS list] {scheme.list} (lambda (x) (not (pair? x)))と同じです。

SRFI-1 では、「真性リストおよびドットリストの両方で、すべての有限リストを 扱う手続き用の終端条件として便利なように用意した」とあります。

Function: list= elt= list …

[R7RS list] {scheme.list} elt= を用いて、n番目の要素をそれぞれ比較することで、 与えられたリストの同値性を決定します。

list= を真性リスト以外に適用するとエラーになります。

同値性判定の手続きは eq? と整合性がなければなりません。すなわち

(eq? x y) ⇒ (elt= x y).

List selectors

Function: first pair
Function: second pair
Function: third pair
Function: fourth pair
Function: fifth pair
Function: sixth pair
Function: seventh pair
Function: eighth pair
Function: ninth pair
Function: tenth pair

[R7RS list] {scheme.list} リスト(非真性でも可)のn番目の要素を返します。

Function: car+cdr pair

[R7RS list] {scheme.list} (car pair) および (cdr pair) の二つの値を返します。

List miscellaneous routines

Function: zip clist1 clist2 …

[R7RS list] {scheme.list} (map list clist1 clist2 …) と同等です。 n 本のリストが zip に渡された場合には、そのなかで一番短いものと 同じ長さのリストを返します。返されたリストは、要素が n 要素のリストで、 そのそれぞれが、引数として渡ってリストの対応する要素になっています。

(zip '(one two three)
     '(1 2 3)
     '(odd even odd even odd even odd even))
     ⇒ ((one 1 odd) (two 2 even) (three 3 odd))

(zip '(1 2 3)) ⇒ ((1) (2) (3))

引数のリストのうち、少くともひとつは有限のリストでなければなりません。

(zip '(3 1 4 1) (circular-list #f #t))
     ⇒ ((3 #f) (1 #t) (4 #f) (1 #t))
Function: unzip1 list
Function: unzip2 list
Function: unzip3 list
Function: unzip4 list
Function: unzip5 list

[R7RS list] {scheme.list} unzip1 はリストのリストを引数としてとります。それぞれの リストは少くとも一つの要素を含むものでなくてはなりません。結果として それぞれのリストの最初の要素のリストを返します。 unzip2 はリストのリストを引数としてとります。それぞれのリストは 少くとも二つの要素を含むものでなくてはなりません。結果として二つの値を 返します。最初の要素のリストと二番目の要素のリストです。unzip3 は 3番目までの要素について同様です。以下も同様です。

(unzip2 '((1 one) (2 two) (3 three))) ⇒
   (1 2 3) and
   (one two three)

List fold, unfold & map

Function: pair-fold kons knil clist1 clist2 …
Function: pair-fold-right kons knil clist1 clist2 …

[R7RS list] {scheme.list} fold および fold-right と同様ですが、kons 手続き は与えられた clistcar ではなく、cdr をとります。

(pair-fold cons '() '(a b c d e))
  ⇒ ((e) (d e) (c d e) (b c d e) (a b c d e))

(pair-fold-right cons '() '(a b c d e))
  ⇒ ((a b c d e) (b c d e) (c d e) (d e) (e))
Function: unfold p f g seed :optional tail-gen

[R7RS list] {scheme.list} 基本リスト再帰構築子です。 以下のように再帰的に定義されています。

(unfold p f g seed tail-gen) ≡
   (if (p seed)
       (tail-gen seed)
       (cons (f seed)
             (unfold p f g (g seed))))

ここでは、p は終了位置の判定、g は現在の「種」から次の「種」 を生成するのに用い、f はそれぞれの「種」をリストの要素に変換する のに用いられます。

(unfold (pa$ = 53) integer->char (pa$ + 1) 48)
  ⇒ (#\0 #\1 #\2 #\3 #\4)
Function: unfold-right p f g seed :optional tail

[R7RS list] {scheme.list} 基本リスト反復構築子です。 以下のように再帰的に定義されています。

(unfold-right p f g seed tail) ≡
  (let lp ((seed seed) (lis tail))
    (if (p seed)
        lis
        (lp (g seed) (cons (f seed) lis))))
(unfold-right (pa$ = 53) integer->char (pa$ + 1) 48)
 ⇒ (#\4 #\3 #\2 #\1 #\0)
Function: map! f clist1 clist2 …

[R7RS list] {scheme.list} 手続き fclist1 の各要素と clist2 の対応する要素 に適用され、結果はひとつのリストになります。clist1 のセルは 結果のリストを構築するのに再利用されます。

Function: map-in-order f clist1 clist2 …

[R7RS list] {scheme.list} map の変形バージョンですが、f の適用順序が、引数として 与えられたリストの要素の左から右への順であることを保証します。 Gauche では map の実装はこの順になっているので、map と 同意です。

Function: pair-for-each f clist1 clist2 …

[R7RS list] {scheme.list} for-each と似ていますが、手続き f はまず clist自体に 適用され、次ににそれらのcdr に適用され、となります。

(pair-for-each write '(a b c))
 ⇒ prints (a b c)(b c)(c)

List partitioning

Function: partition pred list
Function: partition! pred list

[R7RS list] {scheme.list} filterremove を同時に行い、 2つのリストを返します。一つ目は pred により list の要素をフィルタリング した結果で、二つ目は pred により list の要素を削除した結果です。

(partition odd? '(3 1 4 5 9 2 6))
  ⇒ (3 1 5 9) (4 2 6)

partition! はその場で更新されるバージョンです。結果を生成するために list を破壊的に更新するかもしれません。

List searching

Function: take-while pred clist
Function: take-while! pred list

[R7RS list] {scheme.list} clist の最初から、pred を満足する限りの最長部分要素を返します。

Function: drop-while pred clist

[R7RS list] {scheme.list} clist の最初から、pred を満足する限りの最長部分要素を削除し、 残りを返します。

Function: span pred clist
Function: span! pred list
Function: break pred clist
Function: break! pred list

[R7RS list] {scheme.list} span(values (take-while pred clist) (drop-while pred clist)) と等価です。breakpred の意味を反転します。

Function: list-index pred clist1 clist2 …

[R7RS list] {scheme.list} pred を満足する最も左の要素のインデックスを返します。 predを満たす要素が無い場合は#fを返します。

Association lists

Function: alist-cons key datum alist

[R7RS list] {scheme.list} (cons (cons key datum) alist) を返します。 これは、Gauche の組み込み手続き acons の別名です。

Lists as sets

これらの手続きはリストを集合としてあつかいます。すなわち、どのような 要素があるかは重要ですが、その順序は重要ではありません。

この範疇にあるすべての手続きは、比較手続き elt= を最初の引数として とります。この比較手続きは与えられた二つの集合の要素が等しいかどうかを 判定します。

リストは検索に線形時間を必要とするため、ここに挙げた手続きは 大きな集合を扱うには向いていません。もし対象となる集合が 二桁以上の要素を持つことが分かっているなら、scheme.set - R7RSセットを 参照してください。

集合の要素の組み合せについては util.combinations - 組み合わせ も参照してください。

Function: lset<= elt= list1 …

[R7RS list] {scheme.list} list1 のすべての要素が list2 (以降の集合)に含まれている ときに限り #t を返します。リストが与えられなかった場合 および一つだけしか与えられなかった場合には、#t を返します。

Function: lset= elt= list1 list2 …

[R7RS list] {scheme.list} list1 のすべての要素が list2 に含まれており、かつ、 list2 のすべての要素が list1 に含まれていれば、#t を返します。

(lset= eq? '(b e a) '(a e b) '(e e b a)) ⇒ #t
Function: lset-adjoin elt= list elt …

[R7RS list] {scheme.list} elt … を集合 list にまだなければ、追加します。 (順序はとくに決っていません。)

(lset-adjoin eq? '(a b c) 'a 'e) ⇒ '(e a b c)
Function: lset-union elt= list1 …

[R7RS list] {scheme.list} list1 … の和集合を返します。

Function: lset-intersection elt= list1 list2 …

[R7RS list] {scheme.list} すべての list に含まれる要素の集合を返します。

Function: lset-difference elt= list1 list2 …

[R7RS list] {scheme.list} list1 には含まれていて、list2 には含まれていない要素の集合を 返します。引数が n 個与えられた場合には、差分をとる二項演算が 畳み込まれます。

Function: lset-xor elt= list1 …

[R7RS list] {scheme.list} 与えられた集合の排他的論理和を返します。すなわち、list1 および list2 のどちらか一方にのみ属する要素からなる集合を返します。 引数が n 個の場合には、xor の二項演算が畳み込まれます。

Function: lset-diff+intersection elt= list1 list2 …

[R7RS list] {scheme.list} 与えられた集合の差集合と積集合のふたつの集合を返します。

Function: lset-union! elt= list …
Function: lset-intersection! elt= list1 list2 …
Function: lset-difference! elt= list1 list2 …
Function: lset-xor! elt= list1 …
Function: lset-diff+intersection! elt= list1 list2 …

[R7RS list] {scheme.list} それぞれ対応する手続きのその場で更新するバージョンです。 最初の引数のリストのセルが結果を構築するのに再利用されるかもしれません。


10.3.2 scheme.vector - R7RSベクタ

Module: scheme.vector

このモジュールは豊富なベクタ操作を提供します。

以下の手続きはGaucheでは組み込みになっています。説明はベクタを参照してください。 組み込みでない手続きについてのみ解説します。

make-vector          vector               vector?
vector-ref           vector-set!          vector-length
vector-fill!         vector-copy          vector-copy!
vector-append        vector->list         list->vector
reverse-list->vector vector->string       string->vector
vector-map           vector-map!          vector-for-each

このモジュールはsrfi.133として制定され、 srfi.43(srfi.43 - ベクタライブラリ(旧式))を置き換えるものです。 srfi.43の手続きのうち、以下のものは一貫性からインタフェースが 変更されていることに注意してください。

vector-map           vector-map!          vector-for-each
vector-fold          vector-fold-right    vector-count

srfi.43から削られた機能の一部は、 Gaucheの組み込み手続きでサポートされています (例えばsrfi.43vector-mapは組み込みのvector-map-with-indexと 同じです)。新しいコードでsrfi.43を使う必要はほとんどないでしょう。

ベクタ構成子

Function: vector-unfold f length seed …

[R7RS vector] {scheme.vector} 長さlengthのベクタを作って返します。要素は左から右に、 fを繰り返し呼ぶことで計算されます。

手続きfは、seedの数よりひとつ多い引数を取り、同数の値を返さなければなりません。 引数の最初に渡されるのはインデックスです。戻り値の最初の値がそのインデックスの要素の初期値に 使われ、残りの戻り値が次のシード値となります。

(vector-unfold (^[i] (* i i)) 5)
 ⇒ #(0 1 4 9 16)

(vector-unfold (^[i x] (values (cons i x) (* x 2))) 8 1)
 ⇒ #((0 . 1) (1 . 2) (2 . 4) (3 . 8)
    (4 . 16) (5 . 32) (6 . 64) (7 . 128))

註: このプロトコルは、リストのunfoldコンストラクタや、それに倣った 多くの*-unfoldコンストラクタと異なることに注意してください。 ベクタのような固定長構造体では、終端条件を繰り返しの度に検査するより、 最初から長さが分かっている方が意味があります。

Function: vector-unfold-right f length seed …

[R7RS vector] {scheme.vector} 長さlengthのベクタを作って返します。要素は右から左に、 fを繰り返し呼ぶことで計算されます。

手続きfは、seedの数よりひとつ多い引数を取り、同数の値を返さなければなりません。 引数の最初に渡されるのはインデックスです。戻り値の最初の値がそのインデックスの要素の初期値に 使われ、残りの戻り値が次のシード値となります。

(vector-unfold-right (^[i] (* i i)) 5)
 ⇒ #(0 1 4 9 16)

(vector-unfold-right (^[i x] (values (cons i x) (* x 2))) 8 1)
 ⇒ #((0 . 128) (1 . 64) (2 . 32) (3 . 16)
    (4 . 8) (5 . 4) (6 . 2) (7 . 1))
Function: vector-reverse-copy vec :optional start end

[R7RS vector] {scheme.vector} ベクタvecを要素を逆順にしてコピーします。 省略可能引数startendは元のベクタから取り出す範囲を限定します。

(vector-reverse-copy '#(a b c d e) 1 4)
 ⇒ #(d c b)
Function: vector-concatenate list-of-vectors

[R7RS vector] {scheme.vector} (apply vector-append list-of-vectors)と同じです。

Function: vector-append-subvectors spec …

[R7RS vector] {scheme.vector} 引数の数は3の倍数でなければなりません。 引数リストは次の形式をとります。ここで、vecNはベクタ、 startNendNは非負の正確な整数です。

vec1 start1 end1 vec2 start2 end2 …

この手続きは、それぞれの3つ組で指定される部分ベクタをつなぎ合わせたベクタを 作って返します。つまり、以下のコードと同様の動作をしますが、 各部分ベクタのコピーは避けられます。

(vector-append (vector-copy vec1 start1 end1)
               (vector-copy vec2 start2 end2)
               …)

例を示します:

(vector-append-subvectors '#(a b c d e) 0 3
                          '#(f g h i j) 2 5)
  ⇒ #(a b c h i j)

ベクタ上の述語

Function: vector-empty? vec

[R7RS vector] {scheme.vector} ベクターvecの長さが0なら#tを、1以上なら#fを返します。 vecがベクタでなければエラーが投げられます。

Function: vector= elt= vec …

[R7RS vector] {scheme.vector} vec …を要素ごとに比較してゆきます。要素間の比較にはelt=が使われます。 全てのベクタ引数が同じ長さで、対応する要素がelt=によって等しかった場合に、#t が返されます。

elt=は常に二つの引数を取り、 等しければ#tを、そうでなければ#fを返します。

ゼロ個か1個のベクタが渡された場合は、elt=は全く呼ばれず、 vector=は常に#tを返します。

ベクタ上の繰り返し

Function: vector-fold kons knil vec1 vec2 …

[R7RS vector] {scheme.vector} konsは与えられたベクタ引数vec1 vec2 … の数よりひとつ多い引数を取る手続きです。 各ベクタのi番目の要素e_1i e_2i …)に 対して、kons(kons seed e_1i e_2i …) のように順次呼ばれます。ベクタの長さが異なっていた場合、最も短いベクタが尽きたところで 繰り返しは停止します。

seedの初期値はknilで、konsの戻り値が次のseedとして 使われます。最後のkonsの戻り値がvector-foldの戻り値となります。

繰り返しはベクタの左から右へと進みます。

seed引数が要素の前に来ることに注意してください。これは fold (コレクションに対するマッピング参照)とは逆です。 歴史的に生じた不幸なすれちがいです。 vector-fold-leftであれば一貫性があったでしょう。

(vector-fold (^[a b] (cons b a)) '() '#(a b c d))
  ⇒ (d c b a)
Function: vector-fold-right kons knil vec1 vec2 …

[R7RS vector] {scheme.vector} vector-foldと似ていますが、vec1 vec2 …の各要素は 右から左へと読まれます。

ベクタの長さが異なる場合は、最も短いベクタの要素数までを見て、残りは無視します。 下の2番目の例を見てください。

fold-right (シーケンス上のマップ参照)とは異なり、 konsはシード値を最初の引数として受け取ります。

(vector-fold-right (^[a b] (cons b a)) '() '#(a b c d))
  ⇒ (a b c d)

(vector-fold-right (^[s x y] (cons (list x y) s)) '()
                   '#(a b c) '#(1 2 3 4))
  ⇒ ((a 1) (b 2) (c 3))
Function: vector-count pred vec1 vec2 …

[R7RS vector] {scheme.vector} predを引数のベクタの各要素に適用します (N個のベクタが与えられた場合、predはN個の引数を取り、 各ベクタの対応する要素が渡されます)。 そして、predが真の値を返した回数を正確な整数で返します。 predがどのような順番で適用されるかは規定されていません。

(vector-count odd? '#(0 1 2 3 4)
  ⇒ 2

(vector-count < '#(7 3 9 1 5) '#(6 8 2 3 8 8))
  ⇒ 3
Function: vector-cumulate f seed vec

[R7RS vector] {scheme.vector} vecと同じ長さの新たなベクタを作り、以下の手順で要素を埋めてからそれを返します。

結果の最初の要素は、(f seed (vector-ref vec 0))です。

i番目の要素は、i-1番目の結果と、(vector-ref vec i)を 引数にしてfを呼び出した結果です。

(vector-cumulate string-append "z" '#("a" "b" "c"))
  ⇒ #("za" "zab" "zabc")

ベクタ上の検索

Function: vector-index pred vec1 vec2 …
Function: vector-index-right pred vec1 vec2 …

[R7RS vector] {scheme.vector} vec1 vec2 …の要素のうちpredを満たす最初のもの、 あるいは最後のもののインデックスをそれぞれ返します。 predを満たす要素が無ければ#fが返されます。 vector-indexでは、一番短いベクタの終端に達したら処理を終了します。 vector-index-rightでは、全てのベクタは同じ長さでなければなりません。

Function: vector-skip pred vec1 vec2 …
Function: vector-skip-right pred vec1 vec2 …

[R7RS vector] {scheme.vector} predの結果が逆であること以外は、 vector-indexおよびvector-index-rightと同じです。 すなわち、predを満たさない最初あるいは最後の要素のインデックスが返されます。

Function: vector-binary-search vec value cmp :optional start end

[R7RS+ vector] {scheme.vector} ソートされたベクタvec中から値valueを探し、 見つかればそのインデックスを、見つからなければ#fを返します。

vecの要素とvalueの比較は手続きcmpで行われます。 cmpは二つの引数を取り、最初の引数の方が小さければ負の整数を、 等しければ0を、最初の引数の方が大きければ正の整数を買えす手続きです。

vecの要素はcmpによる比較に従い小さい方から順にソート済みで なければなりません。この手続きはその仮定のもとに、二分探索を行います。

省略可能なstartend引数は、Gauche独自の拡張です。指定された場合、 start番目の要素(含む)からend番目の要素(含まない)までが探索の対象となります。

Function: vector-any pred vec1 vec2 …

[R7RS vector] {scheme.vector} vec1 vec2 …の各ベクタの先頭から順に、 ひとつづつ対応する要素を取って、それにpredを適用してゆきます。 predが真の値を返したら、直ちにその値を返します。

predを満たす要素が見つからなければ、#fが返されます。

ベクタの長さは異なっていても構いません。最も短いベクタの要素を使い切ったところで 探索は打ちきられます。

Function: vector-every pred vec1 vec2 …

[R7RS vector] {scheme.vector} vec1 vec2 …の各ベクタの先頭から順に、 ひとつづつ対応する要素を取って、それにpredを適用します。 全ての要素がpredを満たした場合(ベクタの長さが異なる場合は、 最も短いベクタを使い切った時点)で、最後のpredの結果を返します。 途中でpred#fを返した場合は、その先は見ずに直ちに#fを返します。

(vector-every < '#(1 2 3 4 5) '#(2 3 4 4 5)
  ⇒ #f

(vector-every (^[x y] (and (real? x) (real? y) (- x y)))
              '#(1 2 3)
              '#(2 4 6))
  ⇒ -3
Function: vector-partition pred vec

[R7RS vector] {scheme.vector} vecと同じ大きさのベクタを新たにアロケートし、 まずvec中のpredを満たす要素を順に詰めてゆき、 その後をpredを満たさない要素で埋めます。

新たに作られたベクタと、その中でpredを満たさない最初の要素を指す インデックスの二つの値を返します。

(vector-partition odd? '#(1 2 3 4 5 6 7 8))
  ⇒ #(1 3 5 7 2 4 6 8) and 4

ベクタの変更子

Function: vector-swap! vec i j

[R7RS vector] {scheme.vector} veci番目の要素とj番目の要素を交換します。 戻り値はunspecifiedです。

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-swap! v 0 2))
  ⇒ #(c b a d e)
Function: vector-reverse! vec :optional start end

[R7RS vector] {scheme.vector} vecの要素を逆順に並べ替えます。戻り値は未定義です。 省略可能引数startendは影響が及ぶ範囲を限定します。

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse! v 0 4))
  ⇒ #(d c b a e)
Function: vector-reverse-copy! target tstart source :optional sstart send

[R7RS vector] {scheme.vector} vector-copy!と似ていますが、指定範囲を逆順にコピーします。

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse-copy! v 2 '#(1 2)))
  ⇒ #(a b 2 1 e)

targetsourceに同じベクタを指定しても構いません。 コピー範囲が重なっていても問題なく動作します。

(rlet1 v (vector 'a 'b 'c 'd 'e)
  (vector-reverse-copy! v 1 v 1))
  ⇒ #(a e d c b)
Function: vector-unfold! f rvec start end seeds …
Function: vector-unfold-right! f rvec start end seeds …

[R7RS vector] {scheme.vector} rvecの、startからendの直前までの範囲をfが算出する 新たな要素で埋めます。

fは、seeds …の数よりひとつ多い引数を取ります。 最初の引数は現在のインデックスで、それにシード値が続きます。 fは引数と同数の値を返します。最初の戻り値がrvecを埋めるのに使われ、 残りの戻り値は新たなシード値として次のfの呼び出しに使われます。

結果のベクタは、vector-unfold!では左から右へ、 vector-unfold-right!では右から左へと埋められます。 戻り値はunspecifiedです。

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i] (+ i 1)) rvec 1 4)
  rvec)
 ⇒ #(a 2 3 4 e f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold-right! (^[i] (+ i 1)) rvec 1 4)
  rvec)
 ⇒ #(a 2 3 4 e f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i x] (values x (* x 2))) rvec 1 5 10)
  rvec)
 ⇒ #(a 10 20 40 80 f)

(let1 rvec (vector 'a 'b 'c 'd 'e 'f)
  (vector-unfold! (^[i x] (values x (* x 2))) rvec 1 5 10)
  rvec)
 ⇒ #(a 80 40 20 10 f)

ベクタの変換

Function: reverse-vector->list vec :optional start end

[R7RS vector] {scheme.vector} (reverse (vector->list vec start end))と同じですが、より効率的です。


10.3.3 scheme.vector.@ - R7RSユニフォームベクタ

Module: scheme.vector.@

@は次のいずれかに置き換えて読んでください: u8, s8, u16, s16, u32, s32, u64, s64, f32, f64, c64, c128。 (Gaucheのgauche.uvectorモジュールはさらにf16c32を 提供します)。

これらのモジュールは限られた範囲の数値だけを格納するベクタを提供します。 Gaucheでは、数値は連続したメモリ領域に詰められて格納されます。

また、scheme.vector.baseモジュールは全ての要素型についての 基本手続き、つまり次の手続きの@を全ての基本型で置換した手続きをまとめて エクスポートしています: make-@vector@vector@vector? @vector-length@vector-ref@vector-set!@vector->listlist->@vector@?

gauche.uvectorモジュールはこれらのモジュールのスーパーセットで、 このモジュールの全ての手続きはそちらで説明されています。 ユニフォームベクタを参照してください。


10.3.4 scheme.sort - R7RSソート

Module: scheme.sort

ソートおよびソート済みのリストやベクタに関する手続きを提供します。 このモジュールはsrfi.132と同じです。

Gaucheは組み込みでソートとマージの手続きを用意していますが (ソートとマージ参照)、 このモジュールはAPIがちょっと異なります。特に、順序を決める述語が ソートすべきシーケンスより先に来ます。また、ベクタを扱う手続きは一様に start/end引数をサポートします。

このモジュールはまた、(部分的に)ソートされた列に対する便利な手続きをいくつか 定義しています。

Function: list-sort elt< lis
Function: list-sort! elt< lis
Function: list-stable-sort elt< lis
Function: list-stable-sort! elt< lis

[R7RS sort] {scheme.sort} リストlisの要素を比較述語elt<を使ってソートします。 elt<lisからの二要素を引数に取り、最初の引数が厳密に 二番目の引数より小さい場合に限り#tを返します。

ソートされたリストが返されます。!つきの手続きは線形更新版で、 lisを破壊的に再利用することが許されています (再利用しないかもしれません。 したがって呼び出し側は常に戻り値を使う必要があります)。 “stable” がついている ものは安定ソートを行います。

これらは基本的にはGaucheの組み込み手続き sortsort!stable-sortstable-slot!と 同じです。ただ、Gaucheのは引数の順序と、任意のシーケンスを取れるところが異なります (ソートとマージ参照)。

Function: list-sorted? elt< lis

[R7RS sort] {scheme.sort} リストlistが、順序述語elt<での比較において既にソート済みであれば 真を、そうでなければ偽を返します。

ソートとマージsorted?も参照。

Function: list-merge elt< lis1 lis2
Function: list-merge! elt< lis1 lis2

[R7RS sort] {scheme.sort} ソート済みの二つのリストlis1lis2を合わせて、 ソート済みのひとつのリストにして返します。要素は順序述語elt<で比較されます。

list-merge!は、結果のリストを得るためにlis1lis2の メモリを破壊的に再利用します。

ソートとマージmergeおよびmerge!も参照。

Function: vector-sort elt< vec :optional start end
Function: vector-stable-sort elt< vec :optional start end

[R7RS sort] {scheme.sort} ベクタvecの要素を、順序述語elt<によってソートします elt<vecの要素から2つの値を引数として取り、最初の引数が 厳密に2番目の引数より小さい場合に真の値を、そうでなければ#fを返す手続きです。 返り値はソートされた新たなベクタです。 ‘stable’がついている手続きは安定ソートが保証されます。

省略可能なstart/end引数は、vec中のソートすべき範囲の インデックスを指定します。startは開始インデックス (範囲に含まれる)、 endは終了インデックス (範囲に含まれない) です。 返り値のベクタの長さはend - start)になります。 endが省略された場合はvecの最後までが対象になります。

ソートとマージsortstable-sortも参照。

Function: vector-sort! elt< vec :optional start end
Function: vector-stable-sort! elt< vec :optional start end

[R7RS sort] {scheme.sort} ベクタvecの要素を、順序述語elt<を使って「その場で」ソートします。 elt<vecの要素から2つの値を引数として取り、最初の引数が 厳密に2番目の引数より小さい場合に真の値を、そうでなければ#fを返す手続きです。 手続きが返った時点で、vecの内容が書き換わっています。 戻り値は未規定です。呼び出しは副作用のために呼ばれます。

註: 最近追加された名前に!がつくAPIには、線形更新であるものが多いです。 線形更新の場合、引数が更新されるかどうかは不定であり、呼び出し側は返り値を使わねばなりません。 一方、vector-sort!vector-stable-sort!は純粋に副作用のために呼び、 必要最低限のメモリを使うことが保証されています。 (vector-sort!は固定メモリ量で実行されます。 vector-stable-sort!は入力長とおなじ一時領域を使うかもしれません)。

省略可能なstart/end引数は、vec中のソートすべき範囲の インデックスを指定します。startは開始インデックス (範囲に含まれる)、 endは終了インデックス (範囲に含まれない) です。 返り値のベクタの長さはend - start)になります。 endが省略された場合はvecの最後までが対象になります。

ソートとマージsort!stable-sort!も参照。

Function: vector-sorted? elt< vec :optional start end

[R7RS sort] {scheme.sort} vecstart番目 (含まれる) から end番目 (含まれない) までの 要素が、順序述語elt<に照らしてソートされていれば#tを、 そうでなければ#fを返します。 start/end引数が省略された場合はそれぞれ0とvecの長さが使われます。

ソートとマージsorted?も参照。

Function: vector-merge elt< vec1 vec2 :optional start1 end1 start2 end2
Function: vector-merge! elt< rvec vec1 vec2 :optional rstart start1 end1 start2 end2

[R7RS sort] {scheme.sort} ソート済みのベクタvec1vec2の要素を合わせて ひとつのソート済みのベクタを作ります。要素の並びは順序述語elt<で決まります。

省略可能な引数start1end1vec1内の対象とする範囲を、 start2end2vec2内の対象とする範囲を制限します。 各引数は対応するベクタへの整数インデックスであり、start側は含まれ、end側は含まれません。

関数的なバージョンvector-mergeはマージ結果を格納する新たなベクタを 作って返します。

副作用バージョンvector-merge!は、rvec引数に渡されるベクタに結果を格納します。 戻り値は未規定です。省略可能引数rstartrvecのどこから結果を格納するかの インデックスを指定し、省略時は0です。 rvecの長さは rstart + (end1-start1) + (end2-start2) より 大きくなければなりません。

Function: list-delete-neighbor-dups elt= lis
Function: list-delete-neighbor-dups! elt= lis
Function: vector-delete-neighbor-dups elt= vec :optional start end
Function: vector-delete-neighbor-dups! elt= vec :optional start end

[R7RS sort] {scheme.sort} リストlisやベクタvecの要素を順にスキャンし、 隣り合う要素が重複していたらその一方を取り除きます。 要素が等しいかどうかはelt=手続きで判断します。

(list-delete-neighbor-dups eq? '(m i s s i s s i p p i))
  ⇒ (m i s i s i p i)

非破壊的バージョンlist-delete-neighbor-dupsvector-delete-neighbor-dupsでは、結果を格納するリストやベクタが新たに 作られて返されます。

破壊的バージョンlist-delete-neighbor-dups!はアロケーションを行わず、 lisに含まれるペアを再利用して結果を格納します。 これは1パスの繰り返しアルゴリズムを使い、入力が空リストでなければ、入力の最初のセルは 出力の最初のセルになります。

破壊的バージョンvector-delete-neighbor-dups!はちょっと特殊なインタフェースです。 vecを破壊的に変更して結果を格納しますが、ベクタの長さを変えることはできないので、 結果はvecの先頭に詰められ、最終的に結果が格納された次のインデックスnewend が返り値になります。 つまり、この手続きを呼んだ後では、vecのうちstartからnewend までに結果が格納されている状態になっています。 それ以外のvecの要素は変更されません。

省略可能なstartend引数は、vec内で対象とする範囲を 整数インデックスで指定します。

(vector-delete-neighbor-dups eq? '#(a a a b b c c d d e e f f) 3 10)
  ⇒ #(b c d e)

(let1 v '#(a a a b b c c d d e e f f)
  (cons (vector-delete-neighbor-dups! eq? v 3 10) v))
  ⇒ (7 . #(a a a b c d e d d e e f f))

註: gauche.sequsenceモジュールではジェネリックなシーケンスについて 隣接要素の重複削除操作を提供しています。scheme.sortの各手続きに対応する ジェネリックなバージョンは次のとおりです。 詳しくはその他のシーケンス上の操作を参照。

list-delete-neighbor-dups

delete-neighbor-dups

list-delete-neighbor-dups!

delete-neighbor-dups-squeeze!

vector-delete-neighbor-dups

delete-neighbor-dups

vector-delete-neighbor-dups!

delete-neighbor-dups!

Function: vector-select! elt< vec k :optional start end

[R7RS sort] {scheme.sort} vecの要素のうち、k番目に小さい要素を返します。 大小比較は順序述語elt<で判断されます。 kはゼロ起点で、つまり0なら最も小さな要素が返されます。 省略可能なstartend引数はvec内の対象とする範囲を限定します。 0 <= k < (end-start) でなければなりません。

この手続きは平均O(n)で走り、余分なメモリをアロケートしません。 この手続きの実行中にvecの一部は変更されます。

Function: vector-separate! elt< vec k :optional start end

[R7RS sort] {scheme.sort} vec中のインデックスstartからendまでの範囲で、 k番目に小さい要素(ピボット)を見つけ、その範囲の要素を、 「startからstart + kまでには ピボットより小さい要素、その後にピボット、そしてピボットより大きい要素」 と言う具合に並べ替えます。大小比較は述語elt<に従います。 startendが省略された場合はそれぞれ0とvecの長さが使われます。

これは、アロケーションを行わない「分割統治」型のアルゴリズムの部品として使えます。 O(n)時間で完了します。

Function: vector-find-median elt< vec knil :optional mean
Function: vector-find-median! elt< vec knil :optional mean

[R7RS sort] {scheme.sort} vecの要素を比較述語elt<に従って並べた時の中央値を返します。 非破壊バージョンvector-find-medianはO(n)時間で走ります。 破壊バージョンvector-find-median!は、副作用として vecが完全にソートされた状態になると規定されているので、O(n log n)時間かかります。

  1. vecが空なら、knilが返されます。knilが使われるのはこの場合のみです。
  2. vecの要素が奇数個なら、順序で並べたときに中央に来る要素が返されます。
  3. vecの要素が偶数個の場合は、中央に最も近い二つの要素が選びだされ、 それが手続きmeanに渡され、その結果が返り値となります。 meanが省略された場合は、二つの数値の算術平均が使われます。
(vector-find-median < #() 0)
  ⇒ 0

(vector-find-median < #(78 61 19 38 51) 0)
  ⇒ 51

(vector-find-median < #(78 61 19 38 51 52) 0)
  ⇒ 103/2

10.3.5 scheme.set - R7RSセット

Module: scheme.set

セットとバッグは、Scheme値の順序づけのないコレクションです。 セットは重複を考慮しません。既にセット中にある要素をさらに追加しても、 その要素は依然として一つだけセット中にあると認識されます。 一方、バッグは重複を数えます。既にバッグ中にひとつだけある要素と同じものを 追加すると、バッグ中のその要素は二つと数えられます。

要素が「同じ」であるかどうかの判定のため、セットとバッグは構築時に 比較器を取ります。比較器は順序手続きを持っていなくても構いません (要素の順序づけは必要ありません)が、ハッシュ手続きは持っている必要があります。 比較器について詳しくは基本的な比較器を参照してください。

このモジュールは当初srfi.113として定義され、のちにR7RS largeに 採用されました。

Gauche独自拡張として、セットやバッグはコレクションプロトコルを実装しており、 汎用のコレクション操作が適用できます (gauche.collection - コレクションフレームワーク参照)。

(coerce-to <list> (set eq-comparator 'a 'b 'a 'b))
  ⇒ (a b)      ; order may differ

(coerce-to <list> (bag eq-comparator 'a 'b 'a 'b))
  ⇒ (a a b b)  ; order may differ

Constructors

Function: set comparator elt …
Function: bag comparator elt …

[R7RS set] {scheme.set} 与えられたelt …を要素にもつセットとバッグをそれぞれ作って返します。 比較器comparatorは要素の等価性を判定するのに使われます。

(set->list (set eq-comparator 'a 'b 'a 'b))
  ⇒ (a b)

(bag->list (bag eq-comparator 'a 'b 'a 'b))
  ⇒ (a a b b)
Function: set-unfold stop? mapper successor seed comparator
Function: bag-unfold stop? mapper successor seed comparator

[R7RS set] {scheme.set} 手続的にセットとバッグを作ります。 最初の3つの引数stop?mappersuccessorは いずれも現在のシード値を唯一の引数に取る手続きです。 型を考えるとわかりやすいでしょう:

seed      :: Seed
stop?     :: Seed -> Boolean
mapper    :: Seed -> ElementType
successor :: Seed -> Seed

stop?手続きは現在のシード値を見て、繰り返しを停止すべきなら#tを、 そうでなければ#fを返す手続きです。

mapper手続きは現在のシード値から、セットやバッグに加えるべき要素を生成する 手続きです。

successor手続きは現在のシード値から次のシード値を計算する手続きです。

そしてseed引数がシード値の初期値を与えます。

(set->list (set-unfold (^s (= s 75))
                       integer->char
                       (^s (+ s 1))
                       65
                       eqv-comparator))
 ⇒ (#\D #\H #\A #\E #\I #\J #\B #\F #\C #\G)

述語

Function: set-contains? set obj
Function: bag-contains? bag obj

[R7RS set] {scheme.set} objがそれぞれセット/バッグであることを検査します。

Function: set-empty? set
Function: bag-empty? bag

[R7RS set] {scheme.set} セット/バッグが空なら#tを、そうでなければ#fを返します。

Function: set-disjoint? set1 set2
Function: bag-disjoint? bag1 bag2

[R7RS set] {scheme.set} 引数のセット/バッグがそれぞれ共通要素を持たなければ#tを、持っていれば#fを 返します。引数のセット/バッグは同じ比較器を持っていなければならす、そうでなければ エラーが投げられます。

アクセサ

Function: set-member set obj default
Function: bag-member bag obj default

[R7RS set] {scheme.set} objと等しい (セットやバッグの比較器を使って) 要素がセット/バッグにあれば その要素を、無ければdefaultを返します。

比較器の選び方によっては、要素が見つかっても返される値がobjと通常の意味で「等しい」 とは限りません。次の例を参照。

(let1 s (set string-ci-comparator "abc" "def")
  (set-member s "ABC" #f))
  ⇒ "abc"
Function: set-element-comparator set
Function: bag-element-comparator bag

[R7RS set] {scheme.set} セット/バッグの比較器を返します。

アップデータ

Function: set-adjoin set elt …
Function: bag-adjoin bag elt …

[R7RS set] {scheme.set} 元のset/bagに、引数に与えられたelt …の要素を加えた セット/バッグを新たに作って返します。作られるセット/バッグの比較器は 元のset/bagの比較器と同じになります。

Function: set-replace set elt
Function: bag-replace bag elt

[R7RS set] {scheme.set} set/bagの要素のうち、eltと等しい (セット/バッグの比較器の意味で)要素があれば、元の要素を除いてeltを追加した セット/バッグを新たに作って返します。eltと等しい要素が元のセット/バッグに 無ければ元のセット/バッグがそのまま返されます。

(let ((s (set string-ci-comparator "ABC" "def")))
  (set->list (set-replace s "abc")))
  ⇒ ("abc" "def")
Function: set-delete set elt …
Function: bag-delete bag elt …

[R7RS set] {scheme.set} 元のset/bagの要素から、elt …に等しいもの以外を 要素に持つセット/バッグを作って返します。

Function: set-delete-all set elt-list
Function: bag-delete-all bag elt-list

[R7RS set] {scheme.set} 元のset/bagの要素から、elt-listに含まれるもの以外を 要素に持つセット/バッグを作って返します。

Function: set-adjoin! set elt …
Function: bag-adjoin! bag elt …
Function: set-replace! set elt
Function: bag-replace! bag elt
Function: set-delete! set elt …
Function: bag-delete! bag elt …
Function: set-delete-all! set elt-list
Function: bag-delete-all! bag elt-list

[R7RS set] {scheme.set} これらは、対応する(!を除いた名前の)手続きの線形更新版です。 !のない版と同じ動作をしますが、結果を作るのに 引数に渡されたセット/バッグを再利用するかもしれません。

引数に渡したセット/バッグが必ず変更されるとは限らないので、 呼出側は副作用に頼らず戻り値を結果として使う必要があります。

Function: set-search! set elt failure success
Function: bag-search! bag elt failure success

[R7RS set] {scheme.set} 検索と変更を行う手続きです。failuresuccess引数は手続きです。

まず、与えられたセット/バッグからeltに一致する要素が探されます。 見つかった場合、success手続きが次のとおり3つの引数を伴って呼び出されます。

(success item update remove)

ここでitemはset/bagのマッチした要素です。

updateは引数を2つとる手続きで、(update new-item retval)のように 呼ぶことができます。呼び出されると、2つの値を返します。 (1) 元のセット/バッグのitemnew-itemに置き換えたセット/バッグ、 (2) retval

removeは引数を2つとる手続きで、(remove retval)のように 呼ぶことができます。呼び出されると、2つの値を返します。 (1) 元のセット/バッグからitemが除かれたセット/バッグ、 (2) retval

eltに一致する要素が見つからなかった場合は、failure手続きが 次のとおり2つの引数を伴って呼ばれます。

(failure insert ignore)

insert引数はひとつの引数を取る手続きで、 (insert retval)のように呼べます。これは二つの値を返します。 (1)元のセット/バッグにeltを追加したセット/バッグ、(2)retval

ignore引数はひとつの引数を取る手続きで、 (ignore retval)のように呼べます。 これは二つの値を返します。 (1)元のセット/バッグ、(2)retval

元のset/bagは、結果を格納するために updateremoveinsert手続きによって再利用されるかもしれません。

set-search!bag-search!は、successもしくはfailureが 返した値をそのまま返します。これらの呼出側が渡す手続きは、 それに渡される手続き(update, remove, insert, ignore)の いずれかを呼び出し、その結果をそのまま返さねばなりません。 従って全体の戻り値は、(変更されたかもしれない)セット/バッグと、retvalということに なります。

もしバッグ中にeltに一致する要素が複数あった場合、bag-search!は 最初の要素でのみsuccessを起動します。 success手続きの中でbag-search!を再帰的に呼ぶことで 全てのマッチする要素を処理することができます。successfailureは 末尾呼び出しされることが保証されています。

セット全体

Function: set-size set
Function: bag-size bag

[R7RS set] {scheme.set} セット/バッグの中にある要素の数を返します。

Function: set-find pred set failure
Function: bag-find pred bag failure

[R7RS set] {scheme.set} predをセット/バッグの各要素に順に適用し、predが最初に真の値を返した 要素を返します。セット/バッグに順序はないので、 predを満たす要素が複数あった場合にどれが買えされるかは不定です。

predを満たす要素がなかった場合は、引数を取らない手続きfailureが 末尾呼び出しされます。

註: このAPIはscheme.listで定義されるfind (Gaucheでは組み込み) と異なります。findfailue手続きを取りません。

Function: set-count pred set
Function: bag-count pred bag

[R7RS set] {scheme.set} セット/バッグ中のpredを満たす要素の数を返します。

Function: set-any? pred set
Function: bag-any? pred bag

[R7RS set] {scheme.set} セット/バッグ中にひとつでもpredを満たす要素があれば#tを、 そうでなければ#fを返します。

註: これはscheme.listで定義されているany (Gaucheでは組み込み) と異なります。anypredが偽でない値を返したらそれをそのまま返しますが、 set-any?は常に真偽値を返します (なのでクエスチョンマークがついています)。

Function: set-every? pred set
Function: bag-every? pred bag

[R7RS set] {scheme.set} セット/バッグ中の全ての要素がpredを満たせば#tを、 そうでなければ#fを返します。

註: これはscheme.listで定義されているevery (Gaucheでは組み込み) と異なります。everyは全ての要素がpredを満たした場合、最後のpredの 戻り値を返しますが、 set-every?は常に真偽値を返します (なのでクエスチョンマークがついています)。

マップと畳み込み

Function: set-map comparator proc set
Function: bag-map comparator proc bag

[R7RS set] {scheme.set} 与えられたset/bagの各要素にprocを適用した結果を要素として、 comparatorを比較器に使う新たなセット/バッグを作って返します。

Function: set-for-each proc set
Function: bag-for-each proc bag

[R7RS set] {scheme.set} set/bagの各要素にprocを適用します。 procの戻り値は捨てられます。この手続き自体の戻り値は未定義です。

Function: set-fold proc seed set
Function: bag-fold proc seed bag

[R7RS set] {scheme.set} 与えられたセット/バッグの各要素に対し、procを2つの引数を伴って呼び出します。 procの1つ目の引数はセット/バッグの要素、2つ目の引数はシード値です。 最初のシード値はseedで与えられ、各procの戻り値が次のシード値となります。 全ての要素にprocが適用されたら、最後のprocの戻り値が set-fold/bag-foldの戻り値になります。

(bag-fold + 0 (bag eqv-comparator 1 1 2 2 3 3 4 4))
  ⇒ 20
Function: set-filter pred set
Function: bag-filter pred bag

[R7RS set] {scheme.set} 与えられたセット/バッグと同じ比較器を持つ新たなセット/バッグを作り、 元の要素のうち述語predを満たす要素だけを入れて返します。

(set->list (set-filter odd? (set eqv-comparator 1 2 3 4 5)))
  ⇒ (1 3 5)
Function: set-remove pred set
Function: bag-remove pred bag

[R7RS set] {scheme.set} 与えられたセット/バッグと同じ比較器を持つ新たなセット/バッグを作り、 元の要素のうち述語predを満たさない要素だけを入れて返します。

(set->list (set-remove odd? (set eqv-comparator 1 2 3 4 5)))
  ⇒ (2 4)
Function: set-partition pred set
Function: bag-partition pred bag

[R7RS set] {scheme.set} 与えられたセット/バッグと同じ比較器を持つ、二つのセット/バッグを返します。 最初の戻り値には、元のセット/バッグの要素のうちpredを満たすもののみが含まれ、 二番目の戻り値にはそうでない要素のみが含まれます。

(receive (in out) (set-remove odd? (set eqv-comparator 1 2 3 4 5))
  (values (set->list in)
          (set->list out)))
  ⇒ (1 3 5) and (2 4)
Function: set-filter! pred set
Function: bag-filter! pred bag
Function: set-remove! pred set
Function: bag-remove! pred bag
Function: set-partition! pred set
Function: bag-partition! pred bag

[R7RS set] {scheme.set} それぞれの!がない手続きの線形更新版です。 !がない手続きと同様に動きますが、 戻り値を作るために渡されたセット/バッグを破壊することが許されています。

元のセット/バッグが必ず変更されるとは限らないことに注意してください。 副作用を当てにするのではなく、必ず戻り値を使う必要があります。

コピーと変換

Function: set-copy set
Function: bag-copy bag

[R7RS set] {scheme.set} 与えられたセット/バッグのコピーを返します。

Function: set->list set
Function: bag->list bag

[R7RS set] {scheme.set} セット/バッグの持つ要素全てのリストを返します。 セット/バッグは順序を持たないので、要素がどういう順序になるかは不定です。

Function: list->set comparator elt-list
Function: list->bag comparator elt-list

[R7RS set] {scheme.set} 与えられた比較器と要素のリストから、セット/バッグを作って返します。 次のコードと機能的に等価です。

(apply set comparator elt-list)
(apply bag comparator elt-list)
Function: list->set! set elt-list
Function: list->bag! bag elt-list

[R7RS set] {scheme.set} リストelt-listの要素を与えられたセット/バッグに追加し、 更新されたセット/バッグを返します。 元のセット/バッグは破壊的に変更されるかもしれませんし、されないかもしれません。 次のコードと機能的に等価です。

(apply set-adjoin! set elt-list)
(apply bag-adjoin! bag elt-list)
Function: bag->set bag
Function: set->bag set

[R7RS set] {scheme.set} バッグをセットに、あるいはセットをバッグに変換します。 新に作られたセットあるいはバッグを返します。

元のbagに重複する要素が含まれていた場合、 bag->setはそのうちひとつだけを含みます。

Function: set->bag! bag set

[R7RS set] {scheme.set} bagに含まれる全ての要素に、setに含まれる要素を追加したバッグを返します。 bagは破壊的に変更されるかもしれません。 bagsetは同じ比較器を使っていなければなりません。

Function: bag->alist bag

[R7RS set] {scheme.set} bag中の相異なる各要素itemについてその個数をcountとしたとき、 (item . count)のリストを返します。

Function: alist->bag comparator alist

[R7RS set] {scheme.set} alistは要素とその個数のペア (item . count) のリストです。 comparatorを比較器として、それぞれのitemcount個づつ 含むようなバッグを作成して返します。

alist中に重複するitemがあった場合、最初のもののみが考慮されます。

部分集合

Function: set=? set1 set2 …
Function: bag=? bag1 bag2 …

[R7RS set] {scheme.set} 全てのセット/バッグが同じ要素を持っている場合に#tを、そうでなければ#fを 返します。

Function: set<? set1 set2 …
Function: bag<? bag1 bag2 …
Function: set>? set1 set2 …
Function: bag>? bag1 bag2 …
Function: set<=? set1 set2 …
Function: bag<=? bag1 bag2 …
Function: set>=? set1 set2 …
Function: bag>=? bag1 bag2 …

[R7RS set] {scheme.set} これらの述語は集合の包含関係を判定します。例えば(set<? set1 set2)set1set2の真部分集合の時に#tを、そうでなければ#fを 返し、(bag>=? bag1 bag2)bag2bag1の 部分集合(等しい場合を含む)の時に#tを、そうでなければ#fを返すという具合です。

3つ以上の引数が与えられた場合、全ての隣り合う引数同士で関係が成り立っている時のみ #tが返されます。

集合論演算

Function: set-union set1 set2 …
Function: bag-union bag1 bag2 …

[R7RS set] {scheme.set} 与えられた全てのセット/バッグの和集合となるセット/バッグを新に作って返します。

Function: set-intersection set1 set2 …
Function: bag-intersection bag1 bag2 …

[R7RS set] {scheme.set} 与えられた全てのセット/バッグの共通集合となるセット/バッグを新に作って返します。

Function: set-difference set1 set2 …
Function: bag-difference bag1 bag2 …

[R7RS set] {scheme.set} set1/bag1の要素のうち、set2/bag2 …に含まれないもの のみを集めたセット/バッグを新に作って返します。

(sort (set->list (set-difference (set eqv-comparator 1 2 3 4 5 6 7)
                                 (set eqv-comparator 3 5 7 9 11 13)
                                 (set eqv-comparator 4 8 16 32))))
  ⇒ (1 2 6)
Function: set-xor set1 set2
Function: bag-xor bag1 bag2

[R7RS set] {scheme.set} set1/bag1およびset2/bag2に含まれる要素のうち、 どちらか一方にしか含まれない要素のみを集めた集合を新に作って返します。

(sort (set->list (set-xor (set eqv-comparator 2 3 5 7 11 13 17)
                          (set eqv-comparator 3 5 7 9 11 13 15))))
  ⇒ (2 9 15 17)
Function: set-union! set1 set2 …
Function: bag-union! bag1 bag2 …
Function: set-intersection! set1 set2 …
Function: bag-intersection! bag1 bag2 …
Function: set-difference! set1 set2 …
Function: bag-difference! bag1 bag2 …
Function: set-xor! set1 set2
Function: bag-xor! bag1 bag2

[R7RS set] {scheme.set} それぞれ、対応する手続き(!のついていないもの)の線形更新版です。 !のついていない版と同様に動作しますが、結果を生成するために set1/bag1を破壊的に変更するかもしれません。

呼び出し側は、副作用を期待するのではなく、常に戻り値を利用してください。

バッグだけにある操作

Function: bag-sum bag1 bag2 …
Function: bag-sum! bag1 bag2 …

[R7RS set] {scheme.set} 与えられた全てのバッグの要素を合わせたバッグを作って返します。 重複する要素があればその分同じ要素が重ねられます。 bag-sumは常に新たなバッグを作って返しますが、 線形更新版のbag-sum!は結果を作るためにbag1を破壊的に変更するかもしれません。

(sort (bag->list (bag-sum (bag eqv-comparator 1 1 2 4 5 5 6)
                          (bag eqv-comparator 3 3 5 9))))
  ⇒ (1 1 2 3 3 4 5 5 5 6 9)

bag-unionとの違いに注意してください。

(sort (bag->list (bag-union (bag eqv-comparator 1 1 2 4 5 5 6)
                            (bag eqv-comparator 3 3 5 9))))
  ⇒ (1 1 2 3 3 4 5 5 6 9)
Function: bag-product n bag
Function: bag-product! n bag

[R7RS set] {scheme.set} 与えられたバッグの各要素数をn倍したバッグを返します。 bag-productは常に新たなバッグを作りますが、 bag-product!は結果を作るためにbagを破壊的に変更するかもしれません。

(sort (bag->list (bag-product 2 (bag eq-comparator 'a 'b 'r 'a))))
  ⇒ (a a a a b b r r)
Function: bag-unique-size bag

[R7RS set] {scheme.set} bag中の、互いに異なる要素の数を返します。

(bag-unique-size (bag eqv-comparator 1 1 2 2 3 3 4))
 ⇒ 4
Function: bag-element-count bag elt

[R7RS set] {scheme.set} bag中にeltがいくつあるかを返します。

(bag-element-count (bag eqv-comparator 1 1 2 2 2 3 3) 2)
 ⇒ 3
Function: bag-for-each-unique proc bag

[R7RS set] {scheme.set} bag中の相異なる各要素について、procを2つの引数で呼び出します。 引数は、要素と、その要素の数です。

Function: bag-fold-unique proc seed bag

[R7RS set] {scheme.set} bag中の相異なる各要素について、procを3つの引数で呼び出します。 要素、その個数、そして一つ前のシード値です。 seed引数が最初のシード値を与え、その後は各procの戻り値が次のシード値となります。 最後のシード値がbag-fold-uniqueの戻り値となります。

(sort (bag-fold-unique acons '()
        (bag equal-comparator "a" "a" "b" "b" "b" "c" "d"))
      string<? car)
 ⇒ (("a" . 2) ("b" . 3) ("c" . 1) ("d" . 1))
Function: bag-increment! bag elt count
Function: bag-decrement! bag elt count

[R7RS set] {scheme.set} bag中の要素eltの個数をcountだけ増やし/減らします。 線形更新手続きなので、bagは結果を作るために破壊的に変更されるかもしれません。 要素の個数は負にはなりません。aが二つバッグに含まれている状態で (bag-decrement! bag 'a 100)を呼ぶと、 aがひとつも含まれないバッグが返されます。

比較器

Comparator: set-comparator
Comparator: bag-comparator

[R7RS comparator] {scheme.set} セット同士、バッグ同士を比較する比較器です。 セット/バッグに一般的な全順序関係は定義できないので、大小比較手続きは提供されません。 ハッシュ手続きは提供されます。


10.3.6 scheme.charset - R7RS文字集合

Module: scheme.charset

文字集合ライブラリを実装します。元はSRFI-14で定義されたものです。 以下の文字集合手続きと定義済み文字集合はGauche組み込みになっているので、 文字集合を参照してください。

char-set             char-set?            char-set-contains?
char-set-copy        char-set-complement  char-set-complement!

char-set:lower-case  char-set:upper-case  char-set:title-case
char-set:letter      char-set:digit       char-set:letter+digit
char-set:graphic     char-set:printing    char-set:whitespace
char-set:iso-control char-set:punctuation char-set:symbol
char-set:hex-digit   char-set:blank       char-set:ascii
char-set:empty       char-set:full

Gaucheでは<char-set>クラスは<collection>を継承し、 コレクションプロトコルを実装しているので、gauche.collectionモジュールで 提供される操作も使えます (gauche.collection - コレクションフレームワーク参照)。


10.3.6.1 文字集合の構築子

Function: list->char-set char-list :optional base-cs
Function: list->char-set! char-list base-cs

[R7RS comparator] {scheme.charset} 与えられた文字のリストchar-listから文字集合を構築して返します。 文字集合base-csが与えられていた場合、返される文字集合は その文字集合にchar-list中の文字を追加したものとなります。 list->char-set!は、結果を格納するためにbase-csを 変更するかもしれません。

Function: string->char-set s :optional base-cs
Function: string->char-set! s base-cs

[R7RS charset] {scheme.charset} 追加する文字をリストでなく文字列sで与えることを除けば list->char-setlist->char-set!と同じです。

Function: char-set-filter pred char-set :optional base-cs
Function: char-set-filter! pred char-set base-cs

[R7RS charset] {scheme.charset} char-set内の文字のうち、(pred c) が真の値を 返すようなcからなる文字集合を作成して返します。 文字集合base-csが与えられた場合は、その内容が結果に追加されます。 char-set-filter!は、結果を格納するためにbase-csを変更するかも しれません。

Function: ucs-range->char-set lower upper :optional error? base-cs
Function: ucs-range->char-set! lower upper error? base-cs

[R7RS charset] {scheme.charset} lower以上、upper未満のUnicodeコードポイントを持つ文字を服務 文字集合を作って返します。

指定された範囲内に文字を割り当てられていないコードポイントがあった場合、 それは単に無視されます。

指定された範囲内にある有効なコードポイントをGaucheがサポートしていない場合、 error?が偽なら(デフォルト)それは単に無視され、真の値ならエラーが投げられます。 デフォルトではGaucheはutf-8内部エンコーディングでコンパイルされていて、 有効な全てのUnicodeコードポイントが扱えます。しかし、Gaucheをそれ以外の内部エンコーディング でコンパイルした場合は、サポートされないコードポイントがあります。

文字集合base-csが与えられた場合、その内容が結果の文字集合に追加されます。 ucs-range->char-set!は、結果を格納するためにbase-csを 再利用するかもしれません。

Function: integer-range->char-set lower upper :optional error? base-cs
Function: integer-range->char-set! lower upper error? base-cs

{scheme.charset} これらはGauche特有で、scheme.charsetの仕様には含まれていません。 Gaucheがutf-8内部エンコーディングでコンパイルされていた場合(デフォルト)、これらは それぞれucs-range->charsetおよびucs->range-char-set!と同じです。 Gaucheがそれ以外の内部エンコーディングでコンパイルされていた場合は、 範囲指定がそのエンコーディングでの文字コードで解釈されません。

error?およびbase-cs引数の意味はucs-char->char-setと同じです。

Function: ->char-set x

[R7RS charset] {scheme.charset} 様々な種類のオブジェクトを文字集合に変換する関数です。xに 文字のコレクション、文字集合、あるいは文字を渡すことができます。 引数が文字集合の場合はそれがそのまま返されます。 引数が文字の場合は、その文字のみを含む文字集合が返されます。

註: R7RS (scheme charset)->char-set は文字列、文字集合、文字のいずれかのみを 引数に取ります。Gaucheでは文字の任意のコレクションを取るように拡張しました。


10.3.6.2 文字集合の比較

Function: char-set= char-set1 …

[R7RS charset] {scheme.charset} 与えられた文字集合が全て同じ要素を持っている場合に限り#tを返します。

(char-set=)  ⇒ #t
(char-set= (char-set)) ⇒ #t
(char-set= (string->char-set "cba")
           (list->char-set #\a #\b #\c))
  ⇒ #t
Function: char-set<= char-set1 …

[R7RS charset] {scheme.charset} 各char-set引数がそれ以降のchar-setの部分集合になっている場合に限り#tを返します。 引数が無い場合は#tを返します。

Function: char-set-hash char-set :optional bound

[R7RS charset] {scheme.charset} char-setのハッシュ値を非負の正確な整数で返します。boundが与えられた場合、 それは正の正確な整数でなければならず、戻り値は0から(- bound 1)まで(両端含む)の 値を取ります。


10.3.6.3 文字集合のイテレーション

Function: char-set-cursor char-set

[R7RS charset] {scheme.charset} char-set中の最初の文字を指すオブジェクトを返します。 (ここでの「最初」は文字集合を順にたどってゆく際の最初ということです。 文字集合をたどる順は実装依存で、特定の順序を当てにしないようにしてください。) 返されたオブジェクトは、そのままchar-set-refchar-set-cursor-nextend-of-char-set?cursor引数に 渡す以外に使ってはいけません。

Function: char-set-ref char-set cursor

[R7RS charset] {scheme.charset} char-set中の、cursorに指された文字を返します。

cursorchar-set-cursorchar-set-cursor-nextによって char-setから作られたオブジェクトでなければなりません。 cursorchar-setから作られたものでない場合の動作は未定義です。

Function: char-set-cursor-next char-set cursor

[R7RS charset] {scheme.charset} char-set中の、cursorが指している文字の次の文字を指す新たなカーソルを返します。

cursorchar-set-cursorchar-set-cursor-nextによって char-setから作られたオブジェクトでなければなりません。 cursorchar-setから作られたものでない場合の動作は未定義です。

Function: end-of-char-set? cursor

[R7RS charset] {scheme.charset} cursorが文字集合の終端を指していたら#tを、そうでなければ#fを返します。

Function: char-set-fold kons knil char-set

[R7RS charset] {scheme.charset} char-set中の全ての文字について、手続きkonsを、文字とシード値を引数にして 呼び出します。knilが最初のシード値を与え、konsの戻り値が次のシード値となります。 最後のシード値がchar-set-foldの戻り値となります。 文字を取り出す順番は規定されていません。

Function: char-set-unfold pred fun gen seed :optional base-char-set
Function: char-set-unfold! pred fun gen seed base-char-set

[R7RS charset] {scheme.charset} funをシード値に適用して得られる文字から文字集合を作って返します。 繰り返しの度に、まずpredが現在のシード値に対して呼ばれ、それが真の値を返したら 繰り返しは終了で、それまで作られた文字を集めた集合が戻り値となります。 そうでなければfunがシード値を引数として呼ばれ、文字を返します。 次にgenがシード値を引数として呼ばれ、次のシード値を作ります。

base-char-setが与えられた場合は、それと生成された文字との和集合が返されます。 線形更新バージョンであるchar-set-unfold!は、base-char-setを破壊的に 再利用するかもしれません。

Function: char-set-for-each proc char-set

[R7RS charset] {scheme.charset} procchar-set中のそれぞれの文字に適用します。 procの戻り値は捨てられます。この手続きの戻り値は規定されません。

Function: char-set-map proc char-set

[R7RS charset] {scheme.charset} procchar-set中のそれぞれの文字に適用します。 procの戻り値は文字でなければなりません。procの戻り値の文字を集めた 新たな文字集合を返します。


10.3.6.4 文字集合への問い合わせ

Function: char-set-every pred char-set
Function: char-set-any pred char-set
Function: char-set-count pred char-set

[R7RS charset] {scheme.charset} これらの手続きは、predchar-setに含まれる各文字に適用します。

char-set-everypred#fを返したら直ちに#fを返します。 predが最後まで#fを返さなかった場合は、最後のpredの返り値が char-set-everyの返り値となります。

char-set-anypredが真の値を返した場合に直ちにその値を返します。 predが最後まで#fを返した場合には#fを返します。

char-set-countpredが真の値を返した回数を返します。

char-setは非常に大きくなる可能性があり (例えばごく小さな文字集合の補集合)、 その場合、これらの手続きは非常に長くかかり得ることに注意してください。

Function: char-set->list char-set
Function: char-set->string char-set

[R7RS charset] {scheme.charset} char-setに含まれる文字をリストあるいは文字列にして返します。 大きな文字集合に適用する場合は注意してください。


10.3.6.5 文字集合に適用できる代数的関数

Function: char-set-adjoin char-set char1 …
Function: char-set-adjoin! char-set char1 …

[R7RS charset] {scheme.charset} char-setchar1 …を加えた文字集合を返します。

線形更新版のchar-set-adjon!char-set引数を破壊的に再利用するかもしれません。

Function: char-set-delete char-set char1 …
Function: char-set-delete! char-set char1 …

[R7RS charset] {scheme.charset} char-setからchar1 …を除いた文字集合を返します。 char1 …がchar-setに含まれている必要はありません。

線形更新版のchar-set-delete!char-set引数を破壊的に再利用するかもしれません。

Function: char-set-union char-set …
Function: char-set-union! char-set1 char-set2 …

[R7RS charset] {scheme.charset} char-set …内の少なくともひとつに含まれる文字の文字集合を返します。 引数が無ければ空の文字集合を返します。

線形更新版のchar-set-union!char-set1引数を破壊的に再利用するかもしれません。

Function: char-set-intersection char-set …
Function: char-set-intersection! char-set1 char-set2 …

[R7RS charset] {scheme.charset} char-set …の全てに共通して含まれる文字の文字集合を返します。 引数が無ければchar-set:fullを返します。

線形更新版のchar-set-intersection!char-set1引数を破壊的に再利用するかもしれません。

Function: char-set-difference char-set1 char-set2 …
Function: char-set-difference! char-set1 char-set2 …

[R7RS charset] {scheme.charset} char-set1に含まれ、しかしchar-set2 …のどれにも含まれない文字の文字集合を返します。

線形更新版のchar-set-difference!char-set1引数を破壊的に再利用するかもしれません。

Function: char-set-xor char-set …
Function: char-set-xor! char-set1 char-set2 …

[R7RS charset] {scheme.charset} 引数がない場合は空の文字集合を、引数が一つの場合はそれをそのまま返します。 引数が二つの場合、そのどちらか一方に含まれるが両方には含まれない文字の文字集合を返します。 引数が三つ以上の場合は(char-set-xor (char-set-xor set1 set2) set3 …)を 返します。

線形更新版のchar-set-xor!char-set1引数を破壊的に再利用するかもしれません。

Function: char-set-diff+intersection char-set1 char-set2 …
Function: char-set-diff+intersection! char-set1 char-set2 char-set3 …

[R7RS charset] {scheme.charset} (char-set-difference char-set1 char-set2 …の結果と (char-set-intersection char-set1 char-set2 …の結果の 二つの値を返します。


10.3.7 scheme.hash-table - R7RSハッシュテーブル

Module: scheme.hash-table

このモジュールは、元々srfi.125で定義されていたハッシュテーブルのライブラリです。

このモジュールで提供されるハッシュテーブルはGaucheの組み込みハッシュテーブルそのものです。 ただ、SRFI-125はいくつか、Gaucheの元々持っていた手続きと名前が衝突する手続きを 定義しています。Gaucheはそれらの手続きに関しては異なる名前で組み込み手続きを 用意しています。組み込みのハッシュテーブル手続きについては ハッシュテーブルを参照してください。

このモジュールを使うと、手続きはR7RSで定義されたとおりの動作になります。 ポータブルなコードを書く際にこのモジュールを使うと良いでしょう。

SRFI-125はまた、SRFI-69で定義されたいくつかの手続きを、非推奨ながら 互換性のためにサポートしています。これらの非推奨手続きも このモジュールで提供されます。

以下の手続きはGaucheの組み込みと同じです。

hash-table?         hash-table-contains? hash-table-exists?
hash-table-empty?   hash-table=?         hash-table-mutable?
hash-table-ref      hash-table-ref/default
hash-table-set!     hash-table-update!/default
hash-table-clear!   hash-table-size   hash-table-keys
hash-table-values   hash-table-copy   hash-table-empty-copy
hash-table->alist   hash-table-union! hash-table-intersection!
hash-table-difference!                hash-table-xor!

これらの手続きの説明はハッシュテーブルを参照してください。

以下の手続きは、Gaucheの組み込みでは-r7サフィックスをつけた名前で 提供されています。

hash-table         hash-table-delete! hash-table-intern!
hash-table-update! hash-table-pop!    hash-table-find
hash-table-count   hash-table-map     hash-table-for-each
hash-table-map!    hash-table-map->list
hash-table-prune!
Function: make-hash-table comparator arg …
Function: make-hash-table equal-proc hash-proc arg …

[R7RS hash-table] {scheme.hash-table} この手続きは、組み込みのmake-hash-tableを拡張して二番目の形式を許したものです。 二番目の形式は比較器のかわりに二つの手続きをとるもので、SRFI-69互換です。

SRFI-69互換形式では、equal-procはふたつのキーを取りそれが等しいかどうかを 返す述語、hash-procは一つのキーを取りそのハッシュ値を非負の正確な整数で 返す手続きです。 この互換係式は非推奨で、新たなコードでは使うべきではありません。

省略可能なarg …引数は実装依存で、作られるハッシュテーブルの 様々な特性を指定するものです。Gaucheでは無視されます。

Function: hash-table cmpr key value …

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-r7と同じです(ハッシュテーブル参照)。

キーの比較とハッシュに比較器cmprを使う新たなハッシュテーブルを作って返します。 また、ハッシュテーブルの内容はkey value …によって初期化されます。 ここで引数はキーと値が交互に並んだものです。key value …部分の 長さが偶数でなければエラーが投げられます。

SRFI-125では、この手続きは(実装がサポートしていれば)変更不可なハッシュテーブルを 返すと規定されています。Gaucheは変更不可なハッシュテーブルを持っていないので、 変更可能なハッシュテーブルが返りますが、ポータブルなコードを書く際には 返されたテーブルを変更しないようにしてください。 なお、Gaucheも変更不可なマップは持っています (data.imap - 変更不可なマップ参照)。

Function: alist->hash-table alist cmpr arg …
Function: alist->hash-table alist equal-proc hash-proc cmpr arg …

[R7RS hash-table] {scheme.hash-table} この手続きは、組み込みのalist->hash-tableを拡張して二番目の形式を許したものです。 二番目の形式は比較器のかわりに二つの手続きをとるもので、SRFI-69互換です。

SRFI-69互換形式では、equal-procはふたつのキーを取りそれが等しいかどうかを 返す述語、hash-procは一つのキーを取りそのハッシュ値を非負の正確な整数で 返す手続きです。 この互換係式は非推奨で、新たなコードでは使うべきではありません。

省略可能なarg …引数は実装依存で、作られるハッシュテーブルの 様々な特性を指定するものです。Gaucheでは無視されます。

Function: hash-table-unfold p f g seed comparator :optional arg …

[R7RS hash-table] {scheme.hash-table} 省略可能なarg …を許すことを除いて、 Gauche組み込みのhash-table-unfoldと同じです。 arg …は作られるテーブルのパラメータを与える実装依存な引数で、 Gaucheでは今のところ無視されます。 詳しくはハッシュテーブルを参照してください。

Function: hash-table-delete! ht key …

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-delete!-r7と同じです。

ハッシュテーブルhtから、key …を持つエントリを削除します。 htkeyを持っていなくてもエラーにはなりません。 実際に削除されたエントリの数を返します。

組み込みのhash-table-delete!と違うのは次の2点です。 組み込みはkeyをひとつしか取らず、それが実際に削除されたかどうかをブール値で返します。

Function: hash-table-intern! ht key failure

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-intern!-r7と同じです。

ハッシュテーブルhtからキーkeyを持つエントリを探し、 見つかった場合はその値を返します。見つからなかった場合は、手続きfailureを 引数無しで呼び出し、その返り値をkeyに結びついた新たなエントリとして htに追加し、またhash-table-intern!の返り値とします。

Function: hash-table-update! ht key updater :optional failure success

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-update!-r7と同じです。 組み込みのhash-table-update!とは取る引数が異なります。

updaterは1引数の手続き、 failureはサンク、successは1引数の手続きです。

次の式と同様に動作しますが、より効率が良いかもしれません。

(hash-table-set! ht key (updater (hash-table-ref ht key failure success)))
Function: hash-table-pop! ht

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-pop!-r7と同じです。 組み込みのhash-table-pop!とは全く異なる手続きです。

htから任意のエントリをひとつ削除じ、削除したエントリのキーと値を 二つの返り値として返します。

htが空であればエラーが投げられます。

Function: hash-table-find proc ht failure

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-find-r7と同じです。 組み込みのhash-table-findとは引数が異なります。

ht内のひとつのキーと値を引数にしてprocを呼び出します。 procが真の値を返したら、hash-table-findはそれを直ちに返します。 そうでなければ、別のキーと値でprocを呼び出し、全てのキーと値について 試すまで繰り返します。 全てのキーと値についてprocが偽を返した場合は、failureサンクを呼び出し それを結果とします。

Function: hash-table-count proc ht

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-count-r7と同じです。

ハッシュテーブルhtの各エントリについてprocをキーと値を引数にして呼び出し、 procが真の値を返した回数をこの手続きの値とします。

Function: hash-table-map proc cmpr ht

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-map-r7と同じです。 組み込みのhash-table-mapとは異なる手続きです。

キーの比較を比較器cmprで行う新たなハッシュテーブルを作成し、 htの各エントリのキーと値をprocに渡し、 新たなハッシュテーブルにそのキーとprocの戻り値を新たなエントリとして作成します。

Function: hash-table-map! proc ht

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-map-r7!と同じです。

prochtの各エントリのキーと値を引数にして呼び出し、 そのキーに対応する値をprocの戻り値で置き換えます。

Function: hash-table-map->list proc ht

[R7RS hash-table] {scheme.hash-table} これは組み込みのhash-table-map->list-r7と同じで、 また組み込みのhash-table-mapとは引数の順序が異なるだけの違いです (scheme.hash-tablehash-table-mapは全然異なる手続きです)。

htの各エントリのキーと値に対してprocを呼び出し、その結果をリストにして 返します。エントリの順序は規定されません。

Function: hash-table-for-each proc ht
Function: hash-table-for-each ht proc

[R7RS hash-table] {scheme.hash-table} prochtの各エントリのキーと値を引数にして呼び出します。 procの戻り値は捨てられます。この手続きの戻り値は定義されません。

この手続きは、互換性のために2通りの順序で引数を取ります。 scheme.hash-tableが推奨するのは最初の方法です。 組み込みのhash-table-for-each-r7も同じです。 二番目の呼び出しはSRFI-69で規定されていた方法で、 組み込みのhash-table-for-eachはこちらの順序です。

残念ながら、この互換性の問題は大きな混乱のもとになるでしょう。 特にGaucheでは色々なオブジェクトを適用可能にできるので、 手続きとそれ以外のオブジェクトの境目ははっきりしていません。

ひとつのモジュール内では統一した順序で呼び出すことを推奨します。 組み込みのハッシュテーブルAPIを使っているなら(hash-table-for-each ht proc)の 順序を、scheme.hash-tableをインポートしたなら (hash-table-for-each proc ht)という順序を使うと良いでしょう。

Function: hash-table-fold proc seed ht
Function: hash-table-fold ht proc seed

[R7RS hash-table] {scheme.hash-table} procは、キー、対応する値、シード値の3つの引数を取る手続きです。 hash-table-foldはハッシュテーブルhtのそれぞれのエントリについて、 procを呼び出します。シード値の初期値はseedで、 以降は一つ前のprocの戻り値が次のシード値として渡されてゆき、 最後のproc呼び出しの戻り値が全体の戻り値となります。

この手続きもまた、互換性のために二つのインタフェースを用意しています。 最初のインタフェースはscheme.hash-tableライブラリ推奨のもので、 Gauche組み込みのhash-table-fold-r7と同じです。 後者はSRFI-69およびGauche組み込みのhash-table-foldと同じです。

歴史的経緯とはいえ、ふたつの紛らわしいインタフェースが併存するのは残念なことです。 一つのモジュール内では混乱を避けるため、どちらかに統一した方が良いでしょう。 Gauche組み込みのハッシュテーブルインタフェースを他にも使っているなら後者で、 ポータブルなR7RSコードを書いているなら前者で。

Function: hash-table-prune! proc ht

[R7RS hash-table] {scheme.hash-table} 組み込みのhash-table-prune!-r7と同じです。

htの各エントリについて、procをキーと値を引数として呼び出し、 procが真の値を返したエントリをhtから削除します。 戻り値は規定されていません。

Function: hash-table-merge! ht1 ht2

[R7RS hash-table] {scheme.hash-table} Deprecated. これはhash-table-union!と同じで、 SRFI-69との互換性のためだけに提供されています。

Function: hash obj :optional ignore
Function: string-hash obj :optional ignore
Function: string-ci-hash obj :optional ignore
Function: hash-by-identity obj :optional ignore

[R7RS hash-table] {scheme.hash-table} SRFI-69互換性のために提供されているハッシュ関数です。非推奨です。

最初の3つの手続きは、無視される省略可能引数を取ることを除いて、 組み込みのdefault-hashstring-hashstring-ci-hash とそれぞれ同じです。 hash-by-identityも省略可能引数を除いてはdefault-hashと 同じです。名前からeq-hashのように思えるかもしれませんが、 SRFI-125でdefault-hashと同じと規定されています。

新しいコードではこれらを使わず、 (default-comparatorstring-comparatorstring-ci-comparatoreq-comparator等の 比較器を渡すようにしてください (用意されている比較器参照)。 たとえハッシュ関数を渡す必要があったとしても、 hashhash-by-identityの使用は避け、 かわりにdefault-hasheq-hashを使いましょう。

Function: hash-table-equivalence-function ht
Function: hash-table-hash-function ht

[R7RS hash-table] {scheme.hash-table} SRFI-69との互換性のために提供されている手続きで、非推奨です。

ハッシュテーブルhtの等値判定手続きとハッシュ手続きをそれぞれ返します。

SRFI-69ではハッシュ関数は省略可能なbound引数を取るというプロトコルになっています。 そこで、htが比較器、もしくは省略可能引数を取らないハッシュ関数から 作られていた場合、hash-table-hash-functionは元のハッシュ関数をラップして、 省略可能引数boundを取るようにした手続きを返します。

ハッシュテーブルのイントロスペクションには、hash-table-comparatorで 比較器を取り出す方が良いでしょう (ハッシュテーブル参照)。


10.3.8 scheme.ilist - R7RS変更不可リスト

Module: scheme.ilist

このモジュールは変更不可なペアとリストを扱う手続きを提供します。

規格では、Scheme実装は変更可能なペアと変更不可能なペアを別の型として持つことを許していて、 そのためこのモジュールではscheme.listにある多くの手続きの変更不可ペア用バージョンを 提供しています。 しかしGaucheは、変更可能なペアも変更不可なペアもどちらも「ペア」として扱い、 ペアにアクセスする手続きは(ペアを破壊的変更しない限り)変更不可なペアにもそのまま使えます (変更可能なペアと変更不可なペア参照)。

従って、このモジュールが提供する手続きは単に変更可能ペア用バージョンの別名になっています。 (名前からiプレフィクスを除いたものが対応する手続きです)。 このモジュールの手続きは、変更可能なペアが与えられてもエラーにしないことに注意してください。 Gaucheではそれらを区別しませんが、区別する処理系ではエラーになるかもしれません。

proper-ilist?     ilist?            dotted-ilist?     not-ipair?
null-ilist?       ilist=
icar              icdr              icaar             icadr
icdar             icddr             icaaar            icaadr
icadar            icaddr            icdaar            icdadr
icddar            icdddr            icaaaar           icaaadr
icaadar           icaaddr           icadaar           icadadr
icaddar           icadddr           icdaaar           icdaadr
icdadar           icdaddr           icddaar           icddadr
icdddar           icddddr           icar+icdr         ilist-ref
ifirst            isecond           ithird            ifourth
ififth            isixth            iseventh          ieighth
ininth            itenth
idrop             ilist-tail        itake-right
ilast             last-ipair        ilength           icount
ifor-each         ifold             ipair-fold        ireduce
ifold-right       ipair-fold-right  ireduce-right     ipair-for-each
imember           imemv             imemq             ifind-tail
iany              ievery            ilist-index       idrop-while
iassoc            iassq             iassv             iapply
make-ilist-comparator               make-improper-ilist-comparator
make-icar-comparator                make-icdr-comparator
make-ipair-comparator

10.3.9 scheme.rlist - R7RSランダムアクセスリスト

Module: scheme.rlist

このモジュールは、変更不可で、ランダムアクセスがO(log n)であるような、 ペアとリストに替わるデータ構造を提供します。carcdrはO(1)です。 元はsrfi.101として定められました。 ここでは、このデータ型をrlistと呼ぶことにします。

このsrfiでは、組み込みのペアとリストとしてrlistを選択するScheme処理系も可能なように 書かれています。そのため、手続き名がSchemeのペアやリストを扱うプリミティブと 重複しています。このモジュールを使う際には、 (use scheme.rlist :prefix rlist:)といった具合にプリフィクスつきで インポートすると良いでしょう。

Gaucheでは、rlistはskew-list (data.sparse - Skew binary random-access lists参照) の上に 実装されています。skew-listとの大きな違いは、skew-listは常に真正リストですが、 rlistはドットリストが許されることです。(つまり、rlistの最後のペアのcdrには どんなオブジェクトも許されます。)

ただ、真正でないリストを扱うために内部では面倒なことをしています。 速いランダムアクセス可能なリストが必要なら、skew-listをそのまま使った方が良いです。 その上で非真正リストを扱う必要がある場合だけ、このモジュールを使うのが良いでしょう。

次の手続きは、引数や戻り値がrlistであること以外は、組み込みの同名の手続きと同じ動作をします。 (註: このモジュールのlist-reflist-tailは省略可能引数を取りません。 通常のリストに対するlist-reflist-tailが省略可能引数を取るのは Gaucheの独自拡張だからです。)

pair?     cons       car        cdr
caar      cadr       cdar       cddr
caaar     caadr      cadar      caddr
cdaar     cdadr      cddar      cdddr
caaaar    caaadr     caadar     caaddr
cadaar    cadadr     caddar     cadddr
cdaaar    cdaadr     cdadar     cdaddr
cddaar    cddadr     cdddar     cddddr
null?     list?      list       make-list
length    append     reverse    list-tail
list-ref  map        for-each

このモジュールはまた、リテラルのrlistを書くめのquoteという構文もエクスポートします。 (quote (a (b c)))は、 aおよび、「bcを要素に持つrlist」のrlistになります。

scheme.rlistをプリフィクスなしでインポートした場合、 '(a (b c))は組み込みのquoteではなくscheme.rlist#quoteを 使うことに注意してください。

Function: list-set rlist k obj

[R7RS rlist] {scheme.rlist} 元のrlistのうち、k番目の要素がobjに置き換えられた rlistを作って返します。rlistの長さをnとした時、 O(log n)の操作です。

Function: list-ref/update rlist k proc

[R7RS rlist] {scheme.rlist} (list-ref rlist k)の結果と、 (list-set rlist k (proc (list-ref rlist k)))の結果という二つの値を返します。 ただし、別々に呼び出すよりは効率が良いかもしれません。

Function: random-access-list->linear-access-list rlist

[R7RS rlist] {scheme.rlist} 真正のrlistと同じ要素を持つ通常のリストを返します。 rlistが真正でなければエラーが投げられます。 変換はrlistの「背骨」に対してのみ行われることに注意してください。 rlistがネストしていた場合、一番外側のrlistだけが変換されます。

Function: linear-access-list->random-access-list list

[R7RS rlist] {scheme.rlist} 通常の真正リストlistと同じ要素を持つrlistを返します。 listが真正でなければエラーが投げられます。 変換はlistの「背骨」に対してのみ行われることに注意してください。 listがネストしていた場合、一番外側のlistだけが変換されます。


10.3.10 scheme.ideque - R7RS変更不可な両端キュー

Module: scheme.ideque

このモジュールは、関数的な両端キュー (deque:「デック」と読みます) を提供します。 どちらの端からのキュー操作もO(1)償却時間で可能です。

dequeはまた、どちらの方向からでもトラバースできるリストとして使うこともできます。

註: 変更不可である必要がなく、メモリ効率の良いdequeが必要なら、 data.ring-bufferをdequeとして使うことができます(data.ring-buffer - リングバッファ参照)。

このモジュールはsrfi.134として定義され、R7RS largeに取り込まれました。

Gaucheのdata.idequeはこのモジュールのスーパーセットになっています (data.ideque - 変更不可な両端キュー参照)。

Function: ideque element …

[R7RS ideque] {scheme.ideque} element … を要素に持つidequeを作って返します。

Function: ideque-unfold p f g seed

[R7RS ideque] {scheme.ideque} リストを構築するunfoldと同じ要領でidequeを左から構築します (unfoldについてはscheme.list - R7RSリスト参照)。

各繰り返しにて、まずpが現在の状態値に適用されます。 それが真の値を返したら繰り返しは終了です。 そうでなければ、fが状態値に適用され、その結果がidequeの要素のひとつになります。 次にgが状態値に適用され、その結果が次の繰り返しの状態値となります。 fの結果が順に集められて、idequeの内容となります。 seed引数は最初の状態値を与えます。

(ideque->list
  (ideque-unfold (cut > <> 10) square (cut + <> 1) 0))
 ⇒ (0 1 4 9 16 25 36 49 64 81 100)
Function: ideque-unfold-right p f g seed

[R7RS ideque] {scheme.ideque} ideque-unfoldと同じようにidequeを作りますが、 要素が右から生成されます。

(ideque->list
  (ideque-unfold-right (cut > <> 10) square (cut + <> 1) 0))
 ⇒ (100 81 64 49 36 25 16 9 4 1 0)
Function: ideque-tabulate size init

[R7RS ideque] {scheme.ideque} sizeの長さのidequeを作ります。左からi番目の要素は (init i)で計算されます。

(ideque->list (ideque-tabulate 11 square))
 ⇒ (0 1 4 9 16 25 36 49 64 81 100)
Function: ideque? obj

[R7RS ideque] {scheme.ideque} objがidequeなら#tを、そうでなければ#fを返します。

Function: ideque-empty? idq

[R7RS ideque] {scheme.ideque} idqが空なら#tを、そうでなければ#fを返します。

Function: ideque-add-front idq x
Function: ideque-add-back idq x

[R7RS ideque] {scheme.ideque} それぞれ、xがideque idqの前(左)または後(右)に付け加えられた idequeを返します。O(1)の操作です。

Function: ideque-front idq
Function: ideque-back idq

[R7RS ideque] {scheme.ideque} それぞれ、ideque idqの先頭または末尾の要素を返します。 idqが空の場合はエラーが投げられます。 O(1)の操作です。

Function: ideque-remove-front idq
Function: ideque-remove-back idq

[R7RS ideque] {scheme.ideque} それぞれ、ideque idqの先頭または末尾の要素を取り除いたidequeを返します。 idqが空の場合はエラーが投げられます。 O(1)の操作です。

Function: ideque-reverse idq

[R7RS ideque] {scheme.ideque} ideque idqの順序を逆にしたidequeを返します。 O(1)の操作です。

Function: ideque= elt= idq …

[R7RS ideque] {scheme.ideque} 引数のideque idq …が全て同じ長さで、対応する各要素が 全てelt=で比較して等しい場合に#tを、そうでなければ#fを 返します。elt=は、i番目のidequeの要素とi+1番目のidequeの要素を引数として 呼ばれます。

idequeがひとつだけ、あるいは全く渡されなかった場合、elt=は呼ばれず、 #tが返されます。

Function: ideque-ref idq n

[R7RS ideque] {scheme.ideque} ideque idqn番目の要素を返します。 nが範囲外の場合はエラーが投げられます。

Function: ideque-take idq n
Function: ideque-take-right idq n

[R7RS ideque] {scheme.ideque} それぞれ、ideque idqの先頭から/末尾からn要素を内容とするidequeを 返します。nidqの長さより大きい場合はエラーが投げられます。

Function: ideque-drop idq n
Function: ideque-drop-right idq n

[R7RS ideque] {scheme.ideque} それぞれ、ideque idqの先頭から/末尾からn要素を取り除いたものを 内容とするidequeを返します。 nidqの長さより大きい場合はエラーが投げられます。

Function: ideque-split-at idq n

[R7RS ideque] {scheme.ideque} Returns two ideques, the first one is (ideque-take idq n) and the second one is (ideque-drop idq n). An error is signaled if n is greater than the length of idq. 二つの値を返します。最初の値は(ideque-take idq n)の結果と等しく、 次の値は(ideque-drop idq n)の結果と等しいです。 nidqの長さより大きい場合はエラーが投げられます。

Function: ideque-length idq

[R7RS ideque] {scheme.ideque} ideque idqの長さを返します。

Function: ideque-append idq …

[R7RS ideque] {scheme.ideque} 与えられたideque idq …を順につないだidequeqを返します。

Function: ideque-zip idq idq2 …

[R7RS ideque] {scheme.ideque} ideque idq idq2 … の各i番目の要素のリストを要素とする idequeを返します。元のidequeの要素数が異なる場合は、最も短いidequeに揃えます。

(ideque->list
  (ideque-zip (ideque 'a 'b 'c) (ideque 1 2) (ideque 'x 'y 'z)))
 ⇒ ((a 1 x) (b 2 y))
Function: ideque-map proc idq …

[R7RS ideque] {scheme.ideque} idqの各要素についてprocを適用し、その結果を順に返す新たなidequeを 作って返します。procがどういう順番で要素に適用されるかは不定です。 O(n)時間かかります。

R7RSのidequeライブラリはidqが一つの場合のみを定義しています。 idqが二つ以上の場合はGaucheの拡張としてサポートされます。 idqが二つ以上の場合、procは入力のidqの数だけ引数を取ります。 また、結果のidequeの長さは最短の入力で決まります。

(ideque->list (ideque-map square (ideque 1 2 3 4 5)))
  ⇒ (1 4 9 16 25)
(ideque->list (ideque-map + (ideque 1 2 3 4 5) (ideque 2 2 2)))
  ⇒ (11 12 13)
Function: ideque-filter-map proc idq …

[R7RS ideque] {scheme.ideque} idqの各要素にprocを適用し、その結果のうち#fでないものを 集めたidequeを作って返します。 procがどういう順番で要素に適用されるかは不定です。

R7RSのidequeライブラリはidqが一つの場合のみを定義しています。 idqが二つ以上の場合はGaucheの拡張としてサポートされます。 idqが二つ以上の場合、procidqの数だけ引数を取ります。 また、入力のidqのいずれかの最後まで到達した時に処理が終了します。

Function: ideque-for-each proc idq …
Function: ideque-for-each-right proc idq …

[R7RS ideque] {scheme.ideque} procidqの要素に順に(ideque-for-eachは左から右に、 ideque-for-each-rightは右から左に)適用します。procの 結果は捨てられます。

戻り値は未規定です。

R7RSのidequeライブラリはidqが一つの場合のみを定義しています。 idqが二つ以上の場合、procidqの数だけ引数を取ります。

ideque-for-eachは各idequeの要素を左から取るのに対し、 ideque-for-each-rightは各idequeの要素を右から取ります。 どちらも最短のidequeを消費した時点で終了します。

(ideque-for-each ($ display $ list $)
                 (ideque 'a 'b 'c 'd 'e)
                 (ideque 1 2 3))
 ⇒ prints (a 1)(b 2)(c 3)

(ideque-for-each-right ($ display $ list $)
                       (ideque 'a 'b 'c 'd 'e)
                       (ideque 1 2 3))
 ⇒ prints (e 3)(d 2)(c 1)
Function: ideque-fold proc knil idq …
Function: ideque-fold-right proc knil idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-append-map proc idq …

[R7RS ideque] {scheme.ideque}

Function: ideque-filter pred idq
Function: ideque-remove pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-partition pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-find pred idq :optional failure
Function: ideque-find-right pred idq :optional failure

[R7RS ideque] {scheme.ideque}

Function: ideque-take-while pred idq
Function: ideque-take-while-right pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-drop-while pred idq
Function: ideque-drop-while-right pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-span pred idq
Function: ideque-break pred idq

[R7RS ideque] {scheme.ideque}

Function: ideque-any pred idq …
Function: ideque-every pred idq …

[R7RS ideque] {scheme.ideque}

Function: ideque->list idq
Function: list->ideque list

[R7RS ideque] {scheme.ideque}

Function: ideque->generator idq
Function: generator->ideque gen

[R7RS ideque] {scheme.ideque}


10.3.11 scheme.text - R7RS変更不可なテキスト

Module: scheme.text

このモジュールはtextと呼ばれる、O(1)ランダムアクセスができる 変更不可な文字列へのインタフェースを提供します。 元はSRFI-135として規定されました。

Gaucheの文字列は一般的にはマルチバイト文字列のためインデックスアクセスはO(n)と なります。しかし、文字列がASCII文字のみからなる場合、 あるいは文字列インデックスが付加されている場合(文字列索引参照)は、 インデックスアクセスはO(1)になります。 従って、Gaucheではtextは単なる変更不可でインデックスが付加された文字列であり、 string?に対しても#tを返します。

Gaucheではこのsrfiでいうtextual型は文字列型と全く同じであり、 textual-*手続きの大半は対応するstring-*手続きの単なる別名です。

しかし、ポータブルなコードを書いている場合は、処理系によってはtext型と文字列型が 別の型である場合もあることに留意してください。

Function: text? obj

[R7RS text] {scheme.text} objがtext型なら#tを、そうでなければ#fを返します。 Gaucheではtextは文字列インデックスが付加された変更不可な文字列です。 文字列型とtext型が排他ではないことに注意してください。

Function: textual? obj

[R7RS text] {scheme.text} objがtext型か文字列型であれば#tを、そうでなければ#fを返します。 Gaucheではこれは単にstring?の別名です。

Function: textual-null? obj

[R7RS text] {scheme.text} objが空の文字列かtextなら#tを、そうでなければ#fを返します。 Gaucheではこれは単にstring-null?の別名です。

Function: textual-every pred textual :optional start end
Function: textual-any pred textual :optional start end

[R7RS text] {scheme.text} textと文字列の両方に対して、string-everystring-anyのように動作します。 Gaucheではこれらはstring-everystring-anyの別名です。

Function: make-text len char

[R7RS text] {scheme.text} Gaucheではこれはmake-stringとほぼ同じですが、 返される文字列は変更不可であり、また文字列インデックスが付加済みです。 charを省略できないことに注意してください。

Function: text char …

[R7RS text] {scheme.text} stringと似ていますが、 返される文字列は変更不可であり、また文字列インデックスが付加済みです。

Function: text-tabulate proc len

[R7RS text] {scheme.text} string-tabulateと似ていますが、 返される文字列は変更不可であり、また文字列インデックスが付加済みです。 文字列の構築子参照。

Function: text-unfold p f g seed :optional base make-final
Function: text-unfold-right p f g seed :optional base make-final

[R7RS text] {scheme.text} string-unfoldおよびstring-unfold-rightと似ていますが、 返される文字列は変更不可であり、文字列インデックス付加済みになります (文字列の構築子参照)。 また、シードから要素を生成する手続きfは、 文字だけでなく文字列を返すこともできます (その文字列の各文字が結果に挿入されます)。

Function: text-length text

[R7RS text] {scheme.text} textの長さを返します。textがtextでなければエラーが報告されます。

Function: text-ref text index

[R7RS text] {scheme.text} textのindex番目の文字を返します。O(1)アクセスが保証されます。 textがtextでなければエラーが報告されます。

Function: textual-length textual

[R7RS text] {scheme.text} textあるいは文字列の長さを返します。 Gaucheではこれは単にstring-lengthの別名です。

Function: textual-ref textual index

[R7RS text] {scheme.text} textのindex番目の文字を返します。 Gaucheではこれは単にstring-refの別名です。

Function: textual->text textual

[R7RS text] {scheme.text} 文字列を受け取り、同じ内容の、文字列インデックス付加済みで変更不可な文字列を返します。 textualが既にそういう文字列であれば、それがそのまま返されます。

Function: textual->string textual :optional start end
Function: textual->vector textual :optional start end
Function: textual->list textual :optional start end

[R7RS text] {scheme.text} textualを新たにアロケートされた変更可能な文字列、 文字のベクタ、文字のリストにそれぞれ変換します。 Gaucheではこれらはstring-copystring->vectorstring->listの別名です。

Function: string->text string :optional start end
Function: vector->text char-vector :optional start end
Function: list->text char-list :optional start end

[R7RS text] {scheme.text} それぞれ、文字列、文字のベクタ、文字のリストを、 文字列インデックス付きの変更不可な文字列に変換します。 string->textに文字列インデックス付きの変更不可な文字列が渡された場合は それがそのまま返されます。

Function: reverse-list->text char-list

[R7RS text] {scheme.text} (list->text (reverse char-list))と同じですがより効率的な場合があります。

Function: textual->utf8 textual :optional start end

[R7RS text] {scheme.text} 入力のtextまたは文字列をutf8エンコーディングのバイト列に変換し、バイトベクタ(u8vector) として返します。Gaucheではこれはstring->utf8と同じです (Unicode transfer encodings参照)。

Function: textual->utf16 textual :optional start end

[R7RS text] {scheme.text} 入力のtextまたは文字列をutf16エンコーディングのバイト列 (ネイティブバイトオーダー、BOMつき)に変換し、バイトベクタ(u8vector) として返します。Gaucheではこれは (string->utf16 textual (native-endian) #t [start end])と同じです (Unicode transfer encodings参照)。

Function: textual->utf16be textual :optional start end
Function: textual->utf16le textual :optional start end

[R7RS text] {scheme.text} 入力のtextまたは文字列をutf16le/beエンコーディングのバイト列 (BOMなし)に変換し、バイトベクタ(u8vector)として返します。Gaucheではこれはそれぞれ (string->utf16 textual 'big-endian #f [start end])および (string->utf16 textual 'little-endian #t [start end])と同じです (Unicode transfer encodings参照)。

Function: utf8->text bytevector :optional start end

[R7RS text] {scheme.text} bytevector (u8vector)に格納されたutf8オクテット列をtext (インデックス付き変更不可文字列) に変換して返します。 入力がBOMで始まっていた場合、それは文字U+FEFFと解釈されます。 省略可能なstart/end引数は入力bytevectorの範囲を制限します。

入力にutf-8として不正なオクテットが含まれており、Gaucheが内部エンコーディングutf-8で コンパイルされていれば、そのオクテットはUnicode置換文字U+FFFDに変換されます。 (SRFI-135ではその場合は「エラーである」と規定されているので、 実際の処理は処理系依存になります)。

Function: utf16->text bytevector :optional start end
Function: utf16be->text bytevector :optional start end
Function: utf16le->text bytevector :optional start end

[R7RS text] {scheme.text} bytevector (u8vector)に格納されたutf8オクテット列をtext (インデックス付き変更不可文字列) に変換して返します。 utf16->textは、入力がBOMで始まっていればそれに従ってバイトオーダーを 解釈し、BOMが無ければネイティブバイトオーダーを使います。 utf16be->textutf16le->textはそれぞれ 入力がbig/little endianであることを前提に解釈します。先頭にBOMがあれば それはU+FEFFという文字になります。

省略可能なstart/end引数は入力bytevectorの範囲を制限します。

入力のオクテット数 (入力範囲の制限がある場合はend - start)が偶数で なければエラーが投げられます。

入力にutf-16として不正な列 (対になっていないサロゲート) が含まれていた 場合、それはUnicode置換文字U+FFFDに変換されます。 (SRFI-135ではその場合は「エラーである」と規定されているので、 実際の処理は処理系依存になります)。

Function: subtext text start end
Function: subtextual textual start end

[R7RS text] {scheme.text} 入力のtext、あるいはtextual(textまたは文字列)のstart番目の文字から end番目の文字の手前までを取り出してtext (インデックス付加済みの変更不可な文字列) として返します。

Function: textual-copy textual :optional start end

[R7RS text] {scheme.text} textまたは文字列のコピーをtextとして返します。 省略可能なstart/end引数は、 コピーする範囲をstart文字目からend文字目の手前までに制限します。

SRFI-135は、textual-copyが常に新たなtextをアロケートして返すことを 要求しています (subtextualは戻り値が入力と共有されることを許します)。 Gaucheでは、文字列本体はimmutableであり、 文字列のコピーは文字列本体へのポインタをコピーするだけなので、 どちらもあまり変わりませんが。

Function: textual-take textual nchars
Function: textual-drop textual nchars
Function: textual-take-right textual nchars
Function: textual-drop-right textual nchars
Function: textual-pad textual len :optional char start end
Function: textual-pad-right textual len :optional char start end
Function: textual-trim textual :optional pred start end
Function: textual-trim-right textual :optional pred start end
Function: textual-trim-both textual :optional pred start end

[R7RS text] {scheme.text} Gaucheでは、結果が常に変更不可でインデックス付きになること以外は、 対応する文字列操作 (string-takestring-dropstring-take-rightstring-drop-rightstring-padstring-pad-rightstring-trimstring-tirm-rightstring-trim-both) と同じです。 詳しくは文字列の選択を参照してください。

Function: textual-replace textual1 textual2 start1 end1 :optional start2 end2

[R7RS text] {scheme.text} Gaucheでは、戻り値の文字列が常に変更不可かつインデックス付きになること以外は、 string-replaceと同じです。 詳しくは他の文字列操作参照。

Function: textual=? textual1 textual2 textual3 …
Function: textual<? textual1 textual2 textual3 …
Function: textual>? textual1 textual2 textual3 …
Function: textual<=? textual1 textual2 textual3 …
Function: textual>=? textual1 textual2 textual3 …

[R7RS text] {scheme.text}  EN In Gauche, these are just aliases of built-in string=?, string<?, string>?, string<=? and string>?, respectively. See 文字列の色々な比較, for the details. Gaucheではこれらはそれぞれ組み込みの string=?string<?string>?string<=?string>?の別名です。 詳しくは文字列の色々な比較参照。

Function: textual-ci=? textual1 textual2 textual3 …
Function: textual-ci<? textual1 textual2 textual3 …
Function: textual-ci>? textual1 textual2 textual3 …
Function: textual-ci<=? textual1 textual2 textual3 …
Function: textual-ci>=? textual1 textual2 textual3 …

[R7RS text] {scheme.text} Gaucheではこれらはそれぞれunicodeバージョンの string-ci=?string-ci<?string-ci>?string-ci<=?string-ci>?と同じです。 詳しくはフルセットの大文字小文字変換参照。

Function: textual-prefix-length textual1 textual2 :optional start1 end1 start2 end2
Function: textual-suffix-length textual1 textual2 :optional start1 end1 start2 end2
Function: textual-prefix? textual1 textual2 :optional start1 end1 start2 end2
Function: textual-suffix? textual1 textual2 :optional start1 end1 start2 end2

[R7RS text] {scheme.text} Gaucheでは、これらはそれぞれsrfi.13string-prefix-lengthstring-suffix-lengthstring-prefix?string-suffix?の別名です。 詳しくは文字列のプリフィックスとサフィックス参照。

Function: textual-index textual pred :optional start end
Function: textual-index-right textual pred :optional start end
Function: textual-skip textual pred :optional start end
Function: textual-skip-right textual pred :optional start end
Function: textual-contains textual-haystack textual-needle :optional start1 end1 start2 end2
Function: textual-contains-right textual-haystack textual-needle :optional start1 end1 start2 end2

[R7RS text] {scheme.text} Gaucheでは、これらはそれぞれsrfi.13string-indexstring-index-rightstring-skipstring-skip-rightstring-containsstring-contains-rightの別名です。 詳しくは文字列の探索参照。

Function: textual-upcase textual
Function: textual-downcase textual
Function: textual-foldcase textual
Function: textual-titlecase textual

[R7RS text] {scheme.text} Gaucheでは、これらは戻り値が常に変更不可でインデックス付きの文字列になること以外は、 gauche.unicodestring-upcasestring-downcasestring-foldcasestring-titlecasegauche.unicodeとそれぞれ同じです。 詳しくはフルセットの大文字小文字変換参照。

Function: textual-append textual …
Function: textual-concatenate textual-list

[R7RS text] {scheme.text} Gaucheでは、これらは戻り値が常に変更不可でインデックス付きの文字列になること以外は、 それぞれstring-appendおよびstring-concatenateと同じです。

Function: textual-concatenate-reversse args :optional final-textual end

[R7RS text] {scheme.text} argsはtextual (Gaucheでは文字列と同じ) のリストでなければなりません。 また省略可能引数については、final-textualはtextual、 endは非負の正確な整数でなければなりません。

省略可能引数が無い場合、これは戻り値が常に変更不可でインデックス付きの文字列に なること以外は、srfi.13string-concatenate-reverseと同じです (文字列の反転と追加参照)。

final-textualが与えられたら、それが結果の末尾に足されます。 endも与えられたら、(subtext final-textual 0 end)が 結果の末尾に足されます。

Function: textual-join textual-list :optional delimiter grammar

[R7RS text] {scheme.text} 戻り値が常に変更不可でインデックス付きの文字列になることを除き、 string-joinと同じです (文字列を扱うその他の手続き参照)。

Function: textual-fold kons knil textual :optional start end
Function: textual-fold-right kons knil textual :optional start end

[R7RS text] {scheme.text} これらはそれぞれsrfi.13string-foldおよびstring-fold-right の別名です (文字列のマッピング参照)。

Function: textual-map proc textual1 textual2 …

[R7RS text] {scheme.text} 入力textualの、対応する文字それぞれに対してprocが適用されます。 procは文字かtextを返さねばなりません。 procの結果がtextとして集められて返されます。 string-mapと似ていますが、procが文字列を返すことで1-to-nの マッピングが可能です。

procが呼ばれる動的順序は規定されていません。

二つ以上のtextualが渡された場合、一番短いtextualの要素数だけprocは呼ばれます。

(textual-map (^c (string c c)) "abc")
 ⇒ "aabbcc"
(textual-map (^[a b] (if (char<? a b) a b))
             "continuation" "parameterization")
 ⇒ "canaietarioa"
Function: textual-for-each proc textual1 textual2 …

[R7RS text] {scheme.text} 入力textualの、対応する文字それぞれに対して左から右の順にprocが適用されます。 procの結果は捨てられます。 procの結果がtextとして集められて返されます。

二つ以上のtextualが渡された場合、一番短いtextualの要素数だけprocは呼ばれます。

Function: textual-map-index proc textual :optional start end

[R7RS text] {scheme.text}

Function: textual-for-each-index proc textual :optional start end

[R7RS text] {scheme.text}

Function: textual-count textual pred :optional start end

[R7RS text] {scheme.text}

Function: textual-filter pred textual :optional start end
Function: textual-remove pred textual :optional start end

[R7RS text] {scheme.text}

Function: textual-replicate textual from to :optional start end

[R7RS text] {scheme.text}

Function: textual-split textual delimiter :optional grammar limit start end

[R7RS text] {scheme.text} Like string-split, except that the returned strings are all immutable and indexed. See 文字列を扱うその他の手続き, for the details.


10.3.12 scheme.generator - R7RSジェネレータ

Module: scheme.generator

このモジュールは、ジェネレータとアキュムレータを提供します。 これらは最初にSRFI-121で定義され、SRFI-158で拡張された後、 (scheme generator)としてR7RS largeに取り込まれました。

ジェネレータは引数と取らない手続きで、呼ばれる度に値を次々に返し、 EOFを以って終端を示すものです。ジェネレータを扱う手続きは SRFI-121のスーパーセットであるgauche.generatorで提供されています。 詳しくはgauche.generator - ジェネレータを参照してください。

アキュムレータはジェネレータの反対で、値を消費する手続きと考えられます。 アキュムレータは一つの引数を取ります。EOF以外の値が与えられた場合は、 それが内部に何らかの形で蓄えられ、EOFが与えられた場合、 蓄えられた値が返されます。 どのように値が蓄えられるかは各アキュムレータに依存します。

一度EOFが与えられると、アキュムレータは終了状態になります。 その後何度EOFが与えられても同じ蓄積結果を返します。 終了状態になったアキュムレータにEOF以外の値を与えた場合の動作は未定義です。

アキュムレータは、複合的なオブジェクトを生成する手続きで、 実際に生成される値の型をパラメタライズするのに使えます。 次の手続きを見てみましょう。これは二つのジェネレータから交互に値を取り、 それを蓄積して返す手続きです。 (glet*はGaucheの手続きですがSRFI-158には含まれていません。)

(define (intertwine acc gen1 gen2)
  (let loop ()
    (glet* ([a (gen1)]
            [b (gen2)])
      (acc a)
      (acc b)
      (loop)))
  (acc (eof-object)))

この手続きは具体的に返される値が何かは関知しません。 それは引数に与えられたアキュムレータにより決定されます。

(intertwine (list-accumulator) (giota 5) (giota 5 100))
  ⇒ (0 100 1 101 2 102 3 103 4 104)
(intertwine (vector-accumulator) (giota 5) (giota 5 100))
  ⇒ #(0 100 1 101 2 102 3 103 4 104)
(intertwine (bytevector-accumulator) (giota 5) (giota 5 100))
  ⇒ #u8(0 100 1 101 2 102 3 103 4 104)

註: Gaucheでは、クラスを使うことで戻り値となるコンテナの型をパラメタライズできます (例: map-to)。これは多くのコレクションクラスがbuilderプロトコルを サポートしているからです。詳しくはgauche.collection - コレクションフレームワークを見てください。 アキュムレータの利点は、同じ型の戻り値についても、異なる値の蓄積方法 (例えばリストを順に蓄積するか逆順に蓄積するか、等)を提供できることです。

以下のジェネレータ手続きは、gauche.generatorのセクションで 解説してあります(gauche.generator - ジェネレータ参照)。

以下はアキュムレータ手続きです。

Function: make-accumulator kons knil finalizer

[R7RS generator] {scheme.generator} 内部状態をひとつ持つアキュムレータを作って返します。 状態はkhilで初期化されます。 EOFでない値vがアキュムレータに与えられる度に、手続きkons(kons v state)と呼ばれ、その戻り値が新たな状態となります。 EOFがアキュムレータに渡されると、(finalizer state)が呼ばれ、 その結果がアキュムレータの戻り値となります。

Function: list-accumulator
Function: reverse-list-accumulator

[R7RS generator] {scheme.generator} 蓄積された値をリストとして返すアキュムレータを作って返します。 list-accumulatorではリストは与えられた順に、 reverse-list-accumulatorでは逆順になります。

Function: vector-accumulator
Function: reverse-vector-accumulator
Function: bytevector-accumulator

[R7RS generator] {scheme.generator} 蓄積された値をベクタあるいはバイトベクタ(u8vector)として返すアキュムレータを 作って返します。vector-accumulatorbytevector-accumulatorでは値は先頭から順に、 reverse-vector-accumulatorではベクタの最後から逆順に詰められます。 reverse-bytevector-accumulatorはありません。

Function: vector-accumulator! vec at
Function: bytevector-accumulator! bvec at

[R7RS generator] {scheme.generator} vecbvecはそれぞれ変更可能なベクタとバイトベクタ(u8vector)です。 この引数はバッファとして使われます。

与えられた値を、バッファのインデックスatから順に格納してゆくアキュムレータを 作って返します。バッファの最後を越えて値を格納しようとした場合はエラーになります。

EOFが与えられたら、vecまたはbvecをそのまま返します。

Function: string-accumulator

[R7RS generator] {scheme.generator} 文字を受け取り、それを蓄積して最後に文字列として返すアキュムレータを生成して返します。

Function: sum-accumulator
Function: product-accumulator
Function: count-accumulator

[R7RS generator] {scheme.generator} スカラー値を生成するアキュムレータを作って返します。

sum-accumulatorproduct-accumulatorで作られた アキュムレータはそれぞれ、 数値を受け取り、それを蓄積された値に加算または乗算してゆきます。 値の初期値はそれぞれ0と1です。

count-accumulatorで作られたアキュムレータは 任意のオブジェクトを受け取ります。 EOFを受け取ったらそれまで受け取ったオブジェクトの数を返します。


10.3.13 scheme.lseq - R7RS遅延シーケンス

Module: scheme.lseq

This module provides lightweight lazy sequence (lseq), conceptually represented by a pair of element and generator. When the rest of sequence is taken, the generator is evaluated and yields another pair of element and generator, and so on. The overhead is one allocation of a pair per element. It is much lighter than streams (see util.stream - ストリームライブラリ), which requires to create a thunk for every element.

Gauche already has built-in support for such lazy sequences; we go further to make it behave like ordinary pairs—that is, if you take cdr of a lazy pair, we automatically forces the generator so it is indistinguishable from an ordinary pair, modulo side effects. See 遅延シーケンス.

SRFI-127, the original srfi for this module, is a bit ambiguous whether its lazy sequence must be implemented with a pair whose cdr is a generator procedure, or it refers to the pair+generator as a conceptual model. Considering of the purpose of lazy sequence, the concrete implementation shouldn’t matter; that is, the user of lazy sequence should not count on the fact that the lseq is an improper list terminated by a generator procedure. Instead, an lseq should be treated as an opaque object that can be passed to scheme.lseq procedures.

With that premise, we implement this module as just a thin wrapper of Gauche’s native lazy sequence. It is upper-compatible, except that the code that assumes the internal structure could break. Notably, the constructor generator->lseq is the same as Gauche’s built-in, which returns Gauche’s lseq, undistinguishable to the ordinary list.

(procedure? (generator->lseq (generator 1)))
  ;; => #t, in SRFI-127 reference implementation,
  ;;    #f, in our implementation.
Function: lseq? x

[R7RS lseq] {scheme.lseq} Returns true iff x is an object that can be passed to lseq procedures. In Gauche, it returns #t if x is a pair or an empty list, since a lazy pair is indistinguishable from a pair.

Function: lseq=? elt=? lseq1 lseq2

[R7RS lseq] {scheme.lseq} Compare two lseqs element-wise using elt=? and returns #t iff two lseqs are equal.

Function: lseq-car lseq
Function: lseq-first lseq

[R7RS lseq] {scheme.lseq} Returns the first item of lseq. If lseq is empty, an error is raised. In Gauche, these are just aliases of car.

Function: lseq-cdr lseq
Function: lseq-rest lseq

[R7RS lseq] {scheme.lseq} Returns the rest of lseq. If lseq is empty, an error is raised. In Gauche, these are just aliases of cdr.

Function: lseq-take lseq k
Function: lseq-drop lseq k

[R7RS lseq] {scheme.lseq} Returns an lseq that has first k items, or an lseq that skips first k items, respectively.

An error is signaled when the resulting lseq of lseq-take reached at the end of sequence before k items are taken. It is different from Gauche’s ltake, which simply returns () in such case.

On the other hand, lseq-drop is the same as drop in Gauche; it just drops k items from the head of input sequence, regardless of whether it is an ordinary list or lseq.

Function: lseq-realize lseq

[R7RS lseq] {scheme.lseq} Realizes all the elements in lseq, resulting an ordinary list.

Function: lseq->generator lseq

[R7RS lseq] {scheme.lseq} Creates a generator from lseq. In Gauche, this is same as list->generator.

Function: lseq-length lseq

[R7RS lseq] {scheme.lseq} Returns the length of lseq. All the elements in lseq are realized as the side effect. In Gauche, this is same as length.

Function: lseq-append lseq lseq2 …

[R7RS lseq] {scheme.lseq} Append one or more lseqs lazily. This is the same as lappend in Gauche.

Function: lseq-zip lseq lseq2 …

[R7RS lseq] {scheme.lseq} Returns a lazy sequence in which the first element is a list of first elements of lseqs, and so on.

Function: lseq-map proc lseq lseq2 …

[R7RS lseq] {scheme.lseq} Lazy map. The same as Gauche’s lmap. Returns a lazy sequence.

Function: lseq-for-each proc lseq lseq2 …

[R7RS lseq] {scheme.lseq} This one consumes all the input lseqs, applying proc on each corresponding elements of the input sequences for the side effects. In Gauche, it is the same as for-each, for Gauche doesn’t distinguish lseqs and ordinary lists.

Function: lseq-filter pred lseq
Function: lseq-remove pred lseq

[R7RS lseq] {scheme.lseq} Returns an lseq that contains elements from the input lseq that satisfy or don’t satisfy pred, respectively. Lseq-filter is the same as Gauche’s lfilter.

Function: lseq-take-while pred lseq
Function: lseq-drop-while pred lseq

[R7RS lseq] {scheme.lseq} These are the same as Gauche’s ltake-while and drop-while (the latter doesn’t have l-prefix, since it just drops items from the head of the input sequence, regardless of whether it is an ordinary list or an lseq.

Function: lseq-find pred lseq
Function: lseq-find-tail pred lseq
Function: lseq-any pred lseq
Function: lseq-every pred lseq
Function: lseq-index pred lseq
Function: lseq-member pred lseq :optional eq
Function: lseq-memq pred lseq
Function: lseq-memv pred lseq

[R7RS lseq] {scheme.lseq} In Gauche, these are the same as the corresponding list functions, find, find-tail, any, every, list-index, member, memq and memv, respectively, for all of those functions won’t look at input more than necessary so lseqs work just as well as ordinary lists.


10.3.14 scheme.stream - R7RSストリーム

Module: scheme.stream

遅延評価ストリームのユーティリティを提供するモジュールです。 遅延シーケンス(遅延シーケンス参照)よりも重いですが、 「可能な限り遅延する」セマンティクスを厳密に実装しています。 つまり、要素は本当に必要とされるまで決して評価されません。

以下の手続きはGaucheのutil.streamsモジュールで提供されるものと同じです。 説明はutil.stream - ストリームライブラリを参照してください。

stream-null         stream-cons       stream?          stream-null?
stream-pair?        stream-car        stream-cdr       stream-lambda

define-stream       list->stream      port->stream
stream->list        stream-append     stream-concat    stream-constant
stream-drop-while   stream-filter     stream-fold
stream-for-each     stream-from       stream-iterate   stream-length
stream-let          stream-map        stream-match     stream-of
stream-range        stream-ref        stream-reverse   stream-scan
stream-take-while   stream-unfold     stream-unfolds   stream-zip

以下のマクロと手続きはGaucheのutil.streamとはインタフェースが異なります。

stream              stream-take      stream-drop
Macro: stream expr …

[R7RS stream] {scheme.stream} expr …の結果を要素とする新たなストリームを作って返します。 各exprは必要となるまで評価されません。

SRFI-40およびutil.streamstreamは単なる手続きであり、 各exprは呼び出し時に評価されてしまうことが異なります (Stream constructors参照)。

Function: stream-take n stream
Function: stream-drop n stream

[R7RS stream] {scheme.stream} それぞれ、streamの最初のn要素を含むストリーム、 および最初のn要素を除いたストリームを返します。 streamの要素数がnより小さい場合、 stream-takestream全体のコピーを返し、 stream-dropは空のストリームを返します。

引数順がSchemeの慣習と違っていることに注意してください。 Schemeは通常、主となるオブジェクト(この場合はstream)を第一引数に取ります。 util.streamの同名の手続きはそうなっています。


10.3.15 scheme.box - R7RSボックス

Module: scheme.box

Gaucheは組み込みでboxをサポートしています (ボックス参照)。 このモジュールは以下の識別子をエクスポートするラッパーです。

box    box?    unbox    set-box!

10.3.16 scheme.list-queue - R7RSリストキュー

Module: scheme.list-queue

リストを元にしたキューのライブラリです。 Gaucheはdata.queueモジュールでキューをサポートしています (スレッドセーフなキューも含まれています。詳しくはdata.queue - キューを参照。) このモジュールは、主としてポータブルなコードのために、 data.queue<queue>の上に実装されています。

このモジュールでいうリストキューは<queue>のインスタンスそのものなので、 make-queueで作ったキューをscheme.list-queueのAPIに渡したり、 make-list-queueで作ったキューをGaucheのキューAPIに渡すこともできます。

註: このライブラリのAPIには、性能のために、 キューが使う内部のペアをそのまま返すことを要求されている ものがあります。これらの内部ペアはキューの操作によって破壊的に変更される可能性があります。 ユーザ側でも変更した場合、その後のキューの動作は保証されません。

Function: make-list-queue lis :optional last

[R7RS list-queue] {scheme.list-queue} リストlisの内容を初期値として持つリストキューを作って返します。 Gaucheでは、リストキューは<queue>のインスタンスです(data.queue - キュー参照)。

lisの実体は作成されたキューの所有物となります。 呼び出し側は、この関数を呼んだ後でlisを変更してはいけません。 また、作成されたキューの操作によってlisの内容は変更されるでしょう。

省略可能なlast引数は、もし与えられる場合は、lisの最後のペアで なければなりません。この引数が渡された場合、make-list-queueは自分で リストの末尾のペアを見つけるかわりに、呼び出し側を信頼してlastを最後の ペアとして保持します。

Function: list-queue elt …

[R7RS list-queue] {scheme.list-queue} elt …を初期内容とするリストキューを作成して返します。 Gaucheでは、リストキューは<queue>のインスタンスです(data.queue - キュー参照)。

Function: list-queue-copy queue

[R7RS list-queue] {scheme.list-queue} リストキューqueueのコピーを返します。

Function: list-queue-unfold p f g seed :optional queue

[R7RS list-queue] {scheme.list-queue} リストキューqueueの前に、(unfold p f g seed)で生成される 要素を付け足して、queueを返します。 unfoldについてはscheme.list - R7RSリストを参照してください。 queueが省略された場合は新たに作成したキューを使います。

(list-queue-unfold (pa$ = 5) ; p
                   (pa$ * 2) ; f
                   (pa$ + 1) ; g
                   0         ; seed
                   (list-queue 'x 'y 'z))
 ⇒ a queue containing (0 2 4 6 8 x y z)
Function: list-queue-unfold-right p f g seed :optional queue

[R7RS list-queue] {scheme.list-queue} queueの後ろに、(unfold-right p f g seed)で生成される 要素を付け足して、queueを返します。 unfold-rightについてはscheme.list - R7RSリストを参照してください。 queueが省略された場合は 新たに作成したキューを使います。

(list-queue-unfold-right (pa$ = 5) ; p
                         (pa$ * 2) ; f
                         (pa$ + 1) ; g
                         0         ; seed
                         (list-queue 'x 'y 'z))
 ⇒ a queue containing (x y z 8 6 4 2 0)
Function: list-queue? obj

[R7RS list-queue] {scheme.list-queue} queueがリストキューなら#tを、そうでなければ#fを返します。 Gaucheではdata.queueモジュールのqueue?と同じです。

Function: list-queue-empty? queue

[R7RS list-queue] {scheme.list-queue} queueが空なら#tを、そうでなければ#fを返します。 data.queuequeue-empty?と同じです。

Function: list-queue-front queue

[R7RS list-queue] {scheme.list-queue} queueの先頭の要素を返します。queueが空の場合はエラーを報告します。 data.queuequeue-frontと同じです。

Function: list-queue-back queue

[R7RS list-queue] {scheme.list-queue} queueの末尾の要素を返します。queueが空の場合はエラーを報告します。 data.queuequeue-rearと同じです。

Function: list-queue-list queue

[R7RS list-queue] {scheme.list-queue} queueが内部的に保持している要素のリストを返します。 返されたリストは、queueが操作されれば破壊的に変更される可能性があり、 また返されたリストを破壊的に変更した場合はqueueの一貫性が失われます。 この手続きの主な目的は、他のキュー操作を効率よく実装することです。

単にキューの中身にオーバーヘッド無くアクセスしたい場合は、 list-queue-remove-all!が使えないかどうか検討してください。 そちらはキューの中身のリストを直接返すと同時にキュー自体を空にするので、安全です。

Function: list-queue-fist-last queue

[R7RS list-queue] {scheme.list-queue} queueの内部で要素を保持しているリストの先頭と末尾のペアを返します。 キューが空の場合は、二つの空リストを返します。

この手続きも、list-queue-listと同じく、内部のリストを直接返すため、 返されたリストは、queueが操作されれば破壊的に変更される可能性があり、 また返されたリストを破壊的に変更した場合はqueueの一貫性が失われます。 この手続きの主な目的は、他のキュー操作を効率よく実装することであり、 一般的な用途に使うべきではありません。

Function: list-queue-add-front! queue elt

[R7RS list-queue] {scheme.list-queue} eltqueueの先頭に追加します。 data.queue(queue-push! queue elt)と同じです。

Function: list-queue-add-back! queue elt

[R7RS list-queue] {scheme.list-queue} eltqueueの末尾に追加します。 data.queue(enqueue! queue elt)と同じです。

Function: list-queue-remove-front! queue

[R7RS list-queue] {scheme.list-queue} queueの先頭から要素をひとつ取り除き、その取り除かれた要素を返します。 queueが空ならエラーを報告します。 data.queue(dequeue! queue elt)と同じです。

Function: list-queue-remove-back! queue

[R7RS list-queue] {scheme.list-queue} queueの末尾から要素をひとつ取り除き、その取り除かれた要素を返します。 queueが空ならエラーを報告します。 この手続きは、キューの持つ要素数nに対してO(n)の時間がかかります。 もしこの操作を頻繁に必要とするなら、デック(deque, 両端キュー)を使うことを 検討すべきでしょう。(data.ideque - 変更不可な両端キューおよび data.ring-buffer - リングバッファ参照。)

Function: list-queue-remove-all! queue

[R7RS list-queue] {scheme.list-queue} queueを空にして、入っていた全ての要素をリストで返します。 リストはコピーされません。つまりO(1)の操作です。 可能なら、list-queue-listよりはこちらを使う方が安全です。 Gaucheでは、これはdata.queuedeque-all!と同じです。

Function: list-queue-set-list! queue lis :optional last

[R7RS list-queue] {scheme.list-queue} queueを変更して、lisの内容がキューの内容になるようにします。 queueの元の内容は捨てられます。省略可能なlast引数が渡される場合、 それはlisの最後のペアでなければなりません。手続きは呼び出し元を信頼して、 lisをスキャンせずにlastを最後のペアと考えることで O(1)操作を実現しています。

この手続きを呼び出した後では、lisqueueに所有され、破壊的変更を 受けます。この後でlisの内容をあてにしたり変更したりしてはいけません。

Function: list-queue-append queue …

[R7RS list-queue] {scheme.list-queue} 与えられたqueueを全部つないだ要素を持つリストキューを 新たに作成して返します。引数のキューは変更されません。 これは要素の総数nについてO(n)の操作となります。

Function: list-queue-append! queue …

[R7RS list-queue] {scheme.list-queue} 与えられたqueueの要素を全てつないだものを要素とするリストキューを 返します。操作によって、queueの内容は破壊されることがあり、 以降それらのキューを使ってはなりません (Gaucheでは、事故を避けるために、全てのqueueを空にしています)。 結果として返されるキューが、引数のどれともeq?になる必要はない、 ということに注意してください。 これはキューの総数mに対してO(m)の操作です(要素の総数ではなく)。

Function: list-queue-concatenate queues

[R7RS list-queue] {scheme.list-queue} (apply list-queue-append queues).

Function: list-queue-map proc queue

[R7RS list-queue] {scheme.list-queue} procqueueの各要素に適用して得られた結果を要素とする 新たなリストキューを返します。

Function: list-queue-map! proc queue

[R7RS list-queue] {scheme.list-queue} queueの各要素を、それにprocを適用して得られた結果に 置き替えます。

Function: list-queue-for-each proc queue

[R7RS list-queue] {scheme.list-queue} procqueueの各要素に適用します。結果は捨てられます。


10.3.17 scheme.ephemeron - R7RS Ephemeron

Module: scheme.ephemeron

このモジュールはephemeronと呼ばれる、 キーとそれに関連づけられたデータについて弱参照を保持する構造を提供します。 元々はSRFI-142で定義されました。

Gaucheはweak vectorとして弱参照を提供しています (Weakベクタ参照)が、単なるweak pointer (それに指されている オブジェクトの回収を許す) だけでは、mappingのようなキーと値を関連付ける データ構造で弱参照を実現するには不十分なことが知られています。

ephemeronはキーとデータへの参照を保持するレコードで、以下の性質を持ちます。

  1. キーへの参照はweakです。もし、キーへの強参照が、 ephemeronを通じて対応しているデータからのものを除いて 存在しない場合、キーは回収されます。
  2. データへの参照もある意味weakです。 データへの強参照が存在せず、かつ対応するキーへの強参照が無い場合、 データは回収されます。 データへの強参照が無くても、キーが生きていればデータは保持されるという点がポイントです。

ephemeronを完全に実装するには、GCとの統合が必要になります。 今のところ、GaucheのephemeronはGCとは独立に実装されており、 以下の制限があります:

  • データからキーへの強参照があると、キーは回収されません。
  • キーが回収され、データへの強参照が無い状態になってから、データが回収されるには ephemeron-broken?が呼ばれる必要があります。

いつ回収されるかについての規定は仕様にないので、Gaucheの現在の実装もSRFI-142の 仕様は満たしているのですが、実際に使うにあたっては上記の制限を意識する必要があるでしょう。 将来的にはGCと統合されたephemeronをサポートしたいと思っています。

キーあるいはデータが回収された後は (この状態のephemeronを “broken” と呼びます)、 キーやデータを取り出そうとしても意味のある値は得られません。 ephemeron eを使う正しい手順は次のパターンです:

(let ([k (ephemeron-key e)]
      [d (ephemeron-datum e)])
  (if (ephemeron-broken? e)
    (... k and d are invalid ...)
    (... k and d are valid ...)))

つまり、値を取り出した後でephemeronがbrokenかどうかを調べます。 先にephemeron-broken?を呼んでしまうと、その呼び出しから 値を取り出すまでの間にGCが走ってキーやデータが回収されてしまう可能性があります。

Function: make-ephemeron key datum

[R7RS ephemeron] {scheme.ephemeron} keydatumに関連づけるephemeronを作って返します。

Function: ephemeron? obj

[R7RS ephemeron] {scheme.ephemeron} objがephemeronであれば#tを、そうでなければ#fを返します。

Function: ephemeron-key ephemeron
Function: ephemeron-datum ephemeron

[R7RS ephemeron] {scheme.ephemeron} それぞれ、ephemeronのキーとデータを返します。 ephemeronが既にbrokenだと、何が返されるかはわかりません。 なので常に、これらの手続きで値を取り出した後で ephemeron-broken? を呼んで値が有効かどうかチェックする必要があります。 詳しくは上のscheme.ephemeronのエントリを参照してください。

Function: ephemeron-broken? ephemeron

[R7RS ephemeron] {scheme.ephemeron} ephemeronがbrokenであれば#tを、そうでなければ#fを返します。 brokenであるとは、キーや値が既に回収されてしまって取り出せないことを意味します。 詳しくはscheme.ephemeronのエントリを参照してください。

Function: reference-barrier key

[R7RS ephemeron] {scheme.ephemeron} この手続きはそれ自体は何もしませんが、 この手続きが戻るまでkeyへの参照が保持されることを保証します。


10.3.18 scheme.comparator - R7RS比較器

Module: scheme.comparator

このモジュールは、比較器(comparator)とそれに関わる手続きを提供します。 元々はsrfi.128で定義されました。

Gaucheはscheme.comparatorの上位互換である比較器を組み込みで提供しています。 以下の手続きについては、基本的な比較器を参照してください。

comparator? comparator-ordered? comparator-hashable?
make-comparator make-pair-comparator
make-list-comparator make-vector-comparator
make-eq-comparator make-eqv-comparator make-equal-comparator

boolean-hash char-hash char-ci-hash string-hash
string-ci-hash symbol-hash number-hash
hash-bound hash-salt

make-default-comparator default-hash
comparator-register-default!

comparator-type-test-predicate comparator-equality-predicate
comparator-ordering-predicate comparator-hash-function
comparator-test-type comparator-check-type comparator-hash

=? <? >? <=? >=? comparator-if<=>

10.3.19 scheme.regex - R7RS正規表現

Module: scheme.regex

このモジュールは、Scheme正規表現(Scheme Regular Expressions, SRE)の操作を提供します。 元々はsrfi.115で定義されました。

Gaucheは組み込みで正規表現を提供していて、 このモジュールはSREを組み込み正規表現に変換するだけです。 例えばこのモジュールのregexp手続きが返す正規表現オブジェクトは、 Gaucheの<regexp>オブジェクトに他なりません。 また、このモジュールでコンパイルされた正規表現を期待している手続きに、 Gaucheの正規表現オブジェクトを渡すこともできます。

Scheme正規表現構文

構文のまとめ

SREは以下にまとめられた構造を持つS式です。

orを除き、複数の<sre>を引数に取る構文はそれら部分式を シーケンスとして処理します。言い換えれば、 (foo <sre> ...)(foo (seq <sre> ...))と同じということです。

註: SREは縦棒|を選択演算子に使っていますが、GaucheとR7RSでは |はシンボルのエスケープ文字に使われているので、SRE内で使いたければ|\|| と書かなければなりません。orを使った方がわかりやすいでしょう。

    <sre> ::=
     | <string>                    ; A literal string match.
     | <cset-sre>                  ; A character set match.
     | (* <sre> ...)               ; 0 or more matches.
     | (zero-or-more <sre> ...)
     | (+ <sre> ...)               ; 1 or more matches.
     | (one-or-more <sre> ...)
     | (? <sre> ...)               ; 0 or 1 matches.
     | (optional <sre> ...)
     | (= <n> <sre> ...)           ; <n> matches.
     | (exactly <n> <sre> ...)
     | (>= <n> <sre> ...)          ; <n> or more matches.
     | (at-least <n> <sre> ...)
     | (** <n> <m> <sre> ...)      ; <n> to <m> matches.
     | (repeated <n> <m> <sre> ...)

     | (|\||  <sre> ...)           ; Alternation.
     | (or <sre> ...)

     | (:   <sre> ...)             ; Sequence.
     | (seq <sre> ...)
     | ($ <sre> ...)               ; Numbered submatch.
     | (submatch <sre> ...)
     | (-> <name> <sre> ...)               ;  Named submatch.  <name> is
     | (submatch-named <name> <sre> ...)   ;  a symbol.

     | (w/case   <sre> ...)        ; Introduce a case-sensitive context.
     | (w/nocase <sre> ...)        ; Introduce a case-insensitive context.

     | (w/unicode   <sre> ...)     ; Introduce a unicode context.
     | (w/ascii <sre> ...)         ; Introduce an ascii context.

     | (w/nocapture <sre> ...)     ; Ignore all enclosed submatches.

     | bos                         ; Beginning of string.
     | eos                         ; End of string.

     | bol                         ; Beginning of line.
     | eol                         ; End of line.

     | bow                         ; Beginning of word.
     | eow                         ; End of word.
     | nwb                         ; A non-word boundary.
     | (word <sre> ...)            ; An SRE wrapped in word boundaries.
     | (word+ <cset-sre> ...)      ; A single word restricted to a cset.
     | word                        ; A single word.

     | bog                         ; Beginning of a grapheme cluster.
     | eog                         ; End of a grapheme cluster.
     | grapheme                    ; A single grapheme cluster.

     | (?? <sre> ...)              ; A non-greedy pattern, 0 or 1 match.
     | (non-greedy-optional <sre> ...)
     | (*? <sre> ...)              ; Non-greedy 0 or more matches.
     | (non-greedy-zero-or-more <sre> ...)
     | (**? <m> <n> <sre> ...)     ; Non-greedy <m> to <n> matches.
     | (non-greedy-repeated <sre> ...)
     | (atomic <sre> ...)          ; Atomic clustering.

     | (look-ahead <sre> ...)      ; Zero-width look-ahead assertion.
     | (look-behind <sre> ...)     ; Zero-width look-behind assertion.
     | (neg-look-ahead <sre> ...)  ; Zero-width negative look-ahead assertion.
     | (neg-look-behind <sre> ...) ; Zero-width negative look-behind assertion.

     | (backref <n-or-name>)       ; Match a previous submatch.
                              

cset-sreの構文は次のとおりです。

    <cset-sre> ::=
     | <char>                      ; literal char
     | "<char>"                    ; string of one char
     | <char-set>                  ; embedded SRFI 14 char set
     | (<string>)                  ; literal char set
     | (char-set <string>)
     | (/ <range-spec> ...)        ; ranges
     | (char-range <range-spec> ...)
     | (or <cset-sre> ...)         ; union
     | (|\|| <cset-sre> ...)
     | (and <cset-sre> ...)        ; intersection
     | (& <cset-sre> ...)
     | (- <cset-sre> ...)          ; difference
     | (- <difference> ...)
     | (~ <cset-sre> ...)          ; complement of union
     | (complement <cset-sre> ...)
     | (w/case <cset-sre>)         ; case and unicode toggling
     | (w/nocase <cset-sre>)
     | (w/ascii <cset-sre>)
     | (w/unicode <cset-sre>)
     | any | nonl | ascii | lower-case | lower
     | upper-case | upper | title-case | title
     | alphabetic | alpha | alphanumeric | alphanum | alnum
     | numeric | num | punctuation | punct | symbol
     | graphic | graph | whitespace | white | space
     | printing | print | control | cntrl | hex-digit | xdigit

    <range-spec> ::= <string> | <char>

基本パターン

<string>

リテラル文字列。

(regexp-search "needle" "hayneedlehay")
 ⇒ #<regexp-match>
(regexp-search "needle" "haynEEdlehay")
 ⇒ #f
(seq <sre> ...)
(: <sre> ...)

パターンのシーケンス。入力はパターンに順にマッチしなければなりません。 これは正規表現構文(?:re…)と同じです。

(regexp-search '(: "one" space "two" space "three") "one two three")
 ⇒ #<regexp-match>
(or <sre> ...)
(|\|| <sre> ...)

与えられたパターンのどれかにマッチします。 これは正規表現構文pattern1|pattern2|…と同じです。

(regexp-search '(or "eeney" "meeney" "miney") "meeney")
 ⇒ #<regexp-match>
(regexp-search '(or "eeney" "meeney" "miney") "moe")
 ⇒ #f
(w/nocase <sre> ...)

Changes to match the given patterns case-insensitively. Sub-patterns can still be made sensitive with w/case. This is the same as RE syntax (?i:re…)

(regexp-search "needle" "haynEEdlehay") ⇒ #f
(regexp-search '(w/nocase "needle") "haynEEdlehay")
  ⇒  #<regexp-match>

(regexp-search '(~ ("Aab")) "B") ⇒ #<regexp-match>
(regexp-search '(~ ("Aab")) "b") ⇒ #f
(regexp-search '(w/nocase (~ ("Aab"))) "B") ⇒ #f
(regexp-search '(w/nocase (~ ("Aab"))) "b") ⇒ #f
(regexp-search '(~ (w/nocase ("Aab"))) "B") ⇒ #f
(regexp-search '(~ (w/nocase ("Aab"))) "b") ⇒ #f
(w/case <sre> ...)

Changes to match the given patterns case-sensitively. Sub-patterns can still be made case-insensitive. This is the same as RE syntax (?-i:re…). This is the default.

(regexp-search '(w/nocase "SMALL" (w/case "BIG")) "smallBIGsmall")
 ⇒ #<regexp-match>
(regexp-search '(w/nocase (~ (w/case ("Aab")))) "b") ⇒ #f
(w/ascii <sre> ...)

Limits the character sets and other predefined patterns to ASCII. This affects patterns or character sets like any, alpha, (word)

(regexp-search '(w/ascii bos (* alpha) eos) "English")
 ⇒ #<regexp-match>
(regexp-search '(w/ascii bos (* alpha) eos) "Ελληνική") ⇒ #f
(w/unicode <sre> ...)

Changes the character sets and other predefined patterns back to Unicode if w/ascii has been used in the outer scope. This is the default.

(regexp-search '(w/unicode bos (* alpha) eos) "English")
 ⇒ #<regexp-match>
(regexp-search '(w/unicode bos (* alpha) eos) "Ελληνική")
 ⇒ #<regexp-match>
(w/nocapture <sre> ...)

Disables capturing for all submatch and submatch-named inside.

(let ((number '($ (+ digit))))
  (cdr
   (regexp-match->list
    (regexp-search `(: ,number "-" ,number "-" ,number)
                   "555-867-5309")))  ; ⇒ '("555" "867" "5309")
  (cdr
   (regexp-match->list
    (regexp-search `(: ,number "-" (w/nocapture ,number) "-" ,number)
                   "555-867-5309"))))   ⇒ '("555" "5309")

Repeating patterns

(optional <sre> ...)
(? <sre> ...)

Matches the pattern(s) one or zero times.

(regexp-search '(: "match" (? "es") "!") "matches!")
 ⇒ #<regexp-match>
(regexp-search '(: "match" (? "es") "!") "match!")
 ⇒ #<regexp-match>
(regexp-search '(: "match" (? "es") "!") "matche!")
 ⇒ #f
(zero-or-more <sre> ...)
(* <sre> ...)

Matches the pattern(s) zero or more times.

(regexp-search '(: "<" (* (~ #\>)) ">") "<html>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (* (~ #\>)) ">") "<>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (* (~ #\>)) ">") "<html")
 ⇒ #f
(one-or-more <sre> ...)
(+ <sre> ...)

Matches the pattern(s) at least once.

(regexp-search '(: "<" (+ (~ #\>)) ">") "<html>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (+ (~ #\>)) ">") "<a>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (+ (~ #\>)) ">") "<>")
 ⇒ #f
(at-least n <sre> ...)
(>= n <sre> ...)

Matches the pattern(s) at least n times.

(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<table>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<pre>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (>= 3 (~ #\>)) ">") "<tr>")
 ⇒ #f
(exactly n <sre> ...)
(= n <sre> ...)

Matches the pattern(s) exactly n times.

(regexp-search '(: "<" (= 4 (~ #\>)) ">") "<html>")
 ⇒ #<regexp-match>
(regexp-search '(: "<" (= 4 (~ #\>)) ">") "<table>")
 ⇒ #f
(repeated from to <sre> ...)
(** from to <sre> ...)

Matches the pattern(s) at least from times and up to to times.

(regexp-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric))
               "192.168.1.10")
 ⇒ #<regexp-match>
(regexp-search '(: (= 3 (** 1 3 numeric) ".") (** 1 3 numeric))
               "192.0168.1.10")
 ⇒ #f

Submatch Patterns

(submatch <sre> ...)
($ <sre> ...)

Captures the matched string. Each capture is numbered increasing from one (capture zero is the entire matched string). For nested captures, the numbering scheme is depth-first walk.

(submatch-named <name> <sre> ...)
(-> <name> <sre> ...)

Captures the matched string and assigns a name to it in addition to a number. This is the equivalent of (?<name>re…)

(backref <n-or-name>)

Matches a previously matched submatch. This is the same as RE syntax \n or \k<name>.

Character Sets

<char>

A character set contains a single character.

(regexp-matches '(* #\-) "---") ⇒ #<regexp-match>
(regexp-matches '(* #\-) "-_-") ⇒ #f
"<char>"

A character set contains a single character. This is technically ambiguous with SRE matching a literal string. However the end result of both syntaxes is the same.

<char-set>

A SRFI-14 character set.

Note that while currently there is no portable written representation of SRFI 14 character sets, you can use Gauche reader syntax #[char-set-spec], see 文字集合.

(regexp-partition `(+ ,char-set:vowels) "vowels")
 ⇒ ("v" "o" "w" "e" "ls")
(char-set <string>)
(<string>)

A character set contains the characters in the given string. This is the same as `(char-set ,(string->char-set <string>)).

(regexp-matches '(* ("aeiou")) "oui") ⇒ #<regexp-match>
(regexp-matches '(* ("aeiou")) "ouais") ⇒ #f
(regexp-matches '(* ("e\x0301")) "e\x0301") ⇒ #<regexp-match>
(regexp-matches '("e\x0301") "e\x0301") ⇒ #f
(regexp-matches '("e\x0301") "e") ⇒ #<regexp-match>
(regexp-matches '("e\x0301") "\x0301") ⇒ #<regexp-match>
(regexp-matches '("e\x0301") "\x00E9") ⇒ #f
(char-range <range-spec> ...)
(/ <range-spec> ...)

A character set contains the characters within <range-set>. This is the same as RE syntax [].

(regexp-matches '(* (/ "AZ09")) "R2D2") ⇒ #<regexp-match>
(regexp-matches '(* (/ "AZ09")) "C-3PO") ⇒ #f
(or <cset-sre> ...)
(|\|| <cset-sre> ...)

A shorthand for `(char-set ,(char-set-union <cset-sre>...)).

(complement <cset-sre> ...)
(~ <cset-sre> ...)

A shorthand for `(char-set ,(char-set-complement <cset-sre>...)).

(difference <cset-sre> ...)
(- <cset-sre> ...)

A shorthand for `(char-set ,(char-set-difference <cset-sre>...)).

(regexp-matches '(* (- (/ "az") ("aeiou"))) "xyzzy")
 ⇒ #<regexp-match>
(regexp-matches '(* (- (/ "az") ("aeiou"))) "vowels")
 ⇒ #f
(and <cset-sre> ...)
(& <cset-sre> ...)

A shorthand for `(char-set ,(char-set-intersection <cset-sre>...)).

(regexp-matches '(* (& (/ "az") (~ ("aeiou")))) "xyzzy")
 ⇒ #<regexp-match>
(regexp-matches '(* (& (/ "az") (~ ("aeiou")))) "vowels")
 ⇒ #f
(w/case <cset-sre>)
(w/nocase <cset-sre>)
(w/ascii <cset-sre>)
(w/unicode <cset-sre>)

This is similar to the SRE equivalent, listed to indicate that they can also be applied on character sets.

Named Character Sets

Note that if w/ascii is in effect, these character sets will return the ASCII subset. Otherwise they return full Unicode ones.

any

Matches any character. This is the . in regular expression.

nonl

Matches any character other than #\return or #\newline.

ascii

A shorthand for `(char-set ,char-set:ascii).

lower-case
lower

A shorthand for `(char-set ,char-set:lower-case).

upper-case
upper

A shorthand for `(char-set ,char-set:upper-case).

title-case
title

A shorthand for `(char-set ,char-set:title-case).

alphabetic
alpha

A shorthand for `(char-set ,char-set:letter).

numeric
num

A shorthand for `(char-set ,char-set:digit).

alphanumeric
alphanum
alnum

A shorthand for `(char-set ,char-set:letter+digit).

punctuation
punct

A shorthand for `(char-set ,char-set:punctuation).

symbol

A shorthand for `(char-set ,char-set:symbol).

graphic
graph

A shorthand for `(char-set ,char-set:graphic).

(or alphanumeric punctuation symbol)
whitespace
white
space

A shorthand for `(char-set ,char-set:whitespace).

printing
print

A shorthand for `(char-set ,char-set:printing).

control
cntrl

A character set contains ASCII characters with from 0 to 31.

hex-digit
xdigit

A shorthand for `(char-set ,char-set:hex-digit).

Boundary Assertions

bos
eos

Matches the beginning of the string. If start/end parameters are specified, matches the start or end of the substring as specified.

bol
eol

Matches the beginning or end of a line (or the string). For single line matching, this is the same as bos and eos. A line is interpreted the same way with read-line.

bow
eow

Matches the beginning or the end of a word.

  (regexp-search '(: bow "foo") "foo") ⇒ #<regexp-match>
  (regexp-search '(: bow "foo") "<foo>>") ⇒ #<regexp-match>
  (regexp-search '(: bow "foo") "snafoo") ⇒ #f
  (regexp-search '(: "foo" eow) "foo") ⇒ #<regexp-match>
  (regexp-search '(: "foo" eow) "foo!") ⇒ #<regexp-match>
  (regexp-search '(: "foo" eow) "foobar") ⇒ #f
nwb

A shorthand for (neg-look-ahead (or bow eow)).

(word <sre> ...)

Matches the word boundary around the given SRE:

(: bow <sre> ... eow)
(word+ <cset-sre> ...)

Matches a single word composed of characters of the given characters sets:

(word (+ (and (or alphanumeric "_") (or cset-sre ...))))
word

A shorthand for (word+ any).

bog
eog

Matches the beginning or end of a graphame cluster. See Unicode text segmentation, for the low-level grapheme cluster segmentation.

grapheme

Matches a single grapheme cluster. See Unicode text segmentation, for the low-level grapheme cluster segmentation.

Non-Greedy Patterns

(non-greedy-optional <sre> ...)
(?? <sre> ...)

The non-greedy equivalent of (optional <sre>...). This is the same as RE syntax re??

(non-greedy-zero-or-more< <sre> ...)
(*? <sre> ...)

The non-greedy equivalent of (zero-or-more <sre>...). This is the same as RE syntax re*?

(non-greedy-repeated <m> <n> <sre> ...)
(**? <m> <n> <sre> ...)

The non-greedy equivalent of (repeated <sre>...). This is the same as RE syntax re{n,m}?

(atomic <sre> ...)

Atomic clustering. Once <sre> ... matches, the match is fixed; even if the following pattern fails, the engine won’t backtrack to try the alternative match in <sre> .... This is Gauche extension and is the same as RE syntax (?>pattern)

Look Around Patterns

(look-ahead <sre> ...)

Zero-width look-ahead assertion. Asserts the sequence matches from the current position, without advancing the position. This is the same as RE syntax (?=pattern)

(regexp-matches '(: "regular" (look-ahead " expression") " expression")
                "regular expression")
 ⇒ #<regexp-match>
(regexp-matches '(: "regular" (look-ahead " ") "expression")
                "regular expression")
 ⇒ #f
(look-behind <sre> ...)

Zero-width look-behind assertion. Asserts the sequence matches behind the current position, without advancing the position. It is an error if the sequence does not have a fixed length. This is the same as RE syntax (?<=pattern)

(neg-look-ahead <sre> ...)

Zero-width negative look-ahead assertion. This is the same as RE syntax (?!pattern)

(neg-look-behind <sre> ...)

Zero-width negative look-behind assertion. This is the same as RE syntax (?<!pattern)

Using regular expressions

Function: regexp re

[R7RS regex] {scheme.regex} Compiles the given Scheme Regular Expression into a <regexp> object. If re is already a regexp object, the object is returned as-is.

Macro: rx sre

[R7RS regex] {scheme.regex} A macro shorthand for (regexp `(: sre ...)).

Function: regexp->sre re

[R7RS regex] {scheme.regex} Returns the SRE corresponding to the given given regexp object. Note that if the regexp object is not created from an SRE, it may contain features that cannot be expressed in SRE and cause an error.

Function: char-set->sre char-set

[R7RS regex] {scheme.regex} Returns the SRE of the given character set. Currently this is not optimized. If you convert any to SRE for example, you may get an SRE listing every single character.

Function: valid-sre? obj

[R7RS regex] {scheme.regex} Returns true iff obj can be safely passed to regexp.

Function: regexp? obj

[R7RS regex] {scheme.regex} Returns true iff obj is a regexp.

Function: regexp-matches re str [start [end]]

[R7RS regex] {scheme.regex} Returns an <regexp-match> object if re successfully matches the entire string str or optionally from start (inclusive) to end (exclusive), or #f is the match fails.

For convenience, end accepts #f and interprets it as the end of the string.

The regexp-match object will contain information needed to extract any submatches.

Function: regexp-matches? re str [start [end]]

[R7RS regex] {scheme.regex} Similar to regexp-matches but returns #t instead of a <regexp-match> object.

Function: regexp-search re str [start [end]]

[R7RS regex] {scheme.regex} Similar to regexp-matches except that re only has to match a substring in str instead.

Function: regexp-fold re kons knil str [finish [start [end]]]

[R7RS regex] {scheme.regex} Calls the procedure kons for every match found in str with following four arguments:

  • The position of the end of the last matched string.
  • The <regexp-match> object.
  • The argument str.
  • The result of the last kons call or knil if this is the first call.

If finish is given, it is called after all matches with the same parameters as calling kons except that #f is passed instead of <regexp-match> and the result is returned. Otherwise the result of the last kons call is returned.

   (regexp-fold 'word
                (lambda (i m str acc)
                  (let ((s (regexp-match-submatch m 0)))
                   (cond ((assoc s acc)
                          => (lambda (x) (set-cdr! x (+ 1 (cdr x))) acc))
                         (else `((,s . 1) ,@acc)))))
                '()
                "to be or not to be")
   ⇒ '(("not" . 1) ("or" . 1) ("be" . 2) ("to" . 2))
Function: regexp-extract re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of matched string or an empty list if no matches.

   (regexp-extract '(+ numeric) "192.168.0.1")
   ⇒ ("192" "168" "0" "1")
Function: regexp-split re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of not matched substrings. This can be seen as the opposite of regexp-extract where the matched strings are removed instead of returned.

   (regexp-split '(+ space) " fee fi  fo\tfum\n")
   ⇒ ("fee" "fi" "fo" "fum")
   (regexp-split '(",;") "a,,b,")
   ⇒ ("a" "" "b" "")
   (regexp-split '(* numeric) "abc123def456ghi789")
   ⇒ ("abc" "def" "ghi" "")
Function: regexp-partition re str [start [end]]

[R7RS regex] {scheme.regex} Returns a list of all matched and not matched substrings. In other words it’s the combination of regexp-extract and regexp-split where the boundary of matched strings are used to split the original string.

   (regexp-partition '(+ (or space punct)) "")
   ⇒ ("")
   (regexp-partition '(+ (or space punct)) "Hello, world!\n")
   ⇒ ("Hello" ", " "world" "!\n")
   (regexp-partition '(+ (or space punct)) "¿Dónde Estás?")
   ⇒ ("" "¿" "Dónde" " " "Estás" "?")
   (regexp-partition '(* numeric) "abc123def456ghi789")
   ⇒ ("abc" "123" "def" "456" "ghi" "789")
Function: regexp-replace re str subst [start [end [count]]]

[R7RS regex] {scheme.regex} Returns a new string where the first matched substring is replaced with subst. If count is specified, the count-th match will be replaced instead of the first one.

subst can be either a string (the replacement), an integer or a symbol to refer to the capture group that will be used as the replacement, or a list of those.

The special symbols pre and post use the substring to the left or right of the match as replacement, respectively.

subst could also be a procedure, which is called with the given match object and the result will be used as the replacement.

The optional parameters start and end essentially transform the substitution into this

   (regexp-replace re (substring str start end) subst)

except that end can take #f which is the same as (string-length str).

   (regexp-replace '(+ space) "one two three" "_")
   ⇒ "one_two three"
   (regexp-replace '(+ space) "one two three" "_" 1 10)
   ⇒ "ne_two th"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 0)
   ⇒ "one_two three"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 1)
   ⇒ "one two_three"
   (regexp-replace '(+ space) "one two three" "_" 0 #f 2)
   ⇒ "one two three"

Note that Gauche also has a builtin procedure of the same name, but works slightly differently, see 正規表現を使う.

Function: regexp-replace-all re str subst [start [end]]

[R7RS regex] {scheme.regex} Returns a new string where all matches in str are replaced with subst. subst can also take a string, a number, a symbol or a procedure similar to regexp-replace.

(regexp-replace-all '(+ space) "one two three" "_")
   ⇒ "one_two_three"

Note that Gauche also has a builtin procedure of the same name, but works slightly differently, see 正規表現を使う.

Function: regexp-match? obj

[R7RS regex] {scheme.regex} Returns true iff obj is a <regexp-match> object.

(regexp-match? (regexp-matches "x" "x"))  ⇒ #t
(regexp-match? (regexp-matches "x" "y"))  ⇒ #f
Function: regexp-match-count regexp-match

[R7RS regex] {scheme.regex} Returns the number of matches in match except the implicit zero full match. This is just an alias of rxmatch-num-matches minus one.

(regexp-match-count (regexp-matches "x" "x"))  ⇒ 0
(regexp-match-count (regexp-matches '($ "x") "x"))  ⇒ 1
Function: regexp-match-submatch regexp-match field

[R7RS regex] {scheme.regex} This is an alias of rxmatch-substring

   (regexp-match-submatch (regexp-search 'word "**foo**") 0)  ⇒ "foo"
   (regexp-match-submatch
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  ⇒ "*foo*"
   (regexp-match-submatch
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  ⇒ "foo"
Function: regexp-match-submatch-start regexp-match field

[R7RS regex] {scheme.regex} This is an alias of regexp-match-submatch-start.

   (regexp-match-submatch-start
    (regexp-search 'word "**foo**") 0)  ⇒ 2
   (regexp-match-submatch-start
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  ⇒ 1
   (regexp-match-submatch-start
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  ⇒ 2
Function: regexp-match-submatch-end regexp-match field

[R7RS regex] {scheme.regex} This is an alias of regexp-match-submatch-end.

   (regexp-match-submatch-end
    (regexp-search 'word "**foo**") 0)  ⇒ 5
   (regexp-match-submatch-end
    (regexp-search '(: "*" ($ word) "*") "**foo**") 0)  ⇒ 6
   (regexp-match-submatch-end
    (regexp-search '(: "*" ($ word) "*") "**foo**") 1)  ⇒ 5
Function: regexp-match->list regexp-match

[R7RS regex] {scheme.regex} This is an alias of rxmatch-substrings

   (regexp-match->list
    (regexp-search '(: ($ word) (+ (or space punct)) ($ word)) "cats & dogs"))
    ⇒ '("cats & dogs" "cats" "dogs")

10.3.20 scheme.mapping - R7RSマッピング

Module: scheme.mapping
Module: scheme.mapping.hash

このモジュールは、キーから値への変更不可なマッピングを提供します。 元はsrfi.146およびsrfi.146.hashとして規定されました。

scheme.mappingモジュールは、キー間に全順序を定義できるmappingオブジェクトを、 scheme.mapping.hashモジュールは、ハッシュ可能なキーを使うhashmapオブジェクト を提供します。

今のところ、Gaucheはmappingとして組み込みの<tree-map>を (ツリーマップ)、 hashmapとして組み込みの<hash-table>を使っています。 実際の実装は将来変わるかもしれないので、このモジュールを使う場合は具体的なデータ構造を 仮定しないようにしてください。

呼び出し側では、mappingやhashmapは変更不可なオブジェクトとして扱わなければなりません。 このモジュールでは「線形更新」版のAPIも提供されています。これは、 呼び出し側で引数に渡すmappingやhashmapに二度とアクセスしない、という契約のもとに、 渡されたmappingやhashmapを再利用するかもしれないインタフェースです。 線形更新版のAPIは名前の末尾に!がつきます。 ですが副作用は保証されていないので、線形更新版でも常に戻り値を利用する必要があります。


10.3.20.1 Mappings

Class: <mapping>

{scheme.mapping} mappingのクラス。Gaucheでは単に<tree-map>の別名です。

コンストラクタ

Function: mapping comparator key value …

[R7RS mapping] {scheme.mapping} comparatorをキーの比較に用いる新たなmappingを作って返します。 key value … がキー-値の組の初期値となります。

comparatorは、順序手続きか比較手続きを持つ比較器でなければなりません (基本的な比較器参照)。

残りの引数 key value … は偶数個でなければならず、 引数はキーと値を交互に並べたものです。

(define m (mapping default-comparator 'a 1 'b 2))

(mapping-ref m 'a) ⇒ 1
(mapping-ref m 'b) ⇒ 2
Function: mapping-unfold p f g seed comparator

[R7RS mapping] {scheme.mapping} 新たなmappingを作って返します。作られるmappingの内容は、 3つの手続きpfgと初期シード値seedで決まります。

繰り返しごとに、「現在のシード値」が参照されます。シード値の初期値はseedです。

まず、現在のシード値にp (停止述語)が適用されます。それが真の値を返したら、 繰り返しは終了し、それまでに生成されたエントリを持つmappingが返されます。

次に、fが現在のシード値に適用されます。これは二つの値を返さなければなりません。 最初の戻り値がキー、次の戻り値が値と解釈されます。この組がmappingに足されます。

それから、gが現在のシード値に適用されます。その戻り値が次の繰り返しでの シード値となります。これを繰り返します。

次の例は、ASCII文字をASCIIコードにマップするmappingを返します。

(mapping-unfold (cut >= <> 128)
                (^c (values (integer->char c) c))
                (cut + <> 1)
                0
                default-comparator)
Function: mapping/ordered comparator key value …

[R7RS mapping] {scheme.mapping} mappingと同様のコンストラクタですが、 キーがcomparatorの基準で昇順になっていることを呼び出し側が保証します。 実装によってはその事実を利用してmappingよりも効率的なアルゴリズムを 使うかもしれません。Gaucheeでゃこれは今のところmappingと同じです。

Function: mapping-unfold/ordered p f g seed comparator

[R7RS mapping] {scheme.mapping} mapping-unfoldと同様のコンストラクタですが、 キーがcomparatorの基準で昇順になっていることを呼び出し側が保証します。 実装によってはその事実を利用してmapping-unfoldよりも効率的なアルゴリズムを 使うかもしれません。Gaucheeでゃこれは今のところmapping-unfoldと同じです。

述語

Function: mapping? obj

[R7RS mapping] {scheme.mapping} objがマッピングなら#tを、そうでなければ#fを返します。

Function: mapping-empty? m

[R7RS mapping] {scheme.mapping} 引数はマッピングでなければなりません。 mが空なら#tを、そうでなければ#fを返します。 Gaucheではこれはtree-map-empty?と同じです (ツリーマップ参照)。

Function: mapping-contains? m key

[R7RS mapping] {scheme.mapping} mはマッピングでなければなりません。 m中にkeyをキーとするエントリをがあれば#tを、 そうでなければ#fを返します。 Gaucheではこれはtree-map-exists?と同じです (ツリーマップ参照)。

Function: mapping-disjoint? m1 m2

[R7RS mapping] {scheme.mapping} 二つのマッピングm1m2の間に共通するキーがなければ#tを、 そうでなければ#fを返します。

アクセサ

Function: mapping-ref m key :optional failure success

[R7RS mapping] {scheme.mapping} マッピングmからキーkeyを持つエントリを探し、その値が見つかれば それを引数としてsuccessを呼び、その結果を返します。 keyを持つエントリが見つからなかった場合はfailureが引数無しで呼ばれ、 その結果が返ります。 successfailureはどちらも末尾位置で呼ばれます。

failureが省略された場合、キーが見つからなければエラーが投げられます。 successが省略された場合はidentityが使われます。

Function: mapping-ref/default m key default

[R7RS mapping] {scheme.mapping} マッピングmからキーkeyを持つエントリを探し、見つかればその値を、 見つからなければdefaultを返します。

Function: mapping-key-comparator m

[R7RS mapping] {scheme.mapping} マッピングmがキーの比較に使う比較器を返します。 比較器については基本的な比較器を参照してください。

更新

マッピングSRFIの前提は変更不可なデータ構造です。 更新操作には、純粋に関数的なもの(エクスクラメーションマークがついていないもの)と、 線形更新版(エクスクラメーションマークがついているもの)がありますが、 線形更新版も必ずしも引数のマッピングを破壊的変更するとは限りません。 線形更新版を使うことは、呼び出し側で引数に渡したマッピングを二度と使わない(から再利用してよい) ということを伝えるヒントにすぎません。 線形更新版を使うときでも、常に戻り値を使うようにしてください。 線形更新版に渡したマッピングは、その後どういう状態になっているか一切の保証がないので、 そのマッピングを使わないようにしてください。

Function: mapping-adjoin m arg …
Function: mapping-adjoin! m arg …

[R7RS mapping] {scheme.mapping} arg …はキーと値が交互に並んだリストです。マッピングmに、 arg …で与えられるキー-値のエントリを追加したマッピングを返します。 線形更新版のmapping-adjoin!は戻り値を作るのにmを再利用するかもしれません。 mapping-adjoinは常に新たなマッピングを作って返します。

引数は現れる順番に処理されます。もし与えられたキーを持つエントリがmに既にあったなら、 元のエントリが残されます。与えたキーの方を優先させたい場合は 下のmapping-setを見てください。

(mapping-adjoin (mapping default-comparator 'a 1 'b 2) 'c 3 'a 4 'c 5)
 ⇒ mapping with a → 1, b → 2, c → 3
Function: mapping-set m arg …
Function: mapping-set! m arg …

[R7RS mapping] {scheme.mapping} arg …はキーと値が交互に並んだリストです。マッピングmに、 arg …で与えられるキー-値のエントリを追加したマッピングを返します。 線形更新版のmapping-set!は戻り値を作るのにmを再利用するかもしれません。 mapping-setは常に新たなマッピングを作って返します。

引数は現れる順番に処理されます。もし与えられたキーを持つエントリがmに既にあったなら、 新たに与えた値で置き換えられます。元の値の方を優先させたい場合は 上のmapping-adjoinを見てください。

(mapping-set (mapping default-comparator 'a 1 'b 2) 'c 3 'a 4 'c 5)
 ⇒ mapping with a → 4, b → 2, c → 5
Function: mapping-replace m key value
Function: mapping-replace! m key value

[R7RS mapping] {scheme.mapping} マッピングmkeyを持つエントリがある場合、その値をvalueに 置き換えたマッピングを返します。mkeyを持っていなかったらmを そのまま返します。

線形更新版のmapping-replace!は戻り値を作るのにmを再利用するかもしれません。 mapping-replaceは常に新たなマッピングを作って返します。

(mapping-replace (mapping default-comparator 'a 1 'b 2) 'a 3)
 ⇒ mapping with a → 3, b → 2

(mapping-replace (mapping default-comparator 'a 1 'b 2) 'c 3)
 ⇒ mapping with a → 1, b → 2
Function: mapping-delete m key …
Function: mapping-delete! m key …

[R7RS mapping] {scheme.mapping} マッピングmから、key …のいずれかのキーを持つエントリをすべて 取り除いたマッピングを返します。mの中に無いキーは無視されます。

線形更新版のmapping-delete!は戻り値を作るのにmを再利用するかもしれません。 mapping-deleteは常に新たなマッピングを作って返します。

Function: mapping-delete-all m key-list
Function: mapping-delete-all! m key-list

[R7RS mapping] {scheme.mapping} マッピングmから、key-listに含まれるキーを持つエントリを 取り除いたマッピングを返します。mの中に無いキーは無視されます。

線形更新版のmapping-delete-all!は戻り値を作るのにmを再利用するかもしれません。 mapping-delete-allは常に新たなマッピングを作って返します。

Function: mapping-intern m key make-value
Function: mapping-intern! m key make-value

[R7RS mapping] {scheme.mapping} マッピングmからキーkeyを持つエントリを探します。 見つかった場合は、m自身とエントリの値を返します。 見つからなかった場合、サンクmake-valueが引数無しで呼ばれ、 keyをキー、make-valueの結果を値とするエントリをmに追加した マッピングと、make-valueの結果が返されます。

線形更新版のmapping-intern!は戻り値を作るのにmを再利用するかもしれません。 mapping-internは常に新たなマッピングを作って返します。

(mapping-intern (mapping default-comparator 'a 1) 'b (^[] 2))
  ⇒
  mapping with a → 1, b → 2
  and
  2

(mapping-intern (mapping default-comparator 'a 1) 'a (^[] 2))
  ⇒
  mapping with a → 1
  and
  1
Function: mapping-update m key updater :optional failure success
Function: mapping-update! m key updater :optional failure success

[R7RS mapping] {scheme.mapping} Semantically equivalent to this:

(mapping-set m var
  (updater (mapping-ref m key failure success)))

The failure and success optional arguments are procedures with zero and one arguments, respectively. When omitted, failure defaults to a thunk that raises an error, and success defaults to identity.

First, key is looked up in m. If an entry is found, the associated value is passed to success; otherwise, failure is called with no arguments. Either way, let the returned value be v0.

Then, v0 is passed to updater. Let its result be v1.

Finally, a mapping with the same entries as m except the value of key is altered to v1 is returned.

Linear update version mapping-update! may destructively modify m to produce the return value, while mapping-update creates a new mapping.

(mapping-update (mapping default-comparator 'a 1)
                'a (pa$ + 1))
 ⇒ mapping with a → 2

(mapping-update (mapping default-comparator)
                'a (pa$ + 1) (^[] 0))
 ⇒ mapping with a → 1
Function: mapping-update/default m key updater default
Function: mapping-update!/default m key updater default

[R7RS mapping] {scheme.mapping} Search mapping m for a key key. If the entry is found, call updater with its value, and returns a mapping in which the entry with key having the result of updater as a value. If the entry with key is not found in m, call updater with default, and returns a mapping in which the entry with key and the result of updater is added. Semantically, it is the same as the following:

(mapping-set m key (updater (mapping-ref/default m key default)))

Linear update version mapping-update/default! may destructively modify m to produce the return value, while mapping-update/default creates a new mapping.

Function: mapping-pop m :optional failure
Function: mapping-pop! m :optional failure

[R7RS mapping] {scheme.mapping} Choose the least key from a mapping m and returns three values, (1) a mapping that has the same content as m except the entry with the chosen key, (2) the chosen key, and (3) the value associated with the chosen key. If m is empty, failure is called with no arguments in the tail context and its result(s) are returned. If failure is omitted, an error is signalled when m is empty.

Linear update version mapping-update/pop! may destructively modify m to produce the return value, while mapping-update/pop creates a new mapping.

Function: mapping-search m k failure success
Function: mapping-search! m k failure success

[R7RS mapping] {scheme.mapping} Search the key k from the mapping m. If the entry is found, the success procedure is tail-called as (success key value update remove), where key and value are from the found entry, and update and remove are procedures as explained below. If no entry is found, the failure procedure is tail-called as (failure insert ignore), where the arguments are procedures as explained below.

The success procedure is expected to tail-call either update or remove procedures:

The update procedure passed to success takes takes three arguments, new-key, new-value, and retval. It creates a mapping which is the same as m except the original key’s entry is removed, but a new entry with new-key and new-value is adjoined. Then it returns the new mapping and retval.

The remove procedure assed to success takes one argument, retval, and it creates a mapping which is the same as m except the searched entry is removed, and returns the new mapping and retval.

The failure procedure is expected to tail-call either insert or ignore procedures:

The insert procedure passed to failure takes two arguments, value and retval. It creates a new mapping that has all the entires of m and a new entry with k and value, and returns the new mapping and retval.

The ignore procedure takes one argument, retval, and returns the original mapping m and retval.

Linear update version mapping-search! may destructively modify m to produce the return value, while mapping-search creates a new mapping.

マッピング全体

Function: mapping-size m

[R7RS mapping] {scheme.mapping} Returns the number of entries in the mapping m.

Function: mapping-find pred m failure

[R7RS mapping] {scheme.mapping} For each key in the mapping m in increasing order, calls pred with the key and the associated value. If pred returns a true value, immediately returns that key and the value as two values. If no entry satisfy pred, a thunk failure is tail-called.

Function: mapping-count pred m

[R7RS mapping] {scheme.mapping} For each key in the mapping m in increasing order, calls pred with the key and the associated value. Returns the number of times when pred returned a true value.

Function: mapping-any? pred m

[R7RS mapping] {scheme.mapping} Returns #t if any entry of the mapping m of which pred returns a true value with its key and its value. If no entries satisfy pred, #f is returned.

Function: mapping-every? pred m

[R7RS mapping] {scheme.mapping} Returns #t if every entry of the mapping m of which pred returns a true value with its key and its value. If any entry does not satisfy pred, #f is returned.

Function: mapping-keys m
Function: mapping-values m

[R7RS mapping] {scheme.mapping} Returns a fresh list of keys and values of the mapping m, in the increasing order of keys.

Function: mapping-entries m

[R7RS mapping] {scheme.mapping} Returns two values, a fresh list of keys and a fresh list of values in the mapping m, in the increasing order of keys.

マップと畳み込み

Function: mapping-map proc comparator m

[R7RS mapping] {scheme.mapping} The proc argument is a procedure that takes two arguments, a key and a value, and returns two values, a new key and a new value. This procedure applies proc on each key-value in a mapping m, and returns a new mapping that uses comparator for its key comparator and contains all the new keys and values returned by proc.

If proc returns duplicate keys with regard to comparator, one of the key-value associations enters the result mapping. There’s no rule for which one is chosen.

Function: mapping-map/monotone proc comparator m
Function: mapping-map/monotone! proc comparator m

[R7RS mapping] {scheme.mapping} Similar to mapping-map, except that the caller guarantees the order of keys returned from proc w.r.t. comparator preserves the order of keys in m. The resulting new mapping is the same, but the impementation may take advantage of the knowledge for efficiency. In the current Gauche, mapping-map/monotone is the same as mapping-map.

The linear update version mapping-map/monotone! may reuse m to produce the output.

Function: mapping-for-each proc m

[R7RS mapping] {scheme.mapping}

Function: mapping-fold kons knil m

[R7RS mapping] {scheme.mapping}

Function: mapping-fold/reverse kons knil m

[R7RS mapping] {scheme.mapping}

Function: mapping-map->list proc m

[R7RS mapping] {scheme.mapping}

Function: mapping-filter pred m
Function: mapping-filter! pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-remove pred m
Function: mapping-remove! pred m

[R7RS mapping] {scheme.mapping}

Function: mapping-partition pred m
Function: mapping-partition! pred m

[R7RS mapping] {scheme.mapping}

Copying and conversion

Function: mapping-copy m

[R7RS mapping] {scheme.mapping}

Function: mapping->alist m

[R7RS mapping] {scheme.mapping}

Function: alist->mapping comparator alist

[R7RS mapping] {scheme.mapping}

Function: alist->mapping! m alist

[R7RS mapping] {scheme.mapping}

Function: alist->mapping/ordered comparator alist
Function: alist->mapping/ordered! m alist

[R7RS mapping] {scheme.mapping}

Submappings

Function: mapping=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping<? comparator m1 m2 …
Function: mapping<=? comparator m1 m2 …
Function: mapping>? comparator m1 m2 …
Function: mapping>=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping}

Set operations

Function: mapping-union m1 m2 …
Function: mapping-union! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-intersection m1 m2 …
Function: mapping-intersection! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-difference m1 m2 …
Function: mapping-difference! m1 m2 …

[R7RS mapping] {scheme.mapping}

Function: mapping-xor m1 m2 …
Function: mapping-xor! m1 m2 …

[R7RS mapping] {scheme.mapping}

Mappings with ordered keys

Function: mapping-min-key m
Function: mapping-max-key m

[R7RS mapping] {scheme.mapping}

Function: mapping-min-value m
Function: mapping-max-value m

[R7RS mapping] {scheme.mapping}

Function: mapping-min-entry m
Function: mapping-max-entry m

[R7RS mapping] {scheme.mapping}

Function: mapping-key-predecessor m obj failure
Function: mapping-key-successor m obj failure

[R7RS mapping] {scheme.mapping}

Function: mapping-range= m obj
Function: mapping-range< m obj
Function: mapping-range<= m obj
Function: mapping-range> m obj
Function: mapping-range>= m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-range=! m obj
Function: mapping-range<! m obj
Function: mapping-range<=! m obj
Function: mapping-range>! m obj
Function: mapping-range>=! m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-split m obj
Function: mapping-split! m obj

[R7RS mapping] {scheme.mapping}

Function: mapping-catenate comparator m1 key value m2
Function: mapping-catenate! m1 key value m2

[R7RS mapping] {scheme.mapping}

Comparators

Function: make-mapping-comparator comparator

[R7RS mapping] {scheme.mapping}

Variable: mapping-comparator

[R7RS mapping] {scheme.mapping}


10.3.20.2 Hashmaps

Constructors

Function: hashmap comparator key value …

[R7RS mapping] {scheme.mapping.hash} Creates a new hashmap with the given comparator, whose initial content is provided by key value ….

The comparator argument must be a comparator (see 基本的な比較器).

The key value … arguments must be even length, alternating keys and values.

(define m (hashmap default-comparator 'a 1 'b 2))

(hashmap-ref m 'a) ⇒ 1
(hashmap-ref m 'b) ⇒ 2
Function: hashmap-unfold p f g seed comparator

[R7RS mapping] {scheme.mapping.hash} Creates a new hashmap, whose content is populated by three procedures, p, f and g, and a seed value seed, as follows.

In each iteration, we have a current seed value, whose initial value is seed.

First, p, a stop predicate, is applied to the current seed value. If it returns true, we stop iteration and returns the new hashmap.

Next, f is applied to the current seed value. It must return two values. The first one is for a key and the second one for the value. We add this pair to the hashmap.

Then, g is applied to the current seed value. The result becomes the seed value of the next iteration. And we iterate.

The following example creates a hashmap that maps ASCII characters to their character codes:

(hashmap-unfold (cut >= <> 128)
                (^c (values (integer->char c) c))
                (cut + <> 1)
                0
                default-comparator)

Predicates

Function: hashmap? obj

[R7RS mapping] {scheme.mapping.hash} Returns #t iff obj is a hashmap object.

Function: hashmap-empty? m

[R7RS mapping] {scheme.mapping.hash} M must be a hashmap. Returns #t if m is empty, #f otherwise. In Gauche, this is same as tree-map-empty? (see ツリーマップ).

Function: hashmap-contains? m key

[R7RS mapping] {scheme.mapping.hash} M must be a hashmap. Returns #t if m has an entry with key, #f otherwise. In Gauche, this is same as tree-map-exists? (see ツリーマップ).

Function: hashmap-disjoint? m1 m2

[R7RS mapping] {scheme.mapping.hash} Returns #t iff two hashmaps m1 and m2 have no keys in common. In other words, there’s no such key K that satisfy both (hashmap-contains? m1 K) and (hashmap-contains? m2 K).

Accessors

Function: hashmap-ref m key :optional failure success

[R7RS mapping] {scheme.mapping.hash} Get the value from a hashmap m associated with key, and calls success on the value, and returns its result. If m doesn’t have key, failure is invoked with no arguments and its result is returned. Both success and failure is called in tail context.

When failure is omitted and key is not found, an error is signaled. When success is omitted, identity is assumed.

Function: hashmap-ref/default m key default

[R7RS mapping] {scheme.mapping.hash} Returns the value associated to key from a hashmap m. If m doesn’t have key, default is returned.

Function: hashmap-key-comparator m

[R7RS mapping] {scheme.mapping.hash} Returns a comparator used to compare keys in a hashmap m. See 基本的な比較器, for the details of comparators.

Updaters

Note that the basic premise of hashmaps srfi is to treat hashmaps as immutable. Each updating operation comes with a purely functional version (without bang) and a linear update version (with bang), but the linear update version may not require to destructively modiy the passed hashmap; it’s merely a hint that it may reuse the argument for the efficiency. You always need to use the returned hashmap as the result of update. If you use linear update versions, you shouldn’t use the passed hashmap afterwards, for there’s no guarantee how the state of the passed hashmap is.

Function: hashmap-adjoin m arg …
Function: hashmap-adjoin! m arg …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-set m arg …
Function: hashmap-set! m arg …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-replace m key value
Function: hashmap-replace! m key value

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-delete m key …
Function: hashmap-delete! m key …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-delete-all m key-list
Function: hashmap-delete-all! m key-list

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-intern m key failure
Function: hashmap-intern! m key failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-update m key updater :optional failure success
Function: hashmap-update! m key updater :optional failure success

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-update/default m key updater default
Function: hashmap-update!/default m key updater default

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-pop m :optional failure
Function: hashmap-pop! m :optional failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-search m k failure success
Function: hashmap-search! m k failure success

[R7RS mapping] {scheme.mapping.hash}

The whole hashmap

Function: hashmap-size m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-find pred m failure

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-count pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-any? pred m
Function: hashmap-every? pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-keys m
Function: hashmap-values m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-entries m

[R7RS mapping] {scheme.mapping.hash}

Mapping and folding

Function: hashmap-map proc comparator m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-for-each proc m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-fold kons knil m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-map->list proc m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-filter pred m
Function: hashmap-filter! pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-remove pred m
Function: hashmap-remove! pred m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-partition pred m
Function: hashmap-partition! pred m

[R7RS mapping] {scheme.mapping.hash}

Copying and conversion

Function: hashmap-copy m

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap->alist m

[R7RS mapping] {scheme.mapping.hash}

Function: alist->hashmap comparator alist

[R7RS mapping] {scheme.mapping.hash}

Function: alist->hashmap! m alist

[R7RS mapping] {scheme.mapping.hash}

Subhashmaps

Function: hashmap=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap<? comparator m1 m2 …
Function: hashmap<=? comparator m1 m2 …
Function: hashmap>? comparator m1 m2 …
Function: hashmap>=? comparator m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Set operations

Function: hashmap-union m1 m2 …
Function: hashmap-union! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-intersection m1 m2 …
Function: hashmap-intersection! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-difference m1 m2 …
Function: hashmap-difference! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Function: hashmap-xor m1 m2 …
Function: hashmap-xor! m1 m2 …

[R7RS mapping] {scheme.mapping.hash}

Comparators

Function: make-hashmap-comparator comparator

[R7RS mapping] {scheme.mapping.hash}

Variable: hashmap-comparator

[R7RS mapping] {scheme.mapping.hash}


10.3.21 scheme.division - R7RS整数除算

Module: scheme.division

このモジュールは、様々な整数除算操作を包括的に提供します。

整数除算の商と剰余には、除数と被除数の符号の考慮によって、 いくつかの定義が考えられます。 Gaucheはそのうちいくつかの定義を組み込みで提供しています: R5RSのquotientremaindermodulo、 R6RSのdivmoddiv0mod0、 そしてR7RSの floor-quotientfloor-remainderfloor/truncate-quotienttruncate-remaindertruncate/、です。

このモジュールは、R7RSの手続きにさらに ceilingroundeuclideanbalancedのバリエーションを加えます。

scheme.divisionの以下の手続きについては組み込みになっているので、 数値の演算を参照してください。

floor-quotient     floor-remainder    floor/
truncate-quotient  truncate-remainder truncate/
Function: ceiling-quotient n d
Function: ceiling-remainder n d
Function: ceiling/ n d

[R7RS division] {scheme.division}

ceiling-quotient = ceiling(n / d)
ceiling-remainder = n - d * ceiling-quotient
ceiling/ = values(ceiling-quotient, ceiling-remainder)
Function: round-quotient n d
Function: round-remainder n d
Function: round/ n d

[R7RS division] {scheme.division}

round-quotient = round(n/d)
round-remainder = n - d * round-quotient
round/ = values(round-quotient, round-remainder)
Function: euclidean-quotient n d
Function: euclidean-remainder n d
Function: euclidean/ n d

[R7RS division] {scheme.division}

euclidean-quotient = floor(n / d)   if d > 0
                     ceiling(n / d) if d < 0
euclidean-remainder = n - d * euclidean-quotient
euclidean/ = values(euclidean-quotient, euclidean-remainder)

Eclideanバリエーションは、0 <= remainder < abs(d)という関係を常に満たします。 この定義はR6RSのdivmodおよびdiv-and-modと同じです。 但し、R6RS版は非整数を引数に取ることもできます(数値の演算参照)。

Function: balanced-quotient n d
Function: balanced-remainder n d
Function: balanced/ n d

[R7RS division] {scheme.division}

balanced-quotient = roundup(n / d)
balanced-remainder = n - d * balanced-quotient
balanced/ = values(balanced-quotient, balanced-remainder)
  ここでroundup(x)は、|x| - floor(|x|) < 0.5 ならゼロの方向に、
                       |x| - floor(|x|) >= 0.5 ならゼロと逆方向丸めます

Balancedバージョンは-abs(d/2) <= remainder < abs(d/2)という 関係を常に満たします。これはR6RSの div0mod0およびdiv0-and-mod0と同じです。 但し、R6RS版は非整数を引数に取ることもできます(数値の演算参照)。


10.3.22 scheme.bitwise - R7RSビット演算

Module: scheme.bitwise

このモジュールは包括的なビット演算手続きを提供します。 元はSRFI-151で、 ほぼSRFI-60のスーパーセットですが、いくつかの手続きは一貫性と互換性のために 名前が変わりました(SRFI-60についてはsrfi.60 - 整数に対するビット操作参照)。 SRFI-60も以前のコードとの互換性のため残されますが、新たに書くコードは このモジュールを使うことを推奨します。

以下の手続きはGauche組み込みになっています。 説明は基本的なビット演算を参照してください。

integer-length    copy-bit          bit-field

基本演算

Function: bitwise-not n

[R7RS bitwise] {scheme.bitwise} nの各ビットを反転したものを返します。 組み込みのlognotと同じです。(基本的なビット演算参照)。

Function: bitwise-and n …
Function: bitwise-ior n …
Function: bitwise-xor n …
Function: bitwise-eqv n …

[R7RS bitwise] {scheme.bitwise} 引数が与えられない場合、これらはそれぞれ-100-1を 返します。引数がひとつの場合はそれをそのまま返します。 引数が二つの場合は、それらのビット毎のand、ior、xor、及びeqv (xorの論理反転) を 取ったものを返します。3引数以上は、2引数の計算から導かれます。

(bitwise-xor a b c)
 ≡ (bitwise-xor a (bitwise-xor b c))
 ≡ (bitwise-xor (bitwise-xor a b) c)

この定義では、3引数以上のbitwise-eqvは 「すべての引数の該当ビットが同じである時に1」とはならないことに注意してください。

最初の3つの手続きはそれぞれ組み込みの logandlogiorlogxorと同じです (基本的なビット演算参照)。

Function: bitwise-nand n0 n1
Function: bitwise-nor n0 n1
Function: bitwise-andc1 n0 n1
Function: bitwise-andc2 n0 n1
Function: bitwise-orc1 n0 n1
Function: bitwise-orc2 n0 n1

[R7RS bitwise] {scheme.bitwise} これらの手続きは2引数固定です。

nand n0 n1   ≡  (NOT (AND n0 n1))
nor n0 n1    ≡  (NOT (OR n0 n1))
andc1 n0 n1  ≡  (AND (NOT n0) n1)
andc2 n0 n1  ≡  (AND n0 (NOT n1))
orc1 n0 n1   ≡  (OR (NOT n0) n1)
orc2 n0 n1   ≡  (OR n0 (NOT n1))

整数演算

Function: arithmetic-shift n count

[R7RS bitwise] {scheme.bitwise} 整数ncountビット左シフトします。countが負ならば、 n-countビット右にシフトされることになります。

これは組み込みのashと同じです(基本的なビット演算参照)。

Function: bit-count n

[R7RS bitwise] {scheme.bitwise} nが正の場合はn中の1であるビットの数を、 nが負の場合はn中の0であるビットの数を返します。

組み込みのlogcountと同じです(基本的なビット演算参照)。

Function: bitwise-if mask n0 n1

[R7RS bitwise] {scheme.bitwise} 整数を返します。戻り値のn番目のビットは、maskn番目のビットが 1であればn0n番目のビット、0であればn1n番目のビット になります。

(bitwise-if #b10101100 #b00110101 #b11001010)
 ⇒ #b01100110

単一ビットの操作

Function: bit-set? index n

[R7RS bitwise] {scheme.bitwise} nのLSBから数えてindex番目(0ベース)のビットが1であれば #tを、0であれば#fを返します。

組み込みのlogbit?と同じです(基本的なビット演算参照)。

Function: bit-swap index1 index2 n

[R7RS bitwise] {scheme.bitwise} nindex1番目のビットとindex2番目のビットを入れ替えた整数を 返します。インデックスは0ベースでLSBから数えます。

Function: any-bit-set? mask n
Function: every-bit-set? mask n

[R7RS bitwise] {scheme.bitwise} n中で、maskでビットの立っている箇所のビットのいずれか(any-bit-set?) あるいはすべて(every-bit-set?)が1であれば#tを返し、 それ以外では#fを返します。

any-bit-set?は組み込みのlogtestとほぼ同じですが、 logtestは可変長引数です (基本的なビット演算参照)。

Function: first-set-bit n

[R7RS bitwise] {scheme.bitwise} nを割り切る(expt 2 k)のうち最大のkを返します。別の言い方をすれば、 nのビット列のうち一番右にある1のインデックスを返します。 first-set-bitの名前はそこからきています。

(first-set-bit 0) ⇒ -1   ; edge case
(first-set-bit 1) ⇒ 0
(first-set-bit 2) ⇒ 1
(first-set-bit 15) ⇒ 0
(first-set-bit 16) ⇒ 4

これはGauche組み込みのtwos-exponent-factorと同じです (基本的なビット演算参照)。

ビットフィールド操作

Function: bit-field-any? n start end
Function: bit-field-every? n start end

[R7RS bitwise] {scheme.bitwise} n中のstartビット目(含む)からendビット目(含まない)までの ビットフィールドのうち、一つでもビットが立っていた場合(bit-field-any?)、 あるいは全てのビットが立っていた場合(bit-field-every?)に#tを、 それ以外に#fを返します。

Function: bit-field-clear n start end
Function: bit-field-set n start end

[R7RS bitwise] {scheme.bitwise} n中のstartビット目(含む)からendビット目(含まない)までの ビットを全て0あるいは1にした整数値を返します。

Function: bit-field-replace dst src start end

[R7RS bitwise] {scheme.bitwise} dst中のstartビット目(含む)からendビット目(含まない)までの ビットフィールドを、src中の下位(end-start)ビットで置き換えた 値を返します。

(bit-field-replace #b101010 #b010 1 4) ⇒ #b100100

組み込みのcopy-bit-fieldと同じです(基本的なビット演算参照)。

Function: bit-field-replace-same dst src start end

[R7RS bitwise] {scheme.bitwise} dst中のstartビット目(含む)からendビット目(含まない)までの ビットフィールドを、 src中の同じ位置にあるビットフィールドに置き換えた値を返します。

(bit-field-replace-same #b111111 #b100100 1 4) ⇒ #b110101
Function: bit-field-rotate n count start end

[R7RS bitwise] {scheme.bitwise} n中のstartビット目(含む)からendビット目(含まない)までの ビットフィールドを、countビットだけ左にローテートした値を返します。 countが負の場合は-countビットだけ右にローテートします。

(bit-field-rotate #b110100100010000 -1 5 9)
 ⇒ 26768 ;#b110100010010000

(bit-field-rotate #b110100100010000 1 5 9)
 ⇒ 26672 ;#b110100000110000
Function: bit-field-reverse n start end

[R7RS bitwise] {scheme.bitwise} n中のstartビット目(含む)からendビット目(含まない)までの ビットフィールドを逆順にしたものを返します。

(bit-field-reverse #b10100111 0 8)
 ⇒ 229 ; #b11100101

ビット変換

Function: bits->list n :optional len
Function: bits->vector n :optional len

[R7RS bitwise] {scheme.bitwise} 非負整数nを、長さlenの真偽値からなるリストまたはベクタにして返します。 ビットはLSBから順に取り出されます。lenが省略された場合は (integer-length n)が使われます。

(bits->vector #b101101110)
  ⇒ #(#f #t #t #t #f #t #t #f #t)

註: SRFI-60にはinteger->listという似た手続きがありますが、 ビットの順番が逆です。

Function: list->bits bool-list
Function: vector->bits bool-vector

[R7RS bitwise] {scheme.bitwise} 真偽値のリストまたはベクタを受け取り、 LSBから対応するビットを詰めた正確な整数を返します。 返り値は負になることはありません。

(list->bits '(#f #t #t #t #f #t #t #f #t))
 ⇒ #b101101110

註: SRFI-60にはlist->integerという似た手続きがありますが、 ビットの順番が逆です。

Function: bits bool …

[R7RS bitwise] {scheme.bitwise} 真偽値boolの列をLSBから順にビットとして詰めた整数を返します。 返り値は負になることはありません。

(bits #f #t #t #t #f #t #t #f #t)
 ⇒ #b101101110

註: SRFI-60にはbooleans->integerという似た手続きがありますが、 ビットの順番が逆です。

Foldとunfoldとgenerate

Function: bitwise-fold kons knil n

[R7RS bitwise] {scheme.bitwise} 整数nのビットを、LSBから(integer-length n)ビット分、順に調べ、 各ビットを真偽値とみなした値とシード値にkonsを適用してゆきます。 konsの戻り値が次のシード値となり、最後のkonsの結果が返されます。

(bitwise-fold cons '() #b10110111)
 ⇒ (#t #f #t #t #f #t #t #t)
Function: bitwise-for-each proc n

[R7RS bitwise] {scheme.bitwise} 整数nの各ビットを真偽値とみなした値に対して、 LSBから順に(integer-length n)ビット分、procを適用してゆきます。 procの結果は捨てられます。

Function: bitwise-unfold p f g seed

[R7RS bitwise] {scheme.bitwise} 非負整数をLSBから順に1ビットづつ生成します。 seedは状態の値の初期値を与えます。 各繰り返しにおいて、pが現在の状態の値に適用され、 その結果が真ならば繰り返しは終了しbitwise-unfoldは蓄積されたビットを整数として 返します。 そうでなければ、fが現在の状態の値に適用され、 その結果が真の値なら対応するビットが1に、偽なら0になります。 次いでgが現在の状態の値に適用され、その結果が次の繰り返しにおける状態の値となります。

次の式は、nビット目が、nが素数なら1になっているような100ビット長の整数を返します。

(use math.prime)
(bitwise-unfold (cut = 100 <>)
                small-prime?
                (cut + 1 <>)
                0)
Function: make-bitwise-generator n

[R7RS bitwise] {scheme.bitwise} 整数nの各ビットをLSBから順に真偽値として生成するようなジェネレータを作って返します。 返されるジェネレータは無限です。

これはgauche.integerbits->generatorと似ていますが、 bits->generatorが作るジェネレータの方はninteger-lengthで止まります。 詳しくはgauche.generator - ジェネレータを参照してください。


10.3.23 scheme.fixnum - R7RS fixnum

Module: scheme.fixnum

このモジュールはfixnumに特化した操作を提供します。 SRFI-143として制定されました。

fixnumは絶対値が小さめの正確な整数で、極めて効率的に処理できます。 Gaucheのfixnumは、64ビット環境では62ビット、32ビット環境では30ビットの幅を持ちます。

このモジュールの手続きはfixnumの範囲でしか動作を定義されていませんが、 それを強制するのではないことに注意してください。fixnumでない引数を 渡したり、結果がfixnumの範囲外になった場合に何が起きるかは 処理系依存とされています。これらの手続きは、プログラマがその意図を コンパイラに伝えて最適化を期待するためのものと考えると良いでしょう。

現在のGaucheのアーキテクチャでは一般的な数値計算が効率よく実行できるようになっているので、 これらの手続きは対応する手続きの単なる別名になっています。 将来は、fixnum特有の最適化を導入するかもしれません。

手続きfixnum?は組み込みなのでここでは説明しません。 数値に関する述語を参照してください。

Variable: fx-width

[R7RS fixnum] {scheme.fixnum} 2^(w-1) - 1から-2^(w-1)までの正確な整数が全てfixnumであるような 最大の正整数wに束縛された変数です。 組み込み手続きfixnum-widthが返す値と同じです。 (数値の演算参照)。

Gaucheでは、これは通常32ビット環境で30、64ビット環境で62です。

Variable: fx-greatest
Variable: fx-least

[R7RS fixnum] {scheme.fixnum} 最大および最小のfixnumに束縛された変数です。これらの値は 組み込み手続きgreatest-fixnumおよびleast-fixnumが 返すものと同じです(数値の演算参照)。

次の表はGaucheでの典型的な値を示します。

Platformfx-greatestfx-least
32bit536,870,911-536,870,912
64bit2,305,843,009,213,693,951-2,305,843,009,213,693,952
Function: fx=? i …
Function: fx<? i …
Function: fx<=? i …
Function: fx>? i …
Function: fx>=? i …

[R7RS fixnum] {scheme.fixnum} これらは、fixnumのみに適用しなければならないことを除き、組み込みの =<<=>>=と同じです。

Function: fxzero? i
Function: fxpositive? i
Function: fxnegative? i
Function: fxodd? i
Function: fxeven? i

[R7RS fixnum] {scheme.fixnum} これらは、fixnumのみに適用しなければならないことを除き、組み込みの zero?positive?negative?odd?even?と同じです。

Function: fxmax i j …
Function: fxmin i j …

[R7RS fixnum] {scheme.fixnum} これらは、fixnumのみに適用しなければならないことを除き、組み込みの maxおよびminと同じです。

Function: fx+ i j
Function: fx- i j
Function: fx* i j

[R7RS fixnum] {scheme.fixnum} これらは、常に2つの引数を取ること、 fixnumのみに適用しなければならないこと、 そして結果がfixnumの範囲に収まる場合だけに使わなければならないことを除き、 組み込みの+-*と同じです。

Function: fxneg i

[R7RS fixnum] {scheme.fixnum} これは、fixnumのみに適用しなければならないこと、 そして結果がfixnumの範囲に収まる場合だけに使わなければならないことを除き、 組み込みの単項-と同じです。

Function: fxquotient i j
Function: fxremainder i j
Function: fxabs i
Function: fxsquare i

[R7RS fixnum] {scheme.fixnum} これらは、fixnumのみに適用しなければならないこと、 そして結果がfixnumの範囲に収まる場合だけに使わなければならないことを除き、 組み込みのquotientremainderabssquareと 同じです。

Function: fxsqrt i

[R7RS fixnum] {scheme.fixnum} これらは、fixnumのみに適用しなければならないことを除き、 exact-integer-sqrtと同じです。sqrtではありません。 数値の演算参照。

Function: fx+/carry i j k
Function: fx-/carry i j k
Function: fx*/carry i j k

[R7RS fixnum] {scheme.fixnum} これらはそれぞれ、まず (+ i j k)(- i j k)(+ (* i j) k)を計算し、 その結果をfixnumの範囲内に収まる剰余Rと、溢れQに分割して 2つの値として返します。 すなわち、(+ (* Q (expt 2 fx-width)) R)が上記計算と一致します。 QRは常にfixnumの範囲内であり、またR- 2^(w-1) <= R < 2^(w-1)を満たします。ただしwfx-widthです。

(fx*/carry 1845917459 19475917581 4735374)
 ⇒ -942551854601421179 and 8

(+ (* 8 (expt 2 fx-width)) -942551854601421179)
 ⇒ 35950936292817682053

(+ (* 1845917459 19475917581) 4735374)
 ⇒ 35950936292817682053

これらは拡張精度整数演算をfixnum手続き上に効率よく実装するためのプリミティブです。 ただ、Gaucheでは必要ならbignumを使えば良いので、これらは単に互換性のために提供しています。

Function: fxnot i
Function: fxand i …
Function: fxior i …
Function: fxxor i …
Function: fxarithmetic-shift i count
Function: fxlength i
Function: fxbit-count i
Function: fxcopy-bit index i boolean
Function: fxbit-set? index i
Function: fxbit-field i start end
Function: fxfirst-set-bit i

[R7RS fixnum] {scheme.fixnum} これらはfixnumのみに適用しなければならないことを除き、 組み込みのlognotlogandlogiorlogxorashinteger-lengthlogcountcopy-bitlogbit?bit-fieldtwos-exponent-factorとそれぞれ同じです。 詳しくは基本的なビット演算参照。

Function: fxif mask i j
Function: fxbit-field-rotate i start end
Function: fxbit-field-rotate i start end

[R7RS fixnum] {scheme.fixnum} これらはfixnumのみに適用しなければならないことを除き、 SRFI-60のbitwise-ifrotate-bit-fieldreverse-bit-fieldと同じです。 srfi.60 - 整数に対するビット操作参照。


10.3.24 scheme.flonum - R7RS flonum

Module: scheme.flonum

このモジュールはflonumに特化した操作を提供します。 SRFI-144として制定されました。

Gaucheでは、flonumはIEEE754倍精度浮動小数点数です。

このモジュールの手続きはflonumの範囲でしか動作を定義されていませんが、 それを強制するのではないことに注意してください。flonumでない引数を 渡した場合の動作は未定義です。これらの手続きは、プログラマがその意図を コンパイラに伝えて最適化を期待するためのものと考えると良いでしょう。

現在のGaucheのアーキテクチャでは一般的な数値計算が効率よく実行できるようになっているので、 これらの手続きは対応する手続きの単なる別名になっています。 将来は、flonum特有の最適化を導入するかもしれません。

手続きflonum?は組み込みなのでここでは説明しません。 数値に関する述語を参照してください。

定数

We also have a few constants in math.const module (see math.const - 定数).

Constant: fl-e

[R7RS flonum] {scheme.flonum} 自然対数の低e。

Gaucheのmath.constモジュールにも定数eがあります (math.const - 定数参照)。

Constant: fl-1/e

[R7RS flonum] {scheme.flonum} (/ e).

Constant: fl-e-2

[R7RS flonum] {scheme.flonum} (square e).

Constant: fl-e-pi/4

[R7RS flonum] {scheme.flonum} (expt e (/ pi 4)).

Constant: fl-log2-e

[R7RS flonum] {scheme.flonum} (log2 e) ((/ (log 2))と同じ)

Constant: fl-log10-e

[R7RS flonum] {scheme.flonum} (log10 e) ((/ (log 10))と同じ)

Constant: fl-log-2

[R7RS flonum] {scheme.flonum} (log 2).

Constant: fl-1/log-2

[R7RS flonum] {scheme.flonum} (/ (log 2)). (Same as (log2 e)).

Constant: fl-log-3

[R7RS flonum] {scheme.flonum} (log 3).

Constant: fl-log-pi

[R7RS flonum] {scheme.flonum} (log pi).

Constant: fl-log-10

[R7RS flonum] {scheme.flonum} (log 10).

Constant: fl-1/log-10

[R7RS flonum] {scheme.flonum} (/ (log 10)) ((log10 e)と同じ)

Constant: fl-pi

[R7RS flonum] {scheme.flonum} pi.

Constant: fl-1/pi

[R7RS flonum] {scheme.flonum} (/ pi).

Constant: fl-2pi

[R7RS flonum] {scheme.flonum} (* 2 pi).

Constant: fl-pi/2

[R7RS flonum] {scheme.flonum} (/ pi 2).

Constant: fl-pi/4

[R7RS flonum] {scheme.flonum} (/ pi 4).

Constant: fl-pi-squared

[R7RS flonum] {scheme.flonum} (square pi).

Constant: fl-degree

[R7RS flonum] {scheme.flonum} (/ pi 180).

Constant: fl-2/pi

[R7RS flonum] {scheme.flonum} (/ 2 pi).

Constant: fl-2/sqrt-pi

[R7RS flonum] {scheme.flonum} (/ 2 (sqrt pi)).

Constant: fl-sqrt-2

(sqrt 2).

Constant: fl-sqrt-3

[R7RS flonum] {scheme.flonum} (sqrt 3).

Constant: fl-sqrt-5

[R7RS flonum] {scheme.flonum} (sqrt 5).

Constant: fl-sqrt-10

[R7RS flonum] {scheme.flonum} (sqrt 10).

Constant: fl-1/sqrt-2

[R7RS flonum] {scheme.flonum} (/ (sqrt 2)).

Constant: fl-cbrt-2

[R7RS flonum] {scheme.flonum} (expt 2 1/3).

Constant: fl-cbrt-3

[R7RS flonum] {scheme.flonum} (expt 3 1/3).

Constant: fl-4thrt-2

[R7RS flonum] {scheme.flonum} (expt 2 1/4).

Constant: fl-phi

[R7RS flonum] {scheme.flonum} (/ (+ 1 (sqrt 5)) 2).

Constant: fl-log-phi

[R7RS flonum] {scheme.flonum} (log fl-phi).

Constant: fl-1/log-phi

[R7RS flonum] {scheme.flonum} (/ (log fl-phi)).

Constant: fl-euler

[R7RS flonum] {scheme.flonum} Euler’s constant.

Constant: fl-e-euler

[R7RS flonum] {scheme.flonum} (exp fl-euler)

Constant: fl-sin-1

[R7RS flonum] {scheme.flonum} (sin 1)

Constant: fl-cos-1

[R7RS flonum] {scheme.flonum} (cos 1)

Constant: fl-gamma-1/2

[R7RS flonum] {scheme.flonum} (gamma 1/2)

Constant: fl-gamma-1/3

[R7RS flonum] {scheme.flonum} (gamma 1/3)

Constant: fl-gamma-2/3

[R7RS flonum] {scheme.flonum} (gamma 2/3)

Constant: fl-gamma-1/3

[R7RS flonum] {scheme.flonum} (gamma 1/3)

Constant: fl-greatest
Constant: fl-least

[R7RS flonum] {scheme.flonum} 最大/最小の正の有限な浮動小数点数に束縛されています。 これらは、Gaucheの組み込み手続き greatest-positive-flonumおよび least-positive-flonumが返す値とそれぞれ同じです (数値の比較参照)。

Constant: fl-epsilon

[R7RS flonum] {scheme.flonum} Gaucheの(flonum-epsilon)と同じです。 (数値の比較参照)。

Constant: fl-fast-fl+*

[R7RS flonum] {scheme.flonum} これが#tを返した場合、(fl+* x y z)(fl+ (fl* x y) z)と同等の速度、もしくはより速く実行されます。

Constant: fl-integer-exponent-zero
Constant: fl-integer-exponent-nan

[R7RS flonum] {scheme.flonum} これらは、flinteger-exponentが特別な場合に返し得る正確な整数値です。 値そのものに意味はなく、flinteger-exponentの結果と比較するために使われます。

flinteger-exponentは引数が0の時fl-integer-exponent-zeroを、 引数が+nan.0の時fl-integer-exponent-nanを返します。

コンストラクタ

Function: flonum number

[R7RS flonum] {scheme.flonum} numberと等しいflonum、もしくは等しい値がflonumで表現可能でなければもっとも近い flonumを返します。

numberが実数でなければ+nan.0が返されます (これはSRFI-144で推奨されている動作ですが、処理系によってはエラーを投げても良いことに なっているので、ポータブルなコードを書くときは注意してください。)

Function: fladjacent x y

[R7RS flonum] {scheme.flonum} flonum xからyの方向に1最小単位だけ進めたflonumを返します。 x = yなら、xそのものが返されます。

(fladjacent 1.0 2.0) ⇒ 1.0000000000000002
(fladjacent 1.0 0.0) ⇒ 0.9999999999999999
Function: flcopysign x y

[R7RS flonum] {scheme.flonum} 絶対値が(abs x)と同じで、符号がyと同じであるようなflonumを返します。

Function: make-flonum x n

[R7RS flonum] {scheme.flonum} (* x (expt 2 n))なるflonumを返します。 Gaucheのldexpと同じです (数値の変換参照)。

アクセサ

Function: flinteger-fraction x

[R7RS flonum] {scheme.flonum} flonum xの整数部と小数部をそれぞれflonumとして返します。 Gaucheのmodfと同じです (数値の変換参照)。

x+inf.0なら、+inf.00.0が、 x-inf.0なら、-inf.0-0.0が、 そしてx+nan.0なら、+nan.0+nan.0が返されます。 (この動作はSRFI-144では指定されていません。GaucheはPOSIXのmodfの動作に 準じています)。

(flinteger-fraction fl-pi)
 ⇒ 3.0 and 0.14159265358979312
Function: flexponent x

[R7RS flonum] {scheme.flonum} flonum xの指数部をflonumとして返します。xがゼロでない有限値なら、 結果は整数です。

xがゼロなら、-inf.0が、 xが無限大なら、+inf.0が返されます。

(flexponent 1.0)    ⇒ 0.0
(flexponent 1024.0) ⇒ 10.0
(flexponent 0.01)   ⇒ -7.0
(flexponent fl-least) ⇒ -1074.0
Function: flinteger-exponent x

[R7RS flonum] {scheme.flonum} flexponentと同様にxの指数部を返しますが、こちらは正確な整数を返します。

xがゼロの場合、定数fl-integer-exponent-zeroが返されます。 xが無限大の場合、非常に大きな正確な整数 ((ldexp 1 (flinteger-exponent +inf.0))+inf.0になるような 値)が返されます。 x+nan.0の場合、定数fl-integer-exponent-nanが返されます。

Function: flnormalized-fraction-exponent x

[R7RS flonum] {scheme.flonum} flonum xの正規化された仮数部 (符号はxと同じ)をflonumで、 およびxの指数部を正確な整数で2つの返り値として返します。 それらをynとすれば、x = (* y (expt 2 n))であり、 x = (ldexp y n)となります。 この手続きはGaucheのfrexpと同じです(数値の変換参照)。

xがゼロでない有限の値ならば、 最初の返り値は0.5以上で1.0より小さな値になります。 コーナーケースについてはSRFI-144では規程されていませんが、Gaucheは frexpの仕様に沿って、次のようにしています。 x0.0(か-0.0)なら、結果は0.0(か-0.0)と0xが無限大なら、同じ符号の無限大と0x+nan.0なら、+nan.00

(flnormalized-fraction-exponent 12345.6789)
  ⇒ 0.7535204406738282 and 14
(make-flonum 0.7535204406738282 14)
  ⇒ 12345.6789
Function: flsign-bit x

[R7RS flonum] {scheme.flonum} xが正もしくは0.0なら0を、 負もしくは-0.0なら1を返します。 (flsign-bit +nan.0)は実装依存です。

ビット値でなく符号が欲しい場合、flsgnも使えます。

述語

(註: flonum?は組み込みです。数値に関する述語参照)。

Function: fl=? x y z …
Function: fl<? x y z …
Function: fl>? x y z …
Function: fl<=? x y z …
Function: fl>=? x y z …

[R7RS flonum] {scheme.flonum} flonum専用の比較関数です。それぞれ =<><=>=に対応します。

今のところGaucheではこれらは単に汎用の比較関数の別名となっています。 なのでflonum以外の数値が渡されても動作しますが、そうすることはポータブルではありません。 これらの関数の意図は、将来的にコンパイラに型についてのヒントを与え 最適化を可能にすることです。

-0.00.0は数値比較においては等しいものと扱われることに 注意してください。(fl<? -0.0 0.0)#fになります。

引数に+nan.0がひとつでもあれば、結果は常に#fとなります。

Function: flunordered? x y

[R7RS flonum] {scheme.flonum} xyの少なくとも一方が+nan.0であれば#tを、 そうでなければ#fを返します。

Function: flinteger? x

[R7RS flonum] {scheme.flonum} xが整数のflonumであれば#tを、 そうでなければ#fを返します。

Function: flzero? x
Function: flpositive? x
Function: flnevative? x

[R7RS flonum] {scheme.flonum} flonum専用のzero?positive?negative?です。 (flnegative? -0.0)#fであることに注意してください。 負のゼロを普通のゼロと見分けるにはflsign-bitflsgnを使います。

Function: flodd? x
Function: fleven? x

[R7RS flonum] {scheme.flonum} flonum専用のodd?even?です。 xが整数でなければエラーが投げられます。

Function: flfinite? x
Function: flinfinite? x
Function: flnan? x

[R7RS flonum] {scheme.flonum} それぞれflonum専用のfinite?infinite?nan?です (数値に関する述語参照)。

Function: flnormalized? x
Function: fldenormalized? x

[R7RS flonum] {scheme.flonum} それぞれ、xが正規化浮動小数点数、非正規化浮動小数点数の場合に #tを返し、そうでなければ#fを返します。

演算

Function: flmax x …
Function: flmin x …

[R7RS flonum] {scheme.flonum} flonum専用のminmaxです。汎用のminmaxと 異なり、引数がゼロ個でもエラーにならず、それぞれ-inf.0+inf.0が返されます。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: fl+ x …
Function: fl* x …

[R7RS flonum] {scheme.flonum} flonum専用の+.-.です (数値の演算参照)。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: fl+* x y z

[R7RS flonum] {scheme.flonum} (+ (* x y) z)の値を返しますが、 プラットフォームによってはより速く正確な結果を返します。 Gaucheは内部的にはC99のfmaを呼んでいます。 「より正確」というのは、乗算と加算が一度に行われ、丸めが最後に1回だけ起きることを 指します。

註: 0.9.8リリース時点で、MinGWのfma実装は 乗算と加算それぞれに丸めが入るようになっているので、 しばしばわずかにずれた結果を返します。

Function: fl- x y …
Function: fl- x y …

[R7RS flonum] {scheme.flonum} flonum専用の-./.です (数値の演算参照)。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: flabs x

[R7RS flonum] {scheme.flonum} flonum専用のabsです (数値の演算参照)。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: flabsdiff x y

[R7RS flonum] {scheme.flonum} (abs (- x y))を返します。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: flposdiff

[R7RS flonum] {scheme.flonum} (max (- x y) 0)を返します。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: flsgn x

[R7RS flonum] {scheme.flonum} xの符号ビットが0 (ゼロまたは正)なら1.0を、 1 (負および負のゼロ)の場合は-1.0を返します。 (flcopysign 1.0 x)(if (zero? (flsign-bit x)) 1.0 -1.0) と考えることもできます。 (flsgn 0.0)の結果は1.0(flsng -0.0)の結果は-1.0です。 +nan.0を渡した場合の結果は実装上NaNの符号ビットがどうなっているかに よるので、結果は1.0-1.0かのいずれかになりますが、 どちらになるかはっきりしたことは言えません。

符号つきflonumではなく符号ビットそのものを取り出すにはflsign-bitが使えます。

Function: flnumerator x
Function: fldenominator x

[R7RS flonum] {scheme.flonum} flonum専用のnumeratordenominatorです (数値の演算参照)。

無限大とゼロのdenominatorは1.0になります。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

Function: flfloor x
Function: flceiling x
Function: flround x
Function: fltruncate x

[R7RS flonum] {scheme.flonum} flonum専用のfloorceilingroundtruncateです (数値の演算参照)。

引数がflonumかどうかはチェックしていませんが、flonum以外の引数を渡すことは ポータブルではありません。

指数対数関数

Function: flexp x

[R7RS flonum] {scheme.flonum} flonum専用のexpです (数値の演算参照)。 (expt fl-e x)を返します。

Function: flexp2 x

[R7RS flonum] {scheme.flonum} (expt 2 x)を返します。

Function: flexp-1 x

[R7RS flonum] {scheme.flonum} (- 1 (expt fl-e x))を返しますが、xが小さい場合はより正確です。 内部的にはCのexpm1を呼んでいます。

Function: flsquare x

[R7RS flonum] {scheme.flonum} (*. x x)を返します。

Function: flsqrt x

[R7RS flonum] {scheme.flonum} flonum専用のsqrtです。

Function: flcbrt x

[R7RS flonum] {scheme.flonum} flonum xの3乗根を返します。

Function: flhypot x y

[R7RS flonum] {scheme.flonum} (sqrt (* x x) (* y y))を計算しますが、 中間結果でオーバーフローやアンダーフローが起きないように配慮されています。

Function: flexpt x y

[R7RS flonum] {scheme.flonum} flonum専用のexptです(数値の演算参照)。

Function: fllog x

[R7RS flonum] {scheme.flonum} flonum専用のlogです(数値の演算参照)。

Function: fllog1+ x

[R7RS flonum] {scheme.flonum} (log (+ x 1))を返しますが、xがゼロに近い場合により正確です。

Function: fllog2 x
Function: fllog10 x

[R7RS flonum] {scheme.flonum} flonum xの2および10を底とする対数を返します。

Function: make-fllog-base x

[R7RS flonum] {scheme.flonum} xを底とする対数を計算する手続きを返します。xが1.0より大きい実数でない 場合はエラーが投げられます。

(define log5 (make-fllog-base 5.0))

(log5 25.0) ⇒ 5.0

三角関数

Function: flsin x
Function: flcos x
Function: fltan x
Function: flasin x
Function: flacos x
Function: flatan x
Function: flatan y x
Function: flsinh x
Function: flcosh x
Function: fltanh x
Function: flasinh x
Function: flacosh x
Function: flatanh x

[R7RS flonum] {scheme.flonum} それぞれ、flonum専用の sin, cos, tan, asin, acos, sinh, cosh, tanh, asinh, acosh, atanhです (数値の演算参照)。

flatanは1つまたは2つの引数を取ります。(flatan y x)(flatan (/ y x))を計算します (が、より正確です)。

整数除算

Function: flquotient x y

[R7RS flonum] {scheme.flonum} (fltruncate (fl/ x y)) を返します。

結果は常に整数のflonumになります。引数xyは整数である必要はありません。

(flquotient 14.0 4.0)  ⇒ 3.0
(flquotient -14.0 4.0) ⇒ -3.0
(flquotient 14.0 2.5)  ⇒ 5.0
(flquotient -14.2 2.8) ⇒ -5.0
Function: flremainder x y

[R7RS flonum] {scheme.flonum} (- x (* y (flquotient x y)))を返します。

(flquotient 14.0 4.0)  ⇒ 2.0
(flquotient -14.0 4.0) ⇒ -2.0
(flquotient 14.0 2.5)  ⇒ 1.5
(flquotient -14.2 2.8) ⇒ -0.1999999999999993 ; inexact calculation
Function: flremquo x y

[R7RS flonum] {scheme.flonum} 二つの値を返します:

  • xyで割った余り。 ((flremainder x y)と同じですが、異なる計算方法を使うので 最後のビットで差が出るかもしれません)。
  • 2^n (n >= 3) を法とする、x割るyの商。 正確な整数で、x/yと同じ符号を持ちます。

これはC99のremquoに相当します。

周期関数の入力を対称性を使って絞る時に便利です。

特殊関数

Function: flgamma x

[R7RS flonum] {scheme.flonum} flonum xのガンマ関数を計算します。 xが整数の時は、x-1の階乗と一致します。

これはGauche組み込みのgammaと同じです (数値の演算参照)。

Function: flloggamma x

[R7RS flonum] {scheme.flonum} (log (abs (flgamma x)))の値および、(flgamma x)の符号 (正の場合は1.0、負の場合は-1.0)の二つの値を返します。

最初の値はGauche組み込みのlgammaで計算されます (数値の演算参照)。 これはgammaを計算してlogを取るより正確です。 なお、x-inf.0+nan.0の場合、二番目の値は+nan.0になります。

Function: flfirst-bessel n x

[R7RS flonum] {scheme.flonum} n階の第1種ベッセル関数の値を返します。

Function: flsecond-bessel n x

[R7RS flonum] {scheme.flonum} n階の第2種ベッセル関数の値を返します。

Function: flerf x

[R7RS flonum] {scheme.flonum} 誤差関数erfです。

Function: flerfc x

[R7RS flonum] {scheme.flonum} 1 - erf(x) を計算します。


10.3.25 scheme.bytevector - R7RSバイトベクタ

Module: scheme.bytevector

このモジュールはR6RSの(rnrs bytevectors)からの輸入です (R7RSのライブラリ名は単数形であることに注意)。

Gaucheでは「バイトベクタ」はu8vectorです。

以下の手続きはgauche.uvectorのものと同じです。 詳しくはバイトベクタ互換性を参照してください。

bytevector?        make-bytevector     bytevector-length
bytevector=?       bytevector-fill!    bytevector-copy
bytevector-u8-ref  bytevector-u8-set!  bytevector-s8-ref
bytevector-s8-set! bytevector->u8-list u8-list->bytevector

以下の手続きはgauche.unicodeのものと同じです。 詳しくはgauche.unicode - Unicodeユーティリティを参照してください。

string->utf8       string->utf16       string->utf32
utf8->string       utf16->string       utf32->string

このモジュールはbytevector-copy!をexportしていますが、 R7RS baseおよびgauche.unicodeに含まれる同名の手続きと引数の順序が異なります。 gauche.uvectorbytevector-copy!-r6として定義されているものと 同じになります(バイトベクタ互換性参照)。

Macro: endianness symbol

[R7RS bytevector] symbolがエンディアンを示すシンボルであればそれをそのまま返し、 そうでなければマクロ展開時にエラーを投げます。 エラーを早期に検出するのに役立ちます。 また、シンボルがエンディアンを示すという意図を明確にできます。

有効なシンボルはエンディアンネスを参照してください。 biglittleだけがポータブルです。

Function: native-endianness

[R7RS bytevector] システムのネイティブなエンディアンを示すシンボルを返します。 Gauche組み込みのnative-endianと同じです(エンディアンネス参照)。

Function: bytevector-uint-ref bv pos endian size
Function: bytevector-sint-ref bv pos endian size

[R7RS bytevector] u8vector bvの、pos番めのオクテットからsizeオクテットを、 それぞれ符号なしと符号あり整数として読み取ります。 binary.ioモジュールのget-uintget-sintに似ていますが、 引数の順序は異なります。

endianにはエンディアンを示すシンボルを渡します。 bitlittleのみがポータブルに使えます。

Function: bytevector-uint-set! bv pos val endian size
Function: bytevector-sint-set! bv pos val endian size

[R7RS bytevector] それぞれ、符号なし、および符号つき整数valをu8vector bvpos番目のオクテットからsizeオクテットにわたって格納します。 binary.ioput-uint!およびput-sint!と 引数の順序以外は同じです。

endian引数には、Gaucheが許すエンディアンを示すシンボルなら何でも渡せますが、 ポータブルなコードで使えるのはbiglittleだけです。

Function: bytevector->uint-list bv endian size
Function: bytevector->sint-list bv endian size

[R7RS bytevector] u8vector bvからsizeオクテットづつ取り出し、それをそれぞれ符号なし、 および符号つき整数と解釈して、その整数のリストを返します。 bvの長さがsizeの整数倍でなければエラーが投げられます。

endian引数には、Gaucheが許すエンディアンを示すシンボルなら何でも渡せますが、 ポータブルなコードで使えるのはbiglittleだけです。

Function: uint-list->bytevector lis endian size
Function: sint-list->bytevector lis endian size

[R7RS bytevector] lisはそれぞれ符号なしまたは符号つき整数のリストでなければなりません。 (* size (length lis))のu8vectorが作られて、 先頭からsizeオクテットごとに、リストの整数が詰められてゆきます。 そしてそのu8vectorが返されます。

endian引数には、Gaucheが許すエンディアンを示すシンボルなら何でも渡せますが、 ポータブルなコードで使えるのはbiglittleだけです。

Function: bytevector-u16-ref bv k endian
Function: bytevector-s16-ref bv k endian
Function: bytevector-u32-ref bv k endian
Function: bytevector-s32-ref bv k endian
Function: bytevector-u64-ref bv k endian
Function: bytevector-s64-ref bv k endian
Function: bytevector-ieee-single-ref bv k endian
Function: bytevector-ieee-double-ref bv k endian

[R7RS bytevector] u8vector bvkバイト目から所定のバイト数を、endianで指定された バイトオーダーを使って、数値として読み取ります。 これらは引数が全て必須なのを除けば、 Gaucheのbinary.ioにあるget-u16 …と同じです (ieee-singleieee-doublef32f64に相当します)。 詳しくはbinary.io - バイナリI/Oを参照してください。

endian引数には、Gaucheが許すエンディアンを示すシンボルなら何でも渡せますが、 ポータブルなコードで使えるのはbiglittleだけです。

Function: bytevector-u16-native-ref bv k
Function: bytevector-s16-native-ref bv k
Function: bytevector-u32-native-ref bv k
Function: bytevector-s32-native-ref bv k
Function: bytevector-u64-native-ref bv k
Function: bytevector-s64-native-ref bv k
Function: bytevector-ieee-single-native-ref bv k
Function: bytevector-ieee-double-native-ref bv k

[R7RS bytevector] システムのネイティブバイトオーダーを使うこと以外は bytevector-u16-ref …と同じです。

Function: bytevector-u16-set! bv k val endian
Function: bytevector-s16-set! bv k val endian
Function: bytevector-u32-set! bv k val endian
Function: bytevector-s32-set! bv k val endian
Function: bytevector-u64-set! bv k val endian
Function: bytevector-s64-set! bv k val endian
Function: bytevector-ieee-single-set! bv k val endian
Function: bytevector-ieee-double-set! bv k val endian

[R7RS bytevector] 数値をu8vector bvkバイト目から所定のバイト数ぶん、 endianで指定されたバイトオーダーを使って、格納します。 これらは引数が全て必須なのを除けば、 Gaucheのbinary.ioにあるput-u16! …と同じです (ieee-singleieee-doublef32f64に相当します)。 詳しくはbinary.io - バイナリI/Oを参照してください。

endian引数には、Gaucheが許すエンディアンを示すシンボルなら何でも渡せますが、 ポータブルなコードで使えるのはbiglittleだけです。

Function: bytevector-u16-native-set! bv k val
Function: bytevector-s16-native-set! bv k val
Function: bytevector-u32-native-set! bv k val
Function: bytevector-s32-native-set! bv k val
Function: bytevector-u64-native-set! bv k val
Function: bytevector-s64-native-set! bv k val
Function: bytevector-ieee-single-native-set! bv k val
Function: bytevector-ieee-double-native-set! bv k val

[R7RS bytevector] システムのネイティブバイトオーダーを使うこと以外は bytevector-u16-set! …と同じです。


10.3.26 scheme.show - R7RS combinator formatting

Module structure

Module: scheme.show

Exports bindings of R7RS (scheme show) library. From R7RS programs, those bindings are available by (import (scheme show)).

scheme.show is a combination of submodules scheme.show.base, scheme.show.color, scheme.show.columnar and scheme.show.unicode.

Module: scheme.show.base

Exports bindings of R7RS (scheme show base) library. From R7RS programs, those bindings are available by (import (scheme show base)).

This contains most combinator formatting procedures.

Module: scheme.show.color

Exports bindings of R7RS (scheme show color) library. From R7RS programs, those bindings are available by (import (scheme show color)).

This contains formatters to color text using ANSI escape codes.

Module: scheme.show.columnar

Exports bindings of R7RS (scheme show columnar) library. From R7RS programs, those bindings are available by (import (scheme show columnar)).

This contains formatters to help format in columns.

Module: scheme.show.unicode

Exports bindings of R7RS (scheme show unicode) library. From R7RS programs, those bindings are available by (import (scheme show unicode)).

Usage

Combinator formatting provides a functionality similar to format from SRFI-28. But instead of writing a template string, you can use S-expressions, which are called “formatters”. It’s also extensible.

The two main concepts in combinator formatting are formatters and states. Formatters are procedures that specify how or what you want to output. Formatters can be composed to produce complex format. Normal types are also accepted where a procedure takes a formatter, they are formatted with displayed.

Format states let us customize control formatting, for example how many precision digits, what character for padding …. Format states can be changed locally with with or with!.

The entry point to combinator formatting is show, which takes a sequence of formatters and outputs to a port or returns a string.

Function: show output-dest fmt

[R7RS show base] {scheme.show.base} This is the main entry for combinator formatting. All formatters are processed to produce a string to output-dest if it’s a port. If output-dest is #t, the current output port is used. If output-dest is #f, the output string is returned. show return value is otherwise undefined. Non-formatters are also accepted and will be wrapped in displayed formatter.

(show #f "π = " (with ((precision 2)) (acos -1)) nl)
⇒ "π = 3.14\n"

Formatting Objects

Function: displayed obj

[R7RS show base] {scheme.show.base} The formatter that formats the object obj the same as display. This is the default formatter when you pass an object to show.

Function: written obj

[R7RS show base] {scheme.show.base} The formatter that formats the object obj the same as write. Formatting settings numeric and precision are respected for relevant number types as long as the result can still be passed to read.

Function: written-simply obj

[R7RS show base] {scheme.show.base} Similar to written but does not handle shared structures.

Function: pretty obj

[R7RS show base] {scheme.show.base} Pretty prints an object.

Function: pretty-simply obj

[R7RS show base] {scheme.show.base} Similar to pretty but does not handle shared structures.

Function: escaped str [quote-ch esc-ch renamer]

[R7RS show base] {scheme.show.base} Prints a string, adding esc-ch (#\\ by default) in front of all quote-ch (#\" by default).

If esc-ch is #f, escape all quote-ch by doubling it.

If renamer is specified, it’s a procedure that takes one character and returns another character or #f. It serves two purposes: to allow quoting more than one character and to replace them with something else. If the procedure returns #f, the character in question is not escaped. Otherwise the character is escaped and replaced with a new one.

esc-ch could also be a string, but this is Gauche specific behavior.

(show #t (escaped "hello \"world\"")) ⇒ hello \"world\"
(show #t (escaped "hello \"world\"" #\l)) ⇒ he\l\lo "world"
(show #t (escaped "hello \"world\"" #\l #\x)) ⇒ hexlxlo "worxld"
(show #t (escaped "hello \"world\""
                  #\e #f
                  (lambda (x) (if (char=? x #\o) #\O #f))))
⇒ heelleO "weOrld"
Function: maybe-escaped str pred [quote-ch esc-ch renamer]

[R7RS show base] {scheme.show.base} Determines if str needs to be escaped or not. If true, the string is wrapped with quote-ch. The original string is escaped with escaped.

The string needs to be escaped if any quote-ch or esc-ch is present, or any character that makes pred return #t.

(show #t (maybe-escaped "helloworld" char-whitespace?)) ⇒ helloworld
(show #t (maybe-escaped "hello world" char-whitespace?)) ⇒ "hello world"
(show #t (maybe-escaped "hello \"world\"" char-whitespace? #\")) ⇒ "hello \"world\""

Formatting Numbers

Function: numeric num [radix precision sign-rule comma-rule comma-sep decimal-sep]

[R7RS show base] {scheme.show.base} Formats a number. The default values are from state variables below.

(show #f (numeric 1000)) ⇒ "1000"
(show #f (numeric 1000 8)) ⇒ "1750"
(show #f (numeric 1000 8 2)) ⇒ "1750.00"
(show #f (numeric 1000 8 2 #t)) ⇒ "+1750.00"
(show #f (numeric -1000 8 2 (cons "(" ")"))) ⇒ "(1750.00)"
(show #f (numeric 1000 8 2 #t 2)) ⇒ "+17,50.00"
(show #f (numeric 1000 8 2 #t 2 #\')) ⇒ "+17'50.00"
(show #f (numeric 1000 8 2 #t 2 #\' #\:)) ⇒ "+17'50:00"
Function: numeric/comma num [radix precision sign-rule]

[R7RS show base] {scheme.show.base} Formats a number with default comma-rule 3. See numeric for details.

(show #f (numeric/comma 1000)) ⇒ "1,000"
(show #f (with ((comma-sep #\.)) (numeric/comma 1000))) ⇒ "1.000"
Function: numeric/si num [base separator]

[R7RS show base] {scheme.show.base} Formats a numeric with SI suffix. The default base is 1024 and uses suffix names like Ki, Mi, Gi…. Other bases (e.g. 1000) use suffixes k, M, G…. If separator is specified, it’s inserted between the number and suffix.

(show #f (numeric/si 1024)) ⇒ "1Ki"
(show #f (numeric/si 200000 1000)) ⇒ "200k"
(show #f (numeric/si 1024 1024 #\/)) ⇒ "1/Ki"
Function: numeric/fitted width n [arg …]

[R7RS show base] {scheme.show.base} Like numeric but if the result does not fit in width characters with current precision, outputs a string of hashes instead of the truncated and incorrect number.

(show #f (with ((precision 2)) (numeric/fitted 4 1.25))) ⇒ "1.25"
(show #f (with ((precision 2)) (numeric/fitted 4 12.345))) ⇒ "#.##"

Formatting Space

Variable: nl

Outputs a newline.

(show #f nl) ⇒ "\n"
Variable: fl

Short for “fresh line”, make sures the following output is at the beginning of the line.

(show #f fl) ⇒ ""
(show #f "aaa" fl) ⇒ "aaa\n"
Variable: nothing

Outputs nothing. This is useful in combinators as default no-op in conditionals.

Function: space-to column

[R7RS show base] {scheme.show.base} Appends pad-char to reach the given column.

(show #f "abcdef" (space-to 3) "a") ⇒ "   a"
(show #f "abcdef" (space-to 3) "a") ⇒ "abcdefa"
Function: tab-to [tab-width]

[R7RS show base] {scheme.show.base} Outputs pad-char to reach the next tab stop.

Concatenation

Function: each fmt

[R7RS show base] {scheme.show.base}

Function: each-in-list list-of-fmts

[R7RS show base] {scheme.show.base}

Function: joined mapper list [sep]

[R7RS show base] {scheme.show.base} Formats each element in list with mapper and inserts sep in between. sep by default is an empty string, but it could be any string or formatter.

(show #f (joined displayed (list "a" "b") " ")) ⇒ "a b"
(show #f (joined displayed (list "a" "b") nl)) ⇒ "a\nb"
Function: joined/prefix mapper list [sep]

[R7RS show base] {scheme.show.base} Similar to joined except the separator is inserted before every element.

(show #f (joined/prefix displayed '(usr local bin) "/")) ⇒ "/usr/local/bin"
Function: joined/suffix mapper list [sep]

[R7RS show base] {scheme.show.base} Similar to joined except the separator is inserted after every element.

(show #f (joined/suffix displayed '(1 2 3) nl)) ⇒ "1\n2\n3\n"
Function: joined/last mapper last-mapper list [sep]

[R7RS show base] {scheme.show.base} Similar to joined but last-mapper is used on the last element of list instead.

(show #f (joined/last displayed
                      (lambda (last) (each "and " last))
                      '(lions tigers bears)
                      ", "))
⇒ "lions, tigers, and bears"
Function: joined/dot mapper dot-mapper list [sep]

[R7RS show base] {scheme.show.base} Similar to joined but if list is a dotted list, then formats the dotted value with dot-mapper instead.

Function: joined/range mapper start [end sep]

[R7RS show base] {scheme.show.base}

Padding and Trimming

Function: padded width fmt

[R7RS show base] {scheme.show.base} Pads the output of fmt… on the left side with pad-char if it’s shorter than width characters.

(show #f (padded 10 "abc")) ⇒ "       abc"
(show #f (with ((pad-char #\-)) (padded 10 "abc"))) ⇒ "-------abc"
Function: padded/right width fmt

[R7RS show base] {scheme.show.base} Similar to padded but except padding is on the right side instead.

Function: padded/both width fmt

[R7RS show base] {scheme.show.base} Similar to padded but except padding is on both sides, keeping the fmt output at the center.

Function: trimmed width fmt

[R7RS show base] {scheme.show.base} Trims the output of fmt… on the left so that the length is width characters or less. If ellipsis state variable is defined, it will be put on the left to denote trimming.

(show #f (trimmed 5 "hello world")) ⇒ "world"
(show #f (with ((ellipsis "..")) (trimmed 5 "hello world"))) ⇒ "..rld"
Function: trimmed/right width fmt

[R7RS show base] {scheme.show.base} Similar to trimmed but the trimming is on the right.

Function: trimmed/both width fmt

[R7RS show base] {scheme.show.base} Similar to trimmed but the trimming is on both sides, keeping the center of the output.

Function: trimmed/lazy width fmt

[R7RS show base] {scheme.show.base} A variant of trimmed which generates each fmt in left to right order, and truncates and terminates immediately if more than width characters are generated. Thus this is safe to use with an infinite amount of output, e.g. from written-simply on an infinite list.

Function: fitted width fmt

[R7RS show base] {scheme.show.base} A combination of padded and trimmed, ensures the output width is exactly width, truncating if it goes over and padding if it goes under.

Function: fitted/right width fmt

[R7RS show base] {scheme.show.base} A combination of padded/right and trimmed/right, ensures the output width is exactly width, truncating if it goes over and padding if it goes under.

Function: fitted/both width fmt

[R7RS show base] {scheme.show.base} A combination of padded/both and trimmed/both, ensures the output width is exactly width, truncating if it goes over and padding if it goes under.

Columnar Formatting

Function: columnar column

[R7RS show columnar] {scheme.show.columnar}

Function: tabular column

[R7RS show columnar] {scheme.show.columnar}

Function: wrapped fmt

[R7RS show columnar] {scheme.show.columnar}

Function: wrapped/list list-of-strings

[R7RS show columnar] {scheme.show.columnar}

Function: wrapped/char fmt

[R7RS show columnar] {scheme.show.columnar}

Function: justified format

[R7RS show columnar] {scheme.show.columnar}

Function: from-file pathname

[R7RS show columnar] {scheme.show.columnar}

Function: line-numbers [start]

[R7RS show columnar] {scheme.show.columnar}

Colors

Function: as-red fmt
Function: as-blue fmt
Function: as-green fmt
Function: as-cyan fmt
Function: as-yellow fmt
Function: as-magenta fmt
Function: as-white fmt
Function: as-black fmt
Function: as-bold fmt
Function: as-underline fmt

[R7RS show color] {scheme.show.color} Outputs the ANSI escape code to make all fmt… a given color or style.

Unicode

Function: as-unicode fmt

[R7RS show unicode] {scheme.show.unicode}

Function: unicode-terminal-width str

[R7RS show unicode] {scheme.show.unicode}

Higher Order Formatters and State

Function: fn ((id state-var) …) exprfmt

[R7RS show base] {scheme.show.base} This is short for “function” and the analog to lambda. It returns a formatter which on application evaluates each expr and fmt in left-to-right order, in a lexical environment extended with each identifier id bound to the current value of the state variable named by the symbol state-var. The result of the fmt is then applied as a formatter.

As a convenience, any (id state-var) list may be abbreviated as simply id, indicating id is bound to the state variable of the same (symbol) name.

Function: with ((state-var value) …) fmt

[R7RS show base] {scheme.show.base} This is the analog of let. It temporarily binds specified state variables with new values for fmt ….

Function: with! (state-var value) fmt

[R7RS show base] {scheme.show.base} Similar to with but the value updates persist even after with!.

Function: forked fmt1 fmt2

[R7RS show base] {scheme.show.base} Calls fmt1 on (a conceptual copy of) the current state, then fmt2 on the same original state as though fmt1 had not been called (i.e. any potential state mutation by fmt1 does not affect fmt2).

Function: call-with-output formatter mapper

[R7RS show base] {scheme.show.base} A utility, calls formatter on a copy of the current state (as with forked), accumulating the results into a string. Then calls the formatter resulting from (mapper result-string) on the original state.

Standard State Variables

Variable: port

The current port output is written into, could be overriden to capture intermediate output.

Variable: row

The current row of the output.

Variable: col

The current column of the output.

Variable: width

The current line width, used for wrapping, pretty printing and columnar formatting.

Variable: output

The underlying standard formatter for writing a single string.

The default value outputs the string while tracking the current row and col. This can be overridden both to capture intermediate output and perform transformations on strings before outputting, but should generally wrap the existing output to preserve expected behavior.

Variable: writer

The mapper for automatic formatting of non-string/char values in top-level show, each and other formatters. Default value is implementation-defined.

Variable: string-width

A function of a single string. It returns the length in columns of that string, used by the default output.

Variable: pad-char

The character used for by padding formatters, #\space by default

Variable: ellipsis

The string used when truncating as described in trimmed.

Variable: radix

The radix for numeric output, 10 by default. Valid values are from 2 to 36.

Variable: precision

The number of digits written after the decimal point for numeric output. The value is rounded if the numeric value written out requires more digits than requested precision. See the SRFI for exact rounding behavior.

Variable: sign-rule

If #t, always output the plus sign + for positive numbers. If sign-rule is a par of two strings, negative numbers are printed with the strings wrapped around (and no preceding negative sign -).

Variable: comma-rule

The number of digits between commans, specified by comma-sep.

Variable: comma-sep

The character used as comma for numeric formatting, #\, by default.

Variable: decimal-sep

The character to use for decimals in numeric formatting. The default depends on comma-sep, if it’s #\., then the decimal separator is #\,, otherwise it’s #\.

Variable: decimal-align
Variable: word-separator?

Previous: , Up: ライブラリモジュール - R7RS標準ライブラリ   [Contents][Index]


For Gauche 0.9.15Search (procedure/syntax/module):