
@davidtaylor has joined the channel

did the installer script for the current snapshot change in any way recently? context: https://github.com/racket/rackunit/issues/68

when did it change? and did it affect any other travis jobs (such as TR)?

I’m guessing it changed yesterday, as it was last night’s nightly travis run that broke

rerunning the build does not fix the issue, it fails in the same way

haven’t checked any other repos yet

I want to write a defdata
scribble form for documenting Hackett algebraic datatypes. I’ve peeked at the source for defstruct
, but it is pretty complicated! Is there any simpler way to define a custom documentation form? If not, is there something that could help me understand how to write one myself?

I’ll also want to do the same thing for typeclasses.


Or defthing.

@stamourv Thanks, that’s helpful. I guess copying all that stuff out of scribble/private
is currently the only way to do that? :/

I think that’s the best way @robby found. ;)

its just work! :slightly_smiling_face:

“just a small matter of programming” is the phrase that comes to mind.

I’ll be the first to admit I find the scribble internals a little scary :)

@robby what is the purpose of the use of datum-intern-literal
in *defls
?

typesetting examples in my documentation is making me realize that some Hackett forms are totally broken at the top level :(

when evaluating something at the top level with the shape (begin (define-syntax foo ....) (some-macro ....))
, is it possible to arrange for foo
to have been bound by the time some-macro
is expanded?

though, actually, it seems like maybe that does normally happen. so I’m not sure why my tangled macro code is seeing otherwise. :(

Ah… the real issue is that I’m expanding to something like this: (begin
(define-for-syntax a ....)
(define-syntax (b stx)
.... a ....))
…and when b
is expanded, a
’s use produces a use-before-definition error for some reason.

I have no idea why this is the case, much less how to work around it. @mflatt or @samth, can either of you give me some advice here?

This program reproduces the error: #lang racket
(require syntax/parse/define)
(define-simple-macro (f m:id)
(begin
(define-for-syntax x "prop value")
(define-syntax (m stx) x #'(void))))
> (f m)
> (m)
x: undefined;
cannot reference an identifier before its definition
phase: 1

Short answer: the top level is hopeless

I know that, but I would like users to be able to define datatypes in the REPL. :)

I think one of Matthew’s posts in my gist on that topic discussed this issue but I’m not certain

lemme dig that gist up, then…

I think the long answer is to use the (define-syntaxes (x) (values))
hack - in this case under begin-for-syntax

But only when expanding in a top-level context

I see that hack is alluded to here… http://lists.racket-lang.org/dev/archive/2009-October/001381.html …but I don’t really understand what it does.

I guess it’s documented in the reference under “Macro-Introduced Bindings”, but some of this makes my head spin.

Hmm… that hack doesn’t actually work here, though, anyway, unless I’m doing it wrong. This program produces the same error: (define-simple-macro (f m:id)
(begin
(define-for-syntax x "prop value")
(define-syntaxes [x] (values))
(define-syntax (m stx) x #'(void))))

The thing that makes me think this is something different is that the issue is not an unbound identifier error, merely a use-before-definition error.

The empty-(values)
trick seems to be for a forward declaration, but I don’t need a forward declaration here.

I realized I was doing the forward declaration wrong, but doing it right doesn’t change anything, as far as I can tell. :p

@lexi.lambda just looked at that code and I have no idea!

I guess there must an eq or an eq hash somewhere. sorry I’m of no use

That’s fine! I removed it and it seems to work okay, so I’m just hoping there isn’t some important reason that I’ll find out about later.

I think it was only performance. This appears to be the commit where it was introduced:


Of course, something somewhere may accidentally depend on eq-ness. (One of the reasons I don’t like eq!)

@lexi.lambda I think you’re seeing something different than the problem that can be solved with (define-syntaxes [x] (values))
. Your example only fails for me in DrRacket if I haven’t saved the module to a file, which maybe has to do with how DrRacket treats the module; more importantly, I don’t see the problem when using the new expander implementation. I think it’s yet another bug in the old expander’s implementation of module->namespace
.

Ah, hmm, perhaps a DrRacket issue then. That means the actual issue in my code is probably something else, and that test case was oversimplified.

Thank you for looking into it. I’ll try digging into it some more.

My guess is that DrRacket is sometimes masking the bug, and the problem you’re seeing is in module->namespace

How would the old expander be relevant here? I’m running a very new version of Racket.

I guess there are too many “old” expanders now. To me, the current release and main Racket development branch are an old expander (i.e,. the one in C); the new expander (in Racket) is in the racket7 repo

Oh, I see. I am evidently not keeping up with the pace of innovation in the Racket ecosystem. :)

I’ll look into fixing the problem tomorrow

It’s not a big deal if that is, in fact, a red herring. I’ll try and do some more diligent testing to see if it’s actually related to the problem in my real code or not.

Does your real problem involve top-level evaluation?

It does—I’m trying to get something working in the REPL, mostly so that I can use it with scribble/example
.

Likely related, then; it seems clearly to be a bug to fix, in any case

Alright, well, if you get around to fixing it before I figure out what’s wrong with my code, I can let you know if it was the culprit or not.

@mflatt I’m seeing behavior I don’t understand, but I am also having trouble reproducing it in a self-contained test case. I’ve inserted some printf
s in my code, and I’m seeing (local-expand stx 'expression '())
return stx
unchanged, where stx
is some identifier. However, (identifier-binding stx (syntax-local-context) #t)
returns #f
. This only happens at the top level; when the same code is encountered while expanding a module, (identifier-binding stx)
is non-#f
, and local-expand
actually expands to something.
I’m very confused by this behavior. Is there some situation in which local-expand
can pass an identifier through unchanged even though identifier-binding
seems to claim it is unbound? I would expect an unbound identifier error in that scenario, but I also don’t know how the top level treats local-expand
.

Alright, I think I hunted down what was causing that strange error. I think, ultimately, it was user error, though I still don’t understand why local-expand
was behaving that way. Anyway, I’ve run into a different issue, and this program is even smaller. Unfortunately, this fails to compile: #lang racket
(require (for-syntax (for-syntax racket/base)
racket/syntax
syntax/transformer)
syntax/parse/define)
(define-simple-macro (mac id:id)
#:with val (generate-temporary #'id)
(begin
(begin-for-syntax
(define-syntaxes [val] (values))
(define val #'"something"))
(define-syntax id (make-variable-like-transformer val))))
(begin-for-syntax
(local-expand #'(mac foo) 'top-level '()))
This produces this error: foo1: unbound identifier in the transformer environment;
also, no #%top syntax transformer is bound
in: foo1
I tried the define-syntaxes
hack, but it doesn’t seem to help here.

I also tried splitting up the definitions in mac
into multiple macros to try and delay expansion, but that didn’t accomplish anything. I’m pretty lost about how to make this sort of macro cooperate with the top level.