• R7RSライブラリ形式: | ||
• R7RS基本ライブラリ: | scheme.base
| |
• R7RS case-lambda: | scheme.case-lambda
| |
• R7RS文字ライブラリ: | scheme.char
| |
• R7RS複素数: | scheme.complex
| |
• R7RS cxrアクセサ: | scheme.cxr
| |
• R7RS eval: | scheme.eval
| |
• R7RSファイルライブラリ: | scheme.file
| |
• R7RS非正確数: | scheme.inexact
| |
• R7RS遅延評価: | scheme.lazy
| |
• R7RS load: | scheme.load
| |
• R7RSプロセスコンテキスト: | scheme.process-context
| |
• R7RS read: | scheme.read
| |
• R7RS repl: | scheme.repl
| |
• R7RS time: | scheme.time
| |
• R7RS write: | scheme.write
| |
• R5RS compatibility: | scheme.r5rs
|
R7RSのライブラリはdefine-library
フォームで定義されます。
R7RSの観点ではdefine-library
フォーム自体はSchemeコードではありません。
それ自身はScheme世界の外にあります。define-library
フォームが、
R7RS Schemeの境界となるのです。その内側はR7RSの世界であり、
その外側に関してR7RSは関知しません。例えば、R7RSの仕様の範囲内では、
define-library
フォーム自体をマクロで生成する、ということはできません。
Gaucheでは、R7RSの世界をGaucheの世界の中に作っています。
define-library
自体はGauche世界で解釈されます。実際、
define-library
はGaucheのマクロとして実装されています。
けれどもR7RSのコードを書く際には、define-library
がどう実装されているかは
気にする必要はありません。また、define-library
の外側には
何も書かないようにしてください。
[R7RS] library-nameという名前を持つライブラリを定義します。 library-nameはシンボルもしくは10進整数のリストです。
<library-name> : (<identifier-or-base-10-integer> <identifier-or-base-10-integer> ...)
ライブラリ宣言library-declは、エクスポート宣言、
インポート宣言、begin
に囲まれたSchemeコード、
インクルードフォーム、あるいはcond-expand
フォームです。
<library-decl> : (export <export-spec> ...) | <import declaration> | (begin <command-or-definition> ...) | (include <string> <string2> ...) | (include-ci <string> <string2> ...) | (include-library-declarations <string> <string2> ...) | (cond-expand <cond-expand-clause> <cond-expand-clause2> ...) | (cond-expand <cond-expand-clause> <cond-expand-clause2> ... (else <library-decl> ...))
export
宣言はGaucheのexport
フォームと同じです。
モジュールの使用参照。
import
宣言はR7RSのimport
フォームで、
3つのimport形式で説明しています。
include
とinclude-ci
フォームはGaucheのそれと同じです。
インクルード参照。Gaucheはインクルードされるコードの中身については
感知せず、単にその中身をbegin
で囲んで元のフォームと
置き換えるだけです。けれどもR7RSでは、これらのフォームが読み込むファイルには
Schemeコードのみが許されます(例えばdefine-library
フォームや
他のライブラリ宣言フォームはだめです)。
include-library-declarations
宣言はinclude
宣言と
同じように動作しますが、読み込まれるファイルの中身はSchemeコードではなく
ライブラリ宣言として解釈されます。
cond-expand
宣言もGaucheのそれと同じです。
機能条件式参照。
但し、define-library
の直下で使われた場合は、
展開結果もライブラリ宣言になっている必要があります。
scheme.base
- R7RS基本ライブラリ ¶R7RSの(scheme base)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は(import (scheme base))
とすることで
使えます。
以下の構文の手続きはGaucheの組み込みのものと同じです。
quote if include include-ci
cond case and or when unless cond-expand let let* letrec letrec* let-values let*-values begin do make-parameter parameterize guard quasiquote unquote unquote-splicing case-lambda
let-syntax letrec-syntax syntax-rules syntax-error define-syntax
define-values
define-record-type
eqv? eq? equal?
number? complex? real? rational? integer? exact? exact-integer? = < > <= >= zero? positive? negative? odd? even? max min + * - / abs floor/ floor-quotient floor-remainder truncate/ truncate-quotient truncate-remainder quotient modulo remainder gcd lcm numerator denominator floor ceiling truncate round rationalize square exact-integer-sqrt expt inexact exact number->string string->number
not boolean? boolean=?
pair? cons car cdr set-car! set-cdr! caar cadr cdar cddr null? list? make-list list length append reverse list-tail list-ref list-set! memq memv member assq assv assoc list-copy
symbol? symbol=? symbol->string string->symbol
char? char=? char<? char>? char<=? char>=? char->integer integer->char
string? make-string string string-length string-ref string-set! string=? string<? string>? string<=? string>=? substring string-append string->list list->string string-copy string-copy! string-fill! string-map string-for-each
vector? make-vector vector vector-length vector-ref vector-set! vector->list list->vector vector->string string->vector vector-copy vector-copy! vector-append vector-fill!
procedure? apply map call-with-current-continuation call/cc values call-with-values dynamic-wind
error
scheme-report-environment null-environment
input-port? output-port? port? current-input-port current-output-port current-error-port close-port close-input-port close-output-port open-input-string open-output-string get-output-string read-char peek-char read-u8 peek-u8 read-line eof-object? eof-object char-ready? u8-ready? newline write-char write-u8
次の2つの識別子は、scheme
モジュールにあるものがエクスポートされます。
これらはgauche
モジュールの束縛とは異なることに注意してください。
Gaucheの拡張引数(:key
、:optional
等)は認識されません。
define lambda
R7RSのバイトベクタはGaucheのu8vectorと同じです。
以下の手続きはgauche.uvector
のものと同じです。
(バイトベクタ互換性参照)。
bytevector bytevector? make-bytevector bytevector-length bytevector-u8-ref bytevector-u8-set! bytevector-copy bytevector-copy! bytevector-append read-bytevector read-bytevector! write-bytevector
以下の手続きはgauche.vport
のものと同じです。
(gauche.vport
- 仮想ポート参照)。
open-input-bytevector open-output-bytevector get-output-bytevector
そして以下の手続きはgauche.unicode
のものと同じです。
(Unicode transfer encodings参照)。
utf8->string string->utf8
手続きwith-exception-handler
はGauche組み込みのものと同じです。
下位レベルの例外処理機構で説明してあります。
[R7RS base]
{scheme.base
}
Gaucheのraise
は、objが<serious-condition>
でなければ、
例外ハンドラから戻って来ることを許しています。
継続可能な例外報告と継続不可能な例外報告を手続きで区別するのは、
例外ハンドラが渡されたコンディションを再び投げる場合に問題となります
(元のコンディションがraise
で投げられたのかraise-continuable
で
投げられたのか知る術がない!)。
しかしR7RSではそのモデルを採用したため、何とか合わせようとしています。
R7RS版のraise
はGaucheのraise
のラッパーで、
Gaucheのraise
から戻って来たらエラーを投げるようにしています。
R7RSのraise-continuable
は今のところGaucheのraise
の
別名になっています。<serious-condition>
を渡さなければ、
戻ってくることが可能です。R7RS準拠でないのは、
<serious-condition>
かそのサブクラスのオブジェクト(例えば<error>
)を
raise-continuable
に渡した場合ですが、
<error>
を投げて戻って来ることを期待するというのはちょっとおかしいですよね。
[R7RS base]
{scheme.base
}
(condition-has-type? exc <error>))
として定義されています。
[R7RS base]
{scheme.base
}
excが<message-condition>
であれば
message-prefix
の内容を、持っていなければ空文字列を返します。
[R7RS base]
{scheme.base
}
excが<message-condition>
であれば
message-args
の内容を、持っていなければ空文字列を返します。
[R7RS base]
{scheme.base
}
(condition-has-type? e <read-error>))
として定義されています。
[R7RS base]
{scheme.base
}
今のところ、Gaucheは独立した<file-error>
コンディションを持っていませんが、
ファイルエラーのほとんどは<system-error>
として投げられます。
この手続きは<system-error>
のエラーコードを調べ、ファイルに起因するエラー
の場合に#t
を返すようにしています。
[R7RS base]
{scheme.base
}
Gaucheのポートはどちらも扱えるので、これらの手続きはport?
と等価です。
[R7RS base]
{scheme.base
}
iport/oportがそれぞれ入力/出力ポートであり、かつクローズされていなければ
#t
を返します。
[R7RS base]
{scheme.base
}
サポートされているfeature-identifier
のリストを返します。
feature-identifier
については、cond-expand
を参照してください
(機能条件式参照)。
scheme.case-lambda
- R7RS case-lambda ¶R7RSの(scheme case-lambda)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme case-lambda))
とすることで使えます。
このモジュールからエクスポートされるのはcase-lambda
だけで、
Gauche組み込みのcase-lambda
そのものです。
詳しくは手続きを作るを参照してください。
scheme.char
- R7RS文字ライブラリ ¶R7RSの(scheme char)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme char))
とすることで使えます。
以下の手続きはGaucheの組み込みのものと同じです。文字参照。
char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-foldcase char-lower-case? char-numeric? char-upcase char-upper-case? char-whitespace?
以下の手続きはgauche.unicode
で提供されているものと同じです
(フルセットの大文字小文字変換参照)。Unicodeで定義されている
フルセットの大文字小文字変換を使います(例えばドイツ語のエスツェットが考慮されます)。
string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-downcase string-foldcase string-upcase
[R7RS char]
{scheme.char
}
cがNd
カテゴリの文字、つまり十進数の数字を表す文字であれば、
その文字が表す値を返します。それ以外の場合は#f
を返します。
(digit-value #\3) ⇒ 3 (digit-value #\z) ⇒ #f
Unicodeには20種類以上の数字が定義されています。
(digit-value #\x11068) ⇒ 2
Gauche組み込みのdigit->integer
はより汎用的なインタフェースを
持っています(文字参照)。
(digit-value c) ≡ (digit->integer c 10 #t)
scheme.complex
- R7RS複素数 ¶R7RSの(scheme complex)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme complex))
とすることで使えます。
このモジュールは以下の束縛を提供します。 全てGaucheの組み込みです(数値の変換参照)。
angle imag-part magnitude make-polar make-rectangular real-part
scheme.cxr
- R7RS cxrアクセサ ¶R7RSの(scheme complex)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme complex))
とすることで使えます。
このモジュールは以下の束縛を提供します。 全てGaucheの組み込みです(リストへのアクセスと変更参照)。
caaar caadr cadar caddr cdaar cdadr cddar cdddr caaaar caaadr caadar caaddr cadaar cadadr caddar cadddr cdaaar cdaadr cdadar cdaddr cddaar cddadr cdddar cddddr
scheme.eval
- R7RS eval ¶R7RSの(scheme eval)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme eval))
とすることで使えます。
このモジュールはeval
をエクスポートします。これはGauche組み込みのevalと
同じです(eval と repl参照)。
[R7RS eval]
{scheme.eval
}
これはR7RSでeval
に渡せる環境指定子を作る手段です。Gaucheでは、
環境指定子は単なるモジュールオブジェクトです。
引数はr7rs#import
が取るものと同じです。
この手続きはまず空の環境(=無名のモジュールです。
詳しくはモジュールイントロスペクションのmake-module
参照)を作り、
それからimport-listに指定される束縛をインポートします。
以下の例は、scheme.base
及びGauche組み込みのselect-module
を
インポートした環境を作ります。
(environment '(scheme base) '(only (gauche base) select-module)) ⇒ #<module #f> ; an anonymous module
scheme.file
- R7RSファイルライブラリ ¶R7RSの(scheme file)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme file))
とすることで使えます。
次に挙げる束縛はGaucheの組み込みと同じです (ファイルポート及びファイルの状態参照)。
call-with-input-file call-with-output-file file-exists? open-input-file open-output-file with-input-from-file with-output-to-file
以下の束縛はfile.util
で提供されるものと同じです
(ファイル操作参照)。
delete-file
[R7RS file]
{scheme.file
}
Gaucheでは、ポートは同時にテキストポートでもバイナリポートでもあるので、
これらのR7RS手続きは単に
open-input-file
とopen-output-file
の別名になっています。
ファイルポート参照。
scheme.inexact
- R7RS非正確数 ¶R7RSの(scheme inexact)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme inexact))
とすることで使えます。
このモジュールは以下の束縛を提供します。全てGaucheの組み込みです (数値の演算及び数値に関する述語参照)。
acos asin atan cos exp finite? infinite? log nan? sin sqrt tan
scheme.lazy
- R7RS遅延評価 ¶R7RSの(scheme inexact)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme inexact))
とすることで使えます。
以下の束縛は、Gauche組み込みです (Delayとforceとlazy参照)。
delay force promise?
[R7RS lazy]
{scheme.lazy
}
これはGauche組み込みのlazy
と同じです。
使い方についてはDelayとforceとlazyの議論を参照してください。
[R7RS lazy]
{scheme.lazy
}
objがプロミスならそのまま返されます。そうでなければ、
forceされた時にobjが返されるようなプロミスが返されます。
これは手続きなので、objはmake-promise
を呼び出す前に
評価されてしまいます。従って遅延評価には使えませんが、
確実にプロミスを得たい場合に使えます。
force
がプロミスのみを取るような実装ではこの手続きは重要です。
ポータブルなコードは、force
に渡すものがプロミスであることを
確実にしたい場所でこの手続きを使うようにしてください。
Gaucheのforce
はプロミスでない値も取れるので、
Gauche専用のコードを書いている時はこの手続きは不要です。
註: Gaucheの組み込みのmake-promise
はSRFI-226で定義された動作で、
このmake-promise
とは若干違います。
(Delayとforceとlazy参照)。
scheme.load
- R7RS load ¶R7RSの(scheme load)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme load))
とすることで使えます。
[R7RS load]
{scheme.load
}
R7RSのload
は省略可能引数として環境を取ります。
Gaucheのload
では環境はキーワード引数で受け取られることに注意してください。
Schemeファイルのロード参照。
また、Gaucheでは環境は単にモジュールで良いのですが、
ポータブルなコードではR7RSのenvironment
手続きを使って
環境を作る必要があります。scheme.eval
- R7RS eval参照。
scheme.process-context
- R7RSプロセスコンテキスト ¶R7RSの(scheme process-context)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、エクスポートされた束縛は
(import (scheme process-context))
とすることで使えます。
次の束縛はGauche組み込みのものと同じです (コマンドライン引数、およびプログラムの終了参照):
command-line exit
次の束縛はSRFI-98のものと同じです
(srfi.98
- 環境変数へのアクセス参照):
get-environment-variable get-environment-variables
[R7RS process-context]
{scheme.process-context
}
クリーンアップ手続きを飛ばしてプログラムを直ちに終了させます
(dynamic-wind
によって設定されたafterサンクは実行されません)。
内部的には、_exit(2)
システムコールを直接呼んでいます。
省略可能引数はプロセスの終了コードを指定します。
R7RSでは具体的な終了コードの値は示されておらず、ただ#t
が「成功」を、
#f
が「失敗」を意味するとされています。Gaucheでは#t
を終了コード0に、
#f
を終了コード1に対応させています。ポータブルなコードでは真偽値のみを渡してください。
これ以外のcodeの意味については、exit
のエントリを参照してください。
(プログラムの終了)。
scheme.read
- R7RS read ¶R7RS (scheme read)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、
(import (scheme read))
とすることでこれらの名前が使えるようになります。
このモジュールからエクスポートされるのはread
のみで、
これはGaucheでは組み込みになっています。データの読み込み参照。
scheme.repl
- R7RS repl ¶R7RS (scheme repl)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、
(import (scheme repl))
とすることでこれらの名前が使えるようになります。
このモジュールからエクスポートされるのはinteraction-environment
のみで、
これはGaucheでは組み込みになっています。eval と repl参照。
scheme.time
- R7RS time ¶R7RS (scheme time)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、
(import (scheme time))
とすることでこれらの名前が使えるようになります。
[R7RS time]
{scheme.time
}
国際原子時(TAI)の1970年1月1日0時から現在までの経過秒数を実数で返します。
(これは、Unix Epochの8秒前、国際標準時(UTC)で1969年12月31日23:59:52に相当します)。
この起点以来、閏秒がしばしば挿入されてきて、2017年現在、UTCはTAIより37秒遅れています。
すなわち、この手続きが返す秒数は、sys-time
やsys-gettimeofday
が
返すUnix timeより29秒大きい値です。
R7RSがTAIを採用したのは、それが狭義単調増加であり、二つの時刻の差をとるのに
適しているからです。sys-time
やsys-gettimeofday
は
UTCの日付と時間に基づいているので、二つの時刻が閏秒を挟んでいた場合、
差は経過秒数を表しません。
(Unix Timeの正確な定義については、
IEEE Std 1003.1, 2013年版の4.15節、いわゆるSingle Unix Specification 4を参照)。
ただ、次にいつ閏秒が来るかはわからないので、現在の実装では単純に Unix Timeから固定オフセットを引いています。
この差異があることは頭の隅に留めておいてください。
でないと、current-second
の戻り値を
sys-strftime
などUTC時刻のフォーマッタに渡したり、
Unix Timeで表されたタイムスタンプと比較した時にびっくりするかもしれません。
TAIとUTCはSRFI-19で変換できます (日付)。
[R7RS time]
{scheme.time
}
過去のどこかの時点を基準とする、実経過時間を正確な整数で返します。
基準時点はプロセスの起動ごとに変わるかもしれません。
1単位は1秒のjiffies-per-second
分の1です。
「現在のjiffy値」の絶対値に意味はありません。差を取って経過時間を測るのに使います。
[R7RS time]
{scheme.time
}
current-jiffy
が返す時間単位が、1秒あたりいくつあるかを示す定数を返します。
現在のGaucheの実装では、64ビットアークテクチャで10^9 (ナノ秒単位)、
32ビットアーキテクチャで10^4 (100マイクロ秒単位)です。
32ビットアーキテクチャでの分解能がかなり粗いですが、 jiffy値がbignumにオーバーフローするのを防ぐ方を優先しました。 bignumになるとアロケーションが頻繁に起きるのでベンチマークに干渉してしまいます。 現在の数値では、32ビットアーキテクチャだとプロセス開始後53,867杪でbignumになります。 64ビットアーキテクチャではナノ秒単位で測ってもbignumになることを 現実的に心配する必要はありません。
32ビットアーキテクチャでより精度の高いベンチマークを取りたい場合は、
sys-clock-gettime-monotonic
やsys-gettimeofday
を使ってください。
scheme.write
- R7RS write ¶R7RS (scheme write)
ライブラリの束縛をエクスポートします。
R7RSプログラムからは、
(import (scheme write))
とすることでこれらの名前が使えるようになります。
このモジュールからは以下の束縛がエクスポートされます。 いずれもGauche組み込みです (オブジェクトの出力参照)。
display write write-shared write-simple
scheme.r5rs
- R5RS互換性 ¶このモジュールは、R7RSプログラム内でR5RS環境を実現します。
次に挙げる束縛がエクスポートされます。
ここでのlambda
はscheme#lambda
で、
Gaucheの拡張機能 (:optional
など) は認識されないことに注意してください。
拡張された引数リストについては手続きを作る参照。
* + - / < <= = > >= abs acos and angle append apply asin assoc assq assv atan begin boolean? caaaar caaadr caaar caadar caaddr caadr caar cadaar cadadr cadar caddar cadddr caddr cadr call-with-current-continuation call-with-input-file call-with-output-file call-with-values car case cdaaar cdaadr cdaar cdadar cdaddr cdadr cdar cddaar cddadr cddar cdddar cddddr cdddr cddr cdr ceiling char->integer char-alphabetic? char-ci<=? char-ci<? char-ci=? char-ci>=? char-ci>? char-downcase char-lower-case? char-numeric? char-ready? char-upcase char-upper-case? char-whitespace? char<=? char<? char=? char>=? char>? char? close-input-port close-output-port complex? cond cons cos current-input-port current-output-port define define-syntax delay denominator display do dynamic-wind eof-object? eq? equal? eqv? eval even? exact->inexact exact? exp expt floor for-each force gcd if imag-part inexact->exact inexact? input-port? integer->char integer? interaction-environment lambda lcm length let let* let-syntax letrec letrec-syntax list list->string list->vector list-ref list-tail list? load log magnitude make-polar make-rectangular make-string make-vector map max member memq memv min modulo negative? newline not null-environment null? number->string number? numerator odd? open-input-file open-output-file or output-port? pair? peek-char positive? procedure? quasiquote quote quotient rational? rationalize read read-char real-part real? remainder reverse round scheme-report-environment set! set-car! set-cdr! sin sqrt string string->list string->number string->symbol string-append string-ci<=? string-ci<? string-ci=? string-ci>=? string-ci>? string-copy string-fill! string-length string-ref string-set! string<=? string<? string=? string>=? string>? string? substring symbol->string symbol? tan truncate values vector vector->list vector-fill! vector-length vector-ref vector-set! vector? with-input-from-file with-output-to-file write write-char zero?