【问题标题】:How to determine if a variable exists in Chicken Scheme?如何确定 Chicken Scheme 中是否存在变量?
【发布时间】:2016-12-15 02:27:49
【问题描述】:

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) 的代码?

但这应该行不通,因为宏不像函数那样是一等对象......

【问题讨论】:

  • 这你应该在编译时/写时知道。 XY?打算用它做什么?
  • 我已为我的问题添加了详细信息。

标签: scheme chicken-scheme


【解决方案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).

【讨论】:

  • 这是真的,宏可以带一个可选参数。或者,使用let-syntax,您可以创建一个本地可见的宏。您可以从低级宏调用帮助程序:宏没有理由只调用其他宏。只需记住使用use-for-syntax 加载他们的库或以begin-for-syntax 形式自己定义它们。要获得灵感,请查看matchable egg 的实现,它的作用与此非常接近。还有bindings 彩蛋。
【解决方案2】:

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

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

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

【讨论】:

  • 我正在尝试编写一个支持关键字和可选参数的destructuring-bind 宏。为此,我需要递归生成代码。递归调用需要知道它们是否处于关键字模式。我不能使用嵌套方法,因为它是一个宏,并且必须递归生成再次调用该宏的代码。宏接受模式参数是没有意义的,因为那样我必须在第一个实例中使用空参数调用它。我需要的是一个可能存在也可能不存在的词法绑定,并做出相应的反应。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
相关资源
最近更新 更多