Kotaka Danski
Kotaka Danski

Reputation: 600

R5RS circular dependency (cycle in loading)

I have two r5rs files - scheme-interpreter.scm and scheme-interpreter-operations.scm. The first file contains two functions - interpret and evaluate. The second file contains auxilliary functions, which get called inside evaluate. However, these functions can call evaluate as well. Thus, recursion occurs. When I reference each file in the other one like this:

(#%require "scheme-interpreter-operations.scm")
(#%provide (all-defined))
#lang r5rs
(#%require "scheme-interpreter-operations.scm")
(#%provide (all-defined))

I get errors. Is it possible to load files in a circular manner?

Upvotes: 0

Views: 43

Answers (1)

Shawn
Shawn

Reputation: 52644

Using the Racket R5RS language with the racket module system on top like in your sample code, it's possible to have circular dependencies using using lazy-require.

Example:

s1.scm:

#lang r5rs

(#%require "s2.scm")
(#%provide (all-defined))

(define (evaluate x)
  (cond
   ((and (pair? x) (eq? (car x) '+))
    (add (cdr x)))
   ((number? x) x)))

(display (evaluate '(+ 1 2)))
(newline)

s2.scm:

#lang r5rs

(#%require racket/lazy-require)
(lazy-require ("s1.scm" (evaluate))) ; Lazily import evaluate
(#%provide (all-defined))

(define (add x)
  (apply + (map evaluate x)))

And demonstration:

$ racket s1.scm
3

For a general R5RS approach, a (load "s2.scm") in s1.scm works with Chicken, Guile and plt-r5rs, at least (With the Racket specific stuff removed, of course). Adjust filenames appropriately.

Upvotes: 1

Related Questions