Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Matthias Felleisen


On Jan 15, 2015, at 11:13 AM, David Van Horn dvanh...@cs.umd.edu wrote:

 On 1/15/15, 11:04 AM, Matthias Felleisen wrote:
 
 Well that got me all excited. So I tried to get the sample module
 to pass the verification step -- until I realized how restricted
 the grammar is!
 
 (module f racket (provide (contract-out [f (real? . - .
 integer?)])) (define (f n) (/ 1 (- 100 n
 
 I would love to be able to use at least (and/c real? (/c 0)) for
 the domain so I can get the example done.
 
 Or am I overlooking a way to make this work here?
 
 The /c contract is there, but missing from the grammar (we'll fix that).
 
 But (/c 0) will not make this program verify.  You want this contract:
 
 ((and/c real? (lambda (x) (not (= x 100 . - . real?)
 
 Using this contract, the program verifies.


My contract is stronger than yours. So why will it not go through? 
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread David Van Horn
On 1/15/15, 11:27 AM, Matthias Felleisen wrote:
 
 Argh, I wanted the other way (negative). I always get the
 directions confused. Sorry.

Right -- using (and/c real? (/c 0)) will also make this verify.

Thanks for trying it out!

David

 
 
 On Jan 15, 2015, at 11:26 AM, David Van Horn dvanh...@cs.umd.edu
 wrote:
 
 On 1/15/15, 11:17 AM, Matthias Felleisen wrote:
 
 
 On Jan 15, 2015, at 11:13 AM, David Van Horn
 dvanh...@cs.umd.edu wrote:
 
 On 1/15/15, 11:04 AM, Matthias Felleisen wrote:
 
 Well that got me all excited. So I tried to get the sample 
 module to pass the verification step -- until I realized
 how restricted the grammar is!
 
 (module f racket (provide (contract-out [f (real? . - . 
 integer?)])) (define (f n) (/ 1 (- 100 n
 
 I would love to be able to use at least (and/c real? (/c
 0)) for the domain so I can get the example done.
 
 Or am I overlooking a way to make this work here?
 
 The /c contract is there, but missing from the grammar
 (we'll fix that).
 
 But (/c 0) will not make this program verify.  You want
 this contract:
 
 ((and/c real? (lambda (x) (not (= x 100 . - . real?)
 
 Using this contract, the program verifies.
 
 
 My contract is stronger than yours. So why will it not go
 through?
 
 
 
 100 is (/c 0) but (f 100) divides by zero.
 
 David
 

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Robby Findler
FWIW, (/c 0) already implies real?.

Robby

On Thu, Jan 15, 2015 at 10:30 AM, David Van Horn dvanh...@cs.umd.edu wrote:
 On 1/15/15, 11:27 AM, Matthias Felleisen wrote:

 Argh, I wanted the other way (negative). I always get the
 directions confused. Sorry.

 Right -- using (and/c real? (/c 0)) will also make this verify.

 Thanks for trying it out!

 David



 On Jan 15, 2015, at 11:26 AM, David Van Horn dvanh...@cs.umd.edu
 wrote:

 On 1/15/15, 11:17 AM, Matthias Felleisen wrote:


 On Jan 15, 2015, at 11:13 AM, David Van Horn
 dvanh...@cs.umd.edu wrote:

 On 1/15/15, 11:04 AM, Matthias Felleisen wrote:

 Well that got me all excited. So I tried to get the sample
 module to pass the verification step -- until I realized
 how restricted the grammar is!

 (module f racket (provide (contract-out [f (real? . - .
 integer?)])) (define (f n) (/ 1 (- 100 n

 I would love to be able to use at least (and/c real? (/c
 0)) for the domain so I can get the example done.

 Or am I overlooking a way to make this work here?

 The /c contract is there, but missing from the grammar
 (we'll fix that).

 But (/c 0) will not make this program verify.  You want
 this contract:

 ((and/c real? (lambda (x) (not (= x 100 . - . real?)

 Using this contract, the program verifies.


 My contract is stronger than yours. So why will it not go
 through?



 100 is (/c 0) but (f 100) divides by zero.

 David


 _
   Racket Developers list:
   http://lists.racket-lang.org/dev
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread David Van Horn
On 1/15/15, 11:04 AM, Matthias Felleisen wrote:
 
 Well that got me all excited. So I tried to get the sample module
 to pass the verification step -- until I realized how restricted
 the grammar is!
 
 (module f racket (provide (contract-out [f (real? . - .
 integer?)])) (define (f n) (/ 1 (- 100 n
 
 I would love to be able to use at least (and/c real? (/c 0)) for
 the domain so I can get the example done.
 
 Or am I overlooking a way to make this work here?

The /c contract is there, but missing from the grammar (we'll fix that).

But (/c 0) will not make this program verify.  You want this contract:

((and/c real? (lambda (x) (not (= x 100 . - . real?)

Using this contract, the program verifies.

David

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread David Van Horn
On 1/15/15, 11:17 AM, Matthias Felleisen wrote:
 
 
 On Jan 15, 2015, at 11:13 AM, David Van Horn dvanh...@cs.umd.edu
 wrote:
 
 On 1/15/15, 11:04 AM, Matthias Felleisen wrote:
 
 Well that got me all excited. So I tried to get the sample
 module to pass the verification step -- until I realized how
 restricted the grammar is!
 
 (module f racket (provide (contract-out [f (real? . - . 
 integer?)])) (define (f n) (/ 1 (- 100 n
 
 I would love to be able to use at least (and/c real? (/c 0))
 for the domain so I can get the example done.
 
 Or am I overlooking a way to make this work here?
 
 The /c contract is there, but missing from the grammar (we'll
 fix that).
 
 But (/c 0) will not make this program verify.  You want this
 contract:
 
 ((and/c real? (lambda (x) (not (= x 100 . - . real?)
 
 Using this contract, the program verifies.
 
 
 My contract is stronger than yours. So why will it not go through?
 
 

100 is (/c 0) but (f 100) divides by zero.

David

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Asumu Takikawa
On 2015-01-15 14:13:02 -0500, Asumu Takikawa wrote:
   Contract violation: 'fact' violates '='.
   Value
 0.105
   violates predicate
 real?
   An example module that breaks it:
 (module user racket (require (submod .. fact)) (factorial 0.105))
   (Verification takes 0.05s)

Hmm, actually I should've looked at this more carefully. Is this a case
where the tool is telling me that the function is non-terminating on
this input?

Cheers,
Asumu
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Robby Findler
I think this is saying that the result is going to be negative. (But
it won't, since it doesn't terminate.)

Robby


On Thu, Jan 15, 2015 at 1:13 PM, Asumu Takikawa as...@ccs.neu.edu wrote:
 On 2015-01-14 19:11:59 -0500, David Van Horn wrote:
 If you have questions, comments, bugs, or any other feedback, let us
 know, or just file bug reports on the GitHub source code.

 Nice tool! I like the web interface too.

 I was confused by this interaction though. Clicking verify on this:

   (module fact racket
 (define (factorial x)
   (if (zero? x)
   1
   (* x (factorial (sub1 x)
 (provide (contract-out [factorial (- (=/c 0) (=/c 0))])))

 gives me:

   Contract violation: 'fact' violates '='.
   Value
 0.105
   violates predicate
 real?
   An example module that breaks it:
 (module user racket (require (submod .. fact)) (factorial 0.105))
   (Verification takes 0.05s)

 but the value 0.105 shouldn't violate the predicate real? I think.

 Cheers,
 Asumu
 _
   Racket Developers list:
   http://lists.racket-lang.org/dev
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Asumu Takikawa
On 2015-01-14 19:11:59 -0500, David Van Horn wrote:
 If you have questions, comments, bugs, or any other feedback, let us
 know, or just file bug reports on the GitHub source code.

Nice tool! I like the web interface too.

I was confused by this interaction though. Clicking verify on this:

  (module fact racket
(define (factorial x)
  (if (zero? x)
  1
  (* x (factorial (sub1 x)
(provide (contract-out [factorial (- (=/c 0) (=/c 0))])))

gives me:

  Contract violation: 'fact' violates '='.
  Value
0.105
  violates predicate
real?
  An example module that breaks it:
(module user racket (require (submod .. fact)) (factorial 0.105))
  (Verification takes 0.05s)

but the value 0.105 shouldn't violate the predicate real? I think.

Cheers,
Asumu
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Robby Findler
Can you randomly make up programs from your grammar, get example
errors from the tool, and then run those programs to see if you find
bugs in the analysis like that one?

That said, I don't see how the bug in =/c is coming in here. Can you
explain more?

Robby


On Thu, Jan 15, 2015 at 1:42 PM, David Van Horn dvanh...@cs.umd.edu wrote:
 On 1/15/15, 2:13 PM, Asumu Takikawa wrote:
 On 2015-01-14 19:11:59 -0500, David Van Horn wrote:
 If you have questions, comments, bugs, or any other feedback, let
 us know, or just file bug reports on the GitHub source code.

 Nice tool! I like the web interface too.

 I was confused by this interaction though. Clicking verify on
 this:

 (module fact racket (define (factorial x) (if (zero? x) 1 (* x
 (factorial (sub1 x) (provide (contract-out [factorial (- (=/c
 0) (=/c 0))])))

 gives me:

 Contract violation: 'fact' violates '='. Value 0.105 violates
 predicate real? An example module that breaks it: (module user
 racket (require (submod .. fact)) (factorial 0.105))
 (Verification takes 0.05s)

 but the value 0.105 shouldn't violate the predicate real? I think.

 This is reporting that the fact module can break the contract on =
 when it uses =/c; that's a bug in our modelling of =/c, which we
 currently have as:

 (define (=/c n)
   (lambda (m)
 (= m n)))

 But should be:

 (define (=/c n)
   (lambda (m)
 (and (real? m)
  (= m n

 That said, if you change it to (and/c real? (=/c 0)), it says there's
 a counterexample of 2.0, but that's because we check contracts on
 recursive calls (and should not).

 Thanks!

 David

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Alexis King
As an update, I’ve made a bit more progress on this. I’ve implemented an 
impersonate-async-channel function, and I’ve actually included this in the 
exports from racket/contract. I also realized the blame information is correct, 
it works fine. Most of the other issues remain, as well as a few new questions:

There is no impersonate-evt function, so I’m not sure that my implementation 
will work. What should I do about this?
I’d assume this needs to be documented/tested as well. Where should those 
things be located?

 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:
 
 Currently, async channels do not have contracts to check their contents. This 
 is a problem for Typed Racket, and it prevents typed code from interacting 
 with code that produces async channels.
 
 I started looking into how to add contracts to the language, and it seems to 
 use the chaperones/impersonator system, as I suspected. However, async 
 channels obviously cannot be impersonated, so I needed to implement that as 
 well.
 
 I modified the async-channel struct to use generics to allow it to be 
 impersonated or chaperoned, which I have exposed by implementing 
 chaperone-async-channel. I then tried implementing async-channel/c. The 
 internals of the contract system are a little beyond me, but I got a working 
 solution by following the example of the box contracts.
 
 My work thus far can be found here: 
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b
  
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b
 
 First of all, is this a correct approach? Have I done anything wrong, or 
 should I have done anything differently? I didn’t find much documentation on 
 the internals of either of these systems, so I mostly went about things as I 
 found them.
 
 Second, obviously, not everything is implemented here. Among the additional 
 necessary changes are:
 
 I need to implement support for impersonators and impersonator contracts 
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and async-channel/c-stronger. 
 I can probably figure out the latter, but I’m not even sure what the former 
 is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not sure 
 how this works, either. From looking at wrap-box/c, it seems to add some 
 syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap 
 function does? Or do the async-channel functions need to be updated to assign 
 blame?
 
 I’d really like to get this working, and I think I’m close, but I’m a little 
 inexperienced. I’d appreciate any help, even if it’s just pointing me in the 
 right direction.
 
 Thanks!

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Alexis King
Sorry, I wasn’t clear. The chaperone/impersonate-async-channel functions are 
exported from racket/async-channel. The async-channel contracts, however, are 
exported from racket/contract.

 On Jan 15, 2015, at 14:41, Robby Findler ro...@eecs.northwestern.edu wrote:
 
 Just a small nit: why export that function from racket/contract and
 not an async-channel library?
 
 Robby
 
 
 On Thu, Jan 15, 2015 at 3:33 PM, Alexis King lexi.lam...@gmail.com wrote:
 As an update, I’ve made a bit more progress on this. I’ve implemented an
 impersonate-async-channel function, and I’ve actually included this in the
 exports from racket/contract. I also realized the blame information is
 correct, it works fine. Most of the other issues remain, as well as a few
 new questions:
 
 There is no impersonate-evt function, so I’m not sure that my implementation
 will work. What should I do about this?
 I’d assume this needs to be documented/tested as well. Where should those
 things be located?
 
 
 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:
 
 Currently, async channels do not have contracts to check their contents.
 This is a problem for Typed Racket, and it prevents typed code from
 interacting with code that produces async channels.
 
 I started looking into how to add contracts to the language, and it seems to
 use the chaperones/impersonator system, as I suspected. However, async
 channels obviously cannot be impersonated, so I needed to implement that as
 well.
 
 I modified the async-channel struct to use generics to allow it to be
 impersonated or chaperoned, which I have exposed by implementing
 chaperone-async-channel. I then tried implementing async-channel/c. The
 internals of the contract system are a little beyond me, but I got a working
 solution by following the example of the box contracts.
 
 My work thus far can be found here:
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b
 
 First of all, is this a correct approach? Have I done anything wrong, or
 should I have done anything differently? I didn’t find much documentation on
 the internals of either of these systems, so I mostly went about things as I
 found them.
 
 Second, obviously, not everything is implemented here. Among the additional
 necessary changes are:
 
 I need to implement support for impersonators and impersonator contracts
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and
 async-channel/c-stronger. I can probably figure out the latter, but I’m not
 even sure what the former is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not
 sure how this works, either. From looking at wrap-box/c, it seems to add
 some syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap
 function does? Or do the async-channel functions need to be updated to
 assign blame?
 
 
 I’d really like to get this working, and I think I’m close, but I’m a little
 inexperienced. I’d appreciate any help, even if it’s just pointing me in the
 right direction.
 
 Thanks!
 
 
 
 _
  Racket Developers list:
  http://lists.racket-lang.org/dev
 


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Robby Findler
I think they should probably all be exported from racket/async-channel.

Unless there is some reason to modify the internals of racket/contract
to support them?

Robby

On Thu, Jan 15, 2015 at 4:50 PM, Alexis King lexi.lam...@gmail.com wrote:
 Sorry, I wasn’t clear. The chaperone/impersonate-async-channel functions are 
 exported from racket/async-channel. The async-channel contracts, however, are 
 exported from racket/contract.

 On Jan 15, 2015, at 14:41, Robby Findler ro...@eecs.northwestern.edu wrote:

 Just a small nit: why export that function from racket/contract and
 not an async-channel library?

 Robby


 On Thu, Jan 15, 2015 at 3:33 PM, Alexis King lexi.lam...@gmail.com wrote:
 As an update, I’ve made a bit more progress on this. I’ve implemented an
 impersonate-async-channel function, and I’ve actually included this in the
 exports from racket/contract. I also realized the blame information is
 correct, it works fine. Most of the other issues remain, as well as a few
 new questions:

 There is no impersonate-evt function, so I’m not sure that my implementation
 will work. What should I do about this?
 I’d assume this needs to be documented/tested as well. Where should those
 things be located?


 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:

 Currently, async channels do not have contracts to check their contents.
 This is a problem for Typed Racket, and it prevents typed code from
 interacting with code that produces async channels.

 I started looking into how to add contracts to the language, and it seems to
 use the chaperones/impersonator system, as I suspected. However, async
 channels obviously cannot be impersonated, so I needed to implement that as
 well.

 I modified the async-channel struct to use generics to allow it to be
 impersonated or chaperoned, which I have exposed by implementing
 chaperone-async-channel. I then tried implementing async-channel/c. The
 internals of the contract system are a little beyond me, but I got a working
 solution by following the example of the box contracts.

 My work thus far can be found here:
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b

 First of all, is this a correct approach? Have I done anything wrong, or
 should I have done anything differently? I didn’t find much documentation on
 the internals of either of these systems, so I mostly went about things as I
 found them.

 Second, obviously, not everything is implemented here. Among the additional
 necessary changes are:

 I need to implement support for impersonators and impersonator contracts
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and
 async-channel/c-stronger. I can probably figure out the latter, but I’m not
 even sure what the former is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not
 sure how this works, either. From looking at wrap-box/c, it seems to add
 some syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap
 function does? Or do the async-channel functions need to be updated to
 assign blame?


 I’d really like to get this working, and I think I’m close, but I’m a little
 inexperienced. I’d appreciate any help, even if it’s just pointing me in the
 right direction.

 Thanks!



 _
  Racket Developers list:
  http://lists.racket-lang.org/dev



_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Robby Findler
Just a small nit: why export that function from racket/contract and
not an async-channel library?

Robby


On Thu, Jan 15, 2015 at 3:33 PM, Alexis King lexi.lam...@gmail.com wrote:
 As an update, I’ve made a bit more progress on this. I’ve implemented an
 impersonate-async-channel function, and I’ve actually included this in the
 exports from racket/contract. I also realized the blame information is
 correct, it works fine. Most of the other issues remain, as well as a few
 new questions:

 There is no impersonate-evt function, so I’m not sure that my implementation
 will work. What should I do about this?
 I’d assume this needs to be documented/tested as well. Where should those
 things be located?


 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:

 Currently, async channels do not have contracts to check their contents.
 This is a problem for Typed Racket, and it prevents typed code from
 interacting with code that produces async channels.

 I started looking into how to add contracts to the language, and it seems to
 use the chaperones/impersonator system, as I suspected. However, async
 channels obviously cannot be impersonated, so I needed to implement that as
 well.

 I modified the async-channel struct to use generics to allow it to be
 impersonated or chaperoned, which I have exposed by implementing
 chaperone-async-channel. I then tried implementing async-channel/c. The
 internals of the contract system are a little beyond me, but I got a working
 solution by following the example of the box contracts.

 My work thus far can be found here:
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b

 First of all, is this a correct approach? Have I done anything wrong, or
 should I have done anything differently? I didn’t find much documentation on
 the internals of either of these systems, so I mostly went about things as I
 found them.

 Second, obviously, not everything is implemented here. Among the additional
 necessary changes are:

 I need to implement support for impersonators and impersonator contracts
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and
 async-channel/c-stronger. I can probably figure out the latter, but I’m not
 even sure what the former is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not
 sure how this works, either. From looking at wrap-box/c, it seems to add
 some syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap
 function does? Or do the async-channel functions need to be updated to
 assign blame?


 I’d really like to get this working, and I think I’m close, but I’m a little
 inexperienced. I’d appreciate any help, even if it’s just pointing me in the
 right direction.

 Thanks!



 _
   Racket Developers list:
   http://lists.racket-lang.org/dev


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Sam Tobin-Hochstadt
On Thu, Jan 15, 2015 at 4:33 PM, Alexis King lexi.lam...@gmail.com wrote:
 As an update, I’ve made a bit more progress on this. I’ve implemented an
 impersonate-async-channel function, and I’ve actually included this in the
 exports from racket/contract. I also realized the blame information is
 correct, it works fine. Most of the other issues remain, as well as a few
 new questions:

 There is no impersonate-evt function, so I’m not sure that my implementation
 will work. What should I do about this?
 I’d assume this needs to be documented/tested as well. Where should those
 things be located?

Documentation for contracts is here:
https://github.com/plt/racket/blob/master/pkgs/racket-doc/scribblings/reference/contracts.scrbl
and in the dependent files.

Tests for contracts are here:
https://github.com/plt/racket/tree/master/pkgs/racket-test/tests/racket/contract

Sam



 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:

 Currently, async channels do not have contracts to check their contents.
 This is a problem for Typed Racket, and it prevents typed code from
 interacting with code that produces async channels.

 I started looking into how to add contracts to the language, and it seems to
 use the chaperones/impersonator system, as I suspected. However, async
 channels obviously cannot be impersonated, so I needed to implement that as
 well.

 I modified the async-channel struct to use generics to allow it to be
 impersonated or chaperoned, which I have exposed by implementing
 chaperone-async-channel. I then tried implementing async-channel/c. The
 internals of the contract system are a little beyond me, but I got a working
 solution by following the example of the box contracts.

 My work thus far can be found here:
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b

 First of all, is this a correct approach? Have I done anything wrong, or
 should I have done anything differently? I didn’t find much documentation on
 the internals of either of these systems, so I mostly went about things as I
 found them.

 Second, obviously, not everything is implemented here. Among the additional
 necessary changes are:

 I need to implement support for impersonators and impersonator contracts
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and
 async-channel/c-stronger. I can probably figure out the latter, but I’m not
 even sure what the former is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not
 sure how this works, either. From looking at wrap-box/c, it seems to add
 some syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap
 function does? Or do the async-channel functions need to be updated to
 assign blame?


 I’d really like to get this working, and I think I’m close, but I’m a little
 inexperienced. I’d appreciate any help, even if it’s just pointing me in the
 right direction.

 Thanks!



 _
   Racket Developers list:
   http://lists.racket-lang.org/dev


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] question, issue(?) with the scope of identifiers passed into define-syntax-rule

2015-01-15 Thread Thomas Lynch
Yes, I see some of this at the bottom of the chapter 16 in the guide,  and
the recursion supported with
 (require
http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._require%29%29
 (for-meta
http://docs.racket-lang.org/reference/require.html#%28form._%28%28lib._racket%2Fprivate%2Fbase..rkt%29._for-meta%29%29
 n racket/base)).


On Fri, Jan 16, 2015 at 11:21 AM, Thomas Lynch 
thomas.ly...@reasoningtechnology.com wrote:

 Thank you for that nice explanation.  I'm reminded of the scope variables
 carried in Ruby.  In Mathematica the renaming of module variables is
 explicit.  There do not appear to be run phases there.  Also thanks for the
 working example using syntax parse.  Thus far I have working examples using
 define-syntax via datum and define-syntax with case (thanks to Matthais).

 The following questions might best be answered by pointing me to some
 other docs, haven't run across yet:

 Are there more than two phases?  There is the syntax phase, i.e. compile
 time phase, and then a run phase.  Lexical scope at the syntax phase would
 be static based textual layout of the program - i.e. lexical scope.  Then
 the macros (syntax transformers) are gone (as the syntax has been
 transformed) after the syntax phase.  At run time then, we have no access
 to the syntax object information?

 Academic question, but can syntax information, or other values be shared
 across phases?  As an example, could one store the file name, line, and
 column number for an identifier, the make use of that later?

 How is it that we do work inside of a macro, for example by making use of
 require-for-syntax?  Does that imply that the routines that we make use of
 in the macro for doing work had their own syntax phase, and now they are in
 run time phase during the macro's syntax phase?   .. then if those worker
 routines make use of macros ...   seems this recursion could be arbitrarily
 deep.

 Can the syntax analysis be explicitly invoked?   Sort of like (apply ...)
  or (eval ..) ?  Come to think of it, eval must do the syntax phase, then
 the run phase, so perhaps it is calls to that which causes the recursion.

 On Fri, Jan 16, 2015 at 11:01 AM, Alexander D. Knauth 
 alexan...@knauth.org wrote:

 But I think it’s important that it doesn’t use gensym or something like
 that, it uses syntax-marks, which means you can break these lexical scoping
 rules if you want/need to by using either syntax-local-introduce or
 datum-syntax:

 #lang racket
 (require syntax/parse/define)
 (define-simple-macro (with-tables stem body ...)
   #:with table-author-id (syntax-local-introduce #'table-author)
   (let([table-publication (string-append stem _publication)]
[table-author-id (string-append stem _author)]
[table-bridge-publication-author (string-append stem
 _bridge_publication_author)]
[table-unique-counters (string-append stem _unique_counters)]
)
 body ...
 ))
 (with-tables x table-author) ;”x_author


 On Jan 15, 2015, at 9:23 PM, Alexander McLin alex.mc...@gmail.com
 wrote:

 Warning I am still a Racket intermediate user but I've been studying
 syntactic extensions a lot the past several months.

 The problem here is macros in Racket have lexical scope just like
 procedures, they are hygienic macros. The identifiers you introduced in the
 with-tables macro only exist or refer to other bindings in the same lexical
 scope as where you originally wrote the macro.

 When you invoke the macro and pass in table-author, even though it is
 spelled the same as the identifier you wrote in the macro definition, they
 are not the same. When the macro expands, hygiene is implemented by
 renaming all identifiers in the macro to unique non-clashing symbols that
 don't conflict with others existing in the scope the macro is expanding in.

 The table-author identifier in the macro in the let form is renamed to
 something different like g6271 or something along those lines.

 Furthermore, you need to be careful about what you mean by evaluation. In
 the presence of macros, you have the concept of syntax phase(or
 compile-time or expand-time) evaluation versus run-time evaluation. When
 the macro is expanding, it does it thing, processing the original syntax
 into the new piece of syntax that replaces what was there previously such
 as (with-tables x table-author) which is then finally evaluated during
 run-time.

 (with-tables x table-author) will expand into something looking similar
 to the following, just to give you an idea of what macro expansion looks
 like:

 (let ((g6191 (string-append x _publication))
(g6271 (string-append x _author))
(g6369 (string-append x _bridge_publication_author))
(g6445 (string-append x _unique_counters)))
table-author)

 Note that the original table-author identifier has been replaced by a
 different identifier that still has the same binding you originally defined.

 The table-author identifier 

Re: [racket-dev] Implementing contracts for async channels

2015-01-15 Thread Alexis King
Sure thing, done. I’ve moved everything into racket/async-channel, added the 
missing functions, and added some tests. I squashed my commits into one, and 
the result is here:
https://github.com/lexi-lambda/racket/commit/0074ba13b712a87c9d05948ae075bcd74c7651e7
 
https://github.com/lexi-lambda/racket/commit/0074ba13b712a87c9d05948ae075bcd74c7651e7

Two simple points remain:

Where should the documentation go? Should it be under contracts or 
async-channels? I’d prefer the latter, but I’m not sure.
Since there is no impersonate-evt function, I don’t think my 
impersonate-async-channel function will actually work. Is that an accurate 
concern? How could I fix it?

Otherwise, I think this works fine and is probably ready to go.

 On Jan 15, 2015, at 15:09, Robby Findler ro...@eecs.northwestern.edu wrote:
 
 I think they should probably all be exported from racket/async-channel.
 
 Unless there is some reason to modify the internals of racket/contract
 to support them?
 
 Robby
 
 On Thu, Jan 15, 2015 at 4:50 PM, Alexis King lexi.lam...@gmail.com wrote:
 Sorry, I wasn’t clear. The chaperone/impersonate-async-channel functions are 
 exported from racket/async-channel. The async-channel contracts, however, 
 are exported from racket/contract.
 
 On Jan 15, 2015, at 14:41, Robby Findler ro...@eecs.northwestern.edu 
 wrote:
 
 Just a small nit: why export that function from racket/contract and
 not an async-channel library?
 
 Robby
 
 
 On Thu, Jan 15, 2015 at 3:33 PM, Alexis King lexi.lam...@gmail.com wrote:
 As an update, I’ve made a bit more progress on this. I’ve implemented an
 impersonate-async-channel function, and I’ve actually included this in the
 exports from racket/contract. I also realized the blame information is
 correct, it works fine. Most of the other issues remain, as well as a few
 new questions:
 
 There is no impersonate-evt function, so I’m not sure that my 
 implementation
 will work. What should I do about this?
 I’d assume this needs to be documented/tested as well. Where should those
 things be located?
 
 
 On Jan 14, 2015, at 23:44, Alexis King lexi.lam...@gmail.com wrote:
 
 Currently, async channels do not have contracts to check their contents.
 This is a problem for Typed Racket, and it prevents typed code from
 interacting with code that produces async channels.
 
 I started looking into how to add contracts to the language, and it seems 
 to
 use the chaperones/impersonator system, as I suspected. However, async
 channels obviously cannot be impersonated, so I needed to implement that as
 well.
 
 I modified the async-channel struct to use generics to allow it to be
 impersonated or chaperoned, which I have exposed by implementing
 chaperone-async-channel. I then tried implementing async-channel/c. The
 internals of the contract system are a little beyond me, but I got a 
 working
 solution by following the example of the box contracts.
 
 My work thus far can be found here:
 https://github.com/lexi-lambda/racket/commit/84b9f3604891f3f2061fb28ed4800af8afa4751b
 
 First of all, is this a correct approach? Have I done anything wrong, or
 should I have done anything differently? I didn’t find much documentation 
 on
 the internals of either of these systems, so I mostly went about things as 
 I
 found them.
 
 Second, obviously, not everything is implemented here. Among the additional
 necessary changes are:
 
 I need to implement support for impersonators and impersonator contracts
 (right now I’ve only bothered to do chaperones).
 I need to implement async-channel/c-first-order and
 async-channel/c-stronger. I can probably figure out the latter, but I’m not
 even sure what the former is supposed to do.
 I need to implement a wrap-async-channel/c macro for the export. I’m not
 sure how this works, either. From looking at wrap-box/c, it seems to add
 some syntax properties, but I’m not sure what they do or how they work.
 Somehow, the blame information has to be correct. Is that what the wrap
 function does? Or do the async-channel functions need to be updated to
 assign blame?
 
 
 I’d really like to get this working, and I think I’m close, but I’m a 
 little
 inexperienced. I’d appreciate any help, even if it’s just pointing me in 
 the
 right direction.
 
 Thanks!
 
 
 
 _
 Racket Developers list:
 http://lists.racket-lang.org/dev
 
 

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] question, issue(?) with the scope of identifiers passed into define-syntax-rule

2015-01-15 Thread Alexander McLin
Warning I am still a Racket intermediate user but I've been studying
syntactic extensions a lot the past several months.

The problem here is macros in Racket have lexical scope just like
procedures, they are hygienic macros. The identifiers you introduced in the
with-tables macro only exist or refer to other bindings in the same lexical
scope as where you originally wrote the macro.

When you invoke the macro and pass in table-author, even though it is
spelled the same as the identifier you wrote in the macro definition, they
are not the same. When the macro expands, hygiene is implemented by
renaming all identifiers in the macro to unique non-clashing symbols that
don't conflict with others existing in the scope the macro is expanding in.

The table-author identifier in the macro in the let form is renamed to
something different like g6271 or something along those lines.

Furthermore, you need to be careful about what you mean by evaluation. In
the presence of macros, you have the concept of syntax phase(or
compile-time or expand-time) evaluation versus run-time evaluation. When
the macro is expanding, it does it thing, processing the original syntax
into the new piece of syntax that replaces what was there previously such
as (with-tables x table-author) which is then finally evaluated during
run-time.

(with-tables x table-author) will expand into something looking similar
to the following, just to give you an idea of what macro expansion looks
like:

(let ((g6191 (string-append x _publication))
   (g6271 (string-append x _author))
   (g6369 (string-append x _bridge_publication_author))
   (g6445 (string-append x _unique_counters)))
   table-author)

Note that the original table-author identifier has been replaced by a
different identifier that still has the same binding you originally defined.

The table-author identifier you passed to the macro gets inserted in the
body position and then the expanded code is evaluated at run-time and of
course gives you a run-time error since table-author does not refer to
anything and thus when it's evaluated, it is recognized as an undefined
identifier.

(with-tables x hello) works because what you get in return is:

(let ((g6191 (string-append x _publication))
   (g6271 (string-append x _author))
   (g6369 (string-append x _bridge_publication_author))
   (g6445 (string-append x _unique_counters)))
   hello)

hello is just a self-evaluating string giving you back hello from
within the let form.

On Thu, Jan 15, 2015 at 12:12 AM, Thomas Lynch 
thomas.ly...@reasoningtechnology.com wrote:

 I have a simple syntax rule:

   Welcome to Racket v5.2.1.
   racket@ (define-syntax-rule (with-tables stem body ...)
 (let(
   [table-publication (string-append stem _publication)]
   [table-author (string-append stem _author)]
   [table-bridge-publication-author (string-append stem
 _bridge_publication_author)]
   [table-unique-counters (string-append stem _unique_counters)]
   )
   body ...
   ))

 Which works fine when I don't reference the environment defined by the let:


   racket@
   racket@ (with-tables x hello)

   hello


 However when I pass it an identifier corresponding to one of the variables
 defined in the let:

   racket@ (with-tables x table-author)
   reference to undefined identifier: table-author
   stdin::1167: table-author

 The identifier passed in doesn't seem to be part of the local let context,
 but carried in a different context, or perhaps it was evaluated as an
 operand.  I didn't expect either of those.  Can someone point me at a
 description of the expected behavior, or give me a tip here on what is
 happening and why.

 ... in Wolfram language there is a 'Hold' operator for situations like
 this.  Apparently inside the macro we have to do some evaluation to handle
 the work of the macro,  is that why the operand is evaluated?

 Thanks in advance for explaining the evaluation/context model here.

 Thomas

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] question, issue(?) with the scope of identifiers passed into define-syntax-rule

2015-01-15 Thread Alexander D. Knauth
But I think it’s important that it doesn’t use gensym or something like that, 
it uses syntax-marks, which means you can break these lexical scoping rules if 
you want/need to by using either syntax-local-introduce or datum-syntax:

#lang racket
(require syntax/parse/define)
(define-simple-macro (with-tables stem body ...)
  #:with table-author-id (syntax-local-introduce #'table-author)
  (let([table-publication (string-append stem _publication)]
   [table-author-id (string-append stem _author)]
   [table-bridge-publication-author (string-append stem 
_bridge_publication_author)]
   [table-unique-counters (string-append stem _unique_counters)]
   )
body ...
))
(with-tables x table-author) ;”x_author


On Jan 15, 2015, at 9:23 PM, Alexander McLin alex.mc...@gmail.com wrote:

 Warning I am still a Racket intermediate user but I've been studying 
 syntactic extensions a lot the past several months.
 
 The problem here is macros in Racket have lexical scope just like procedures, 
 they are hygienic macros. The identifiers you introduced in the with-tables 
 macro only exist or refer to other bindings in the same lexical scope as 
 where you originally wrote the macro.
 
 When you invoke the macro and pass in table-author, even though it is spelled 
 the same as the identifier you wrote in the macro definition, they are not 
 the same. When the macro expands, hygiene is implemented by renaming all 
 identifiers in the macro to unique non-clashing symbols that don't conflict 
 with others existing in the scope the macro is expanding in.
 
 The table-author identifier in the macro in the let form is renamed to 
 something different like g6271 or something along those lines.
 
 Furthermore, you need to be careful about what you mean by evaluation. In the 
 presence of macros, you have the concept of syntax phase(or compile-time or 
 expand-time) evaluation versus run-time evaluation. When the macro is 
 expanding, it does it thing, processing the original syntax into the new 
 piece of syntax that replaces what was there previously such as (with-tables 
 x table-author) which is then finally evaluated during run-time.
 
 (with-tables x table-author) will expand into something looking similar to 
 the following, just to give you an idea of what macro expansion looks like:
 
 (let ((g6191 (string-append x _publication))
(g6271 (string-append x _author))
(g6369 (string-append x _bridge_publication_author))
(g6445 (string-append x _unique_counters)))
table-author)
 
 Note that the original table-author identifier has been replaced by a 
 different identifier that still has the same binding you originally defined.
 
 The table-author identifier you passed to the macro gets inserted in the body 
 position and then the expanded code is evaluated at run-time and of course 
 gives you a run-time error since table-author does not refer to anything and 
 thus when it's evaluated, it is recognized as an undefined identifier.
 
 (with-tables x hello) works because what you get in return is:
 
 (let ((g6191 (string-append x _publication))
(g6271 (string-append x _author))
(g6369 (string-append x _bridge_publication_author))
(g6445 (string-append x _unique_counters)))
hello)
 
 hello is just a self-evaluating string giving you back hello from within 
 the let form.
 
 On Thu, Jan 15, 2015 at 12:12 AM, Thomas Lynch 
 thomas.ly...@reasoningtechnology.com wrote:
 I have a simple syntax rule:
 
   Welcome to Racket v5.2.1.
   racket@ (define-syntax-rule (with-tables stem body ...)
 (let(
   [table-publication (string-append stem _publication)]
   [table-author (string-append stem _author)]
   [table-bridge-publication-author (string-append stem 
 _bridge_publication_author)]
   [table-unique-counters (string-append stem _unique_counters)]
   )
   body ...
   ))
 
 Which works fine when I don't reference the environment defined by the let:
 
   racket@
   racket@ (with-tables x hello)
   hello
 
 
 However when I pass it an identifier corresponding to one of the variables 
 defined in the let:
 
   racket@ (with-tables x table-author)
   reference to undefined identifier: table-author
   stdin::1167: table-author
 
 The identifier passed in doesn't seem to be part of the local let context, 
 but carried in a different context, or perhaps it was evaluated as an 
 operand.  I didn't expect either of those.  Can someone point me at a 
 description of the expected behavior, or give me a tip here on what is 
 happening and why.
 
 ... in Wolfram language there is a 'Hold' operator for situations like this.  
 Apparently inside the macro we have to do some evaluation to handle the work 
 of the macro,  is that why the operand is evaluated? 
 
 Thanks in advance for explaining the evaluation/context model here.
 
 Thomas 
 
 _
   Racket Developers list:
   

Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread David Van Horn
On 1/15/15, 2:13 PM, Asumu Takikawa wrote:
 On 2015-01-14 19:11:59 -0500, David Van Horn wrote:
 If you have questions, comments, bugs, or any other feedback, let
 us know, or just file bug reports on the GitHub source code.
 
 Nice tool! I like the web interface too.
 
 I was confused by this interaction though. Clicking verify on
 this:
 
 (module fact racket (define (factorial x) (if (zero? x) 1 (* x
 (factorial (sub1 x) (provide (contract-out [factorial (- (=/c
 0) (=/c 0))])))
 
 gives me:
 
 Contract violation: 'fact' violates '='. Value 0.105 violates
 predicate real? An example module that breaks it: (module user
 racket (require (submod .. fact)) (factorial 0.105)) 
 (Verification takes 0.05s)
 
 but the value 0.105 shouldn't violate the predicate real? I think.

This is reporting that the fact module can break the contract on =
when it uses =/c; that's a bug in our modelling of =/c, which we
currently have as:

(define (=/c n)
  (lambda (m)
(= m n)))

But should be:

(define (=/c n)
  (lambda (m)
(and (real? m)
 (= m n

That said, if you change it to (and/c real? (=/c 0)), it says there's
a counterexample of 2.0, but that's because we check contracts on
recursive calls (and should not).

Thanks!

David

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread David Van Horn
On 1/15/15, 2:48 PM, Robby Findler wrote:
 Can you randomly make up programs from your grammar, get example 
 errors from the tool, and then run those programs to see if you
 find bugs in the analysis like that one?

Yes, we're planning to do this.

 That said, I don't see how the bug in =/c is coming in here. Can
 you explain more?

On further inspection, the counterexample is wrong.  (There are
counterexamples due to the model of =/c, but the one that reported is
not an actual one.)  This will be fixed shortly.

David

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] question, issue(?) with the scope of identifiers passed into define-syntax-rule

2015-01-15 Thread Thomas Lynch
Thank you for that nice explanation.  I'm reminded of the scope variables
carried in Ruby.  In Mathematica the renaming of module variables is
explicit.  There do not appear to be run phases there.  Also thanks for the
working example using syntax parse.  Thus far I have working examples using
define-syntax via datum and define-syntax with case (thanks to Matthais).

The following questions might best be answered by pointing me to some other
docs, haven't run across yet:

Are there more than two phases?  There is the syntax phase, i.e. compile
time phase, and then a run phase.  Lexical scope at the syntax phase would
be static based textual layout of the program - i.e. lexical scope.  Then
the macros (syntax transformers) are gone (as the syntax has been
transformed) after the syntax phase.  At run time then, we have no access
to the syntax object information?

Academic question, but can syntax information, or other values be shared
across phases?  As an example, could one store the file name, line, and
column number for an identifier, the make use of that later?

How is it that we do work inside of a macro, for example by making use of
require-for-syntax?  Does that imply that the routines that we make use of
in the macro for doing work had their own syntax phase, and now they are in
run time phase during the macro's syntax phase?   .. then if those worker
routines make use of macros ...   seems this recursion could be arbitrarily
deep.

Can the syntax analysis be explicitly invoked?   Sort of like (apply ...)
 or (eval ..) ?  Come to think of it, eval must do the syntax phase, then
the run phase, so perhaps it is calls to that which causes the recursion.

On Fri, Jan 16, 2015 at 11:01 AM, Alexander D. Knauth alexan...@knauth.org
wrote:

 But I think it’s important that it doesn’t use gensym or something like
 that, it uses syntax-marks, which means you can break these lexical scoping
 rules if you want/need to by using either syntax-local-introduce or
 datum-syntax:

 #lang racket
 (require syntax/parse/define)
 (define-simple-macro (with-tables stem body ...)
   #:with table-author-id (syntax-local-introduce #'table-author)
   (let([table-publication (string-append stem _publication)]
[table-author-id (string-append stem _author)]
[table-bridge-publication-author (string-append stem
 _bridge_publication_author)]
[table-unique-counters (string-append stem _unique_counters)]
)
 body ...
 ))
 (with-tables x table-author) ;”x_author


 On Jan 15, 2015, at 9:23 PM, Alexander McLin alex.mc...@gmail.com wrote:

 Warning I am still a Racket intermediate user but I've been studying
 syntactic extensions a lot the past several months.

 The problem here is macros in Racket have lexical scope just like
 procedures, they are hygienic macros. The identifiers you introduced in the
 with-tables macro only exist or refer to other bindings in the same lexical
 scope as where you originally wrote the macro.

 When you invoke the macro and pass in table-author, even though it is
 spelled the same as the identifier you wrote in the macro definition, they
 are not the same. When the macro expands, hygiene is implemented by
 renaming all identifiers in the macro to unique non-clashing symbols that
 don't conflict with others existing in the scope the macro is expanding in.

 The table-author identifier in the macro in the let form is renamed to
 something different like g6271 or something along those lines.

 Furthermore, you need to be careful about what you mean by evaluation. In
 the presence of macros, you have the concept of syntax phase(or
 compile-time or expand-time) evaluation versus run-time evaluation. When
 the macro is expanding, it does it thing, processing the original syntax
 into the new piece of syntax that replaces what was there previously such
 as (with-tables x table-author) which is then finally evaluated during
 run-time.

 (with-tables x table-author) will expand into something looking similar
 to the following, just to give you an idea of what macro expansion looks
 like:

 (let ((g6191 (string-append x _publication))
(g6271 (string-append x _author))
(g6369 (string-append x _bridge_publication_author))
(g6445 (string-append x _unique_counters)))
table-author)

 Note that the original table-author identifier has been replaced by a
 different identifier that still has the same binding you originally defined.

 The table-author identifier you passed to the macro gets inserted in the
 body position and then the expanded code is evaluated at run-time and of
 course gives you a run-time error since table-author does not refer to
 anything and thus when it's evaluated, it is recognized as an undefined
 identifier.

 (with-tables x hello) works because what you get in return is:

 (let ((g6191 (string-append x _publication))
(g6271 (string-append x _author))
(g6369 (string-append x _bridge_publication_author))

Re: [racket-dev] Announcing Soft Contract Verification tool

2015-01-15 Thread Benjamin Greenman
I tried writing a small program, but got stuck pretty early on. When I try
verifying the divides? function below, the tool times out. What's
happening?

(module div racket
  (provide (contract-out [divides? (- positive? positive? boolean?)]))

  (define (positive? x)
(and (integer? x) (= 0 x)))

  (define (divides? a b)
(cond [(= 0 b) #t]
  [( b a) #f]
  [else (divides? a (- b a))]))

)

On Thu, Jan 15, 2015 at 3:14 PM, David Van Horn dvanh...@cs.umd.edu wrote:

 On 1/15/15, 2:48 PM, Robby Findler wrote:
  Can you randomly make up programs from your grammar, get example
  errors from the tool, and then run those programs to see if you
  find bugs in the analysis like that one?

 Yes, we're planning to do this.

  That said, I don't see how the bug in =/c is coming in here. Can
  you explain more?

 On further inspection, the counterexample is wrong.  (There are
 counterexamples due to the model of =/c, but the one that reported is
 not an actual one.)  This will be fixed shortly.

 David

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev

_
  Racket Developers list:
  http://lists.racket-lang.org/dev