[racket-dev] Experiments with closure conversion
I have a control-flow analysis of a subset of Racket that is similar to R4RS Scheme (only with immutability in the right places). In fact, I have many - in order to compare different analyses' effectiveness and precision, I have a series of post-hoc analyses and program transformations I want to do. One is lightweight closure conversion (Wand Steckler 1996) Is a source-source transform that uses immutable vectors for passed environments and unsafe references for variable lookups enough to get the Racket compiler to pick up on what I'm doing? I'm really not quite sure which question to ask, since I haven't made my own higher-order language compiler top to bottom before, and don't know if there might be internal represenations that I'd need to use rather than user-level representations. Thanks, -Ian _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
On 2012-11-21 12:10:10 -0500, ro...@racket-lang.org wrote: 9863366 Robby Findler ro...@racket-lang.org 2012-11-21 07:29 : | extend data/queue library Nice! | [...] | | - make queues be sequences directly (and use make-do-sequence | to implement in-queue instead of building a list) Should queues also be streams or just sequences? | - added non-empty-queue? (note extra hypen as compared | to the past; this seems better since the function | wasn't exported before and we already have other | functions named non-empty-something but not | others namedn nonempty-something) The inconsistency now between `non-empty-queue?` and `nonempty-queue/c` seems unfortunate. Can we change the contract name too? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Experiments with closure conversion
I think I don't yet understand the question. Are you wondering about what happens to performance of a Racket program when you convert the program's source before giving it to Racket? And you wonder specifically about performing lightweight closure conversion and how Racket will treat the converted program? If so, since Racket has its own closure conversion, my guess is that manually managing your own conversions will perform less well. It seems possible, though, that you can convert a program so that it performs better by using vectors that effectively allow sharing among closures. At Wed, 21 Nov 2012 11:56:11 -0500 (EST), J. Ian Johnson wrote: I have a control-flow analysis of a subset of Racket that is similar to R4RS Scheme (only with immutability in the right places). In fact, I have many - in order to compare different analyses' effectiveness and precision, I have a series of post-hoc analyses and program transformations I want to do. One is lightweight closure conversion (Wand Steckler 1996) Is a source-source transform that uses immutable vectors for passed environments and unsafe references for variable lookups enough to get the Racket compiler to pick up on what I'm doing? I'm really not quite sure which question to ask, since I haven't made my own higher-order language compiler top to bottom before, and don't know if there might be internal represenations that I'd need to use rather than user-level representations. Thanks, -Ian _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] Experiments with closure conversion
Your answer sounds like we're on the same page, so I'll follow up. Is there any way to communicate with Racket's closure conversion so that lightweight closures use the same representation? I would have to ensure that lightweight closures never flow to functions that I myself don't have the ability to transform to use the right calling convention. Sharing is a separate optimization I am considering (Shao Appel 2000) Thanks, -Ian - Original Message - From: Matthew Flatt mfl...@cs.utah.edu To: J. Ian Johnson i...@ccs.neu.edu Cc: dev dev@racket-lang.org Sent: Wednesday, November 21, 2012 12:56:09 PM GMT -05:00 US/Canada Eastern Subject: Re: [racket-dev] Experiments with closure conversion I think I don't yet understand the question. Are you wondering about what happens to performance of a Racket program when you convert the program's source before giving it to Racket? And you wonder specifically about performing lightweight closure conversion and how Racket will treat the converted program? If so, since Racket has its own closure conversion, my guess is that manually managing your own conversions will perform less well. It seems possible, though, that you can convert a program so that it performs better by using vectors that effectively allow sharing among closures. At Wed, 21 Nov 2012 11:56:11 -0500 (EST), J. Ian Johnson wrote: I have a control-flow analysis of a subset of Racket that is similar to R4RS Scheme (only with immutability in the right places). In fact, I have many - in order to compare different analyses' effectiveness and precision, I have a series of post-hoc analyses and program transformations I want to do. One is lightweight closure conversion (Wand Steckler 1996) Is a source-source transform that uses immutable vectors for passed environments and unsafe references for variable lookups enough to get the Racket compiler to pick up on what I'm doing? I'm really not quite sure which question to ask, since I haven't made my own higher-order language compiler top to bottom before, and don't know if there might be internal represenations that I'd need to use rather than user-level representations. Thanks, -Ian _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] check-match?
Thanks Asumu for merging and fixing my docs bug. Since this was my first time contributing, I figured I'd write up what the steps were for future first-time Racket hackers before I forget: http://jpolitz.github.com/blog/2012/11/21/racket-contributing-tutorial.html Cheers, Joe On Tue, Nov 20, 2012 at 8:41 AM, Robby Findler ro...@eecs.northwestern.edu wrote: I'm not sure how to find the right incantation to pull this down, but this commit looks good to push to our repo. Robby On Tue, Nov 20, 2012 at 12:33 AM, Joe Gibbs Politz j...@cs.brown.edu wrote: I think I've successfully sent a thingie to you: https://github.com/plt/racket/pull/171 Let me know if I Did It Wrong. This is the first time I've clicked the Pull Request button on Github. On Mon, Nov 19, 2012 at 10:12 PM, Joe Gibbs Politz j...@cs.brown.edu wrote: Gotcha. match-pred can be a separate thing. check-match can also let you use the identifiers bound in the match with an optional third argument, which relies on more than match-pred anyway. That's what I'm doing. On Mon, Nov 19, 2012 at 9:30 PM, Robby Findler ro...@eecs.northwestern.edu wrote: I think it is better to have a check-match since that way people are more likely to find it. Robby On Mon, Nov 19, 2012 at 7:56 PM, Joe Gibbs Politz j...@cs.brown.edu wrote: (? P) = (lambda (x) (match x [P true] [_ false])) I like this quite a bit. It wouldn't be crazy to add it as match-pred(icate) right next to match-lambda, match-let, and friends (http://docs.racket-lang.org/reference/match.html?q=matchq=match-pred#(form._((lib._racket/match..rkt)._match-lambda))). Then, for rackunit, it's just up to how much we like writing (check-match foo P) vs. (check-pred (match-pred P) foo) Both seem handy to me. _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
On Wed, Nov 21, 2012 at 11:52 AM, Asumu Takikawa as...@ccs.neu.edu wrote: | [...] | | - make queues be sequences directly (and use make-do-sequence | to implement in-queue instead of building a list) Should queues also be streams or just sequences? I didn't think about this: if you think they should also be streams, that's okay with me. I'm not really sure of the benefits. I mostly made these changes to the library because I needed a few more things for my own use of this library; it wasn't an attempt to be comprehensive. | - added non-empty-queue? (note extra hypen as compared | to the past; this seems better since the function | wasn't exported before and we already have other | functions named non-empty-something but not | others namedn nonempty-something) The inconsistency now between `non-empty-queue?` and `nonempty-queue/c` seems unfortunate. Can we change the contract name too? I don't think the contract should be used at all actually (use the predicate instead), but I also don't to remove it because I think breaking old programs in dumb ways is too annoying to our users. Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
On 2012-11-21 12:50:49 -0600, Robby Findler wrote: On Wed, Nov 21, 2012 at 11:52 AM, Asumu Takikawa as...@ccs.neu.edu wrote: Should queues also be streams or just sequences? I didn't think about this: if you think they should also be streams, that's okay with me. I'm not really sure of the benefits. I actually asked this because I'm not sure myself. We have two APIs: sequences and streams, but it's not entirely clear to me when to prefer one over the other. Streams support `first`, `rest`, and `empty?`. Sequences don't directly support either `first` or `rest`, but with the `sequence-ref` and `sequence-tail` functions you can emulate them. One advantage of streams is that there's now an easy way to implement them (via the `gen:stream` generic interface). Is there a guiding principle behind these APIs? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
Oh, I'm not sure. I just picked sequences to fit into for loops. (Indeed, the code was mostly there already, I just stuck it on the struct.) On Wed, Nov 21, 2012 at 1:22 PM, Asumu Takikawa as...@ccs.neu.edu wrote: On 2012-11-21 12:50:49 -0600, Robby Findler wrote: On Wed, Nov 21, 2012 at 11:52 AM, Asumu Takikawa as...@ccs.neu.edu wrote: Should queues also be streams or just sequences? I didn't think about this: if you think they should also be streams, that's okay with me. I'm not really sure of the benefits. I actually asked this because I'm not sure myself. We have two APIs: sequences and streams, but it's not entirely clear to me when to prefer one over the other. Streams support `first`, `rest`, and `empty?`. Sequences don't directly support either `first` or `rest`, but with the `sequence-ref` and `sequence-tail` functions you can emulate them. One advantage of streams is that there's now an easy way to implement them (via the `gen:stream` generic interface). Is there a guiding principle behind these APIs? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
While we're on the subject, I see I re-indented Carl's test cases. That was an accident and I'm sorry; I didn't mean to. Robby _ Racket Developers list: http://lists.racket-lang.org/dev
Re: [racket-dev] [plt] Push #25728: master branch updated
On Wed, Nov 21, 2012 at 2:22 PM, Asumu Takikawa as...@ccs.neu.edu wrote: On 2012-11-21 12:50:49 -0600, Robby Findler wrote: On Wed, Nov 21, 2012 at 11:52 AM, Asumu Takikawa as...@ccs.neu.edu wrote: Should queues also be streams or just sequences? I didn't think about this: if you think they should also be streams, that's okay with me. I'm not really sure of the benefits. I actually asked this because I'm not sure myself. We have two APIs: sequences and streams, but it's not entirely clear to me when to prefer one over the other. I've been thinking about this as well. I think that sequences are just an interface. If you give me a bunch of functions that fit the interface, then you have a sequence. It's completely extensional. You dont care how they are implemented. It's the same as iterators in java and other languages. Streams are a specific kind of sequence where you have extra requirements on the internal workings (ie laziness/memoization). The problem is that in Racket, streams are defined by a it's own, separate interface (via prop:stream), which (1) is not sufficient because it doesnt capture the other properties that traditionally define streams, and (2) is redundant since it largely overlaps with the sequence interface. So it truly seems like we have two things (streams and sequences) that are basically the same thing, and one of the things (streams) is not really what it claims to be. (I'm guessing in the past, a stream in racket was what a sequence is today and that's where the mixup is coming from?) Even worse, racket streams (the actual implementation, not the interface) are implemented on top of srfi 41 streams but doesnt use the srfi correctly so we really do not have streams at all (see pr 13257). I'm trying to think of the right way to fix things but I think we at least need to throw out the current streams interface. Streams support `first`, `rest`, and `empty?`. Sequences don't directly support either `first` or `rest`, but with the `sequence-ref` and `sequence-tail` functions you can emulate them. One advantage of streams is that there's now an easy way to implement them (via the `gen:stream` generic interface). Is there a guiding principle behind these APIs? Cheers, Asumu _ Racket Developers list: http://lists.racket-lang.org/dev _ Racket Developers list: http://lists.racket-lang.org/dev