The following message is a courtesy copy of an article that has been posted as well. From: Brian Denheyer The define structure part I understand, I figured that out pretty early on. What's got me stuck is how you actually use the structure you've created. I keep wanting to do something like (yes you can tell I'm a python guy) : (import structure) (use things which were exported from structure, maybe with some type of qualifier...) So after some muddling around I ended up with : #! /usr/local/bin/scsh \ -lm module-def.scm -o module -s !# (code which uses things in module... ) Brian, you are on the right track here. I'll describe things in more detail below. So other than setting up the script in this manner I really don't understand how you "import" things from the structures which you've defined. I have the paper which talks all about the module system and it still it eludes me. I'm thinking that maybe the "code which uses..." part should actually be in the define-structure, but then how would I run it ? Just loading the module definition doesn't work, e.g. scsh -s module-def.scm results in : Error: undefined variable module (package user) That's right -- it doesn't work. Because module-def.scm doesn't contain Scheme. It contains expressions from the module-definition language -- expressions of the form (define-structure int-funs (exports factorial ack fib) (open scheme) (begin (define (factorial n) ...) (define (ack n) ...) (define (fib n) ...))) If you look in the R4RS spec, you won't see the DEFINE-STRUCTURE form defined -- that's what I mean by "it's not Scheme." The problem is that if you just say scsh -s module-def.scm then scsh is going to load module-def.scm into the user package. Well, the user package opens (or "imports", if you like) bindings for all the standard Scheme things (variables like CAR, DISPLAY, and syntax keywords like LAMBDA, QUOTE, DEFINE), plus all the scsh stuff like FORK and EXEC. But the user package *doesn't* have any bindings for DEFINE-STRUCTURE. So you'll lose -- the (define-structure int-funs ...) expression won't make sense. However, there's another package, the config package. This package is very different -- it *doesn't* have bindings for CAR, CDR, APPEND, LAMBDA, etc., but it *does* have DEFINE-STRUCTURE available. You *can* load an expression written in the module language into this package. That's what scsh -lm module-defs.scm does. It's also what happens if you say ,config ,load module-defs.scm at the scsh prompt. If module-defs.scm contains the structure definition I sketched out above, then after you do this, your scsh has a new package available. This package is bound to the variable int-funs in the config package. Here, let me say that again. In the user package, you still just have CAR, CDR, APPEND, LAMBDA, COND and friends. In the config package, you have the keyword DEFINE-STRUCTURE, plus a new variable binding -- the variable INT-FUNS is bound to your new package. The config package is a package that contains other packages. For example, it contains a variable PP, which is bound to the pretty-printer package, which itself exports the variable P, which is the pretty-printing procedure. In the config package, you will also find packages like SCSH and SCHEME. OK, so far so good. We have our new package loaded. Notice that our package definition (define-structure int-funs (exports factorial ack fib) (open scheme) (begin (define (factorial n) ...) (define (ack n) ...) (define (fib n) ...))) opened the SCHEME package. What does this mean? Well, it means that the package system looks in the config package for a variable named SCHEME. This guy's value is itself a package -- the one defining and exporting all the standard Scheme bindings. The package system grabs all these bindings and makes them available to int-funs -- so the forms in int-fun's (BEGIN ...) clause get to use things like LAMBDA, IF, +, etc. If int-fun had contained a (FILES foo.scm bar.scm) clause, the source in these files would have been able to reference these Scheme bindings, too. Now that we have our int-fun package defined, we'd like to use the functions it defines. There are a couple of ways we could do this. - From the scsh prompt, we could say ,in int-funs This would "move" the scsh interpreter into the package int-funs (which it would find by looking in the config package, where all the packages are defined). Now we can see all the stuff in this package. Not just the three bindings we exported (factorial, ack & fib), but all the unexported internals, as well. We can redefine stuff, try things out, and so forth, all in our package. - From the scsh prompt, we could say ,open int-funs This would import int-funs' exported bindings (factorial, ack & fib) into our current package (which is probably the user package). Now we can reference these three bindings from the user package. - If we are doing a script, we could say something like this: #!/usr/local/bin/scsh \ -lm foo-module.scm -o int-funs -s !# (display (factorial (string->number (argv 1)))) (write-char #\newline) The command line says: (1) load foo-module.scm into the config package (so it better contain source written in the module language), (2) open the package int-funs in the current package (which is by default the user package, though we could have changed it with the -m switch), (3) load our script and then exit. Voila -- your script got access to your little package of integer functions. I think S48's module system is an incredibly cool mechanism. It's more than just allowing you to define modules of Scheme code. You get to define complete sets of language bindings, including all the syntax keywords like LAMBDA and IF and so on. If your package opens the SCHEME package, your package can be defined in terms of Scheme; no sweat. But if you *don't* open the SCHEME package, you don't get any of it! You can instead open up some other *completely different* set of keywords and base function bindings. Can't do that in C. -Olin P.S. It's an undocumented feature of S48's module system, but you aren't even restricted to Scheme's s-expression syntax when you use Kelsey and Rees' module system. There's an extra clause in the DEFINE-STRUCTURE form that lets you specify the parser function used to parse the files named in the FILES clause. Now *that's* a general module system!