[plt-dev] compound units and contracted signatures

From: Philippe Meunier (meunier at ccs.neu.edu)
Date: Tue May 19 04:08:04 EDT 2009

Hello,

I've started using contracted signature for units, and I have a couple
of comments.

Here's a simple unit (in t-unit.ss):

#lang scheme/unit
(require "t-sig.ss")
(import)
(export (rename t^ (new-make-t make-t)))

(define-struct t ())

(define (new-make-t s)
  (if (eq? s 'yes)
      (make-t)
      33))

and the corresponding contracted signature in t-sig.ss:

#lang scheme
(provide t^)

(define-signature t^
  ((contracted (t? (any/c . -> . boolean?))
               (make-t (symbol? . -> . t?)))))

and it works great:

> (define-values/invoke-unit t@ (import) (export t^))
> (make-t 'yes)
#<t>
> (make-t 'no)
(unit t@) broke the contract (-> symbol? t?) on make-t; expected <t?>, given: 33

I like the fact that the contracted t? can be used in another
contract, that's great.

Now I'd like to have another unit in s-unit.ss that imports t^:

#lang scheme/unit
(require "s-sig.ss" "t-sig.ss")
(import t^)
(export s^)

(define (wrap-make-t x) (make-t x))

with the corresponding contracted signature in s-sig.ss:

#lang scheme
(provide s^)

(define-signature s^
  (t? ; already contracted in t-sig.ss
   (contracted (wrap-make-t (symbol? . -> . t?)))))

and then create a compound unit:

#lang scheme
(require "t-unit.ss" "t-sig.ss" "s-unit.ss" "s-sig.ss")
(define c@ (compound-unit (import)
                          (export S)
                          (link [((T : t^)) t@]
                                [((S : s^)) s@ T])))

Unfortunately that doesn't work:

define-unit: import t? is exported in: (define-unit s@ (import t^) (export s^) (define (wrap-make-t x) (make-t x)))

So I have to do some extra gymnastic in s-unit.ss:

#lang scheme/unit
(require "s-sig.ss" "t-sig.ss")
(import t^)
(export (rename s^ (same-t? t?)))

(define same-t? t?)
(define (wrap-make-t x) (make-t x))

and the compound unit now works.

So here are my comments:

- I think it would be nice to get rid of the "imports cannot be
  exported" restriction.  It looks to me like it only forces one to do
  extra gymnastic with things like same-t? and I'm not sure what the
  benefit of the restriction is.  And if I have several imports that I
  want to re-export to use in the contracted signature s^ then using
  something like (define same-t? t?) multiple times becomes rapidly
  ugly.

- It's a bit annoying that I have to have t? listed in both t^ and s^:

  (define-signature t^
    ((contracted (t? (any/c . -> . boolean?))
                 (make-t (symbol? . -> . t?)))))

  (define-signature s^
    (t? ; already contracted in t-sig.ss
     (contracted (wrap-make-t (symbol? . -> . t?)))))

  and that I have to remember that the t? in s^ should not be
  contracted a second time.  It would be nicer to be able to simply
  define s^ as:

  (define-signature s^
    ((contracted (wrap-make-t (symbol? . -> . t?)))))

  and then have a compound-unit-with-contracted-signatures form that
  would automatically bind the t? used in s^ with the t? contracted in
  t^ when the different pieces of the compound unit are put together.
  Any chance of having something like this in the future? :-)

Philippe




Posted on the dev mailing list.