让我通过比较来说明我的问题。在Common Lisp中,我可以将包定义拆分为多个文件,足以在每个文件中声明它们分别为in-package
和load
。
但是在Guile Scheme中,我似乎应该define-module
,为每个文件分开吗?好吧,我仍然可以load
像在CL中那样运行某些文件,并且看起来可以正常工作,define-modules
似乎不限于像在CL中那样位于单个文件中,但是我会收到有关未定义名称的警告(是在load
版文件中定义的),因此我感到这不是Guile期望的。是否有(1)像在CL中那样在多个文件之间拆分模块的方法,或者(2)我应该分别使用use-module
自动加载功能和每个文件的define-module
吗?
答案 0 :(得分:1)
实际上,您可以在load
中define-module
内define-module
,但是它将在编译时报告未绑定的变量。
习惯用法是每个文件中的;; in earth-software-system.scm
(define-module (earth-software-system))
(use-modules (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(re-export bullet-train) ;; possibly re-exporting imported bindings
...
:
earth-software-system/bullet-train.scm
然后在;; in earth-software-system/bullet-train.scm
(define-module (earth-software-system bullet-train))
(use-modules (srfi srfi-9))
(define-public bullet-train 42)
...
中,您可以:
define-public
请注意以下事实:use-modules
和每个define-module
的单个导入并不广泛。这是GNU Guix项目中依赖(define-module (guix cpio)
#:use-module ((guix build utils) #:select (dump-port))
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-11)
#:use-module (rnrs bytevectors)
#:use-module (rnrs io ports)
#:use-module (ice-9 match)
#:export (cpio-header?
make-cpio-header
file->cpio-header
file->cpio-header*
write-cpio-header
read-cpio-header
write-cpio-archive))
进行导入和导出的示例:
import
如今,我更喜欢use-modules
的{{1}}形式:
;; in earth-software-system.scm
(define-module (earth-software-system))
(import (prefix (earth-software-system bullet-train) 'bt:)
(import (srfi srfi-9))
(re-export bt:bullet-train) ;; possibly re-exporting imported bindings
...
与使用use-modules
的前缀语法相比,前缀语法也更容易记住。这是受R6RS library
格式和R7RS define-library
格式的启发。我不建议在Guile中使用library
表单,因为它不能正确报告行数。
即使未使用@@
syntax导出表单来测试某些棘手行为,GNU Guile也允许导入表单。
您可以将load
替换为include
,但我从未在Guile中使用它