[racket] Confused about define-values(-for-export) forms in define-signature

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Apr 2 17:41:15 EDT 2014

At Tue, 1 Apr 2014 02:29:17 -0400 (EDT), Daniel Feltey wrote:
> The define-signature form allows define-values and define-values-for-export 
> forms in its body. According to the documentation the define-values form should 
> prefix any unit that imports the signature, and define-values-for-export should 
> suffix any unit that exports the signature, but the actual behavior doesn't 
> seem to match the documentation.
> I can define the following signature and unit:
> (define-signature x^
>   ((define-values-for-export (x) 5)
>    x
>    ))
> (define x@
>   (unit (import)
>         (export x^)))
> (define-values/invoke-unit x@ (import) (export x^))
> This makes sense to me, because the definition for x is available within the x@ 
> unit, but it must also be listed in the signature by name in order to actually 
> export the value, so that x is defined when invoking the unit with 
> define-values/invoke-unit.
> What confuses me is that I can also define the following signature and unit:
> (define-signature y^
>   ((define-values (y) 5)))
> (define y@
>   (unit (import)
>         (export y^)))
> (define-values/invoke-unit y@ (import) (export y^))
> This does introduce a binding for y with the value 5, but I don't understand 
> why.

A `define-values` in a signature adds a definition to any *importing*
context (in contrast to `define-values-for-export` which adds a
definition in any *exporting* context). The `define-values/invoke-unit`
form "imports" the signature into the definition context.

> Since the y^ signature is being exported instead of imported I expected 
> that the value of y should not be available in the y@ unit, and furthermore 
> there is no need to declare y in the signature as a variable which the unit 
> must define. So why is it the case that this unit defines and exports the value 
> of y, when according to the documentation this shouldn't happen.

As you say, `y` isn't bound in the unit `y@` by the export of `y^`.

With the `define-values/invoke-unit` form in the same context, though,
the unit `y@` will be able to refer to `y`, just like any other binding
in the unit's environment.

Posted on the users mailing list.