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

127 Views Asked by At

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))?

1

There are 1 best solutions below

2
Peter Winton On BEST ANSWER

--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

  • make an environment containing test-function,
  • parameterize interaction-environment to that environment, then
  • evaluate new-cafe.

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