## Two suggestions about Kernel modules

### Foreword

The first part of this was inspired by my desire to bundle testing submodules with Kernel modules. The second part was inspired by my email exchange with John Shutt after I sent the first part to him.

Klink is at the point where I'm starting to think about built-in test support. (Till now it has relied entirely on an external tester I wrote for emacs) That brought up an issue about modules.

#### The dilemma

As I see it, the dilemma (multilemma) is this:

1. IMO as a tester, tests ought to group with modules, for many reasons.
2. I doubt it makes sense for modules to have canonical names or identities, so I can't tell the tests about the module, I have to tell the module about the tests.
• So a test harness needs to be able to look at an environment and find the tests in it, if any. This probably implies they live somewhere in that environment.
3. Reserving a name to always have a special meaning, such as "tests" or "tests", seems wrong for many reasons.
4. make-keyed-static-variable wants to make a fresh environment.
• That requires always loading the tests first, which is problematic at best.
• Even if I can load a module before I load the tests for it, I'd still need to maintain a mapping from module to tests.
• That makes it impossible to define tests incrementally.
5. I could bind an object that a test-definer would write into. Say, an environment (In fact I will, to name sub-tests). But I'd still have to always place the binder around the entire module.
• It's an error opportunity, having to always remember to do that.
• It's structurally noisy.
• The same would have to be done for every functionality that wants to let individual modules "say something about themselves".
6. I could fake it with gensyms but with all the keyed variable support, it'd be a shame.

#### Possible solutions

##### Keyed setters

Have make-keyed-static-variable also make a setter, something with semantics similar to:

($vau (value) env ($set! env KEY value))


where KEY refers to the shared secret. If the "binder" return is analogous to $let', this would be analogous to $set!'. This would not make a fresh environment.

• Con: Creates uncertainty and error opportunities about what environment is being defined into.
• Con: Doesn't cooperate with constructs like \$provide'
##### Let accessors have defaults

Another possibility is for the accessor to optionally, if it finds no binding, make one and record it. Presumably it'd evaluate something to make a default.

• Con: Same cons as above.
##### Smarter modules

Taking horn #5 of the multilemma as a first draft, provide a construction that surrounds a module with all the binders it should have.

Issues:

• Its identity:
• Is the entry point get-module' with a larger mandate?
• Or is it a separate thing? IMHO no.
• And should this be available on its own? Meaning "bind all the usual things but don't load anything". IMHO yes.
• So which binders should it use?
• Interested ones are somehow registered externally.
• What happens for binders that are defined after a module is loaded?
• Are they missing forever? That seems unfortunate.
• Alternatively, they could behave as if their binders had been used in the first place, since nothing can have accessed them yet (which must have made an error).
• Pro: This neatly handles circular dependencies and even self-dependencies.
• How may they be registered?
• If any combiner of the proper signature can be registered, stray code could be registered and subtly change the behavior of all sorts of modules. That'd be a serious problem.
• So ISTM registering should be something only make-keyed-static-variable or similar can do. We know it makes a normal, harmless binder.
• What specifically registers a binder?
• make-keyed-static-variable, on some optional argument?
• A relative of make-keyed-static-variable that always registers the binder?
• make-keyed-module-variable'

#### Coda

I lean towards the 3rd solution, smarter modules.

What do you think?