greg
2018-5-27 13:32:39

@ghoetker You could store each pkg as each value: (values (hash-ref pkg 'name) pkg).


greg
2018-5-27 13:33:24

OK yes this means you have the name in both the key and inside the pkg value. For version 0.1 and ~7,000 items, I’m not sure that matters. If it mattered? You could I guess do something like (values (hash-ref pkg 'name) (hash-remove pkg 'name)).


samth
2018-5-27 14:18:19

@krismicinski I’m not sure what you’re asking. What identifier are you referring to?


krismicinski
2018-5-27 16:58:17

@samth basically, I want to add a new identifier to the whole module, say, current-call-stack that will be available in every form of that module, and will give represent the call stack. My vision for how I’d do this is to—at each application site—add the current lambda’s syntactic point to some list that is accessible by the callee (in a degenerate case: some global variable). Obviously there are other ways to keep track of the stack, but this is the best minimal example I can think up for illustrating what I think I need. I’m implementing a runtime security monitor that tracks when you branch on high-security data and needs to add it to a program counter, which is then available in the branches to know what data you’ve currently branched on.

I guess one naive way that I could think to do this would be to gensym a new name while macro-rewriting, and then set! that in all of my macros, and then have my macros insert that symbol as they perform their task, but that doesn’t seem like a very robust idea (and not good for things like threads / exns), so I was thinking of using parameters instead. The identifier doesn’t have to be accessible to the instrumented code, only the macros I’m splicing into the code.


lexi.lambda
2018-5-27 17:01:03

@krismicinski Maybe insert with-continuation-mark in places. See also errortrace, which basically does this (though in a different way than modifying #%app).


krismicinski
2018-5-27 17:01:43

yeah, continuation marks are not a bad idea for this, I’ll read up and think over them for a while.


samth
2018-5-27 19:17:31

@krismicinski I think you’re maybe overthinking this


samth
2018-5-27 19:19:16

just define (#%app f . args) to expand to (parameterize ([current-call-stack (cons '(f . args) (current-call-stack))]) (#%plain-app f . args))


krismicinski
2018-5-27 19:49:52

@samth ah so I tried this, but what I don’t understand here is how current-call-stack gets defined in the first place, then. At some point, current-call-stack has to be initialized to an empty list, otherwise I get scoping errors.


greg
2018-5-27 20:00:44

~As well as #%app, you could provide your own #%module-begin. Maybe that is how/where you would (define current-call-stack (make-parameter '()))?~


samth
2018-5-27 20:01:01

current-call-stack should be defined in whatever module you define #%app in


krismicinski
2018-5-27 20:04:15

Yeah, so I do it in #%module-begin right now, but that seems broken


krismicinski
2018-5-27 20:06:15

When I define it in the module itself I’m getting similar struggles, but I’m not sure why because that makes sense to me


krismicinski
2018-5-27 20:08:15

I think it’s because when I type (define current-call-stack (make-parameter '())) it uses the macro on the make-parameter application, wherein there’s no current-call-stack in scope..?


krismicinski
2018-5-27 20:08:26

(at least, that’s what I’m getting out of the macro stepper if I’m interpreting it correctly)


krismicinski
2018-5-27 20:14:01

why the crossout? This seems like the right intuition to me.


samth
2018-5-27 20:38:40

@krismicinski [samth@hermes:~/work/reviews/oopsla18 (master) plt] cat ~/tmp/xx.rkt #lang racket/load (module lib racket (provide (rename-out [app #%app]) current-stack show) (define-syntax-rule (show) ;; to avoid this appearing in the stack (displayln (current-stack))) (define-syntax-rule (app f . args) (parameterize ([current-stack (cons '(f . args) (#%app current-stack))]) (#%app f . args))) ;; use racket's #%app (define current-stack (make-parameter null)) ) (module use racket (require 'lib) (define (f x) (g x)) (define (g x) (h x)) (define (h x) (show) 1) (f 100)) (require 'use) [samth@hermes:~/work/reviews/oopsla18 (master) plt] r ~/tmp/xx.rkt ((h x) (g x) (f 100)) 1


krismicinski
2018-5-27 20:39:24

This is great!


krismicinski
2018-5-27 20:39:27

Really helps..


krismicinski
2018-5-27 20:40:30

Am I right in saying that you’re using #%app to avoid the macro rewriter then calling your rule again..?


samth
2018-5-27 20:40:37

yes


samth
2018-5-27 20:40:42

although it’s not needed


samth
2018-5-27 20:40:47

i’m just making it clearer


krismicinski
2018-5-27 20:40:54

right


samth
2018-5-27 20:40:58

because it’s called app there so it wouldn’t be used anyway


krismicinski
2018-5-27 20:41:53

One thing I don’t understand is why the (require 'lib) works the way it does: it’s rewriting the #%app form. Does that mean that if I redefine #%app in the current module (e.g., the test module you wrote) it would behave the same way?


krismicinski
2018-5-27 20:42:19

I guess I’ve only ever used this like (module name lib ...


krismicinski
2018-5-27 20:52:34

@samth great! That works! I think this is actually what I want, too, since I want current-pc (in my case) to be across the whole program (anything using that code) rather than a per-module variable, too. Here’s my updated implementation for ref of what I came up with: https://github.com/fordsec/racets/blob/master/src/racets-mlang.rkt#L39


krismicinski
2018-5-27 20:55:02

@lexi.lambda thanks for the help, too. My suspicion is that I could also do this with continuation marks, but it’s not immediately obvious quite yet. I’ll probably have to ponder that one for a while..


krismicinski
2018-5-27 20:56:35

Here’s the test that uses it and now passes :slightly_smiling_face: https://github.com/fordsec/racets/blob/master/src/tests.rkt


samth
2018-5-27 21:16:01

(require 'lib) just requires 'lib


samth
2018-5-27 21:16:15

the meaning of #%app is as if you had written it literally


samth
2018-5-27 21:17:33

for continuation marks, just replace the (parameterize ...) with (with-continuation-mark 'current-stack '(f . args) (#%app f . args))


samth
2018-5-27 21:17:56

and access it with (continuation-mark-set->list 'current-stack (current-continuation-marks))


krismicinski
2018-5-27 21:20:32

frankly my hesitation here is because I just don’t understand continuation marks well enough, this example makes sense, and I guess if I wanted to instrument application for things like if statements and branches I’d also just use continuation marks there…?


samth
2018-5-27 21:20:57

continuation marks are just a lower-level mechanism that’s a lot like parameters


krismicinski
2018-5-27 21:21:17

yeah, makes sense, since parameters seem to do the work of making things nicer than set! for things like dynamic-wind, etc…


samth
2018-5-27 21:22:18

for reference, parameters are implemented on top of continuation marks


krismicinski
2018-5-27 21:22:49

yeah, that’s what I figured :slightly_smiling_face:. Alright, I’m going to keep charging ahead with this, and then once I have the core problems figured out, just switch to using CMs


krismicinski
2018-5-27 21:23:10

I remember looking into CMs when I was trying to write a small abstract interpreter for racket, and they seemed like a good encompassing abstraction