質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Scheme

Schemeは、Lispから派生したプログラミング言語の一つであり、仕様または実装を指す場合もあります。言語自体の仕様はシンプルで、関数型言語として理解しやすいことから記号処理などで主に用いられている言語です。

Q&A

解決済

2回答

635閲覧

In procedure module-lookup: Unbound variable: dimensionsというエラーが出る

ruei

総合スコア284

Scheme

Schemeは、Lispから派生したプログラミング言語の一つであり、仕様または実装を指す場合もあります。言語自体の仕様はシンプルで、関数型言語として理解しやすいことから記号処理などで主に用いられている言語です。

0グッド

0クリップ

投稿2018/10/07 20:50

編集2018/10/08 05:01

Schemeのライブラリlibctlを勉強しています。

Scheme

1(load "libctl/base/io-vars.scm") 2(load "libctl/base/matrix3x3.scm") 3(load "libctl/base/vector3.scm") 4(load "libctl/base/utils.scm") 5(load "libctl/base/class.scm") 6(load "libctl/utils/geom.scm")

を動かしてみると、

libctl/utils/geom.scm:196:0: In procedure module-lookup: Unbound variable: dimensions

というエラーがでます。
libctl/utils/geom.scmの196行目を覗くと

(define-input-var dimensions 3 'integer)

となっています。
define-input-varの定義はlibctl/base/io-vars.scmにあり、

(defmacro-public define-input-var (name init-val var-type-name . var-constraints) `(begin (define-param ,name ,init-val) (input-var! (lambda () ,name) (quote ,name) ,var-type-name ,@var-constraints)))

となっています。

エラーの原因が分かりません。
解決方法をご教示いただけると幸いです。

(define-input-var dimensions 3 'integer)を動かすのに必要そうな場所をbase/io-vars.scmから抜粋して以下のように一つのファイルにして実行するとエラーは出なくなります。

(define input-var-list '()) (define (make-var value-thunk var-name var-type-name var-constraints) (list var-name var-type-name var-constraints value-thunk)) (defmacro-public define-param (name value) `(define ,name (if (defined? (quote ,name)) ,name ,value))) (define (input-var! value-thunk var-name var-type-name . var-constraints) (let ((new-var (make-var value-thunk var-name var-type-name var-constraints))) (set! input-var-list (cons new-var input-var-list)) new-var)) (defmacro-public define-input-var (name init-val var-type-name . var-constraints) `(begin (define-param ,name ,init-val) (input-var! (lambda () ,name) (quote ,name) ,var-type-name ,@var-constraints))) ;---------ここまでbase/io-varsの抜粋------------------- (define-input-var dimensions 3 'integer)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

geom.scm の中で define-class マクロを展開しようとして、 define-class のマクロ変換子の中で使われている list-transform-positive を呼び出せなかったということですね。

これは上で説明したように、「プログラム全体のマクロ展開を先にする」というルールが効いているんだと思います。 マクロ展開が先なので、 define-class を展開しようとしたときはまだ list-transform-positive という手続きは定義されていないのです。

手続きの定義とマクロ展開の順序についてはモジュール (Scheme の用語としてはライブラリと言っています) を単位とする「メタレベル」の考え方が R6RS で整理されましたが、 libctl の側はモジュールを使わずにファイルを分けているだけという状態なので、依存関係 (定義の順序) の制御が何も出来ていません。
(import を使うのがよりよいと述べたのは、 import はモジュールを単位として依存関係を記述する新しい機構だからです。)

投稿2018/10/08 09:32

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ruei

2018/10/08 10:01

これは動かすにはimportが使えるように書き換える以外に打つ手なしでしょうか。。。
SaitoAtsushi

2018/10/08 11:19

はい。 それが最も確実な方法だと思います。 ただ、メタレベルの仕組みについて日本語で説明した書籍は存在せず、 Scheme 好きな人がブログなどで取り上げたものがわずかにあるのみです。 ましてや、 Guile 固有の事情までは日本語の情報は全くと言ってよいほど期待できません。 処理系をインストールしたばかりの初心者にとってはずいぶん長い道程になることは覚悟する必要があるでしょう。
ruei

2018/10/08 11:37

ひえ・・・。 非常に丁寧にありがとうございました。
guest

0

ベストアンサー

私の手元に Guile の実行環境がなく挙動を確認できていないので、 Scheme 一般の理屈で説明します。

load の評価タイミングはマクロ展開のタイミングとの関係が言語仕様では曖昧です。

load は (構文ではなく) 手続きですから、プログラム全体のマクロ展開を完了させてから実際の式評価に移るような処理系であったならば、今回の質問にあるような (define-input-var dimensions 3 'integer) という式が評価される時点では define-input-var というマクロは定義されていないことになります。

define-input-var がマクロなどの構文として定義されていないならば、その引数は通常の式の規則で評価しようとするので dimensions は単なる式として解釈されます。 dimensions を式として解釈しようとすればそんな変数は無いのでエラーメッセージは Unbound variable なのです。

load はそういう微妙な存在なので、簡単な解決方法は include を使うことです。 よりよい方法は import を使うことなのですが、 libctl はその方法を想定していないように見えます。

投稿2018/10/08 06:20

SaitoAtsushi

総合スコア5444

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ruei

2018/10/08 07:15 編集

loadはマクロの展開と評価のタイミングが処理系に依存しているのですね。ありがとうございます。 loadをincludeに変えたところ、次のような問題が発生しました。 (include "../../libctl/base/utils.scm") (include "../../libctl/base/vector3.scm") (include "../../libctl/base/matrix3x3.scm") (include "../../libctl/base/class.scm") (include "../../libctl/base/io-vars.scm") (include "../../libctl/base/extern-funcs.scm") (include "../../libctl/utils/ctl-io.scm") だと問題なく実行されるのですが、末尾にさらに (include "../../libctl/utils/geom.scm") を加えると、 WARNING: compilation of /xxx/sample.scm failed: ERROR: Unbound variable: list-transform-positive というエラーが出ます。list-transform-positiveはlibctl/base/utils.scmで定義されており、しかも、geom.scmをgrepで検索した限りではlist-transform-positiveというマクロは使われていないため困惑しています。原因が分かるようでしたら教えてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問