【问题标题】:Evaluating a literal as an expression (Scheme)将文字评估为表达式(方案)
【发布时间】:2012-09-07 23:04:33
【问题描述】:

我正在尝试将文字评估为 Scheme 中的表达式(目前使用 Guile)。示例:

(define x '(+ 6 6))
(define y (evaluate-literal x))     ; Expected result:  y = 12

(这里,evaluate-literal 是我正在寻找的占位符。)是否有一个 lisp 函数/习语可以做到这一点?我之所以需要这样做是因为表达式在定义时可能是无效的,但稍后在评估时会是一个有效的表达式。


目前我的解决方法是使用delayforce,但这不是很优雅:

(define x (delay (+ 6 6)))
(define y (force x))

【问题讨论】:

  • 你可以使用eval,我想。但我认为delay 甚至普通的lambda 更可取。
  • 在这种情况下你会如何使用lambda
  • @fyl 我编辑了我的答案,展示了如何使用lambda

标签: scheme expression literals evaluation


【解决方案1】:

最简单的方法是使用eval,尽管很难安全使用。请参阅此post 了解原因。

(define x '(+ 6 6))
(define y (eval x))

使用内置的delay/force 程序是一个很好的解决方案:

(define x (delay (+ 6 6)))
(define y (force x))

或者,正如 cmets 中所建议的,您可以使用 lambda 来实现您自己的 delay/force 语法:

(define-syntax my-delay
  (syntax-rules ()
    ((my-delay object)
     (lambda () object))))

(define (my-force delayed-object)
  (delayed-object))

(define x (my-delay (+ 6 6)))
(define y (my-force x))

上面是一个玩具实现,一个真实世界的实现会记住结果以避免每次都调用lambda,但你明白了。

【讨论】:

  • 使用延迟/强制或 lambda 的解决方案比使用 eval 的解决方案更可取。有关安全使用 eval 的难度的更多信息,请参阅 Matthew Flatt 关于此主题的博文:blog.racket-lang.org/2011/10/…
  • Matthew Flatt 的博客是 ablour #lang Racket 但 Scheme R5RS 中的 eval 工作方式不同
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-24
  • 2011-06-03
  • 1970-01-01
  • 2010-12-25
  • 2011-08-03
相关资源
最近更新 更多