Part IV

Scheme Programs and Shell Scripts

1  How to Run It All

We can develop the program in DrScheme or with the plain mzscheme interpreter. Assuming mzscheme is on your PATH, you can run it in your favorite Unix shell. A read-eval-print prompt will appear and you are ready to work:

   $ mzscheme -g -l mzlib.ss 
   Welcome to MzScheme ...
   Identifiers and symbols are ...
   > (load "grades.ss")
   > (define a-line '(Adam 50 55 45 30))
   > (compute-one-average a-line)
   (Adam 45.0)
   > (define two-lines (list a-line a-line))
   > (compute-averages two-lines)
   ((Adam 45.0) (Adam 45.0))
   > ^D 
   $ 

The -g flag and the -l mzlib.ss put the interpreter into a state that resembles DrScheme. Using load, we can import the definitions from a Scheme file into the read-eval-print loop. In our example, we get two definitions: compute-one-average and compute-averages. The next four lines define an example of a line, test compute-one-average on that example, define a list of two lines, and finally test compute-average on it. Now that we have convinced ourselves that the programs work, we quit the interpreter with Control-D.

Once we have developed our Scheme program, we can wrap it all up in a shell script:

#!/bin/sh
string=? ; exec mzscheme -g -l mzlib.ss -r $0 "$@" 
(load "grades.ss")
(pretty-print (compute-averages (read)))

The first two lines start the sh Unix shell and execute MzScheme on the file. The rest of the lines are plain Scheme expressions. They load our definitions,7 read the data, apply compute-averages, and print the result.

To turn the file, say grade into a useful script, don't forget to

   $ chmod +x grade

i.e., make the file executable. Now we can forget which language we used to get our job done and simply write

   $ ./grade < grades.dat > averages.dat

to compute the grade-point averages.


7 No, we don't need to use load. We can just in-line the file directly. Indeed, DrScheme knows about #! so that we can even develop the script directly inside of DrScheme.