[racket-dev] Experiments with closure conversion

2012-11-21 Thread J. Ian Johnson
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

2012-11-21 Thread Asumu Takikawa
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

2012-11-21 Thread Matthew Flatt
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

2012-11-21 Thread J. Ian Johnson
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?

2012-11-21 Thread Joe Gibbs Politz
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

2012-11-21 Thread Robby Findler
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

2012-11-21 Thread Asumu Takikawa
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

2012-11-21 Thread Robby Findler
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

2012-11-21 Thread Robby Findler
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

2012-11-21 Thread Stephen Chang
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