
does anyone else on Mac OS get an invisible frame/window from DrRacket called “root”? i.e. if I hit command+tab, move over to DrRacket and press the down arrow to tile display all the open DrRacket windows, it displays the window you would expect (i.e. DrRacket) and a window called “root” that seems to have a 0x0 window (or some other invisible size). The only reason this matters is I believe it is breaking the “mission control” Mac OS feature (i.e. 3 finger swipe up on the track pack, or ctrl+up). I think whenever that invisible “root” window exists corresponds to the “mission control” feature displaying no windows… which is extremely annoying.

(Note: the “root” window does not exist when I start DrRacket… it’s opened some time later — I’ll see if I can figure out a rhyme or reason to when it seems to appear)

Thanks @mflatt - that sorted it out.

@pnwamk do you have any DrRacket plugins installed?

Yes, one



@pnwamk maybe its pointless, but I’ve been meaning to try out todo-list anyway. I’ll see if I can reproduce the issue.

@pnwamk what does the ‘root’ window look like? (how do you know it is there?)

@pnwamk or do you have weird tiling when your press ^[down]?

I got this window without plugins. It appears if I start DrRacket and close the window. DrRacket keeps running and if I right-click on its icon in the dock and choose Show All Windows, I can see the Root window.

@spdegabrielle the root window looks like its 0 pixels high and maybe 20 pixels across (i.e. its sort of just a short horizontal line) and it says “root” above it. The only way I’ve been able to see it is by pressing cmd+tab, moving over to DrRacket, and pressing the down arrow.

I’ll make sure to take a screenshot next time it happens… xD

I am able to reproduce the behavior! yay!


@spdegabrielle detailed steps to reproduce exist, FYI

is there a way to do the opposite of syntax-local-eval
?

as in, I’ve got an internal-definition-context?
value, an identifier, and an arbitrary value and I want to bind the identifier to the value with define-syntax
within the context

all I see is syntax-local-bind-syntaxes
which binds identifiers to the result of a syntax object representing a compile-time expression

I have a sneaking suspicion that trying to introduce an identifier to value binding directly like this is either impossible or not a good idea

@notjack Evil answer: you could use 3D syntax. #lang racket
(require syntax/parse/define)
(begin-for-syntax
(struct non-marshallable-box (value)))
(define-simple-macro (smuggle x:id e:expr)
#:do [(define ctx (syntax-local-make-definition-context))
(define value-to-smuggle (non-marshallable-box 42))
(syntax-local-bind-syntaxes (list #'x) #`(quote #,value-to-smuggle) ctx)]
#:with result (local-expand #'e 'expression '() ctx)
result)
(define-simple-macro (unsmuggle x:id)
#:with val (non-marshallable-box-value (syntax-local-value #'x))
(quote val))
(smuggle y (unsmuggle y)) ; => 42

what are the karmic consequences of this evil?

This particular instance is, as far as I can tell, “safe”, since the 3D syntax is erased by the time the program fully expands. But I don’t know for sure, so don’t quote me on that.

don’t quote
you on it eh?

:rimshot:

:finger guns:

it’s hard to tell if this is a bad idea or not

Yeah, I have no idea if it is or isn’t.

it feels like a bad idea

Probably @mflatt could speak to whether or not there’s some pitfall I don’t know about. I’ve never actually tried doing something like that in practice.

but really I can’t tell at all

Yes, I think that’s a safe use of 3-D syntax.

@mflatt would it be unsafe if the definition created by smuggle
was provided by a module?

I can say that yes, it would be, but I don’t understand how a binding in an internal definition context could be provided by a module…

in my case I have a structure that implements prop:rename-transformer
and contains an internal definition context as a field

I’ll be honest, I don’t really understand the implications of what you just said… are you provide
ing a binding that is bound to an instance of that struct? Won’t that provide the target of the rename transformer, not the struct itself? Unless it’s marked 'not-free-identifier=?
… but that seems unlikely.

it’s marked 'not-free-identifier=?

Oh. Okay… so then what do you do with this definition context inside the struct, and why does it matter that it implements prop:rename-transformer
?

well… I’m trying something kind of weird

…do you have prop:rename-transformer
bound to a procedure that… forges an identifier and calls internal-definition-context-introduce
on it?

In any case, if you’re doing something like that in a straightforward way (or as straightforward as that can be), that would still be safe, since the internal definition context would be recreated on each instantiation of the module (and therefore so would the value embedded in 3D syntax). On the other hand, if you wanted to make that the same across instantiations, I don’t see how you could do it.

I’m trying to do something similar to this: https://github.com/racket/typed-racket/blob/master/typed-racket-lib/typed-racket/typecheck/renamer.rkt#L15

basically, I’m making a rename transformer that lets me stick arbitrary static info on an identifier in an extensible way

the transformer normally behaves as whatever the original identifier is

when you construct it, you can give it a map of static info kinds to identifiers bound with define-syntax
to values

and you can instruct it via a parameter to instead use one of those transformer bindings as its rename target instead of the original identifier

the static info kinds have contracts attached so you can let multiple different macros communicate multiple different kinds of static info via the same identifier without requiring they cooperate with each other, and you get contracts that are enforced at the time you try to attach static info to an identifier

so the rename transformer has an internal definition context contained within it

I see… I think you might run into the problem that side-effects aren’t preserved?

If you have the ability to attach arbitrary information to an identifier, doesn’t that mean that the identifier isn’t defined in the same module as the places where its meanings might be defined? Or do they all have to be defined at once?

They all must be defined at once, and there’s no mutation involved I think

but I’m not deeply familiar with how module instantiations and visits work so it’s entirely possible this won’t work at all

Well, there’s mutation in the sense that you’re calling syntax-local-bind-syntaxes
, no?

But it seems alright, anyway, if all of that is happening in one module. Each time the module containing the definition is instantiated, it will re-create the internal definition context, so the 3D syntax never ends up in the fully-expanded program.

the bindings created with syntax-local-bind-syntaxes
are themselves rename transformers to already-created bindings elsewhere, so I can link things up - the bindings for the static values themselves aren’t contained in that context

Hm. Well, I probably can’t understand the precise indirections without looking at your code, but the gist of it is that you just can’t have 3D syntax embedded in a fully-expanded program (since it can’t be marshalled to bytecode), but you can have as much 3D syntax as you want as long as it only lives during expansion and is gone by the time expansion completes.

So if you embed 3D syntax in some code that doesn’t get erased, like on the RHS of a module-level define-syntax
or inside a begin-for-syntax
block, that’s bad. But if you have an expression that creates 3D syntax in those places, that’s fine, since the thing marshalled to bytecode is the expression, not the 3D syntax.

Now, I’m going to do a little bit of inductive reasoning here, so take this with a grain of salt, but all internal definition contexts become letrec-syntaxes+values
eventually. And if you look at the grammar for fully-expanded programs, letrect-syntaxes+values
can never appear in a fully-expanded program, only letrec-values
, so the syntax bindings must be erased by the time a program expands. Therefore, I imagine any 3D syntax embedded in the RHS of a syntax binding in an internal definition context must be safe.

You’ll end up duplicating any work that you do to construct that internal definition context if you’re sticking its creation on the RHS of a module-level define-syntax
, since it will be recreated every time that module is instantiated. But that’s probably fine, since it seems like the values you’re smuggling this way are not morally different from the RHSs of your usual instances of module-level define-syntax
, which are also recreated on every module instantiation.

So there’s my handwaving as to why I think you’ll be okay if you do that, but I’ve been wrong before. ;)

this sounds about right

god I hope this works