> On Oct 18, 2017, at 8:09 AM, Matthias Felleisen <matth...@ccs.neu.edu>
> 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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to