表題

文字セット ライブラリ

著者

Olin Shivers

状態

この SRFI は現在「確定」の状態である。 SRFI の各状態の説明については ここ を参照せよ。 この SRFI に関する議論については メーリングリストのアーカイブ を参照せよ。

目次

概要

さまざまな文字セットを効率よく表現したり操作することはたいして魅力的ではないが、 テキスト処理コードにとっては非常に便利な機能であり、 他のライブラリにおいても実装されることがしばしばある。 そのため、早い時期にこの機能の基盤を定めておくことは有益である。 この SRFI では、そのための汎用的なライブラリを定義する。 この SRFI には参照実装が付属している。 参照実装はかなり効率的で、移植性が高く、 「フリーソフトウェア」としての著作権が与えられている。 この実装は、ASCII や Latin-1 のような 7 ビットまたは 8 ビットの小さな文字タイプに対して最適化されている。 Unicode のような 16 ビットまたは 32 ビットの文字タイプに対しては、 データ構造やアルゴリズムを変更する必要があるだろう。 しかし、ここで定める仕様は、このような大きな文字タイプのことも考慮して 注意深く設計されている。 今後の SRFI では、次の事項も定義されるだろう。

変数の索引

このライブラリでエクスポートされる束縛の完全な一覧を以下に示す。 モジュール システムやパッケージ システムをもつ Scheme 処理系では、 これらの手続きはモジュール名 "char-set-lib" に含めるべきである。

述語と比較
char-set? char-set= char-set<= char-set-hash
文字セット内の文字の列挙
char-set-cursor char-set-ref char-set-cursor-next end-of-char-set?
char-set-fold char-set-unfold char-set-unfold!
char-set-for-each char-set-map
文字セットの作成
char-set-copy char-set

list->char-set  string->char-set
list->char-set! string->char-set!

char-set-filter  ucs-range->char-set 
char-set-filter! ucs-range->char-set!

->char-set
文字セットの問い合わせ
char-set->list char-set->string
char-set-size char-set-count char-set-contains?
char-set-every char-set-any
文字セット代数
char-set-adjoin  char-set-delete
char-set-adjoin! char-set-delete!

char-set-complement  char-set-union  char-set-intersection
char-set-complement! char-set-union! char-set-intersection!

char-set-difference  char-set-xor  char-set-diff+intersection
char-set-difference! char-set-xor! char-set-diff+intersection!
標準文字セット
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

論拠

文字セットを効率的に操作する機能は、 テキスト処理コードにとって非常に有用である。 この機能を、汎用的で効率的に実装されたライブラリにカプセル化しておけば、 テキスト処理を行うときの助けになる。 このライブラリでは、文字セットを表現するために "char-set" という新しいデータ構造を定義する。 char-set 型は、他のすべての型とは異なる型である。

このライブラリは、異なる文字タイプを使用するさまざまな実装において 移植性があるように設計されている。 とくに、ASCII、Latin-1、Unicode の間で移植性がある。 Unicode の場合は、Java との互換性を保つようにいくらか努力をした (ただ一つの非互換な仕様については char-set:whitespace を参照せよ)。

線形更新操作

この SRFI の手続きは、基本的に「純粋関数的」である。 つまり、手続きはその引数を変更しない。 しかし、この SRFI では、いくつかの「線形更新」(linear-update) 手続きを定義する。 これらは、純粋関数的意味論および副作用的意味論をハイブリッドした意味論をもつ。 この種の手続きでは、結果を作成するために引数に対して副作用を及ぼすことが許されるが、 それは必須ではない。 線形更新手続きの実装では、副作用のない純粋関数的な実装を行うこともできるし、 副作用を及ぼす実装を行ってもよい。 どのような実装を行うかは、 背景にあるデータ構造を考慮した上で、 実装の効率性や容易性により選択すればよい。

線形更新手続きの名前は、末尾に "!" が付加される。

線形更新手続きを使用する場合、 副作用的に実装されていることを当てにしてはいけない。 たとえば、次のコードは正しくない。

(let* ((cs1 (char-set #\a #\b #\c))      ; cs1 = {a,b,c}.
       (cs2 (char-set-adjoin! cs1 #\d))) ; Add d to {a,b,c}.
  cs1) ; Could be either {a,b,c} or {a,b,c,d}.

しかし、次のコードは正しい。

(let ((cs (char-set #\a #\b #\c)))
  (char-set-adjoin! cs #\d)) ; Add d to {a,b,c}.

したがって、線形更新手続きを使用する場合、関数型スタイルで書くことはできるが、 その引数として渡したオブジェクトを別の場所で使用していないことを確認しなければならない。 引数として渡されたオブジェクトは、潜在的に変更されている可能性があるため、 別の場所で使用してはいけないのである (そのため「線形更新」と呼ばれる)。

線形更新手続きには、次の利点がある。

ASCII や Latin-1 をベースにした Scheme 実装では、 純粋関数的な表現は正しい選択であることに注意せよ。 その場合の文字セットは、4 つの 32 ビット ワードで表現できるからである。 この表現では、純粋な集合代数操作は非常に高速で効率的である。 線形更新操作を使用してコードを書くプログラマは、 システムが複数のプラットフォームに渡る最良の実装を提供してくれることを期待できる。

実用上は、限られたローカル コンテキストにおいて副作用的に文字セットを作成し、 作成された文字セットをローカル スコープ外に純粋関数的に返すような用途において、 線形更新手続きは最も有用である。

線形更新手続きに渡された引数は潜在的に副作用を受けるが、 その引数が線形性をもつかどうかを判断するための方法は Scheme にはない。 線形であるかどうかを判断する機能 (linear type checker) はないし、 線形性の違反を検出する実行時機構もない。 (しかし DrScheme のような洗練されたプログラミング環境では可能かもしれない)

SRFI 以外の推奨事項

以下の R5RS の述語は、

char-alphabetic?
char-numeric?
char-whitespace?
char-upper-case?
char-lower-case?

以下の SRFI 14 の文字セットに一致するかもしれないし、 一致しないかもしれないことに注意せよ。

char-set:letter
char-set:digit
char-set:whitespace
char-set:upper-case
char-set:lower-case

実装者は、上記の述語をこの SRFI の文字セットと一致するように定義することを 強く推奨する。 そうしないと大きな混乱が生じるだろう。

仕様

以下で手続きの仕様を記述するにあたり、次のことを前提とする。

手続きに対して、ここで指定された型以外の値を渡すと、エラーである。

特に断りのない限り、手続きは、引数で指定された文字セットとは (線形更新の意味で) 異なる文字セットを返す。 たとえば、char-set-adjoin は、 引数に文字を 1 つも指定しない場合であっても、 新しい文字セットを返すことが保証される。

角括弧に囲まれた引数はオプションである。 手続きの解説で特に断りのない限り、 これらのオプション引数は前から順番に任意の数を指定することができる。 オプション引数を 1 つも指定しなくてもよいし、すべて指定してもよい。 手続きが多重値を返す場合も、戻り値を角括弧内に記述する。 たとえば、次のようなシグニチャをもつ手続きの場合、

halts? f [x init-store] -> [boolean integer]
1 つ (f)、 2 つ (f, x)、または、 3 つ (f, x, init-store) の引数をとり、ブール値と整数値の 2 つの値を返す。

後ろに "..." がつく引数は、 0 個以上の引数を意味する。 たとえば、次のシグニチャをもつ手続きの場合、

sum-squares x ...  -> number
0 個以上の引数をとる (x ...)。 また、次のシグニチャをもつ手続きの場合、
spell-check doc dict1 dict2 ... -> string-list
2 つの必須引数 (docdict1) をとり、 0 個以上のオプション引数 (dict2 ...) をとる。

一般的な手続き

char-set? obj -> boolean
オブジェクト obj が文字セットであるか判定する。
char-set= cs1 ... -> boolean
文字セットが等しいか判定する。

境界条件:

(char-set=) => true
(char-set= cs) => true

論拠: 推移的な二項関係は、Scheme では n-項関係に拡張することができ、 より明快で簡潔なコードを書くことができる。 n-項関係を 1 階 (first-order) で使用する限りにおいては、 引数の数が 0 個や 1 個であることはまずないが、 高階で使用する場合や、マクロ展開されたコードで使用する場合、 引数の数が 0 個や 1 個ということがあり得る。 たとえば、次の式を考える。

(apply char-set= cset-list)

これはリストが空であるか 1 個の要素しかもたない場合は、はっきりとした定義をもつ。 そこで、この関係を任意個の引数に対して拡張した。 実装者たちは、n-項関係を 2 個より少ない引数に対しても適用するような 高階の使用例を報告している。 Scheme の慣習では汎用的に使えるものを定義するから、 ここでは完全に汎用的な拡張を行った。

この拡張に対する反論は、 R5RS の推移的な二項算術関係 (=, < など) は、少なくとも 2 つの引数を必要としており、 0 個や 1 個の引数を許すと、この慣例を破ってしまうことになるというものである。 しかし、少なくとも後方互換ではある。

char-set<= cs1 ... -> boolean
すべての文字セット csi が 文字セット csi+1 の部分集合であれば真を返す。

境界条件:

(char-set<=) => true
(char-set<= cs) => true

論拠: 0 個および 1 個の引数に関する議論については char-set= を参照せよ。 char-set のリストの単調増加性を調べるための次の式を考えてみるとよい。

(apply char-set<= cset-list)
char-set-hash cs [bound] -> integer
文字セット cs のハッシュ値を計算する。 bound は非負の正確整数で、 ハッシュ関数の値の範囲を指定する。 正の数を指定すると、戻り値が [0,bound) の範囲に制限される。

bound が 0 であるか指定されない場合、 実装固有のデフォルト値が使用される。

不変式:

(char-set= cs1 cs2) => (= (char-set-hash cs1 b) (char-set-hash cs2 b))

次の実装は正しい実装だが、推奨されない。

(define (char-set-hash cs . maybe-bound) 1)

論拠: この手続きの使用者がハッシュ値の制限を指定できることにより、 使用者のコードで通常よく行われるハッシュ値の剰余計算が必要なくなり、 コードが簡単になる。 また、ハッシュ関数の実装でこの制限値を利用することにより、 ハッシュ値の計算が効率的になる可能性がある。 たとえば、制限値が小さい場合、 計算の途中の値が多倍長整数 (bignum) にならないように計算することで、 固定長整数 (fixnum) に固有の高速な計算処理を行うことができるかもしれない。

文字セット内の文字の列挙

char-set-cursor cset -> cursor
char-set-ref cset cursor -> char
char-set-cursor-next cset cursor -> cursor
end-of-char-set? cursor -> boolean
カーソルは文字セット内の文字を列挙するための低レベルな機能である。 カーソルは、文字セット内の文字を指し示すインデックスである。 char-set-cursor は、 指定された文字セットに対する新しいカーソルを作成する。 文字セットの文字は char-set-ref で取得する。 カーソルのインデックスは char-set-cursor-next でインクリメントする。 これにより、文字セット内のすべての文字を列挙することができる。 カーソルが最後の文字を越えると、 end-of-char-set? は真を返す。 最後の文字を越えたカーソルを char-set-refchar-set-cursor-next に渡すとエラーである。

カーソルの値は異なる文字セットとともに使用してはならない。 カーソルを作成したときの文字セットとは異なる文字セットを char-set-refchar-set-cursor-next に指定した場合、 その結果や作用は未定義である。

カーソルの値は他の型と異なる必要はない。 整数値、リンクリスト、レコード、手続き、などの型であってよい。 これを許すことにより、カーソルはとても「軽量」にすることができるので、 カーソルの実装が単純であっても、厳しいループの中でも使用可能なものとなり得る。

ループ マクロを使用して文字セット内の文字を列挙するためには、 これらの手続きが必要であることに注意せよ。

例:

(define cs (char-set #\G #\a #\T #\e #\c #\h))

;; 文字セット cs の要素をリストに集める。
(let lp ((cur (char-set-cursor cs)) (ans '()))
  (if (end-of-char-set? cur) ans
      (lp (char-set-cursor-next cs cur)
          (cons (char-set-ref cs cur) ans))))
  => (#\G #\T #\a #\c #\e #\h)

;; 同じことをリストの逆畳み込み (SRFI 1) を利用して行う。
(unfold-right end-of-char-set?
              (curry char-set-ref cs)
	      (curry char-set-cursor-next cs)
	      (char-set-cursor cs))
  => (#\G #\T #\a #\c #\e #\h)

論拠: カーソル API の上記の 4 つの手続きは、 リスト、文字列、および文字セットに関する SRFI で提供される逆畳み込み関数のプロトコルに 適合していることに注意せよ (上の例を参照せよ)。 これと比較するために、 より簡単な 2 つの関数を考えてみる (これらの関数は逆畳み込みに使えないので否決された)。 その 2 つの関数とは、 char-set-cursor と、 カーソルと文字セットを文字と次のカーソルにマップする関数である。 もしカーソルが文字セットの終端に達した場合、 この関数は文字ではなく偽値を返し、 終端に達した別の文字セットも返す。 この方法を使うと、他の 3 つの関数を 1 つの関数に結合することができる。

char-set-fold kons knil cs -> object
文字セットの基本的な列挙を行う手続きである。 初期値 knil を使用して、 関数 kons を文字セット cs に適用する。 つまり、cs が空セットである場合、 この手続きは knil を返す。 空セットでない場合、cs の 1 つの要素 c が選択され、 cs' を残りの選択されない文字のセットとすると、 次の値を返す。
(char-set-fold kons (kons c knil) cs')

例:

;; 文字セットに含まれる文字のリスト (CHAR-SET-MEMBERS)
(lambda (cs) (char-set-fold cons '() cs))

;; 文字セットのサイズ (CHAR-SET-SIZE)
(lambda (cs) (char-set-fold (lambda (c i) (+ i 1)) 0 cs))

;; 文字セットにいくつの母音が含まれているか?
(lambda (cs)
  (char-set-fold (lambda (c i) (if (vowel? c) (+ i 1) i))
                 0 cs))
char-set-unfold  f p g seed [base-cs] -> char-set
char-set-unfold! f p g seed base-cs -> char-set
文字セットの基本的なコンストラクタである。

より正確に言うと、次のように定義できる。 ただし、オプション引数の処理は省略している。

(define (char-set-unfold p f g seed base-cs)
  (char-set-unfold! p f g seed (char-set-copy base-cs)))

(define (char-set-unfold! p f g seed base-cs)
  (let lp ((seed seed) (cs base-cs))
        (if (p seed) cs                                 ; P says we are done.
            (lp (g seed)                                ; Loop on (G SEED).
                (char-set-adjoin! cs (f seed))))))      ; Add (F SEED) to set.
(実際の実装はもっと効率的にできるだろう)

例:

(port->char-set p) = (char-set-unfold eof-object? values
                                      (lambda (x) (read-char p))
                                      (read-char p))

(list->char-set lis) = (char-set-unfold null? car cdr lis)
char-set-for-each proc cs -> unspecified
手続き proc を文字セット cs の各文字に適用する。 proc が各文字に適用される順序は規定されないので、 この手続きを呼び出すごとに適用順序が異なることもあり得る。

この手続きの戻り値は規定されない。 この手続きを呼び出すたびに戻り値が異なることもあり得る。 戻り値は、コマンド継続 (command continuation) に渡すことができる値 (または多重値) であれば何でもよい。 たとえば、begin 式の非終端サブフォームの値でもよい。 R5RS においては、このことは、1 つの値を返さなければならないという制限になる。 非-R5RS システムではこの制限はない。

char-set-map proc cs -> char-set
proc は文字を受け取り文字を返す手続きである。 この手続きを文字セットcs 内のすべての文字に適用し、 その戻り値を集めて新しい文字セットを作成する。

つまり、手続き proc を char -> char の手続きから char-set -> char-set の手続きに格上げする。

例:

(char-set-map char-downcase cset)

文字セットの作成

char-set-copy cs -> char-set
文字セット cs のコピーを返す。 「コピー」ということの意味は、 引数に渡した文字セットも、この手続きが返した文字セットも、 以下に述べる線形更新手続きに渡すことができるということである。 一方の文字セットを線形更新手続きに渡しても、 もう一方の文字セットが変更されることはない。

以下で述べる線形更新手続きを純粋関数的に実装するシステムでは、 この手続きを恒等関数として実装してもよい。 そのため、元の文字セットとそのコピーを eq? により区別できることは保証されない

char-set char1 ... -> char-set
指定された文字をもつ文字セットを返す。
list->char-set  char-list [base-cs] -> char-set
list->char-set! char-list base-cs -> char-set
文字のリスト char-list で指定された文字をもつ文字セットを返す。

文字セット base-cs が指定された場合、 char-list 内の文字がそれに追加される。 list->char-set!base-cs を再利用して副作用を及ぼしてもよい (副作用がなくてもよい)。 list->char-set はまったく新しい文字セットを作成する。

string->char-set  s [base-cs] -> char-set
string->char-set! s base-cs -> char-set
文字列 s 内の文字を含む文字セットを返す。

文字セット base-cs が指定された場合、 s の文字はそこに追加される。 string->char-set!base-cs を再利用して副作用を及ぼしてもよい (副作用がなくてもよい)。 string->char-set はまったく新しい文字セットを作成する。

char-set-filter  pred cs [base-cs] -> char-set
char-set-filter! pred cs base-cs -> char-set
文字セット cs 内の文字 c(pred c) を満たす文字からなる文字セットを返す。

文字セット base-cs が指定されている場合、 pred で選別された文字がそこに追加される。 char-set-filter!base-cs を再利用して副作用を及ぼしてもよい (副作用がなくてもよい)。 char-set-filter はまったく新しい文字セットを作成する。

この手続きの実装では、pred の参照を保持しておいて char-set-filterchar-set-filter! から戻った後でそれを呼び出す、ということをしてはいけない。 pred が変更可能な外部データに依存しているかもしれないし、 あるいは、副作用をもつかもしれないので、 そういったオンデマンドの実装は許されない。

論拠: この手続きは、文字述語をそれに等価な文字セットに変換する方法を提供する。 引数 cs は、その述語の定義域を制限する働きをする。 32 ビット Unicode のような巨大な文字タイプの実装において char-set:full のような文字セットにフィルタをかけると 非常に高価な操作になるということを、 プログラマは意識しなければならない。 このライブラリの初期の草案では predicate->char-set という単純な手続きを定義したが、 この理由により否決され、char-set-filter のほうが採択された。

ucs-range->char-set  lower upper [error? base-cs] -> char-set
ucs-range->char-set! lower upper error? base-cs -> char-set
lowerupper は非負の正確整数で lower <= upper を満たすこと。

ISO/IEC 10646 UCS-4 の半開コード範囲 [lower,upper) を含む文字セットを返す。

文字セット base-cs が指定された場合、 指定された範囲の文字がそこに追加される。 ucs-range->char-set!base-cs を再利用して副作用を及ぼしてもよい (副作用がなくてもよい)。 ucs-range->char-set はまったく新しい文字セットを作成する。

ASCII は Latin-1 のサブセットであり、 Latin-1 は 16 ビット Unicode のサブセットであり、 16 ビット Unicode は 32 ビット UCS-4 のサブセットであることに注意せよ。 Scheme 実装において文字がどのように表現されているにせよ、 文字コードに固有の処理はこの手続きに任せることになるため、 このライブラリを使用するコードには移植性がある。 言い換えると、 この SRFI に準拠する Scheme 実装が、 文字コードとして EBCDIC や SHIFT-JIS を使用してもよいが、 その場合、指定範囲の UCS 文字をネイティブ表現にマップ可能であればマップし、 マップ不可能であればエラーを発生させなければならない。

->char-set x -> char-set
x を char-set 文字セットに強制変換する。 x は、文字列、文字、文字セットのいずれかとする。 文字列は、それを構成する文字を含む文字セットに変換される。 文字は、その文字だけを含む文字セットに変換される。 文字セットを指定すると、それがそのまま返される。 この手続きは、ユーザー フレンドリーなインターフェイスを提供する 別の手続きから使用されることを意図している。

文字セットの問い合わせ

char-set-size cs -> integer
文字セット cs の要素数を返す。
char-set-count pred cs -> integer
pred を文字セット cs 内の文字に適用し、 その述語が真となった文字数を返す。
char-set->list cs -> character-list
文字セット cs の文字のリストを返す。 cs の文字がリスト内に現れる順序は定義されず、 この手続きを呼び出すごとに異なることもあり得る。
char-set->string cs -> string
文字セット cs の文字で構成される文字列を返す。 文字セット cs の文字が文字列中に現れる順序は定義されないので、 手続きの呼び出しごとに異なる可能性がある。
char-set-contains? cs char -> boolean
この手続きは、文字 char が文字セット cs に含まれているか検査する。

MIT Scheme の character-set パッケージは、 この手続きに char-set-member? という名前を付けているが、 引数の順序がその名前と整合していない。

char-set-every pred cs -> boolean
char-set-any   pred cs -> boolean
char-set-every 手続きは、 文字セット cs のすべての文字に対して述語 pred が真となるときに、真を返す。 同様に、char-set-any は文字セット cs のすべての文字に対して pred を適用し、 最初に真となった値を返す。 すべての文字で真とならない場合は、偽を返す。 文字セット cs の文字に述語が適用される順序は規定されない。

述語が真となる文字を知りたければ、 char-set-any を使用し、 その述語の戻り値として文字そのものを返せばよい。 たとえば、

(char-set-any (lambda (c) (and (char-upper-case? c) c))
              cs)

文字セット代数

char-set-adjoin cs char1 ... -> char-set
char-set-delete cs char1 ... -> char-set
文字セット cs に文字 chari を追加/削除する。
char-set-adjoin! cs char1 ... -> char-set
char-set-delete! cs char1 ... -> char-set
線形更新バージョン。 これらの手続きは、最初の引数に対して副作用を及ぼしてもよい (副作用がなくてもよい)。
char-set-complement cs -> char-set
char-set-union cs1 ... -> char-set
char-set-intersection cs1 ... -> char-set
char-set-difference cs1 cs2 ... -> char-set
char-set-xor cs1 ... -> char-set
char-set-diff+intersection cs1 cs2 ... -> [char-set char-set]
これらの手続きは、文字セットの補集合、和集合、積集合、差集合、 排他的和集合を計算する。 和集合、積集合、排他的和集合は n-項の手続きである。 差集合も n-項の手続きであり、左結合的に作用し (つまり、最初の引数とそれ以外の引数の和集合との差分を計算する)、 少なくとも 1 つの引数を必要とする。

境界条件:

(char-set-union) => char-set:empty
(char-set-intersection) => char-set:full
(char-set-xor) => char-set:empty
(char-set-difference cs) => cs

char-set-diff+intersection は、引数の差集合と積集合を同時に返す。 つまり、最初の引数を 2 つに分割する。 次の式に等しい。

(values (char-set-difference cs1 cs2 ...)
        (char-set-intersection cs1 (char-set-union cs2 ...)))
しかし、もっと効率的に実装することができる。

Scheme 実装が 32 ビット Unicode のような巨大な文字タイプを使用している場合、 char-set-complement は潜在的に非常に高価な操作であることを、 プログラマは意識するべきである。 その可能性がある場合、char-set-difference を使用してより小さな領域に対して補集合をとるとよい。

char-set-complement! cs -> char-set
char-set-union! cs1 cs2 ... -> char-set
char-set-intersection! cs1 cs2 ... -> char-set
char-set-difference! cs1 cs2 ... -> char-set
char-set-xor! cs1 cs2 ... -> char-set
char-set-diff+intersection! cs1 cs2 cs3 ... -> [char-set char-set]
文字セット代数の線形更新バージョン。 これらの手続きは、最初の引数に対して副作用を及ぼしてもよい (副作用がなくてもよい)。

char-set-diff+intersection! は、 2 つの必須引数 cs1cs2 に対して副作用を及ぼしてもよい。

標準文字セット

便宜のために、いくつかの文字セットがあらかじめ定義されている。

char-set:lower-case 小文字
char-set:upper-case 大文字
char-set:title-case 表題文字 (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 ISO 制御文字
char-set:punctuation 区切り文字
char-set:symbol 記号文字
char-set:hex-digit 16 進数文字: 0-9, A-F, a-f
char-set:blank ブランク文字 -- 水平空白文字
char-set:ascii ASCII 文字セットのすべての文字
char-set:empty 空の文字セット
char-set:full すべての文字

char-set:letter の中に大文字でも小文字でもない文字が 存在する可能性があることに注意せよ。 このことは、Unicode のような ASCII よりも豊富な文字タイプを使用する実装で起きる。 図形文字 (graphic character) とは、紙の上にインクを残す文字のことである。 これらの文字セットの正確な構成は、 Scheme 処理系が提供する文字タイプにより異なる可能性があるが、 ASCII を使用した Scheme 実装における定義を以下に示す。

char-set:lower-case a-z
char-set:upper-case A-Z
char-set:letter A-Z および a-z
char-set:digit 0123456789
char-set:punctuation !"#%&'()*,-./:;?@[\]_{}
char-set:symbol $+<=>^`|~
char-set:whitespace スペース、改行、タブ、フォームフィード
垂直タブ、復帰
char-set:blank スペース、タブ
char-set:graphic letter + digit + punctuation + symbol
char-set:printing graphic + whitespace
char-set:iso-control ASCII の 0-31 および 127

文字セット char-set:ascii が存在するということは、 その Scheme システムで実装されている文字セットが少なくとも (制御文字も含めて) ASCII ぐらいに豊富でなければならないことを意味している。

論拠: R5RS や Posix では "alphabetic/numeric" という用語が使われていたが、 Unicode では "letter/digit" という用語が使われており、 ここではこちらの用語を採択している。

Unicode, Latin-1, ASCII における標準文字セットの定義

Unicode Scheme 実装においては、ベースとなる文字セットは Java の Unicode 仕様と互換性をもたせる。 ASCII または Latin-1 においては、 単純に Unicode をその最初の 128 または 256 コードに制限することにする。 ASCII, Latin-1, Unicode のいずれもベースとしない Scheme 実装においては、 これらの定義の意味や精神を保持するように努めるべきである。

以下の解説では、しばしば「Unicode 文字データベース」を参照している。 これは次の URL から入手できるファイルである。

ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt

各行には Unicode 文字の属性が書かれている。 セミコロンで区切られた最初のフィールドは、 文字コードの 16 進数値である。 2 つめのフィールドは文字の名前、 3 つめのフィールドは 2 文字のカテゴリ名である。 他のフィールドは、単純な一対一のケース マッピングとその他の情報を表す。 ファイル形式の詳細については、次の URL を参照せよ。

ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.html

特に、3 つめのフィールドの 2 文字のカテゴリ名は、 以下の解説で頻繁に参照する。

char-set:lower-case

Unicode では、Java の仕様にしたがうものとする。 以下の場合に小文字とする。

ASCII の小文字は、以下の文字とする。

abcdefghijklmnopqrstuvwxyz

Latin-1 では、ASCII の小文字に加えて、次の 33 文字を小文字とする。

00B5 MICRO SIGN
00DF LATIN SMALL LETTER SHARP S
00E0 LATIN SMALL LETTER A WITH GRAVE
00E1 LATIN SMALL LETTER A WITH ACUTE
00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX
00E3 LATIN SMALL LETTER A WITH TILDE
00E4 LATIN SMALL LETTER A WITH DIAERESIS
00E5 LATIN SMALL LETTER A WITH RING ABOVE
00E6 LATIN SMALL LETTER AE
00E7 LATIN SMALL LETTER C WITH CEDILLA
00E8 LATIN SMALL LETTER E WITH GRAVE
00E9 LATIN SMALL LETTER E WITH ACUTE
00EA LATIN SMALL LETTER E WITH CIRCUMFLEX
00EB LATIN SMALL LETTER E WITH DIAERESIS
00EC LATIN SMALL LETTER I WITH GRAVE
00ED LATIN SMALL LETTER I WITH ACUTE
00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
00EF LATIN SMALL LETTER I WITH DIAERESIS
00F0 LATIN SMALL LETTER ETH
00F1 LATIN SMALL LETTER N WITH TILDE
00F2 LATIN SMALL LETTER O WITH GRAVE
00F3 LATIN SMALL LETTER O WITH ACUTE
00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX
00F5 LATIN SMALL LETTER O WITH TILDE
00F6 LATIN SMALL LETTER O WITH DIAERESIS
00F8 LATIN SMALL LETTER O WITH STROKE
00F9 LATIN SMALL LETTER U WITH GRAVE
00FA LATIN SMALL LETTER U WITH ACUTE
00FB LATIN SMALL LETTER U WITH CIRCUMFLEX
00FC LATIN SMALL LETTER U WITH DIAERESIS
00FD LATIN SMALL LETTER Y WITH ACUTE
00FE LATIN SMALL LETTER THORN
00FF LATIN SMALL LETTER Y WITH DIAERESIS

これらの文字のうち次の 3 文字は、対応する大文字が Latin-1 に存在しないことに注意せよ。

00B5 MICRO SIGN
00DF LATIN SMALL LETTER SHARP S
00FF LATIN SMALL LETTER Y WITH DIAERESIS

(互換マイクロ文字 (compatibility micro character) の大文字は Latin-1 には存在しないギリシャ文字のミューになる。 ドイツ語のシャープ s 文字 (German sharp s character) の大文字は 2 つの文字 "SS" になる。 y-with-diaeresis の大文字は Latin-1 には存在しない文字になる。)

(次のドキュメントで定義されている Java の小文字の仕様は、

http://java.sun.com/docs/books/jls/html/javalang.doc4.html#14345

矛盾したものであることに注意せよ。 U+00B5 MICRO SIGN は (Unicode 3.0 の) 小文字としての条件を満たすが、 小文字の番号リストには記載されていない。)

(次のドキュメントで定義されている Java の isLowerCase() の仕様は、

http://java.sun.com/products/jdk/1.2/docs/api/java/lang/Character.html#isLowerCase(char)

相互に矛盾した「小文字」の定義を与えていることに注意せよ。 1 つめの定義は、この SRFI の定義と同じである。 それに続いて次のように書かれている。 「Unicode 2.0 標準規格において小文字として定義されている文字 (Unicode 仕様データファイルのカテゴリ Ll に属する文字) を小文字と定義し、かつ、その文字に限り小文字と定義する。」 これが 2 つめの定義である。 1 つめの定義では、 U+00AA FEMININE ORDINAL INDICATOR と U+00BA MASCULINE ORDINAL INDICATOR は小文字ではないが、 2 つめの定義では、これらは小文字になる。 Java のドキュメントには Latin-1 サブセットにおける小文字の一覧を記載しているが、 これが 3 つめの定義である。 この一覧では U+00B5 MICRO SIGN が除外されているが、 この文字は、1 つめと 2 つめの定義に含まれている。)

char-set:upper-case

Unicode では、Java の仕様にしたがうものとする。 以下の場合に大文字とする。

ASCII の大文字は、以下の文字とする。

ABCDEFGHIJKLMNOPQRSTUVWXYZ

Latin-1 では、ASCII の大文字に加えて、次の 30 文字を大文字とする。

00C0 LATIN CAPITAL LETTER A WITH GRAVE
00C1 LATIN CAPITAL LETTER A WITH ACUTE
00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX
00C3 LATIN CAPITAL LETTER A WITH TILDE
00C4 LATIN CAPITAL LETTER A WITH DIAERESIS
00C5 LATIN CAPITAL LETTER A WITH RING ABOVE
00C6 LATIN CAPITAL LETTER AE
00C7 LATIN CAPITAL LETTER C WITH CEDILLA
00C8 LATIN CAPITAL LETTER E WITH GRAVE
00C9 LATIN CAPITAL LETTER E WITH ACUTE
00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX
00CB LATIN CAPITAL LETTER E WITH DIAERESIS
00CC LATIN CAPITAL LETTER I WITH GRAVE
00CD LATIN CAPITAL LETTER I WITH ACUTE
00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX
00CF LATIN CAPITAL LETTER I WITH DIAERESIS
00D0 LATIN CAPITAL LETTER ETH
00D1 LATIN CAPITAL LETTER N WITH TILDE
00D2 LATIN CAPITAL LETTER O WITH GRAVE
00D3 LATIN CAPITAL LETTER O WITH ACUTE
00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX
00D5 LATIN CAPITAL LETTER O WITH TILDE
00D6 LATIN CAPITAL LETTER O WITH DIAERESIS
00D8 LATIN CAPITAL LETTER O WITH STROKE
00D9 LATIN CAPITAL LETTER U WITH GRAVE
00DA LATIN CAPITAL LETTER U WITH ACUTE
00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX
00DC LATIN CAPITAL LETTER U WITH DIAERESIS
00DD LATIN CAPITAL LETTER Y WITH ACUTE
00DE LATIN CAPITAL LETTER THORN

char-set:title-case

Unicode では、文字属性データベースでカテゴリ Lt をもつ文字を表題文字 (titlecase) とする。 このカテゴリの文字は非常に少ない。 Unicode 3.0 における 31 文字すべてを以下に示す。

01C5 LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
01C8 LATIN CAPITAL LETTER L WITH SMALL LETTER J
01CB LATIN CAPITAL LETTER N WITH SMALL LETTER J
01F2 LATIN CAPITAL LETTER D WITH SMALL LETTER Z
1F88 GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89 GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F98 GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99 GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA8 GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9 GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FBC GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FCC GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FFC GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI

ASCII と Latin-1 では表題文字 (titlecase) は存在しない。

char-set:letter

Unicode では、 Unicode 文字データベースでレター カテゴリ (Lu, Ll, Lt, Lm, Lo) に属する文字をレター (letter) とする。

ASCII では以下の 52 文字をレターとする。

abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ

Latin-1 には 117 文字のレターがある。 Latin-1 の char-set:lower-casechar-set:upper-case に属する 115 文字と、以下の 2 文字をレターとする。

00AA FEMININE ORDINAL INDICATOR
00BA MASCULINE ORDINAL INDICATOR

(Unicode では、これらの 2 文字は小文字とされるが、 Java や SRFI 14 では小文字とはならない。)

char-set:digit

Unicode では、文字属性データベースでカテゴリ Nd をもつ文字を数字 (digit) とする。 Latin-1 と ASCII では、0123456789 を数字とする。 Unicode では、他のコードブロックに Gujarati digits や Tibetan digits などの別の数字文字が存在する。

char-set:hex-digit

16 進数文字 (hex digit) は、0123456789abcdefABCDEF のみとする。

char-set:letter+digit

char-set:letterchar-set:digit の和集合。

char-set:graphic

図形文字 (graphic character) とは、紙にインクを残す文字のことである。 ASCII と Latin-1 の図形文字は、以下の文字である。

char-set:letter
char-set:digit
char-set:punctuation
char-set:symbol

char-set:printing

印字文字 (printing character) とは、印字したときに空間を占有する文字のことである。 つまり、図形文字か空白である。 char-set:printingchar-set:whitespacechar-set:graphic の和集合である。

char-set:whitespace

Unicode では、空白文字 (whitespace character) とは、以下のいずれかである。

Unicode 3.0 では、24 文字の空白文字がある。

0009 HORIZONTAL TABULATION \t control-I
000A LINE FEED \n control-J
000B VERTICAL TABULATION \v control-K
000C FORM FEED \f control-L
000D CARRIAGE RETURN \r control-M
0020 SPACE Zs
00A0 NO-BREAK SPACE Zs
1680 OGHAM SPACE MARK Zs
2000 EN QUAD Zs
2001 EM QUAD Zs
2002 EN SPACE Zs
2003 EM SPACE Zs
2004 THREE-PER-EM SPACE Zs
2005 FOUR-PER-EM SPACE Zs
2006 SIX-PER-EM SPACE Zs
2007 FIGURE SPACE Zs
2008 PUNCTUATION SPACE Zs
2009 THIN SPACE Zs
200A HAIR SPACE Zs
200B ZERO WIDTH SPACE Zs
2028 LINE SEPARATOR Zl
2029 PARAGRAPH SEPARATOR Zp
202F NARROW NO-BREAK SPACE Zs
3000 IDEOGRAPHIC SPACE Zs

ASCII の空白文字は、上記一覧のうちの最初の 6 文字、 ラインフィード、水平タブ、垂直タブ、フォームフィード、復帰、スペース、である。 これらの文字は、Posix の isspace() 手続きにより認識される文字でもある。 Latin-1 では、これらに加えて、ノーブレークスペース (no-break space) を追加する。

ノート:Java の isWhitespace() メソッドとは互換性がない。 このメソッドは、次の文字を含み、

0009 HORIZONTAL TABULATION (\t control-I)
001C FILE SEPARATOR (control-\)
001D GROUP SEPARATOR (control-])
001E RECORD SEPARATOR (control-^)
001F UNIT SEPARATOR (control-_)

次の文字は含まない。

00A0 NO-BREAK SPACE

Java がノーブレークスペースを含んでいないことで、 トークナイザは単純に文字ストリームの「空白」の位置で分割できるようになっている。 しかし、この文字を除外することで、他の場面で例外を設けなければならなくなる。 たとえば、char-set:printing は単純に char-set:graphicchar-set:whitespace の和集合としては定義できなくなる。

char-set:iso-control

ISO 制御文字 (ISO control character) は、 [U+0000,U+001F] および [U+007F,U+009F] の範囲の Unicode/Latin-1 文字である。

ASCII では、この文字セットは [U+0000,U+001F] の範囲と 文字 U+007F に制限される。

Unicode では、この文字セットには属さない別の制御文字を定義していることに注意せよ (そのため名前に "iso-" というプレフィックスをつけているのである)。 この制限により、Java の IsISOControl() メソッドとの互換性が保てる。

char-set:punctuation

Unicode では、 Unicode 文字データベースにおいて何らかの区切りカテゴリ (Pc, Pd, Ps, Pe, Pi, Pf, Po) に属する文字を区切り文字 (punctuation character) とする。

ASCII では、次の 23 文字を区切り文字とする。

!"#%&'()*,-./:;?@[\]_{}

Latin-1 では、これに 6 文字を追加する。

00A1 INVERTED EXCLAMATION MARK
00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
00AD SOFT HYPHEN
00B7 MIDDLE DOT
00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
00BF INVERTED QUESTION MARK

9 つの ASCII 文字 $+<=>^`|~ は区切り文字ではないことに注意せよ。 これらは「記号文字」である。

char-set:symbol

Unicode では、Unicode 文字データベースにおいて何らかの記号カテゴリ (Sm, Sc, Sk, So) に属する文字を記号文字 (symbol character) とする。 ASCII では、次の 9 文字を記号文字とする。

$+<=>^`|~

Latin-1 では、これに 18 文字を追加する。

00A2 CENT SIGN
00A3 POUND SIGN
00A4 CURRENCY SIGN
00A5 YEN SIGN
00A6 BROKEN BAR
00A7 SECTION SIGN
00A8 DIAERESIS
00A9 COPYRIGHT SIGN
00AC NOT SIGN
00AE REGISTERED SIGN
00AF MACRON
00B0 DEGREE SIGN
00B1 PLUS-MINUS SIGN
00B4 ACUTE ACCENT
00B6 PILCROW SIGN
00B8 CEDILLA
00D7 MULTIPLICATION SIGN
00F7 DIVISION SIGN

char-set:blank

ブランク文字 (blank character) とは、 水平空白 (horizontal whitespace) のことである。 Unicode では、ブランク文字は次のいずれかである。

Unicode 3.0 では、次の 18 文字がブランク文字である。

0009 HORIZONTAL TABULATION \t control-I
0020 SPACE Zs
00A0 NO-BREAK SPACE Zs
1680 OGHAM SPACE MARK Zs
2000 EN QUAD Zs
2001 EM QUAD Zs
2002 EN SPACE Zs
2003 EM SPACE Zs
2004 THREE-PER-EM SPACE Zs
2005 FOUR-PER-EM SPACE Zs
2006 SIX-PER-EM SPACE Zs
2007 FIGURE SPACE Zs
2008 PUNCTUATION SPACE Zs
2009 THIN SPACE Zs
200A HAIR SPACE Zs
200B ZERO WIDTH SPACE Zs
202F NARROW NO-BREAK SPACE Zs
3000 IDEOGRAPHIC SPACE Zs

ASCII のブランク文字は、上記の最初の 2 文字、水平タブとスペースである。 Latin-1 では、これにノーブレークスペースが追加される。

Java には「ブランク文字」という概念がないので、 互換性の問題はない。

参照実装

この SRFI には参照実装が付属している。 以下の URL からダウンロードできる。

http://srfi.schemers.org/srfi-14/srfi-14.scm

私はこのソースコードを「オープンな」著作権とともにネットワーク上においた。 この参照実装のいくつかのコードは古い MIT Scheme の実装を元にしているので、 MIT Scheme の著作権 (これは一般的な BSD スタイルのオープンソース著作権である。 詳細はソースファイルを参照せよ。) も含めている。 その他のコードは scsh またはこの SRFI のために私自身が書いた。 私はこのコードを scsh の著作権の下に指定したが、 これもまた一般的な BSD スタイルのオープンソース著作権である。

このコードは移植性を考慮して書かれているので、 どんな Scheme 実装にも簡単に移植できるだろう。 R4RS には以下の点で準拠していないが、 これらについてはコメントの中で明快に検討している。

このライブラリは明快に書かれているし、きちんとコメントされている。 現在のソースは約 375 行のコードと 375 行のコメントおよび空白で書かれている。 また、効率のことも考えて書かれている。 よく使用されるケースでは、高速処理を行っている。

特定の Scheme 実装においてこれ以上最適化できないというわけではない。 参照実装の性能を向上させるための方法については、 コメントの中で言及している。

要するに、このライブラリを採用してよい結果を得られるように、 この参照実装が実装者 (あるいは通常のプログラマ) に苦痛を与えないように書いたのである。

この参照実装では、ASCII/Latin-1 文字セットに対して 256 文字の文字列という、 単純で効率の悪い表現方法を使用している。 文字コードが i の文字が集合に含まれるのは s[i] = ASCII 1 (soh, or ^a) の場合であり、 集合に含まれないのは s[i] = ASCII 0 (nul) の場合である。 16 または 32 バイトのビット列表現を使えば、 ずっと高速で小型になるだろう。 ビット集合を使用した移植性のあるコードを書くには、 ビット演算やバイト ベクタの標準が定まるのを待たなければならない。

Unicode のような大きな文字タイプに対しては、 希薄な表現 (sparse representation) を使用し、 かつ、その Latin-1 サブセットに対しては濃密な 32 バイト ビット セットで表現するのがよいだろう。

謝辞

The design of this library benefited greatly from the feedback provided during the SRFI discussion phase. Among those contributing thoughtful commentary and suggestions, both on the mailing list and by private discussion, were Paolo Amoroso, Lars Arvestad, Alan Bawden, Jim Bender, Dan Bornstein, Per Bothner, Will Clinger, Brian Denheyer, Kent Dybvig, Sergei Egorov, Marc Feeley, Matthias Felleisen, Will Fitzgerald, Matthew Flatt, Arthur A. Gleckler, Ben Goetter, Sven Hartrumpf, Erik Hilsdale, Shiro Kawai, Richard Kelsey, Oleg Kiselyov, Bengt Kleberg, Donovan Kolbly, Bruce Korb, Shriram Krishnamurthi, Bruce Lewis, Tom Lord, Brad Lucier, Dave Mason, David Rush, Klaus Schilling, Jonathan Sobel, Mike Sperber, Mikael Staldal, Vladimir Tsyshevsky, Donald Welsh, and Mike Wilson. I am grateful to them for their assistance.

I am also grateful the authors, implementors and documentors of all the systems mentioned in the introduction. Aubrey Jaffer should be noted for his work in producing Web-accessible versions of the R5RS spec, which was a tremendous aid.

This is not to imply that these individuals necessarily endorse the final results, of course.

During this document's long development period, great patience was exhibited by Mike Sperber, who is the editor for the SRFI, and by Hillary Sullivan, who is not.

参考文献とリンク

[Java]
関連する Java クラスのドキュメント
http://java.sun.com/products/jdk/1.2/docs/api/java/lang/Character.html
http://java.sun.com/products/jdk/1.2/docs/api/java/lang/String.html
http://java.sun.com/products/jdk/1.2/docs/api/java/lang/StringBuffer.html
http://java.sun.com/products/jdk/1.2/docs/api/java/text/Collator.html
http://java.sun.com/products/jdk/1.2/docs/api/java/text/package-summary.html
[MIT-Scheme]
http://www.swiss.ai.mit.edu/projects/scheme/
[R5RS]
Revised5 report on the algorithmic language Scheme.
R. Kelsey, W. Clinger, J. Rees (editors).
Higher-Order and Symbolic Computation, Vol. 11, No. 1, September, 1998.
and ACM SIGPLAN Notices, Vol. 33, No. 9, October, 1998.
Available at http://www.schemers.org/Documents/Standards/.
[SRFI]
SRFI のウェブサイト
http://srfi.schemers.org/
[SRFI-14]
SRFI-14: 文字列ライブラリ
http://srfi.schemers.org/srfi-14/
HTML 形式:
http://srfi.schemers.org/srfi-14/srfi-14.html
テキスト形式:
http://srfi.schemers.org/srfi-14/srfi-14.txt
参照実装のソースコード
http://srfi.schemers.org/srfi-14/srfi-14.scm
Scheme 48 module specification, with typings:
http://srfi.schemers.org/srfi-14/srfi-14-s48-module.scm
回帰テストのスイート
http://srfi.schemers.org/srfi-14/srfi-14-tests.scm
[Unicode]
http://www.unicode.org/
[UnicodeData]
Unicode 文字のデータベース
ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.txt
ftp://ftp.unicode.org/Public/UNIDATA/UnicodeData.html

著作権

Certain portions of this document -- the specific, marked segments of text describing the R5RS procedures -- were adapted with permission from the R5RS report.

All other text is copyright (C) Olin Shivers (1998, 1999, 2000). All Rights Reserved.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.