@section 独自拡張

@subsection ファイルのロード

@defspec load ファイル名
戻り値: 未定義@*
[R5RS]Schemeソースファイルを読み込みます。
リソースファイルは変数*load-path*のリストにあるディレクトリ配下から検索され、最後にカレントディレクトリ配下のリソースが検索されます。ファイル名の拡張子".scm"は省略することができます。
@end defspec

@defvar *load-path*
loadにてリソースファイルを検索するときのディレクトリのパスが格納されている変数です。変更するときは専用の手続きload-use-pathを使用してください。
@end defvar

@defspec add-load-path ディレクトリ名 [endflg]
戻り値: 未定義@*
*load-path*にパッケージパスを追加するときに使用する特殊形式です。endflgに#tを指定すると*load-path*の末尾にパスが追加されます。その他の時は*load-path*の先頭に追加されます。
@end defspec

@defspec use リソースファイルパス
戻り値: 未定義@*
Javaのリソースファイルとして存在するSchemeソースファイルを読み込みます。
リソースファイルは変数*use-path*のリストにあるパッケージ配下から検索され、最後にルート(デフォルト)パッケージ配下のリソースが検索されます。ファイル名の拡張子".scm"は省略することができます。
@end defspec

@defvar *use-path*
useにてリソースファイルを検索するときのパッケージのパスが格納されている変数です。変更するときは専用の特殊形式add-use-pathを使用してください。
*use-path*にはデフォルトでパッケージ net.morilib.lisp.libが登録されています。
@end defvar

@defspec add-use-path パッケージ名 [endflg]
戻り値: 未定義@*
*use-path*にパッケージパスを追加するときに使用する特殊形式です。endflgに#tを指定すると*use-path*の末尾にパスが追加されます。その他の時は*use-path*の先頭に追加されます。
@end defspec


@subsection Javaクラスの使用

@defspec  . instance method args
@defspecx . classname method args
戻り値: Javaメソッドの戻り値に対応する値@*
Javaのメソッドを呼び出します。@*
第1引数に束縛済みの変数を与えたときはそのJavaインスタンスのメソッドを呼び出します。@*
第1引数に未束縛のシンボルを与えたときはシンボルをクラス名としてstaticなメソッドを呼び出します。
@end defspec

@defspec new classname args
戻り値: Javaインスタンス@*
Javaクラスのコンストラクタを呼び出します。
@end defspec

@defspec java-import 内部クラス名 クラスパス
戻り値: 未定義@*
クラスパスで指定されたJavaクラスを定義します。
この形式は、

@itemize @bullet
@item    プロパティに対しては"内部クラス名- プロパティ名"という名称のアクセサ手続き
@item    その他のメソッドに対しては"内部クラス名-メソッド"という名称の手続き
@end itemize

を自動的に生成します。
@end defspec

@defun java-new 内部クラス名 コンストラクタ引数 @dots{}
戻り値: Javaインスタンス@*
Javaのインスタンスを生成します。
コンストラクタに与える引数は内部でSchemeのデータ型に対応するJavaの型に変換されてコンストラクタに与えられます。リストはJavaの配列に変換されます。
@end defun

@defun 内部クラス名-プロパティ名 Java インスタンス [index]
戻り値: Javaの値がScheme型に変換できるときはScheme型、それ以外はJavaインスタンス@*
Javaインスタンスのプロパティにアクセスします。たとえば、

@example
package example;
public class Bean1 @{
    private String prop1;
    private String[] prop2 = new String[10];
    public String getProp1() @{ return prop1; @}
    public String setProp1(String x) @{ prop1 = x; @}
    public String getProp2(int i) @{ return prop2[i]; @}
    public String setProp2(int i, String x) @{
        prop2[i] = x;
    @}
@}
@end example

で定義されたJavaBeanがあり、

@example
(java-import bean1 example.Bean1)
(define b (java-new bean1))
@end example

でBeanを定義したとするとき、prop1の値を得るときには、

@example
(bean1-prop1 b)
@end example

prop2の0番目の値を得るときには、

@example
(bean1-prop2 b 0)
@end example

とすれば得られます。
プロパティに値をセットしたいときには一般化されたset!を用います。たとえば上記の例でprop1に文字列"abc"をセットしたいときは、

@example
(set! (bean1-prop1 b) "abc")
@end example

prop2の2番目のインデックスに文字列"string"をセットしたいときは、

@example
(set! (bean1-prop1 b 2) "string")
@end example

とすればセットできます。
@end defun

@defun 内部クラス名-メソッド名 Javaインスタンス 引数 @dots{}
戻り値: Javaの値がScheme型に変換できるときはScheme型、それ以外はJavaインスタンス@*
Javaインスタンスのメソッドにアクセスします。たとえば、

@example
package example;
public class Class1 @{
    public void print(String args@dots{}) @{
        for(String s : args) @{
            System.out.println(s + ":");
        @}
    @}
@}
@end example

で定義されたJavaクラスがあり、

@example
(java-import class1 example.Class1)
(define x (java-new class1))
@end example

でクラスを定義したとするとき、メソッドprintを呼び出すには、

@example
(class1-print x "a" "b" "c")
@end example

と記述します。
引数は内部でSchemeのデータ型に対応するJavaの型に変換されてコンストラクタに与えられます。リストはJavaの配列に変換されます。
メソッドがオーバーロードされているとき、メソッドは引数の型により選択されます。
@end defun


@subsection formatについて

@defun format [output-port] format args @dots{}
戻り値: output-portが#fまたは省略されたときはフォーマットされた文字列、それ以外は未定義@*
[SRFI-28+]フォーマットされた文字列を取得、または出力ポートに出力します。この手続きはSRFI-28に規定されたものに加え、Common Lispに由来するいくつかの機能を追加しています。
output-portに出力ポートが指定されたときは出力ポートにフォーマットされた文字列を出力します。output-portが#fまたは指定されなかったときはフォーマットされた文字列を戻り値として取得します。
Schluesselがサポートしているフォーマット文字列は以下の通りです。

@itemize @bullet
@item
    ~A : displayによるフォーマット
    オプションとして
        最小文字数(第1引数
        パディングされる文字長の倍数(第2引数
        少なくとも追加されるパディング文字数(第3引数
        パディング文字(第4引数
    をサポートしています。
@item
    ~S : writeによるフォーマット
    フォーマットにwriteを使用すること以外~Aと同じです。
@item
    ~D, ~B, ~O, ~X : 10進・2進・8進・16進数による整数のフォーマット
    オプションとして
        最小文字数(第1引数
        パディングされる文字長の倍数(第2引数
        桁区切りに使用する文字(第3引数 デフォルトはカンマ","
        区切る桁数(第4引数 デフォルトは3
    をサポートしています。
@item
    ~~ : チルダ"~"自身
@item
    ~% : 改行文字
@end itemize
@end defun


@subsection 伝統的なマクロ

@defspec  define-macro name procedure
@defspecx define-macro (name args @dots{}) procedure
戻り値:  未定義@*
伝統的なマクロを定義します。
@end defspec

@defun  macroexpand form
@defunx macroexpand-1 form
戻り値: マクロを展開した結果のS式@*
マクロを展開した結果を得ます。
macroexpandはマクロを展開した最終結果を得ます。
macroexpand-1は1フェーズだけマクロを展開します。
@end defun

@defun gensym
戻り値: 一時的に生成されたシンボル@*
一時的に生成されたシンボルを得ます。
@end defun


@subsection #構文の定義

@defun define-sharp-symbol pattern expression
戻り値: 未定義@*
ユーザにて#構文に関連づけられたシンボルを定義します。
patternは# 構文を定義するパターンを指定します。
パターンには以下の正規表現が使用できます。(Javaのフルの正規表現は使用できません)
@multitable @columnfractions .15 .7
@item rs @tab rとsの連結
@item r|s @tab rまたはs
@item r* @tab rの0回以上の繰り返し
@item r+ @tab rの1回以上の繰り返し
@item r? @tab rの0または1回の出現
@item (r) @tab rそのもの
@item . @tab 改行以外の任意の文字
@item [a-zA] @tab 文字セット
@item [^a-zA] @tab 補文字セット
@end multitable

例えば、

@example
(define-sharp-symbol "#s" 'success)
@end example

は、構文#sにシンボル'successを結びつけます。
@end defun

@defun define-sharp-syntax pattern expression follow-exp?
戻り値: 未定義@*
ユーザにて#構文に関連づけられた構文を定義します。
patternは# 構文を定義するパターンを指定します。
パターンはdefine-sharp-symbolと同じものが指定できます。

構文はパーサにより以下のように展開されます。

@example
(expression マッチした#構文の文字列 #構文に続くS式)
@end example

「#構文に続くS式」は引数follow-exp?が#f でないときにあたえられます。(デフォルトでは#fです

例えば、

@example
(define-sharp-syntax "#@{.*@}" (lambda (x) (display x)))
@end example

は、構文#@{@dots{}@}にマッチした構文の内容をプリントします。実行例は以下の通りです。

@example
> #@{aaaa@}
@{aaaa@}#<undef>
@end example

@example
(define-sharp-syntax "#\\?=>" (lambda (x y) (display y)) #t)
@end example

は、構文#?=>に続くS式の内容をプリントします。"?"はパターンのメタ文字のためエスケープする必要があります。"\"はSchemeのメタ文字でもあるため"\"を2つ続ける必要があります。実行例は以下の通りです。

@example
> #?=>1
1#<undef>
> #?=>(list 1 2 3)
(1 2 3)#<undef>
@end example
@end defun

@subsection 数学の特殊関数

@defun besselJ z nu
戻り値: Bessel関数@math{J_\nu(z)}@*
次数nuのBessel関数@math{J_\nu(z)}を求めます。
@math{z}は複素数、@math{\nu}は実数である必要があります。
@end defun

@defun besselY z nu
戻り値: Neumann関数@math{Y_\nu(z)}@*
次数nuのNeumann関数@math{Y_\nu(z)}を求めます。
@math{z}は複素数、@math{\nu}は実数である必要があります。
@end defun

@defun besselI z nu
戻り値: 変形Bessel関数@math{I_\nu(z)}@*
次数nuの変形Bessel関数@math{I_\nu(z)}を求めます。
@math{z}は複素数、@math{\nu}は実数である必要があります。
@end defun

@defun besselK z nu
戻り値: 変形Bessel関数@math{K_\nu(z)}@*
次数nuの変形Bessel関数@math{K_\nu(z)}を求めます。
@math{z}は複素数、@math{\nu}は実数である必要があります。
@end defun

@defun gamma z
戻り値: ガンマ関数@math{\Gamma(z)}@*
ガンマ関数@math{\Gamma(z)}を求めます。
@math{z}は複素数である必要があります。
@end defun

@subsection その他

@deffn {Reader Syntax} #[charset]
@var{charset}で与えられた文字セットを構築します。
@end deffn

@deffn  {Reader Syntax} nnn[.n]see
@deffnx {Reader Syntax} nnn[.n]fee
@deffnx {Reader Syntax} nnn[.n]dee
@deffnx {Reader Syntax} nnn[.n]lee
[R5RS] 2進浮動小数点を記述します。@*
指数部に
@itemize @bullet
@item "s"をつけると半精度
@item "f"をつけると単精度
@item "d","l"をつけると倍精度(4倍精度はサポートしていません)
@end itemize
となります。
@end deffn

@deffn  {Reader Syntax} nnn[.n]dfee
@deffnx {Reader Syntax} nnn[.n]ddee
10進浮動小数点を記述します。@*
指数部に
@itemize @bullet
@item "df"をつけるとDecimal32
@item "dd"をつけるとDecimal64
@end itemize
となります。@*
Decimal32は@math{\pm 0.000000 \times 10^{-95}}から
@math{\pm 9.999999 \times 10^{96}}まで、@*
Decimal64は@math{\pm 0.000000000000000 \times 10^{-383}}から
@math{\pm 9.999999999999999 \times 10^{384}}までの10進小数を扱えます。
@end deffn


