> On Oct 18, 2017, at 8:09 AM, Matthias Felleisen <[email protected]>
> wrote:
> 
> Wouldn’t something like this work for Hackett?

I don’t think so. Perhaps it would be better illustrated with an
example.

First, consider the Hackett definition of, say, the `Maybe` type:

    (data (Maybe a) (Just a) Nothing)

This defines two runtime bindings with the following types:

    Just : (forall [a] {a -> (Maybe a)})
    Nothing : (forall [a] (Maybe a))

It also defines a type-level binding, `Maybe`, which is in the type
namespace.

Now consider the Hackett definition of the 2-tuple type:

    (data (Tuple a b) (Tuple a b))

This defines two bindings, one in the value namespace and one in the
type namespace. Troublingly, they are both named `Tuple`.

To work around this duplication, these two bindings are exported as
`Tuple` and `#%hackett-type:Tuple`. When imported, the latter is
unprefixed and injected into the type namespace. But what about
Scribble? I might like to write the following:

    @(examples
       (: (Tuple 42 "hello") (Tuple Integer String)))

This will evaluate properly, and it will typeset like this:

    > (: (Tuple 42 "hello") (Tuple Integer String)))
    : (Tuple Integer String)
    (Tuple 42 "hello")

But what about the links? The first `Tuple` should link to the value
constructor (which is actually called `Tuple`), and the second `Tuple`
should link to the type constructor (actually called
`#%hackett-type:Tuple`). It won’t, however, because Scribble will link
them both to the value constructor.

I could do what you describe and create separate bindings for the two:

    @(module values-for-label racket
       (require (for-label (only-in hackett Tuple))
                scribble/manual)
       (provide Tuple)
       (define Tuple @racket[Tuple]))

    @(module types-for-label racket
       (require (for-label (only-in hackett
                                    [#%hackett-type:Tuple Tuple]))
                scribble/manual)
       (provide t:Tuple)
       (define t:Tuple @racket[Tuple]))

Now I can use these two different bindings in a paragraph by writing
`@Tuple` or `@t:Tuple`, and they will both typeset as “Tuple”. But this
still doesn’t solve the problem of scribble/example, since the following
doesn’t work:

    @(examples
       (: (Tuple 42 "hello") (#,t:Tuple Integer String)))

That’s because the `examples` form doesn’t allow escaping, which makes
sense, since there would be no way to know what `#,t:Tuple` should mean
when performing sandboxed evaluation. It’s theoretically possible to use
eval:alts to manually provide a version of the program for typesetting
and a version for evaluation:

    @(examples
       (eval:alts (: (Tuple 42 "hello") (#,t:Tuple Integer String))
                  (: (Tuple 42 "hello") (Tuple Integer String))))

...but this sort of defeats the purpose of having examples that are
automatically typeset.

A solution I alluded to in my previous email would be to provide a
notion of “eval transformers” that work like the existing “element
transformers” that scribble/racket provides. That way, `t:Tuple` could
be both an element transformer and an eval transformer that do the right
thing in each context. Otherwise, I’m not sure if there’s a different
solution (at least without dramatically changing how the documentation
is put together).

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to