【发布时间】:2018-04-09 01:47:09
【问题描述】:
我的儿子和我正在一起学习 Racket,并且正在构建一个非常简单的基于文本的冒险,以直接从 REPL 中使用。因此,例如,玩家可以输入(go 'north) 或(take 'apple)。
在完成了一些基本工作后,我儿子认为引用名词有点痛苦(奇怪的是,括号并没有打扰他!),所以我们用宏修改了一下,我们确实得到了一些工作,但它需要一个显式的函数和一个相应的宏,例如
(define (do-take item) ...)
(define-syntax (take stx)
(define item (cadr (syntax->datum stx)))
(datum->syntax stx `(do-take ',item)))
我认为我们可以做得比这更好,所以我阅读了更多内容并想出了这个:
(require (for-syntax racket/syntax))
(define-syntax (define-verb stx)
(syntax-case stx ()
[(_ (verb noun) body-first body-rest ...)
(with-syntax ([verb-fun (format-id stx "do-~a" #'verb)])
#'(begin
(define-syntax-rule (verb noun) (verb-fun 'noun))
(define (verb-fun noun) body-first body-rest ...)))]))
所以现在,我们可以写(define-verb (take item) ...),REPL 的玩家可以输入(take apple)。
我的问题是,考虑到我们想要实现的目标,这是否是一种合理的方法,或者是否有更简单/惯用的方法来实现相同的目标?
【问题讨论】: