【问题标题】:Why is Racket evaluating both of these functions in one case, but not the other?为什么 Racket 在一种情况下评估这两个功能,而不是另一种情况?
【发布时间】:2022-12-01 01:25:22
【问题描述】:

将函数 my-if 定义为在内部使用 cond 会导致与直接使用 cond 不同的行为。

使用cond,DrRacket 解释器只打印第一个displayln 的字符串。

代码:

(cond
  (#t (displayln "Cond: should run"))
  (else (displayln "Cond: shouldn't run")))

输出:

Cond: should run

使用my-if,DrRacket 解释器打印两个字符串,尽管看起来(至少对我而言)它应该扩展为相同的代码。

代码:

(define (my-if condition statement-if statement-else)
  (cond (condition statement-if)
        (else statement-else)))

(my-if
 #t
 (displayln "should run")
 (displayln "shouldn't run"))

输出:

My-If: should run
My-If: shouldn't run

我假设由 define 创建的函数将扩展为与 cond 相同的代码,但考虑到它有不同的结果,我假设它没有。

鉴于代码的 2 个版本有不同的结果,我的猜测与急切/惰性求值或 cond 本身就是一个宏有关。

【问题讨论】:

标签: functional-programming racket side-effects


【解决方案1】:

Racket 中的函数应用通过以下方式评估:

  • 评估函数
  • 评估参数
  • 将函数应用于参数

由于您正在编写 (my-if #t (displayln "should") (displayln "shouldn't")),因此首先评估每个参数(包括 displaylns)。

这就是为什么不能将条件定义为函数的原因。您真正需要的是 Racket 的宏系统。然后,您可以通过以下方式将 my-if 定义为宏:

#lang racket

(define-syntax-rule (my-if c t e)
  (cond
    [c t]
    [else e]))

(my-if #t (displayln "should run") (displayln "shouldn't run"))

请注意,与首先评估参数的函数应用程序不同,宏实际上在语法上进行了扩展(在 Racket 中,也是 hygenically)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2020-03-31
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    相关资源
    最近更新 更多