Search code examples
chicken-scheme

Interpreting multiple modules


I would like to have multiple modules in my program. Eg. module foo, and module bar. Module foo would refer to module bar. Then I would like to be able to test those modules in the csi (interpreted) repl. The root of this question is if I can run my code withouth having to compile it. Below is my example.

Note: I'm a scheme newbie, so there may be other issues with this code. Feel free to point anything out, and I will try to correct.

foo.scm

(use r7rs)
(define-library (foo)
  (import (scheme base)
          (prefix bar bar:))
  (export add-some-stuff)
  (begin

    (define baz 1)

    (define (add-some-stuff)
      (+ baz bar:bork))

    ))

bar.scm

(use r7rs)
(define-library (bar)
  (import (scheme base))
  (export bork)
  (begin

    (define bork 2)))

Results would hope to be:

$ csi
> ,l foo.scm
> (import (prefix foo foo:))
> (foo:add-some-stuff)
;;=> 3

Here's the error I get:

$ csi -q
#;1> ,l foo.scm
; loading foo.scm ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/chicken.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/foreign.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-4.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/extras.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/srfi-13.import.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-compile-time.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-library.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs-support.so ...

Note: re-importing already imported syntax: syntax-rules

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: define-record-type

Note: re-importing already imported syntax: include

Note: re-importing already imported syntax: include

Note: re-importing already imported syntax: import

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/r7rs.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/numbers.so ...
; loading /usr/local/Cellar/chicken/4.12.0/lib/chicken/8/scheme.base.so ...

Note: re-importing already imported syntax: syntax-rules

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import

Note: re-importing already imported syntax: cond-expand

Note: re-importing already imported syntax: import-for-syntax

Note: re-importing already imported syntax: import

Error: (import) during expansion of (import ...) - cannot import from undefined module: bar

    Call history:

    numbers.scm:1672: scan-real
    <syntax>      (define-library (foo) (import (scheme base) (prefix bar bar:)) (export add-some-stuff) (begin (defin...
    <syntax>      (##core#module foo ((##r7rs#foo)) (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#u...
    <syntax>      (##core#define-syntax ##r7rs#foo (##core#lambda _ (quote (##core#undefined))))
    <syntax>      (##core#lambda _ (quote (##core#undefined)))
    <syntax>      (##core#begin (##core#quote (##core#undefined)))
    <syntax>      (##core#quote (##core#undefined))
    <syntax>      (##core#undefined)
    <syntax>      (##sys#provide (##core#quote foo))
    <syntax>      (##core#quote foo)
    <syntax>      (import-for-syntax (only r7rs begin cond-expand export import import-for-syntax include include-ci s...
    <syntax>      (##core#undefined)
    <syntax>      (import (only r7rs begin cond-expand export import import-for-syntax include include-ci syntax-rules...
    <syntax>      (##core#undefined)
    <syntax>      (##core#begin (import (scheme base) (prefix bar bar:)) (##core#begin (export add-some-stuff) (##core...
    <syntax>      (import (scheme base) (prefix bar bar:))  <--
#;1>

Solution

  • Kooda from the #chicken irc channel recommended the system egg, and it seems to be doing what I'm looking for. In short, one needs to create a .system file that specifies the dependency tree, which is described below. It's a little unfortunate that Chicken Scheme can't figure out the internal module dependencies from looking at the import statements in each module, but I think this is the next best thing.

    $ chicken-install system
    

    create a file called so-question-chicken-scheme.system. That file should contain:

    (define-system so-question-chicken-scheme
      (scheme-file "bar")
      (scheme-file "foo" depends: '("bar")))
    

    Here's the interpreter results

    $ csi -q
    #;1> (use system)
    #;2> (load "so-question-chicken-scheme.system")
    #;3> (load-system so-question-chicken-scheme)
    #;4> (import (prefix foo foo:))
    #;5> foo:add-some-stuff
    #<procedure (add-some-stuff)>
    #;6> (foo:add-some-stuff)
    3