
@moraga86 has joined the channel

I think I am very close to getting multiple namespaces working semi-smoothly in Hackett. The only significant remaining obstacle is documenting Hackett’s base types and type-level forms, like forall
. I use defform
and defidform
to document them, but frustratingly, it seems impossible to get defform
to document an identifier with any other name than how it is exported from the module. I am, however, reluctant to reimplement half of defform
in Hackett.

I guess I could just copy scribble/private/manual-form
into Hackett’s codebase and tweak it slightly, but that seems like the option of last resort. Maybe it will be necessary, though.

all the software i’ve ever worked on / written professionally is exactly this. :disappointed:

Is there not an introducer you can use on an identifier to assert which namespace it’s in?

The trouble is that Scribble’s binding documentation forms don’t really pay any attention to hygiene. (But shhh, don’t tell anyone.)

Oh that’s a pity

time for a “Scribble: closing the book on unhygienic documentation tools” ?

#lang scribble/manual2

I’m not even sure if respecting hygiene would actually solve this problem, though, sadly. There’s a variety of moving parts at play.

can a module provide the same symbol with two different bindings?

if not I’m not sure how hygiene applies to scribble

Can anyone remind me why syntax parameters can’t be just be implemented with parameterize at phase 1 + syntax-local-expand-expression? The Scheme Workshop paper includes a comment that this wouldn’t work because compile-time state is ephemeral, but I can’t figure how to construct an example where it would matter given local-expand’s refusal to look under let-syntax anyway. The solution in the racket 7 expander doesn’t feel appreciably different than using a phase 1 parameter, as there it’s using the current expand context parameter.

@michael.ballantyne not sure, but since parameters are intrinsically related to thread cells and the like it seems like a strange choice in general. Macro expansion isn’t performed in a multi-threaded way (at least within a module)

so why add the complexity of thread cells at all if there’s no concurrency involved?

Isn’t that just an argument to use fluid-let instead of parameterize?

I guess my impression from the seeming deprecation of fluid-let is that parameterize is just as efficient for Racket, or at least efficient enough, but I don’t really know.

Parameters also have a nicer API where you explicitly call out your dynamically bound values as parameters up-front, which is another reason to like them regardless of whether you care about the threading behavior.

I’m guessing the compile time state part of the paper is referring to how using state and side effects during macro expansion can cause differences to arise based on whether modules are compiled ahead of time or compiled and run interactively

I don’t know the details well enough to think of a specific example and demonstrate how it goes wrong, but reading The Separate Compilation Guarantee in the racket reference and reading the Composable and Compilable Macros paper are probably good places to go hunting for details

not at the same phase.

@michael.ballantyne I don’t know, but using syntax-local-expand-expression
would force a specific expansion order, whereas syntax parameters don’t.

@michael.ballantyne I think the paper’s explanation was probably intended to address wrapping a local-expand
with parameterize
, and probably we agree that such an implementation wouldn’t work. I don’t quite see what you have in mind with let-syntax
. In any case, the current implementation also supports splicing-syntax-parameterize
in a way that I think parameters can’t. (I forget where splicing parameterize is used, but it seemed important at some point.)

I’m getting good milage out of it :)