How to avoid loading cycle in Racket?

左心房为你撑大大i 提交于 2020-01-24 04:22:07

问题


I have quite simple set of .rkt sources and, say, "a.rkt" and "b.rkt" among them. I'd like to be able to write (require "a.rkt") in "b.rkt" and vice versa. Now I'm facing error about "loading cycle".

Can I solve this issue with bare modules without adding units? Does Racket have anything similar to forward declaration so I could simple add missing signature instead of requiring? If both answers are "No", does someone know good and understandable tutorial on how to implement units with typed/racket (aside of official docs)?


回答1:


You can use 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))

Notice that you must tell lazy-require the specific things you want to import. That's because it is implemented in terms of dynamic-require plus set!.

If you peek at the source for xrepl, you'll see it define a defautoload macro, which (modulo some N/A details) is simply:

(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))))
    ...))


来源:https://stackoverflow.com/questions/52137060/how-to-avoid-loading-cycle-in-racket

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!