【发布时间】:2019-01-12 10:05:08
【问题描述】:
我正在尝试使用来自this accepted answer 的方案实现在 Racket LISP 中为个人学习项目实现协程。但是,将我的 .rkt 文件加载到球拍 repl 中时,出现以下错误:
; 3.rkt:111:18: define: not allowed in an expression context
; in: (define (run-handler) (make-generator (lambda (yield) (send
; (get-dp-data-object key) run))))
似乎在抱怨这部分代码中的定义:
108 (define-syntax (define-coroutine stx)
109 (syntax-case stx ()
110 ((_ (name . args) . body )
111 #`(define (name . args)
112 (make-generator
113 (lambda (#,(datum->syntax stx 'yield))
114 . body))))))
根据accepted answer here,Scheme 不共享这个确切的错误,并且在尝试在表达式中定义时是 Racket 所独有的。
代码调用(define-coroutine)似乎是:
518 ;; Qt-esque connect macro
519 (define-syntax connect-message
520 (syntax-rules ()
521 [(register src-obj-key msg-type dst-obj-key handler)
522 (register-message-handler
523 msg-type
524 (begin
525 (define-coroutine
526 (handler-accessor)
527 (if (eqv? (get-dp-data-object dst-obj-key) #f)
528 #f
529 (send
530 (get-dp-data-object dst-obj-key)
531 handler
532 (get-field args msg))))
533 handler-accessor))]))
这是我的第一个 Racket 项目,所以我在学习很多。上面的(开始)是试图定义并返回一个调用对象方法的协程。我确信这段代码 sn-p 有很多问题,但是调试器阻止了我上面的问题,阻止我得到以后的错误:)
我在 Racket、Scheme 或 LISP 方面几乎不够熟练,无法解决这个问题,目前我几乎无法理解这个错误。有人可以为我解决这个问题并希望能纠正这个问题,以便我可以让这个协程代码在 Racket 中工作吗?
【问题讨论】:
-
既然
define-coroutine的body从来没有yield什么的,那么使用它的目的是什么?你不能用(lambda () same-body)替换整个开头吗?