schemechez-scheme

Why is my (chez) scheme symbol not visible when running with --program, but is with --script?


I'm trying to get my head around using Chez Scheme and running programs with it, and I encountered a thing I can't quite make sense of. Lets say I wanted to have a scheme program that did some stuff, defined some functions, and then ran the REPL. This is what I got just playing around with it:

(import (chezscheme))

(define test-function
  (lambda (x y)
    (+ (* 2 x) y)))

(display (test-function 3 4))
(new-cafe)

Doesn't do anything fancy, just defines a function, displays a test output, then starts the REPL using new-cafe (which I found in the Chez Scheme docs). Here's my question, this works fine if I run it using --script:

$ scheme --script test.ss
10
> (test-function 5 6)
16

But test-function is not defined inside the REPL when I run it as --program:

$ scheme --program test.ss
10
> (test-function 5 6)
Exception: variable test-function is not bound
Type (debug) to enter the debugger.

Notice, however, that it did print the 10, so (test-function 3 4) does work inside test.ss, it just doesn't work inside of (new-cafe).

There's something fundamental I don't understand here. What, exactly, is the difference between --script and --program, and why doesn't REPL recognize (test-function) when running as --program (even though it IS recognized outside of (new-cafe))?


Solution

  • --script evaluates expressions one at a time in the mutable interaction environment.

    --program evaluates the expressions as if they were wrapped in a top-level-program form.

    new-cafe evaluates its expressions within the interaction environment. Definitions within a top-level-program form do not affect the interaction environment, so new-cafe doesn't see them.

    What you need to do is

    In order to make an environment containing test-function, test-function must be exported from a library. The easiest way to do that is to create a separate file.

    mylib.ss

    (library (mylib)
      (export test-function)
      (import (chezscheme))
    
      (define test-function
        (lambda (x y)
          (+ (* 2 x) y))))
    

    test.ss

    (import (chezscheme))
    (parameterize ([interaction-environment
                    (copy-environment (environment '(chezscheme) '(mylib)) #t)])
      (new-cafe))
    
    $ scheme --program test.ss
    > (test-function 5 6)
    16