1

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

4

2 回答 2

2

上面的答案在某种程度上是“正确的”,但也有一些错误。

  1. define-syntax-rule不是从syntax/parse/define。如果你想使用define-syntax-rule,没有必要(require syntax/parse/define)

  2. 当我(if #t 1 2 3)和你打电话时会发生什么ifelse在你的宏中是一个模式变量,所以它可以匹配任何东西。你打算允许这种情况发生吗?如果没有,您可以在这里使用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)会因错误而失败。

于 2020-02-12T17:34:54.733 回答
1

感谢@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))
于 2020-02-12T04:35:12.370 回答