0

Chicken Scheme 有没有办法在运行时确定当前是否定义了变量?

(let ((var 1))
 (print (is-defined? var))   ; #t

(print (is-defined? var))    ; #f

编辑:XY 问题。

我正在编写一个生成代码的宏。这个生成的代码必须以相互递归的方式调用宏——让宏简单地调用自身是行不通的。当宏被递归调用时,我需要它的行为与最初调用时不同。我会使用嵌套函数,但是呃....它是一个宏。

粗略的例子:

(defmacro m (nested)
 (if nested
  BACKQUOTE(print "is nested")
  BACKQUOTE(m #t)

(是的,我知道 scheme 不使用 defmacro,但我来自 Common Lisp。而且我似乎无法在这里加上反引号,否则一切都会陷入困境。)

我不希望宏的 INITIAL 调用采用仅在递归调用时才有意义的额外参数。我希望它通过其他方式知道。

我可以获取生成的代码来调用嵌套在第一个宏中并且在调用站点不存在的宏吗?例如,生成调用(,other-macro)而不是(macro)?

但这不应该起作用,因为宏不是像函数那样的一流对象......

4

2 回答 2

1

当你编写递归宏时,我的印象是你有一个宏扩展(m a b ...),它变成了一个(m-helper a (b ...))可能变成(let (a ...) (m b ...)). 这不是直接递归的,因为您正在将代码转换为恰好包含宏的代码。

有了destructuring-bind你真的只需要跟踪两个变量。一个用于car和一个用于cdr并带有一个隐式重命名宏,不是来自表单的东西被重命名,因此是卫生的:

(define-syntax destructuring-bind
  (ir-macro-transformer
   (lambda (form inject compare?)
     (define (parse-structure structure expression optional? body)
       ;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals
       )

     (match form
       [(structure expression) . body ]
       `(let ((tmp ,expression))
          ,(parse-structure structure 'tmp #f body))))))

要检查输入中的某些内容是否与您使用提供的compare?过程相同的符号。例如。(compare? expression '&optional).

于 2016-08-09T16:54:45.530 回答
0

通常没有办法做到这一点,因为 Scheme 是词法范围的。如果引用未定义的变量是错误的,那么询问是否定义了变量没有多大意义。

对于顶级/全局变量,您可以使用symbol-utils egg,但考虑到模块内的全局变量也被重写为其他东西,它可能不会像您预期的那样工作。

也许如果你能说出你真正想做的事情,我可以帮助你提供替代解决方案。

于 2016-08-09T09:07:18.200 回答