lexi.lambda
2018-1-26 18:06:48

@mflatt I’m trying to add splicing-parameterize to racket/splicing, but I’m not quite sure how to implement @ryanc’s suggestion to let go of the reference to the parameterization after the bodies. I thought about treating the final body specially, but as a particularly perplexing edge case, it could expand into (begin), in which case inspecting the previous body is necessary.


mflatt
2018-1-26 19:26:12

@lexi.lambda I think Ryan’s suggestion was to add (set! new-parameterization #f) only in a module or top-level context. It should be easy there, and it should be unneeded elsewhere.


lexi.lambda
2018-1-26 19:27:15

That will still cause different behavior in the REPL, right? It will always produce #<void> instead of printing a value, if relevant.


lexi.lambda
2018-1-26 19:27:27

But maybe that’s acceptable.


mflatt
2018-1-26 19:28:06

I see what you mean, and I agree that it’s acceptable.


lexi.lambda
2018-1-26 19:28:30

Okay, works for me. Thanks for your input; I’ll probably open a PR soon.


leif
2018-1-26 19:41:11

@lexi.lambda YAY! :heart:


leif
2018-1-26 20:46:59

@mflatt I have a question involving two modules A and B, as well as a third module C that dynamically visits A.

B uses an accumulator during expansion


leif
2018-1-26 20:48:41

Which it provides (for-syntax).

A requires B, and since this accumulator is used at phase 1 B is freshly…err…instantiated (I think that’s the word?)


leif
2018-1-26 20:49:32

Anyway, if C dynamically visits A, is there any way I can get the accumulators that B built up (and provided) for that specific instantiation for A?


mflatt
2018-1-26 20:50:57

How does C dynamically visit A?


leif
2018-1-26 20:59:04

Honestly, any way that makes it possible.


leif
2018-1-26 20:59:22

A and B are files on the machine.


leif
2018-1-26 21:00:08

I’m happy to parse them as syntax objects and call expand, I’m happy to call dynamic-require on the module path, and honestly, I’m happy to do other things which I’m sure I left out as well.


samth
2018-1-26 21:00:40

@leif have A serialize the accumulator into a begin-for-syntax that re-creates it when C visits A


samth
2018-1-26 21:00:50

a la YWIW


leif
2018-1-26 21:01:46

@samth So, I am not directly writing A.


leif
2018-1-26 21:02:00

However, I do have control over the language A is written in.


samth
2018-1-26 21:02:11

so make the language do that


leif
2018-1-26 21:02:19

So are you saying all modules written in the language A is written in should have that export?


samth
2018-1-26 21:03:14

yes (although I wouldn’t describe it as an export)


leif
2018-1-26 21:04:39

Okay, then if A doesn’t export it (or its serialization), how can C get it?


leif
2018-1-26 21:04:58

I mean, making the box isn’t the problem, its getting it from B to C.


leif
2018-1-26 21:06:44

Oh, or are you just saying that A should define it, but not export it.


samth
2018-1-26 21:06:47

the technique I described is how C can get it


leif
2018-1-26 21:06:54

And then C should grab the namespace for A.


leif
2018-1-26 21:06:59

I guess that might work.


samth
2018-1-26 21:07:01

and neither “define” nor “export” are good words here


leif
2018-1-26 21:14:01

So, IIRC, YWIW uses begin-for-syntax inside of a syntax object to sort of…re-build information every time module A is visited.


leif
2018-1-26 21:15:10

Where as I don’t really care about whether or not the data is there after re-expansions. Rather, I would like something a little more subtle.


leif
2018-1-26 21:16:15

I want the actual accumulator used during the visit to B, not just a serialization. And I want it because I am expecting A to be an incomplete (readable but with, say, buggy macros) file.


leif
2018-1-26 21:17:32

This is because that accumulator contains, more or less diagnostic information that B uses in the language implementation. But now I’m also trying to make a tool to print that information out. And I don’t want to assume A actually finished expanding.


leif
2018-1-26 21:18:57

@samth So if YWIW talks about that sort of thing and I completely missed it, I’m sorry. If I understand its section 3 (where you implement records) of the paper you’re talking about, yes?


samth
2018-1-26 21:19:12

Yes, that’s right


samth
2018-1-26 21:19:25

I don’t think you can get “the actual value”


leif
2018-1-26 21:19:42

Ah, okay.


leif
2018-1-26 21:19:51

hmmph…sad day. Thanks.


leif
2018-1-26 21:20:30

But ya, that’s why I was asking @mflatt, because if its at all possible, I’m sure he’d know. (As I’m not aware of anyone in the Racket ecosystem actually trying to do such a…odd…thing.)


samth
2018-1-26 21:20:31

but why is “the actual value” needed


leif
2018-1-26 21:20:45

Because A may not have finished expanding.


samth
2018-1-26 21:20:55

I don’t see how that’s related


leif
2018-1-26 21:21:45

Like, say, they could have written the file:

#lang the-lang
(f 1 2 3)

And the expander throws and error saying f is unbound.


samth
2018-1-26 21:22:00

sure


leif
2018-1-26 21:22:13

From what I gather, the technique used in YWIW assumes the Zoo file actually expands.


leif
2018-1-26 21:22:29

So it can grab the serialized value from its code.


samth
2018-1-26 21:22:38

no, that’s not how it works


samth
2018-1-26 21:23:27

the technique inserts expressions which mutate state, and then other code looks at that state


leif
2018-1-26 21:24:26

Right. IIRC it inserts something like: (register-def #'c-name #'p-name #'(f-name ...))) (copy/paste from the paper)


samth
2018-1-26 21:24:48

yes


leif
2018-1-26 21:25:16

Mmm…so you’re saying that C should get access to the registry that register def adds to


samth
2018-1-26 21:25:22

yes


leif
2018-1-26 21:25:39

AH, okay.


leif
2018-1-26 21:25:52

Wow, that’s subtle.


leif
2018-1-26 21:26:25

(I mean, there was a LOT of really cute subtle stuff in the paper I did pick up, but that use of the idea was not one I put two and two together.)


leif
2018-1-26 21:32:41

@samth Ah, okay. I think I remember the problem I had with that. Namely, I still can’t get my hands on the registry register-def mutates. (Unless its somehow parameterizable by C)


samth
2018-1-26 21:33:13

B should provide it


samth
2018-1-26 21:33:20

and the C requires B


leif
2018-1-26 21:33:39

Oh, you mean B should provide it at phase 0?


leif
2018-1-26 21:34:04

(I mean, it already provides it at phase 1, but obviously it will get reset every time the module runs.)


leif
2018-1-26 21:34:47

err…every time module A gets visited.


samth
2018-1-26 21:36:15

I mean B should be something like:


samth
2018-1-26 21:36:41
(module B racket/base
  (define registry (make-hash))
  (provide registry))

leif
2018-1-26 21:48:39

@samth Sure, I have a module: (module submod-acc racket/base (provide (all-defined-out)) (define editor-list-box (box '())) (define editor-mixin-list-box (box '()))) (require (for-syntax 'submod-acc))


leif
2018-1-26 21:48:48

Where editor-list-box is the registry.


leif
2018-1-26 21:49:20

But whenever I do a dynamic-require of A, that box is (expectedly) empty.


leif
2018-1-26 21:50:51

(I’ve also been doing the dynamic require with the (void) argument)


leif
2018-1-26 21:51:00

So it visits the module.


samth
2018-1-26 21:51:38

right, so you need to make A update that box


samth
2018-1-26 21:51:51

or B, since A depends on B


leif
2018-1-26 21:53:05

I already do that (unless its wrong):

(define-for-syntax (add-syntax-to-editor! stx)
  (define existing (unbox editor-submod-box))
  (when (null? existing)
    (syntax-local-lift-module-end-declaration
     #'(define-editor-submodule)))
  (set-box! editor-submod-box (append (reverse (syntax->list stx)) existing)))

(define-syntax (editor-submod stx)
  (syntax-parse stx
    [(_ body ...)
     (add-syntax-to-editor! (syntax-local-introduce #'(body ...)))
     #'(begin)]))

leif
2018-1-26 21:53:16

(The same trick that also lets module+ work.)


leif
2018-1-26 21:53:42

OH


leif
2018-1-26 21:54:11

Except I forgot to add it to the template for the editor-submod….


leif
2018-1-26 22:02:02

@samth Hmm…nope, still empty.

I added: #'(begin (begin-for-syntax (set-box! editor-list-box ....)))


leif
2018-1-26 22:02:15

Into the template.


samth
2018-1-26 22:02:50

that will change the box at at phase 1 of the expansion of A


leif
2018-1-26 22:02:51

Also I’m currently trying to get it with something like: (dynamic-require 'editor/stdlib (void)) (dynamic-require '(submod editor/lang submod-acc) 'editor-list-box)


samth
2018-1-26 22:02:57

is that what you want?


samth
2018-1-26 22:03:20

that won’t do what you want wrt those dynamic-require calls, which are doing things at phase 0


samth
2018-1-26 22:03:51

what you want is to generate code that updates the box at whatever phase you actually want it


leif
2018-1-26 22:03:53

Ah, woops, the second one should be dynamic-require-for-syntax


leif
2018-1-26 22:04:26

But ya, it should be at module A’s phase 1.


leif
2018-1-26 22:04:43

OMG, it dynamic-require-for-syntax worked:


leif
2018-1-26 22:04:47
(dynamic-require 'editor/stdlib (void))
(dynamic-require-for-syntax '(submod editor/lang submod-acc)
                            'editor-list-box)

samth
2018-1-26 22:05:39

you might find our PLDI’11 or Scheme’07 papers clearer on this


leif
2018-1-26 22:06:41

That’s the advanced macrology paper iirc right?


leif
2018-1-26 22:07:07

(Or the TR paper from the macro perspective.)


samth
2018-1-26 22:11:01

yes


leif
2018-1-26 22:11:51

Okay cool.


leif
2018-1-26 22:12:03

It looks like its working now. Thanks so much for your help.