pnwamk
2018-4-7 16:03:30

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.


pnwamk
2018-4-7 16:04:25

(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)


spdegabrielle
2018-4-7 16:17:00

Thanks @mflatt - that sorted it out.


spdegabrielle
2018-4-7 16:20:45

@pnwamk do you have any DrRacket plugins installed?


pnwamk
2018-4-7 16:21:27

Yes, one



pnwamk
2018-4-7 16:23:03
I just opened a file that uses it and didn’t see the “root” window pop up =

spdegabrielle
2018-4-7 16:25:34

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


spdegabrielle
2018-4-7 16:26:33

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


spdegabrielle
2018-4-7 16:34:03

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


sergej
2018-4-7 17:46:42

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.


pnwamk
2018-4-7 21:11:20

@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.


pnwamk
2018-4-7 21:12:06

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


pnwamk
2018-4-8 01:02:02

I am able to reproduce the behavior! yay!



pnwamk
2018-4-8 01:03:26

@spdegabrielle detailed steps to reproduce exist, FYI


notjack
2018-4-8 02:31:27

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


notjack
2018-4-8 02:32:14

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


notjack
2018-4-8 02:33:18

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


notjack
2018-4-8 02:33:46

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


lexi.lambda
2018-4-8 03:08:09

@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


notjack
2018-4-8 03:10:07

what are the karmic consequences of this evil?


lexi.lambda
2018-4-8 03:10:27

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.


notjack
2018-4-8 03:10:39

don’t quote you on it eh?


lexi.lambda
2018-4-8 03:10:43

:rimshot:


notjack
2018-4-8 03:10:54

:finger guns:


notjack
2018-4-8 03:11:50

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


lexi.lambda
2018-4-8 03:12:05

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


notjack
2018-4-8 03:12:33

it feels like a bad idea


lexi.lambda
2018-4-8 03:12:37

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.


notjack
2018-4-8 03:12:38

but really I can’t tell at all


mflatt
2018-4-8 05:24:28

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


notjack
2018-4-8 05:31:07

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


lexi.lambda
2018-4-8 05:32:05

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…


notjack
2018-4-8 05:32:56

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


lexi.lambda
2018-4-8 05:35:59

I’ll be honest, I don’t really understand the implications of what you just said… are you provideing 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.


notjack
2018-4-8 05:36:14

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


lexi.lambda
2018-4-8 05:36:53

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?


notjack
2018-4-8 05:38:06

well… I’m trying something kind of weird


lexi.lambda
2018-4-8 05:39:15

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


lexi.lambda
2018-4-8 05:42:04

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.



notjack
2018-4-8 05:45:17

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


notjack
2018-4-8 05:46:06

the transformer normally behaves as whatever the original identifier is


notjack
2018-4-8 05:47:24

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


notjack
2018-4-8 05:48:09

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


notjack
2018-4-8 05:49:16

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


notjack
2018-4-8 05:49:40

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


lexi.lambda
2018-4-8 05:55:50

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


lexi.lambda
2018-4-8 05:56:52

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?


notjack
2018-4-8 05:57:36

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


notjack
2018-4-8 05:58:07

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


lexi.lambda
2018-4-8 05:58:58

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


lexi.lambda
2018-4-8 06:00:43

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.


notjack
2018-4-8 06:02:10

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


lexi.lambda
2018-4-8 06:05:03

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.


lexi.lambda
2018-4-8 06:06:47

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.


lexi.lambda
2018-4-8 06:09:42

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.


lexi.lambda
2018-4-8 06:11:51

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.


lexi.lambda
2018-4-8 06:12:46

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


notjack
2018-4-8 06:14:03

this sounds about right


notjack
2018-4-8 06:15:04

god I hope this works