R6RS:標準ライブラリ
標準ライブラリの概要
- Unicode
- バイトベクタ
- リストユーティリティ
- ソート
- 制御構造
- レコード
- 例外とコンディション
- I/O
- ファイルシステム
- コマンドライン引数とexit
- 補助算術手続き
- syntax-case
- ハッシュテーブル
- 列挙
- eval
- 変更可能なペア
- 変更可能な文字列
- R5RS互換ライブラリ
Unicode
文字と文字列にかかわる関数の多くがUnicodeと一貫性を持つように、 ここで定義されます。文字のケースや種別が関与する手続きはすべてこちら。 char-alphabetic? などの判別式はUnicodeのカテゴリを参照します。
大文字小文字変換は、一般的なUnicodeでは一対一の変換になりません(ß <-> SS とか、 σ, ς <-> Σ とか)。char-upcaseなどの文字ごとの変換は、Unicodeで 1文字への変換が規定されていればそれを、規定されていなければ文字をそのまま 返します。(char-upcase #\ß) => #\ß とか。この意味では文字ごとの ケース変換は不完全。
文字列のケース変換は一対Nの変換を扱えます。
(string-upcase "Straße") => "STRASSE" (string-downcase "XAOΣΣ") => "χαoσς"
これらの変換はlocale independentな範囲で行われます。
文字列に対してUnicodeのnormalizationを行う手続きも用意されます。 (Cf. x:string-normalize-nfd etc.)
バイトベクタ
バイナリデータを扱うプリミティブとして、バイトベクタが導入されました。 こんなふうにリテラル表記します:
#vu8(0 1 2 3)
srfi-4のuniform vectorに似ていますが、バイトベクタはより汎用的で、 単なるバイト列として扱ってそこから複数バイトの数値を取り出したり セットしたり、utf-8文字列やutf-16文字列とみなして文字列に変換したり することができます。
リストユーティリティ
srfi-1にあったようないくつかの良く使われるユーティリティが提供されます。 ちょっとした違い:
- any, every に相当するものとして for-all と exists が定義されます。 後者の方が意図が明確である、という判断です。x:any, x:every, x:for-all, x:exists
- foldのかわりにfold-leftが提供されます。意味的にはfold-leftとfold-rightの
対の方が一貫性があります。
fold op s (x0 x1 ... xn-1 xn) = (xn op (xn-1 op (...(x1 op (x0 op s))...))) fold-left op s (x0 x1 ... xn-1 xn) = ((...((s op x0) op x1) ... xn-1) op xn) fold-right op s (x0 x1 ... xn-1 xn) = (x0 op (x1 op (...(xn-1 op (xn op s))...)))
- (2007/10/03 14:41:53 PDT): 右辺の op が infix operator 表記になっていますが、これは意図的?
- Shiro:意図的です。見にくい?
ソート
list-sort, vector-sort, vector-sort! が提供されます。
制御構造
when, unless, do, case-lambda が提供されます。
レコード
ユーザ定義構造体です。ここは、コンパイラで効率の良いコードを出すために 2段重ねの仕様になっています。マクロを使って構文レベルで定義するものと、 手続き的に定義するものです。
例外とコンディション
おおむねsrfi-34 (x:SRFI-34) に沿った例外システムです。
I/O
ポートしか無かったR5RSに比べ大幅に拡張されました。 低レベルの入出力手続きが豊富に提供され、馴染み深いread, write, display, read-charなどの手続きはそれを利用した高レベル手続きとして定義されます。
- ポートには、バイナリI/Oを行うbinary portと文字I/Oを行うtextual portがある。 binary portが基本。 textual portはbinary portにトランスコーダを付加することでつくり出せる。
- トランスコーダはバイナリストリームをどうやって文字ストリームと解釈するかを 指定するオブジェクト。文字エンコーディング(codec)、改行のスタイル、 そして変換エラー時の処理モードを指定できる。
- ポートにseek/tell動作が加わった (port-position, set-port-position!)
- ファイル、バイトベクタ、文字列に対してポートをオープンする手続きが用意されている。 ファイルポートに対してはバッファリングモードも指定できる。
- カスタムポート(手続き的ポート、Gaucheのgauche.vport) を作る手続きも用意 されている。
- standard-{input|output|error}-port : プロセスの標準入出力に結びつけられた バイナリポートを新たに作って返す。 fdopen(0, "rb), fdopen(1, "wb"), fdopen(2, "wb")してる感じ。 複数のポートインスタンスが同じリソースに同時アクセスした場合の動作は規定されない。
- current-{input|output|error}-port : 現在のデフォルト入出力ポートを 返す。これらはテキストポート。プロセス開始時にどういうトランスコーダで これらのポートが用意されてるかは処理系依存。
ファイルシステム
file-exists? と delete-file が用意されました。 これで最低限、ファイルを読む前に存在をチェックするとか、 作ったファイルを消すとかいうことが可能になります。
コマンドライン引数とexit
手続きcommand-lineでコマンドライン引数を取ることができます。 exitでプロセスを抜けられます。
補助算術手続き
fixnum専用演算、flonum専用演算が用意された。コンパイラはこれらが使われてたら ばりばり最適化できます。
ビット演算も入りました。
syntax-case
低レベルな健全マクロ。
ハッシュテーブル
順当に入りました。ハッシュテーブルのAPIはScheme実装間でえらいバリエーションが ある (Cf x:Concept:HashTable) ので、それをうまく避けて新しい APIを定義しています (Cf. x:hashtable-ref)。
列挙
シンボルのセットを列挙型として使うためのインフラ。 I/Oのファイルオプションとかエンディアン指定なんかで使ってるので そのインフラとして入っていると思われます。
eval
evalのための環境の指定方法が変わりました。environment手続きによって 一種の一時的な匿名名前空間を作り、その中でeval出来るようになっています。
既存のライブラリやトップレベルプログラムの束縛をいじることは出来ないので、 まあ、コンパイラに優しい仕様と言えるでしょう。
変更可能なペア
set-car!とset-cdr!. R6RS:変更点参照。
変更可能な文字列
string-set!とstring-fill!. R6RS:変更点参照。
R5RS互換ライブラリ
R6RS:変更点参照。