[plt-dev] compound units and contracted signatures
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