言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

r6rs library

SchemeR6RS でライブラリを書く方法について調べてみた。

プログラムを書く時に、色んな人が適当なライブラリを書くと関数名がダブってしまう事がよくあります。R6RS ではライブラリという仕組みを使って名前のダブリを防ぎます。

まず自分の書いたプログラムからライブラリを使う方法です。

;; hello.ss
(import (rnrs))
(display "Hello, World!\n")

このプログラムでは、rnrs というライブラリの中にある display 関数を使って "Hello, World!\n" を表示します。プログラムを実際に使う方法は Scheme の実装によって微妙に違います。PLT-Scheme の場合

$ plt-r6rs hello.ss
Hello, World!

ikarus の場合

$ ikarus --r6rs-script hello.ss 
Hello, World!

のようになります。

これでライブラリを呼ぶ方法が分かりました。次にライブラリを書きます。ライブラリを書くには library という特別な構文を使います。例として、"Hello, World!\n" を出力する say-hello 関数をライブラリにしてみます。

;; my-lib/main.ss
#!r6rs

(library (my-lib)
  (export say-hello)
  (import (rnrs))
  
  (define (say-hello)
    (display "Hello, World!\n")))

まずプログラムの最初の #!r6rs は何のために必要なのか分かりませんがとにかく無いと PLT が文句を言います。

次に、library の後ろにライブラリ名 (my-lib) を書きます。このようにライブラリ名はシンボルのリストになっています。export というのはライブラリの中で公開したい関数名です。import は先ほどと同じく display を呼ぶために使っています。

つまり、R6RS のライブラリは、ライブラリ名、公開したい関数名、参照しているライブラリ名、ライブラリ本体から成ります。このライブラリを使うメインプログラムを作ります。

;; hello2.ss
(import (my-lib))
(say-hello)

さて、ここで問題は、このメインプログラムとライブラリの配置方法です。なんと R6RS では、ライブラリの書き方だけが指定されていてどのようにファイルに置くか決められていません! しかし PLT も ikarus も同じ方法でいけるみたいなのでご紹介します。ライブラリの名前が my-lib の時、my-lib という名前のディレクトリを作ってその中に main.ss という名前でライブラリを保存します。

それからプログラムの実行方法は PLT の場合 ++path でライブラリの位置を指定して

$ plt-r6rs ++path . hello2.ss
Hello, World!

ikarus の場合

$ ikarus --r6rs-script hello2.ss
Hello, World!

となります。他にも階層的ライブラリの作り方、特定の名前だけインポートする方法など数多くの機能がありますが省略します。