解释多个模块
Interpreting multiple modules
我想在我的程序中有多个模块。例如。模块 foo
和模块 bar
。模块 foo
将引用模块 bar
。然后我希望能够在 csi(解释)repl 中测试这些模块。这个问题的根源是我是否可以 运行 我的代码而无需编译它。下面是我的例子。
注意:我是scheme新手,所以这段代码可能还有其他问题。有什么不对的地方欢迎指出,我会尽量改正。
foo.scm
(use r7rs)
(define-library (foo)
(import (scheme base)
(prefix bar bar:))
(export add-some-stuff)
(begin
(define baz 1)
(define (add-some-stuff)
(+ baz bar:bork))
))
bar.scm
(use r7rs)
(define-library (bar)
(import (scheme base))
(export bork)
(begin
(define bork 2)))
结果希望是:
$ csi
> ,l foo.scm
> (import (prefix foo foo:))
> (foo:add-some-stuff)
;;=> 3
这是我得到的错误:
$ csi -q
#;1> ,l foo.scm
; loading foo.scm ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/chicken.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/foreign.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-4.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/extras.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-13.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-compile-time.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-library.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.so ...
Note: re-importing already imported syntax: syntax-rules
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: define-record-type
Note: re-importing already imported syntax: include
Note: re-importing already imported syntax: include
Note: re-importing already imported syntax: import
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.so ...
Note: re-importing already imported syntax: syntax-rules
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
Error: (import) during expansion of (import ...) - cannot import from undefined module: bar
Call history:
numbers.scm:1672: scan-real
<syntax> (define-library (foo) (import (scheme base) (prefix bar bar:)) (export add-some-stuff) (begin (defin...
<syntax> (##core#module foo ((##r7rs#foo)) (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#u...
<syntax> (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#undefined))))
<syntax> (##core#lambda _ (quote (##core#undefined)))
<syntax> (##core#begin (##core#quote (##core#undefined)))
<syntax> (##core#quote (##core#undefined))
<syntax> (##core#undefined)
<syntax> (##sys#provide (##core#quote foo))
<syntax> (##core#quote foo)
<syntax> (import-for-syntax (only r7rs begin cond-expand export import import-for-syntax include include-ci s...
<syntax> (##core#undefined)
<syntax> (import (only r7rs begin cond-expand export import import-for-syntax include include-ci syntax-rules...
<syntax> (##core#undefined)
<syntax> (##core#begin (import (scheme base) (prefix bar bar:)) (##core#begin (export add-some-stuff) (##core...
<syntax> (import (scheme base) (prefix bar bar:)) <--
#;1>
这有一些问题:
加载 bar
模块的语法错误,import
需要一个库列表,其中 (scheme base)
是一个,(prefix bar bar:)
会是另一个。
虽然 R7RS egg 添加了对其模块语法的支持,但它重用了现有的模块加载支持,这依赖于将模块编译到共享库和可加载位置的导入库,如 egg存储库或当前目录。因此,在使用它们之前,您必须使用 csc -R r7rs -sJ
以正确的顺序编译这两个模块。
csc -R r7rs -sJ bar.scm
成功,csc -R r7rs -sJ foo.scm
不成功。这是因为前一个调用由于 (define-library (other-module) ...)
而发出 other-module.import.scm
。这需要更改以匹配您将其导入的标识符。
通过这些更改,我可以成功地重现您的示例会话。以下是构建步骤和输入文件的摘要:
csc -R r7rs -sJ bar.scm
csc -R r7rs -sJ foo.scm
foo.scm
(use r7rs)
(define-library (foo)
(import (scheme base)
(prefix bar bar:))
(export add-some-stuff)
(begin
(define baz 1)
(define (add-some-stuff)
(+ baz bar:bork))
))
bar.scm
(use r7rs)
(define-library (bar)
(import (scheme base))
(export bork)
(begin
(define bork 2)))
#chicken irc 频道的 Kooda 推荐了 system egg,它似乎符合我的要求。简而言之,需要创建一个 .system
文件来指定依赖树,如下所述。有点不幸的是,Chicken Scheme 无法通过查看每个模块中的 import 语句来找出内部模块依赖关系,但我认为这是下一个最好的选择。
$ chicken-install system
创建一个名为 so-question-chicken-scheme.system
的文件。该文件应包含:
(define-system so-question-chicken-scheme
(scheme-file "bar")
(scheme-file "foo" depends: '("bar")))
这是解释器结果
$ csi -q
#;1> (use system)
#;2> (load "so-question-chicken-scheme.system")
#;3> (load-system so-question-chicken-scheme)
#;4> (import (prefix foo foo:))
#;5> foo:add-some-stuff
#<procedure (add-some-stuff)>
#;6> (foo:add-some-stuff)
3
我想在我的程序中有多个模块。例如。模块 foo
和模块 bar
。模块 foo
将引用模块 bar
。然后我希望能够在 csi(解释)repl 中测试这些模块。这个问题的根源是我是否可以 运行 我的代码而无需编译它。下面是我的例子。
注意:我是scheme新手,所以这段代码可能还有其他问题。有什么不对的地方欢迎指出,我会尽量改正。
foo.scm
(use r7rs)
(define-library (foo)
(import (scheme base)
(prefix bar bar:))
(export add-some-stuff)
(begin
(define baz 1)
(define (add-some-stuff)
(+ baz bar:bork))
))
bar.scm
(use r7rs)
(define-library (bar)
(import (scheme base))
(export bork)
(begin
(define bork 2)))
结果希望是:
$ csi
> ,l foo.scm
> (import (prefix foo foo:))
> (foo:add-some-stuff)
;;=> 3
这是我得到的错误:
$ csi -q
#;1> ,l foo.scm
; loading foo.scm ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/chicken.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/foreign.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-4.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/extras.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-13.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-compile-time.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-library.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.so ...
Note: re-importing already imported syntax: syntax-rules
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: define-record-type
Note: re-importing already imported syntax: include
Note: re-importing already imported syntax: include
Note: re-importing already imported syntax: import
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.so ...
Note: re-importing already imported syntax: syntax-rules
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
Note: re-importing already imported syntax: cond-expand
Note: re-importing already imported syntax: import-for-syntax
Note: re-importing already imported syntax: import
Error: (import) during expansion of (import ...) - cannot import from undefined module: bar
Call history:
numbers.scm:1672: scan-real
<syntax> (define-library (foo) (import (scheme base) (prefix bar bar:)) (export add-some-stuff) (begin (defin...
<syntax> (##core#module foo ((##r7rs#foo)) (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#u...
<syntax> (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#undefined))))
<syntax> (##core#lambda _ (quote (##core#undefined)))
<syntax> (##core#begin (##core#quote (##core#undefined)))
<syntax> (##core#quote (##core#undefined))
<syntax> (##core#undefined)
<syntax> (##sys#provide (##core#quote foo))
<syntax> (##core#quote foo)
<syntax> (import-for-syntax (only r7rs begin cond-expand export import import-for-syntax include include-ci s...
<syntax> (##core#undefined)
<syntax> (import (only r7rs begin cond-expand export import import-for-syntax include include-ci syntax-rules...
<syntax> (##core#undefined)
<syntax> (##core#begin (import (scheme base) (prefix bar bar:)) (##core#begin (export add-some-stuff) (##core...
<syntax> (import (scheme base) (prefix bar bar:)) <--
#;1>
这有一些问题:
加载
bar
模块的语法错误,import
需要一个库列表,其中(scheme base)
是一个,(prefix bar bar:)
会是另一个。虽然 R7RS egg 添加了对其模块语法的支持,但它重用了现有的模块加载支持,这依赖于将模块编译到共享库和可加载位置的导入库,如 egg存储库或当前目录。因此,在使用它们之前,您必须使用
csc -R r7rs -sJ
以正确的顺序编译这两个模块。csc -R r7rs -sJ bar.scm
成功,csc -R r7rs -sJ foo.scm
不成功。这是因为前一个调用由于(define-library (other-module) ...)
而发出other-module.import.scm
。这需要更改以匹配您将其导入的标识符。
通过这些更改,我可以成功地重现您的示例会话。以下是构建步骤和输入文件的摘要:
csc -R r7rs -sJ bar.scm
csc -R r7rs -sJ foo.scm
foo.scm
(use r7rs)
(define-library (foo)
(import (scheme base)
(prefix bar bar:))
(export add-some-stuff)
(begin
(define baz 1)
(define (add-some-stuff)
(+ baz bar:bork))
))
bar.scm
(use r7rs)
(define-library (bar)
(import (scheme base))
(export bork)
(begin
(define bork 2)))
#chicken irc 频道的 Kooda 推荐了 system egg,它似乎符合我的要求。简而言之,需要创建一个 .system
文件来指定依赖树,如下所述。有点不幸的是,Chicken Scheme 无法通过查看每个模块中的 import 语句来找出内部模块依赖关系,但我认为这是下一个最好的选择。
$ chicken-install system
创建一个名为 so-question-chicken-scheme.system
的文件。该文件应包含:
(define-system so-question-chicken-scheme
(scheme-file "bar")
(scheme-file "foo" depends: '("bar")))
这是解释器结果
$ csi -q
#;1> (use system)
#;2> (load "so-question-chicken-scheme.system")
#;3> (load-system so-question-chicken-scheme)
#;4> (import (prefix foo foo:))
#;5> foo:add-some-stuff
#<procedure (add-some-stuff)>
#;6> (foo:add-some-stuff)
3