我应该为Guile项目中的每个文件定义单独的模块吗?

时间:2019-07-07 02:32:46

标签: module scheme guile

让我通过比较来说明我的问题。在Common Lisp中,我可以将包定义拆分为多个文件,足以在每个文件中声明它们分别为in-packageload

但是在Guile Scheme中,我似乎应该define-module,为每个文件分开吗?好吧,我仍然可以load像在CL中那样运行某些文件,并且看起来可以正常工作,define-modules似乎不限于像在CL中那样位于单个文件中,但是我会收到有关未定义名称的警告(是在load版文件中定义的),因此我感到这不是Guile期望的。是否有(1)像在CL中那样在多个文件之间拆分模块的方法,或者(2)我应该分别使用use-module自动加载功能和每个文件的define-module吗?

1 个答案:

答案 0 :(得分:1)

实际上,您可以在loaddefine-moduledefine-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中使用它