pocmatos
2018-4-11 09:10:16

Are there any gotchas I should be aware of when using the Racket logo on a commercial website to link to the racket webpage? Can’t seem to find any ‘logo’ webpage with usage, etc. Something like: https://llvm.org/Logo.html


jerome.martin.dev
2018-4-11 11:18:32

please, anything BUT the npm model


pocmatos
2018-4-11 12:20:31

Does anyone have any experience with scripting docker-machine commands in racket?


blerner
2018-4-11 14:12:06

QQ: is there a simple require we can use in ISL+ to include hash-maps?


lexi.lambda
2018-4-11 15:02:28

@mflatt Can I throw some questions your way about local-expand and first-class definition contexts? And if so, would the mailing list be a better place for you than slack?


mflatt
2018-4-11 15:02:48

Here is fine


lexi.lambda
2018-4-11 15:04:46

Okay, great. I’ve been spending some time over the past few days abusing local-expand, so in the process I’ve run into some things I don’t really understand. :) I think the biggest thing I’m confused about is the relationship (if one exists) between using a list for the context argument to local-expand and the internal definition context argument.


lexi.lambda
2018-4-11 15:06:22

After reading the section on first-class definition contexts in the sets of scopes paper again a few times, I picked up that internal-definition-context-introduce essentially corresponds to an outside-edge scope. But what corresponds to the inside-edge scope?


mflatt
2018-4-11 15:10:44

Offhand, I would characterize it more as an inside-edge scope. An outside-edge could simply be applied to the body up front.

There is a kind of redundancy between the context as a list and the definition-context argument. The context as a list is meant for public visibility through syntax-local-context, though, while the provided definition context is not exposed that way. Macros might use the result of syntax-local-context – for example, to determine that a previously lifted definition definition can still be accessed, as the contract system does. But macros should not be able to get the definition-context value and directly add bindings or otherwise abuse it.


mflatt
2018-4-11 15:11:37

A drawback of separate arguments is that there’s no enforcement of the intended correlation between the context list and definition contexts.


lexi.lambda
2018-4-11 15:14:47

Re: inside- vs outside-edge, yes, you’re right; I just checked the section of the paper again and discovered I’d misremembered which one it was. Wrt a list context as an argument to local-expand, what exactly does it do? Is it only relevant to macros that look at syntax-local-context? I guess maybe that’s always true for the context argument, since I suppose things like define just signal errors when syntax-local-context is 'expression, but I’m wondering what effect setting the context to, say, (list (gensym)) actually has on forms in racket/base.


mflatt
2018-4-11 15:17:28

Yes, it only affects the result of syntax-local-context. Well, the distinction between top-level, expression, etc., affects some built-in forms, but the built-in forms don’t care about the list content as a context; all lists are treated the same as just “a definition context”.


lexi.lambda
2018-4-11 15:21:09

I see, interesting. That helps to clarify some of my confusion. What I’m essentially doing is abusing local-expand to reimplement parts of the macroexpander in userspace code so that I can inject custom behavior at certain places in the expansion process (for Hackett, that means defining my own “core forms” for the type/value language, and for the mutation testing project I’ve just started working on with Christos, it means creating mutant variants of forms that are discovered as forms are expanded). Due to the way local-expand adds identifiers to the stop list, that means I’m trying to emulate what the expander does when it sees core forms like #%plain-lambda and letrec-syntaxes+values.


lexi.lambda
2018-4-11 15:22:31

What I’ve been doing is creating a first-class definition context to hold the bindings, then recursively calling local-expand on the body of each form until the program is fully-expanded. Then I replace the binding identifiers with equivalents that have the definition context’s scope added to them.


lexi.lambda
2018-4-11 15:24:05

This seems to work okay when I control the language (in the case of Hackett), but I’ve been running into some situations in which the scopes don’t seem quite right when I’m expanding some racket/base forms (in the case of mutation testing), so I’m trying to ensure I’m jumping through all the appropriate hoops.


lexi.lambda
2018-4-11 15:26:56

I’ve also been running into confusion about where to insert syntax-disarms and syntax-rearms, as well as whether or not what I’m doing is actually safe with regard to the syntax taint system, but maybe I can postpone that question for another day.


mflatt
2018-4-11 15:29:04

Would it be easier/better/relevant to revisit the question of automatically add to the stop list? I think it’s probably not always necessary with scope sets, so maybe we should add a way to disable the additions.


lexi.lambda
2018-4-11 15:31:45

After spending a lot of time over the past few days thinking about this, I’m not sure it would work, but I’m also not sure it wouldn’t—I don’t really know enough about the expander to say for sure. But from what I think I understand, the problem is that partial expansion doesn’t interact well with let-syntax bindings, since if the body of a let-syntax is partially expanded, residual uses of the syntax bindings will be out of context when the form is subsequently expanded. Is that accurate?


mflatt
2018-4-11 15:37:49

Hm, yes… the primitive letrec-syntaxes+values form currently doesn’t support expansion that keeps the letrec-syntaxes+values; and if it did, I guess there would have to be some way of avoiding multiple evaluation of its RHSs.


lexi.lambda
2018-4-11 15:38:53

@robby FWIW, DrRacket background expansion got stuck again on my machine (for the first time in a while), but I don’t think I have the relevant instrumentation inserted for that to be helpful. If it would be helpful, I can insert the instrumentation if you tell me what to do in the case that it happens again.


lexi.lambda
2018-4-11 15:42:39

I think the fundamental issue makes sense, and I think it’s actually mostly okay for what I’m doing. With Hackett, the only issue I’ve actually run into with my solution is the interaction with forms that care about recursive expansion, like the new implementation of syntax-parameterize. That problem is a bit trickier to solve, though, since it essentially means I want the expander to operate using a different set of core forms. From syntax-parameterize’s POV, it needs its bodies to be fully-expanded, so just propagating the stop list wouldn’t be enough. Rather, syntax-parameterize would actually have to yield to my custom expander code so that I can handle those forms properly.


robby
2018-4-11 15:45:08
env PLTSTDERR=info@drracket-background-compilation drracket

robby
2018-4-11 15:45:35

to see if it is working, put this program in the definitions window and wait more than a second or two, but less than 100 seconds:


robby
2018-4-11 15:46:09
#lang racket
(begin-for-syntax
  (let hi-spencer ()
    (void
     (let hi-shu-hung ()
       (void
        (let dan ()
          (void
           (sleep 100))))))))

lexi.lambda
2018-4-11 15:46:15

There are plenty of other ways to solve the problem, though, if we permit modifying the macroexpander. I guess one might be enabling users to define new forms that are treated similarly to Racket’s existing core syntactic forms, in the sense that the macroexpander would yield control to them when seeing one but wouldn’t expand its expansion. That would allow me to use ordinary recursive expansion instead of doing hacky things with the stop list to emulate recursive expansion with a different set of core forms. I don’t really know how to enforce the appropriate protocol there, though (since it would be easy to construct misbehaving “custom core forms”).


robby
2018-4-11 15:46:16

and then add some whitespace somewhere


robby
2018-4-11 15:46:33

You should see someone that looks like a stacktrace


mflatt
2018-4-11 15:46:39

I haven’t thought enough about the problem, but assuming that we can’t solve it by adjusting local-expand, I wonder if syntax-parameterize needs to support some way for macros to cooperate with it


robby
2018-4-11 15:47:10

the output from drracket-background-compilation: expanding-place.rkt: 00 starting monitors to the end of the stack trace is hopefully helpful for the real bug.


lexi.lambda
2018-4-11 15:47:45

Okay, turning the logger on should be sufficient? I don’t need to patch DrRacket’s code in any way, right?


robby
2018-4-11 15:48:06

Yes. Right.


lexi.lambda
2018-4-11 15:48:19

Okay, thanks, I’ll do that.


lexi.lambda
2018-4-11 15:52:12

I think the problem is not specific to syntax-parameterize but rather any form that performs recursive expansion.


lexi.lambda
2018-4-11 15:52:52

It works for Hackett because I control the whole language. I could get away with reimplementing syntax-parameterize to use my custom expansion code, but I’d rather not. It wouldn’t work if I didn’t control the whole language.


lexi.lambda
2018-4-11 15:53:39

It sort of works with mutation testing because I’m not adding any new forms to the stop list. So if a form forces expansion using local-expand, the program will still work, I just might miss some opportunities to insert mutations.


lexi.lambda
2018-4-11 15:55:52

But I think @michael.ballantyne’s point in the GH issue I opened about syntax-parameterize and @notjack’s thoughts here in Slack are on the right track: if people are interested in using local-expand in this way, then uses of local-expand probably need to affect nested uses of local-expand in some way. But that raises questions about both safety and API design wrt backwards compatibility, I think.


lexi.lambda
2018-4-11 15:57:58

(The “custom core forms” idea I mentioned earlier would work for Hackett, but not mutation testing, which to be fair is meaningful. Hackett is doing what I think is a reasonable thing to be doing, but the thing I’m doing for mutation testing is kind of evil, since I’m intentionally screwing with code other macros are supposed to control. So maybe it isn’t a good idea to try and come up with a single solution for both problems just because I’m currently solving them in similar, albeit hacky ways.)


mflatt
2018-4-11 16:05:34

It makes sense that a way for macros to cooperate with syntax-parameterize could generalize to a way for macros to cooperate more with macros that use local-expand. I’m open to experiments, but I certainly don’t know the answer offhand.


lexi.lambda
2018-4-11 16:09:46

Yes, I didn’t by any means expect you to. :) I was mostly just hoping to get an answer to my first question; the rest of this is just handwaving. I think I may be unblocked for now on the mutation testing thing I’m tinkering with, which is good enough. I’m not totally sure what to do about Hackett right now, but I can probably do a different hack in the immediate future (by avoiding syntax-parameterize using either syntax-local-get-shadower or just breaking hygiene with datum->syntax).


steve
2018-4-11 16:33:47

@steve has joined the channel


michael.ballantyne
2018-4-11 17:03:16

@lexi.lambda I think adding support for core forms to the expander is definitely a better way to go than trying to emulate the expander in userspace, given that you can’t wrest control of what a call to local-expand in a macro does. There are lots of uses for custom core forms.


samth
2018-4-11 17:29:28

Certainly Typed Racket would find “custom core forms” useful as well


lexi.lambda
2018-4-11 18:14:50

@mflatt @michael.ballantyne @samth From your perspectives, what would the API for a “custom core form” binding look like? Obviously it would be neither safe nor very user-friendly to provide the expander’s add-core-form! API as it is, but maybe it can be done in a way that feels similar to writing an ordinary transformer, with the exception that the result isn’t re-expanded by the expander to avoid infinite loops?


lexi.lambda
2018-4-11 18:16:33

I think my only real question is how users would instruct which parts of a core form ought to be expanded by the expander. Would it be enough for them to just call local-expand on those pieces?


michael.ballantyne
2018-4-11 20:12:19

(define-syntax my-core-form (make-core-form-expander (lambda (stx) …)))


michael.ballantyne
2018-4-11 20:12:48

Then inside use local-expand and the first-class definition context API.


lexi.lambda
2018-4-11 20:13:35

Yes, that’s pretty much exactly what I had in mind, too. If you think that would work, it doesn’t sound too difficult to add to the expander.


lexi.lambda
2018-4-11 20:15:13

I guess you’d have to handle some error case when a core form appears in a fully-expanded program (but, of course, not under quote-syntax).


michael.ballantyne
2018-4-11 20:15:14

If there are custom core forms it is no longer the case that the result of expansion is necessarily a racket core form or that it can be be represented by the expander in its “parsed” AST form.


lexi.lambda
2018-4-11 20:15:54

When/where are the parsed AST forms used?


michael.ballantyne
2018-4-11 20:20:08

Having a little difficulty tracking it down exactly, but my intuition is that it expands directly to parsed AST forms rather than syntax objects when the result of the expansion is going to be directly compiled or evaluated.


michael.ballantyne
2018-4-11 20:20:31

So eval would do that, whereas a user call to expand wouldn’t.


michael.ballantyne
2018-4-11 20:21:59

Last I talked to matthew he seemed to feel that the standard top-level expand function should error if it expands to something other than a racket core form, and that there should be an alternate API for expansions where an extended target language is OK.


michael.ballantyne
2018-4-11 20:23:13

I don’t think that would be a problem, but it’s less clear to me whether local-expand should have a variant or the existing local-expand should be okay returning new core forms.


abmclin
2018-4-11 21:10:02

I’m curious to the reason why define-struct/contract does not support the #:methods keyword?


abmclin
2018-4-11 21:13:17

I’m trying to add gen:custom-write to a struct I have protected with contracts via define-struct/contract but alas not possible. I can simple revert to using struct but is there any other way to attach contracts to a struct? So far it appears I have only two options: define-struct/contract or (provide (contract-out (struct ...))). I don’t want the provide option since I’m not exporting the struct outside the module but I still want to protect it with contracts because it’s handling critical data.


notjack
2018-4-11 21:20:20

@abmclin I think define-struct and define-struct/contract ought to be considered deprecated (in the context of #lang racket and #lang racket/base at least)


notjack
2018-4-11 21:21:05

You can put the struct in a submodule


abmclin
2018-4-11 21:21:49

ah, that would work


notjack
2018-4-11 21:22:57

you could also use with-contract, but you’d have to list every identifier bound by the struct individually and I think it would shadow the static struct info binding (not sure on that one)


abmclin
2018-4-11 21:23:30

ok