[plt-scheme] Units with 1 piece missing

From: Synx (plt at synx.us.to)
Date: Thu Aug 13 00:01:16 EDT 2009

So I've got units working, but as I write various programs using these
units, I find myself duplicating a lot of code. Forming the compound
unit for each program is exactly the same, except for that 1 unit that
changes, according to which program it is. So I end up with a bunch of
modules defining compound units that are exactly alike except for the
unit that implements (run).

I tried making a general procedure where I pass a runner as a lambda,
but it ended up looking like this:

---
(require
  "foo-unit.ss"
  "foo-sig.ss"
  "bar-unit.ss"
  "bar-sig.ss"
  "baz-unit.ss"
  "baz-sig.ss"
  "blech-unit.ss"
  "blech-sig.ss"
  "beep-unit.ss"
  "beep-sig.ss"
  "feep-unit.ss"
  "feep-sig.ss"
  "run-sig.ss")

(define-compound-unit/infer common@
  (import)
  (export foo^ bar^ baz^ blech^ beep^ feep^)
  (link foo@
	bar@
        baz@
        blech@
        beep@
        feep@))

(define (do runner)
  (define running@
    (compound-unit
      (import)
      (export RUN)
      (link [((RUN : run^)) runner FOO BAR BAZ BLECH BEEP FEEP]
            [((FOO : foo^) (BAR : bar^) (BLECH : blech^) (BEEP : beep^)
(FEEP : feep^)) common@ RUN])))
  (define-values/invoke-unit running@
    (import)
    (export run^))
  (run))
---

Besides being full of redundancy, there are a few problems with that
code. First off, the documentation says "The right-hand side of a link
declaration specifies the imports to be supplied to the unit produced by
the corresponding unit-expr." But the syntax only allows one import to
be supplied to the unit. So my "runner FOO BAR BAZ BLECH ..." thing
errors out, and the docs sure don't offer any suggestion how to specify
"imports" that it claims are possible.

Secondly, I have to require all the signatures from all those modules,
to explicitly export them in the compound unit. When I make a compound
unit definition thing for every time I want to swap out a run^, I only
have to require "run-sig.ss".

What I'm basically saying is I want something like this:
---
(require
  "foo-unit.ss"
  "bar-unit.ss"
  "baz-unit.ss"
  "blech-unit.ss"
  "beep-unit.ss"
  "feep-unit.ss"
  "run-sig.ss")

(define (do runner)
  (define-compound-unit combined@
    (import)
    (export run^)
    (link foo@ bar@ baz@ blech@ beep@ feep@
          runner)))
(provide do)
---

And of course that doesn't work. I can't figure out how to make
something nearly as elegant as that when supplying a procedure that lets
me plug the 1 "missing piece" into place with the rest of the units.


Posted on the users mailing list.