如何重新定义Scheme/Racket基本形式?

How to redefine Scheme/Racket fundamental forms?

Racket 内置基本形式 2-arm if,但是它没有 else 这个词,所以我想给它添加 else 这个词。

此代码有效:

(require syntax/parse/define)
(define-syntax-rule (myif Cond Form1 else Form2)
  (if Cond Form1 Form2)
)

(myif #t (displayln 1) else (displayln 2))

然而 myif 不适合作为关键字,将其更改为 if 会引发错误:

if: use does not match pattern: (if Cond Form1 else Form2)
in: (if #t (displayln 1) (displayln 2))

如何重新定义表格if

感谢@AlexKnauth 的评论,我可以重新定义 if 如下:

(require syntax/parse/define)
(require (only-in racket/base [if r-if]))

(define-syntax-rule (if Cond Form1 else Form2)
  (r-if Cond Form1 Form2)
)

(if #t (displayln 1) else (displayln 2))

上面的答案在一定程度上是"correct",但是有一些错误。

  1. define-syntax-rule 不是来自 syntax/parse/define。如果要使用define-syntax-rule,则不需要(require syntax/parse/define)

  2. 当我用你的 if 调用 (if #t 1 2 3) 时会发生什么? else 在你的宏中是一个模式变量,所以它可以匹配任何东西。你打算允许这种情况发生吗?如果没有,您可以在这里使用 syntax/parse/define 的功能。你可以这样写:

    (require syntax/parse/define)
    (define-simple-macro (if test-expr:expr 
                             {~datum then} 
                             then-expr:expr 
                             {~datum else} 
                             else-expr:expr)
      (racket:if test-expr then-expr else-expr))
    

    因此 (if 1 then 2 else 3) 将扩展为 (racket:if 1 2 3),但 (if 1 0 2 0 3) 将失败并出现错误。