s c h e m a t i c s : c o o k b o o k

/ Cookbook.UnitSig

This Web

TOC (with recipes)

Other Webs



Schematics Home
Sourceforge Page
Original Cookbook

Scheme Links

Scheme FAQ
Scheme Cross Reference
Scheme48 SCM
MIT Scheme scsh
JScheme Kawa
Chicken Guile
Bigloo Tiny
Gambit LispMe

Lambda the Ultimate

Creating and using a Signed Unit


You want to create something like a module, but incomplete, so that some functionality is defined elsewhere and imported at compile-time. What's more, you don't want to worry about circular references, where module a refers to module b which refers to some part of module a.

Signed units are PLT scheme's implementation of functors, and are essentially composable classes for those people who rest firmly in the OO world; classes with mixins, but a little more flexible than that. They're not intended to replace modules, but rather compliment them. To start using signed units, the first step is to require unitsig.ss.


500 Can't connect to (connect: Connection refused)

To create a signed unit, the first thing you need is a signature, which is a single form containing all the symbols that your unit will import or all the symbols your unit will export, or some subset of either of those. So if your unit imports the symbols:

and you want to export the symbols

Your signatures can look like this

500 Can't connect to (connect: Connection refused)

The circumflex at the end means nothing to unit/sig -- it's just syntactic sugar that has become a kind of standard convention when working with units. When I said that they can be subsets earlier, I meant I could have split the first signature or second signature into two separate signatures, something along the lines of:

500 Can't connect to (connect: Connection refused)

And it would have been logically the same. The only thing to remember here is to not mix your export and import signatures, as that will be important later. Now, to go about defining that unit.

500 Can't connect to (connect: Connection refused)

And that's it -- you have a signed unit. It's incomplete, though, because we haven't defined our actors yet. These are actually either defined as a separate unit or defined at the top level. Let's take the case where they're defined as a separate unit, though, because this is effectively a functor, which is a very tidy way of composing programs from components.

500 Can't connect to (connect: Connection refused)

Not bad. Note the differences with the movie@ unit. Most importantly, import is completely bare, which means that no other symbols are needed to make actors@ complete. Note also that every symbol specified in the acting-troupe^ signature is defined here in the module. So let's do the obvious thing:

500 Can't connect to (connect: Connection refused)

Eek! That produced an error that our symbols were undefined. Let's look at why. Invoking units with invoke-unit or invoke-unit/sig does not define anything at the top level. Exports are only meant to be exported to other units. There is a function (define-values/invoke-unit/sig) which when used in place of invoke-unit/sig will define the symbols from actors@ -- all the symbols needed for acting-troupe at the top level, but that's 'messy' on the namespace. A more proper solution to this problem is to define a compound-unit/sig:

500 Can't connect to (connect: Connection refused)

This new compound unit will invoke without objections:

500 Can't connect to (connect: Connection refused)

Note that we use the define-values variant to make sure that the symbols from movie@ are defined at the top level at the end of the invocation. There is another way to do things and that is to realize that a unit, signed or not, is a function and should return a value. Thus, changing our unit slightly:

500 Can't connect to (connect: Connection refused)

Doing things this way, we can control whether or not and what the symbol for and-the-holy-grail is at the top level. Now calling invoke-unit/sig will return a <#procedure> instead of void, which you can bind or immediately apply.


Take note that this only describes the basic features of signed units, and that there is considerably more functionality embedded in unitsig.ss. From here you can begin coding component software with an understanding of what a unit is, what a signature is, and why to bother with a compound-unit. After having read this tutorial, you should be able to gradually add the more esoteric functionality of unit/sig to your repertoire by reading the MzLib? documentation and experimenting with the functions within.

Comments about this recipe


-- JeffHeard - 18 Aug 2006

TopicType: Recipe
ParentTopic: GettingStartedRecipes
TopicOrder: 999

Copyright © 2004 by the contributing authors. All material on the Schematics Cookbook web site is the property of the contributing authors.
The copyright for certain compilations of material taken from this website is held by the SchematicsEditorsGroup - see ContributorAgreement & LGPL.
Other than such compilations, this material can be redistributed and/or modified under the terms of the GNU Lesser General Public License (LGPL), version 2.1, as published by the Free Software Foundation.
Ideas, requests, problems regarding Schematics Cookbook? Send feedback.
/ You are Main.guest