如何避免球拍中的加载周期?

时间:2018-09-02 12:32:50

标签: scheme racket

我有一组非常简单的.rkt源,例如,其中有“ a.rkt”和“ b.rkt”。我希望能够在“ b.rkt”中写(require "a.rkt"),反之亦然。现在,我遇到有关“加载周期”的错误。

我可以在不添加单元的情况下使用裸模块解决此问题吗? Racket是否具有类似于前向声明的内容,因此我可以简单地添加缺少的签名而不是要求?如果两个答案均为“否”,那么有人会知道如何使用typed/racket(官方文档的 a )来实现单元的良好易懂的教程吗?

1 个答案:

答案 0 :(得分:3)

您可以使用lazy-require

;; a.rkt
#lang racket
(require racket/lazy-require)
(lazy-require ["b.rkt" (b)])
(provide a)
(define (a) 'a)
(list (a) (b))

;; b.rkt
#lang racket
(require racket/lazy-require)
(lazy-require ["a.rkt" (a)])
(provide b)
(define (b) 'b)
(list (a) (b))

请注意,您必须告诉lazy-require您要导入的特定内容。这是因为它是根据dynamic-requireset!来实现的。

如果窥视source for xrepl,您会看到它定义了一个defautoload宏,该宏(以一些N / A细节为模)很简单:

(define-syntax-rule (defautoload libspec id ...)
  (begin
    (define id
      (make-keyword-procedure
       (λ (kws kw-args . args)
         (set! id (dynamic-require 'libspec 'id))
         (keyword-apply id kws kw-args args))))
    ...))