# Module inter-depandancies

**URL:** <https://racket.discourse.group/t/module-inter-depandancies/3133>\
**Category:** Questions & Answers\
**Created:** [August 30, 2024, 10:17am UTC](https://racket.discourse.group/t/module-inter-depandancies/3133 "2024-08-30T10:17:54Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 30, 2024, 10:17am UTC](https://racket.discourse.group/t/module-inter-depandancies/3133/1 "2024-08-30T10:17:55Z")

</div>

hello,

In R6RS code i have a module A (assignment) that needs a module B (set-values-plus) and B also needs module A. Should i put all code in the same module? or is there a way to solve this problem otherwise,because when i ran a test code using modules A and B it seems to goes in an infinite loop....

here is the headers containing the import of my modules for now:

set-values-plus.sls :

```scheme
#!r6rs

(library (set-values-plus) 

  (export set!-values-plus
	  return-values
	  create-return-values
	  define-or/and-set!-values)

  
  (import (rnrs base (6))
	      (Scheme+R6RS assignment))

```

assignment.sls :

```scheme
#!r6rs

(library (assignment) ; R6RS

  (export <- ->
	   ← →
	   := =:
	   <v v>
	   ⇜ ⇝)

  (import (rnrs base (6))
	  (for (rnrs base (6)) expand) ; import at expand phase (not run phase)
	  (for (rnrs syntax-case (6)) expand)
	  (for (only (rnrs io simple (6)) display newline) expand)
	  (for (Scheme+R6RS parse-square-brackets) expand) ; import at expand phase (not run phase)
	  (only (rnrs control (6)) when)
	  (only (srfi :1) first second third fourth fifth)
	  (only (srfi :13) string-set! string-copy!)
	  (srfi :25)
	  (only (srfi :43) vector-copy vector-copy!)
	  (srfi :69) ; hash table
	  (rename (flomat) (repeat repeat-flomat)
			    (shape shape-flomat)
			    (transpose transpose-flomat))
	  (Scheme+R6RS parse-square-brackets)
	  (Scheme+R6RS for_next_step)
	  (Scheme+R6RS array)
	  (Scheme+R6RS slice)
	  (Scheme+R6RS declare)
	  (Scheme+R6RS block)
	  (Scheme+R6RS def)
	  (Scheme+R6RS bracket-apply)
	  (Scheme+R6RS set-values-plus)
	  (Scheme+R6RS overload)
	  (only (racket match) match ==))

 

```

i add that i even checked the Guile version of the same code and all is working without the 'import':

```scheme
(define-module (set-values-plus)

  #:export (set!-values-plus
	    return-values
	    create-return-values))

```

idem for the Kawa version:

```scheme
(define-library (set-values-plus) ; R7RS

  (import (kawa base))

  (export set!-values-plus
	  return-values
	  create-return-values)

```

no specific 'import' of the other module are required.

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 30, 2024, 9:35pm UTC](https://racket.discourse.group/t/module-inter-depandancies/3133/2 "2024-08-30T21:35:13Z")

</div>

finally just put all the definition in the same module and it works.

---

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [August 31, 2024, 1:26am UTC](https://racket.discourse.group/t/module-inter-depandancies/3133/3 "2024-08-31T01:26:24Z")

</div>

> [@damien\_mattei](#):
>
> In R6RS code i have a module A (assignment) that needs a module B (set-values-plus) and B also needs module

R6RS libraries cannot have cyclic dependencies. It is hard to find an explicit statement of this fact: the best I came up with is [Rationale chapter 7](https://www.r6rs.org/final/html/r6rs-rationale/r6rs-rationale-Z-H-9.html), which says, “The library system does not address the following goals, which were considered during the design process … mutually dependent libraries …”. Similarly, the [implicit phasing paper](https://legacy.cs.indiana.edu/~dyb/pubs/implicit-phasing.pdf) says:

> In general, each library is expanded before it is imported into dependent libraries. The `import` forms of a set of libraries implicitly define a dependency graph. The graph is necessarily acyclic because a [sic] library import relationships cannot be recursive

In the report itself, I haven't found an direct statement, though I think the requirement can be inferred from various passages, e.g. this one from [chapter 7](https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-10.html):

> The transformer expressions and bindings are evaluated and created from left to right, as described in chapter [10](https://www.r6rs.org/final/html/r6rs/r6rs-Z-H-13.html#node_chap_10). The expressions of variable definitions are evaluated from left to right, as if in an implicit `letrec*`, and the body expressions are also evaluated from left to right after the expressions of the variable definitions. A fresh location is created for each exported variable and initialized to the value of its local counterpart. The effect of returning twice to the continuation of the last body expression is unspecified.

There are various techniques for breaking cycles. You can see some examples in the implementation of Racket CS and the "Rumble" layer, e.g.:

> <https://github.com/racket/racket/blob/72a1cbabcf7f4540919ba1ce5d96ff74ce3debda/racket/src/cs/rumble/foreign.ss#L786-L803>

The need for an imperative hook is typical, so, yes, it is almost always best to restructure your code to avoid the dependency cycle.

> [@damien\_mattei](#):
>
> i add that i even checked the Guile version of the same code and all is working without the 'import':

The current implementation of modules in Guile allows cyclic dependencies, though cycles can easily create use-before-definition errors that, in my experience, are obscure and painful to debug. I say “current implementation” because I know several Guile folks find the current (ill-defined) semantics regrettable, and I think there's interest in forbidding cycles if acceptable solutions can be found for existing code bases that use them (e.g. Guix). Here's some relevant discussion from [a blog post by Andy Wingo](https://wingolog.org/archives/2024/05/16/on-hoot-on-boot), the Guile maintainer:

> [@](#):
>
> … Precise, meaning that R6RS modules are static, in a way that Guile modules, at least in absolute terms, are not: Guile programs can use first-class accessors on the module systems to pull out bindings. This is yet another example of what I impute as the original sin of 1990s language development, that modules are just mutable hash maps. You see it in Python, for example: because you don’t know for sure to what values global names are bound, it is easy for any discussion of what a particular piece of code means to end in dispute.
> 
> The question is, though, are the semantics of name binding in a language fixed and absolute? Once your language is booted, are its aspects definitively attributed? I think some perfection, in the sense of becoming more perfect or more like the thing you should be, is something to salute. Anyway, in Guile it would be coherent with Scheme’s lexical binding heritage to restitute some certainty as to the meanings of names, at least in a default compilation node. Lexical binding is, after all, the foundation of the [Macro Writer’s Statute of Rights](https://www.youtube.com/watch?v=LIEX3tUliHw). Of course if you are making a build for development purposes, not to distribute, then you might prefer a build that marks all bindings as dynamic. Otherwise I think it’s reasonable to require the user to explicitly indicate which definitions are denotations, and which constitute locations.

The underlying Racket module system does not support cyclic dependencies, either, but Racket's [`unit` system](https://docs.racket-lang.org/guide/units.html) is a mechanism for modular code that does support cyclic dependencies. (In fact, `unit` predates `module` in Racket.)

---

<div class="post-metadata">

**Author:** ![damien\_mattei](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/damien_mattei/32/2706_2.png) [@damien\_mattei](https://racket.discourse.group/u/damien_mattei)\
**Post date:** [August 31, 2024, 8:02am UTC](https://racket.discourse.group/t/module-inter-depandancies/3133/4 "2024-08-31T08:02:46Z")

</div>

yes "mutual dependencies" are not allowed in R6RS. Not sure about Racket but Kawa and Guile yes. I make this part run by putting all the definitions in the same file but this could have failed because, in my code i define a macro \<- that use another macro set!-values-plus that itself use \<- . That could lead to infinite recursive loops ! but as there is some conditionals (branching) in the 2 macros , it is written a way it is not possible of course to branch in infinite loop.

Basically set!-values-plus set! many values to identifier using \<- which is an enhanced set! but itself \<- allow multiple bindings and reuse set!-values-plus... Finally it finish using set! when the multiple-values are simplify in one-value assignment.

example from code comments:

```scheme
(define T (make-vector 5))
{(x {T[4]} z) <v (values 1 2 3)}

 {T[4]}
 2

 (declare u v w a b c)
 {(a b c) <v (x {T[4]} z) <v (u v w) <v (values 1 2 3)}

(list a b c x {T[4]} z u v w)
 '(1 2 3 1 2 3 1 2 3)

```

\<v is a multiple values assignment operators like in Python with tuples (a, b , c) = (1 , 2 ,3)

\<v use set!-values-plus that use \<- , \<- can use set! or more complex assignment like vector-set! for vector, or other for hash tables....

About the python global variables, it is true it is not always obvious when reading code which value take a global variable, but it is clearly know by the program at runtime. There is the same thing in Scheme when defining a toplevel variable....
