Common Lisp相当于Racket的“模块语言”

时间:2017-03-20 22:04:59

标签: lisp common-lisp racket

我想创建一个带有一组Common Lisp宏的DSL(特定于域的语言),并限制在DSL中编写的文件的解析。我没有必要定义一个特殊的语法,只是为了限制DSL的表现力,以便你不能加载包含任意命令的文件。

在Racket中,此功能由所谓的“模块语言”提供,使用except-outall-from-out等表单来定义DSL中可用的语言绑定,请参阅{{3} }

您还可以对DSL文件执行静态检查,以检查它们是否符合您的规范。 Matthew Flatt在本文中对此进行了解释:https://docs.racket-lang.org/guide/module-languages.html(在“模块语言”和“静态检查”部分中)

是否有一种简单的方法可以在Common Lisp中获得类似的功能?

1 个答案:

答案 0 :(得分:3)

它被称为packages。您创建一个包并定义要导入和导出的内容。

(defpackage :my-fancy-package                       
  (:use :common-lisp)
  (:export :test))

(in-package :my-fancy-package)
(defun test (x)
 (list x x))

(defpackage :test
  (:use :my-fancy-package))

(in-package :test)

(+ 1 2) ; get undefined function +
(test 1 2)
; ==> (1 2)

它不像球拍一样安全,因为它意味着让我们不要混淆定义而不是屏蔽操作:

(cl:+ 1 2)
; ==> 3

CL没有all-from-out等,但您可以通过循环导出:

(let ((pack (find-package :my-fancy-package)))
  (do-all-symbols (sym pack) 
    (when (eql (symbol-package sym) pack) 
      (export sym))))

关于静态检查我不这么认为。您可以在宏中进行编译时检查,并在函数中进行运行时检查。