Re: [racket-dev] contract-out
Everyone rolling their own is bad. We want people to contract their code, and they don't want to always pay for the overhead. #2 sounds the best, since that could be again abstracted over by the user, this time with one line instead of the sevel it takes to implement provide-cond-contract. This also has the advantage that the user can have access to any subforms someone else adds later. -Ian - Original Message - From: Sam Tobin-Hochstadt sa...@ccs.neu.edu To: J. Ian Johnson i...@ccs.neu.edu Cc: Matthew Flatt mfl...@cs.utah.edu, dev@racket-lang.org Sent: Sun, 25 Sep 2011 11:34:39 -0400 (EDT) Subject: Re: [racket-dev] contract-out On Sun, Sep 25, 2011 at 10:55 AM, J. Ian Johnson i...@ccs.neu.edu wrote: Very nice! Is it easy to make a provide form that conditionally provides with contracts, such as Sam's provide-cond-contract in typed-scheme/utils/utils.rkt? The trouble with this is that it's not clear how it should be controlled. There are a few obvious possibilities: 1. There's a global flag for all of Racket which turns contracts on and off. It should be pretty clear that this is a bad idea. 2. There's a form like `(contract-cond-out expr stuff ...)' which uses the contracts in `stuff' IFF `expr' is true. This is easy to implement, but pretty inconvenient to use. 3. Something like the status quo, where everyone defines their own thing, but maybe with some abstraction. 4. A compiler flag. We don't have anything like this, though, currently, and it's not clear how it should work. -Ian - Original Message - From: Matthew Flatt mfl...@cs.utah.edu To: dev@racket-lang.org Sent: Sat, 24 Sep 2011 09:41:17 -0400 (EDT) Subject: [racket-dev] contract-out The `racket/contract' and `racket' modules now provide `contract-out', which is a `provide' form for contracts. Use (provide (contract-out )) instead of (provide/contract ) There's one difference between `(provide (contract-out ))' and `(provide/contract )': contract expressions in contract-out' are implicitly moved to the end of the module, which means that they can refer to variables that are defined later. For example, the following program works as you'd expect: #lang racket (provide (contract-out [mask-of (turtle? . - . color?)]) turtle? color?) (define (turtle? v) (memq v '(Leonardo Michelangelo Donatello Raphael))) (define (color? v) (memq v '(blue orange purple red))) (define (mask-of t) (match t ['Leonardo 'blue] ['Michelangelo 'orange] ['Donatello 'purple] ['Raphael 'red])) The `contract-out' form is implemented as a provide pre-transformer, which is a new kind of `provide' form that is now supported by `racket/provide-transform'. _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
Right now, in the Typed Racket implementation, there's forms like this: (provide-cond-contract [foo foo?]) Option #2 would be something like this: (provide (cond-contract-out enable-contracts? [foo foo?])) and everywhere has to reference the `enable-contracts?' identifier. I'm not convinced that this is that much nicer than rolling your own. On Sun, Sep 25, 2011 at 7:41 PM, J. Ian Johnson i...@ccs.neu.edu wrote: Everyone rolling their own is bad. We want people to contract their code, and they don't want to always pay for the overhead. #2 sounds the best, since that could be again abstracted over by the user, this time with one line instead of the sevel it takes to implement provide-cond-contract. This also has the advantage that the user can have access to any subforms someone else adds later. -Ian - Original Message - From: Sam Tobin-Hochstadt sa...@ccs.neu.edu To: J. Ian Johnson i...@ccs.neu.edu Cc: Matthew Flatt mfl...@cs.utah.edu, dev@racket-lang.org Sent: Sun, 25 Sep 2011 11:34:39 -0400 (EDT) Subject: Re: [racket-dev] contract-out On Sun, Sep 25, 2011 at 10:55 AM, J. Ian Johnson i...@ccs.neu.edu wrote: Very nice! Is it easy to make a provide form that conditionally provides with contracts, such as Sam's provide-cond-contract in typed-scheme/utils/utils.rkt? The trouble with this is that it's not clear how it should be controlled. There are a few obvious possibilities: 1. There's a global flag for all of Racket which turns contracts on and off. It should be pretty clear that this is a bad idea. 2. There's a form like `(contract-cond-out expr stuff ...)' which uses the contracts in `stuff' IFF `expr' is true. This is easy to implement, but pretty inconvenient to use. 3. Something like the status quo, where everyone defines their own thing, but maybe with some abstraction. 4. A compiler flag. We don't have anything like this, though, currently, and it's not clear how it should work. -Ian - Original Message - From: Matthew Flatt mfl...@cs.utah.edu To: dev@racket-lang.org Sent: Sat, 24 Sep 2011 09:41:17 -0400 (EDT) Subject: [racket-dev] contract-out The `racket/contract' and `racket' modules now provide `contract-out', which is a `provide' form for contracts. Use (provide (contract-out )) instead of (provide/contract ) There's one difference between `(provide (contract-out ))' and `(provide/contract )': contract expressions in contract-out' are implicitly moved to the end of the module, which means that they can refer to variables that are defined later. For example, the following program works as you'd expect: #lang racket (provide (contract-out [mask-of (turtle? . - . color?)]) turtle? color?) (define (turtle? v) (memq v '(Leonardo Michelangelo Donatello Raphael))) (define (color? v) (memq v '(blue orange purple red))) (define (mask-of t) (match t ['Leonardo 'blue] ['Michelangelo 'orange] ['Donatello 'purple] ['Raphael 'red])) The `contract-out' form is implemented as a provide pre-transformer, which is a new kind of `provide' form that is now supported by `racket/provide-transform'. _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev -- sam th sa...@ccs.neu.edu -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
How about we write a define-toggle-contract-out form, so everyone can define their own without actually implementing their own. Something like so: (define-toggle-contract-out my-contract-out #:disable) ;; comment out keyword to enable (provide (my-contract-out [thing thing/c])) Carl Eastlund On Sun, Sep 25, 2011 at 7:41 PM, J. Ian Johnson i...@ccs.neu.edu wrote: Everyone rolling their own is bad. We want people to contract their code, and they don't want to always pay for the overhead. #2 sounds the best, since that could be again abstracted over by the user, this time with one line instead of the sevel it takes to implement provide-cond-contract. This also has the advantage that the user can have access to any subforms someone else adds later. -Ian - Original Message - From: Sam Tobin-Hochstadt sa...@ccs.neu.edu To: J. Ian Johnson i...@ccs.neu.edu Cc: Matthew Flatt mfl...@cs.utah.edu, dev@racket-lang.org Sent: Sun, 25 Sep 2011 11:34:39 -0400 (EDT) Subject: Re: [racket-dev] contract-out On Sun, Sep 25, 2011 at 10:55 AM, J. Ian Johnson i...@ccs.neu.edu wrote: Very nice! Is it easy to make a provide form that conditionally provides with contracts, such as Sam's provide-cond-contract in typed-scheme/utils/utils.rkt? The trouble with this is that it's not clear how it should be controlled. There are a few obvious possibilities: 1. There's a global flag for all of Racket which turns contracts on and off. It should be pretty clear that this is a bad idea. 2. There's a form like `(contract-cond-out expr stuff ...)' which uses the contracts in `stuff' IFF `expr' is true. This is easy to implement, but pretty inconvenient to use. 3. Something like the status quo, where everyone defines their own thing, but maybe with some abstraction. 4. A compiler flag. We don't have anything like this, though, currently, and it's not clear how it should work. -Ian - Original Message - From: Matthew Flatt mfl...@cs.utah.edu To: dev@racket-lang.org Sent: Sat, 24 Sep 2011 09:41:17 -0400 (EDT) Subject: [racket-dev] contract-out The `racket/contract' and `racket' modules now provide `contract-out', which is a `provide' form for contracts. Use (provide (contract-out )) instead of (provide/contract ) There's one difference between `(provide (contract-out ))' and `(provide/contract )': contract expressions in contract-out' are implicitly moved to the end of the module, which means that they can refer to variables that are defined later. For example, the following program works as you'd expect: #lang racket (provide (contract-out [mask-of (turtle? . - . color?)]) turtle? color?) (define (turtle? v) (memq v '(Leonardo Michelangelo Donatello Raphael))) (define (color? v) (memq v '(blue orange purple red))) (define (mask-of t) (match t ['Leonardo 'blue] ['Michelangelo 'orange] ['Donatello 'purple] ['Raphael 'red])) The `contract-out' form is implemented as a provide pre-transformer, which is a new kind of `provide' form that is now supported by `racket/provide-transform'. _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
That's the best solution I've come up with, which is basically the abstraction I suggested under #4. sam th On Sunday, September 25, 2011, Carl Eastlund wrote: How about we write a define-toggle-contract-out form, so everyone can define their own without actually implementing their own. Something like so: (define-toggle-contract-out my-contract-out #:disable) ;; comment out keyword to enable (provide (my-contract-out [thing thing/c])) Carl Eastlund On Sun, Sep 25, 2011 at 7:41 PM, J. Ian Johnson i...@ccs.neu.edu wrote: Everyone rolling their own is bad. We want people to contract their code, and they don't want to always pay for the overhead. #2 sounds the best, since that could be again abstracted over by the user, this time with one line instead of the sevel it takes to implement provide-cond-contract. This also has the advantage that the user can have access to any subforms someone else adds later. -Ian - Original Message - From: Sam Tobin-Hochstadt sa...@ccs.neu.edu To: J. Ian Johnson i...@ccs.neu.edu Cc: Matthew Flatt mfl...@cs.utah.edu, dev@racket-lang.org Sent: Sun, 25 Sep 2011 11:34:39 -0400 (EDT) Subject: Re: [racket-dev] contract-out On Sun, Sep 25, 2011 at 10:55 AM, J. Ian Johnson i...@ccs.neu.edu wrote: Very nice! Is it easy to make a provide form that conditionally provides with contracts, such as Sam's provide-cond-contract in typed-scheme/utils/utils.rkt? The trouble with this is that it's not clear how it should be controlled. There are a few obvious possibilities: 1. There's a global flag for all of Racket which turns contracts on and off. It should be pretty clear that this is a bad idea. 2. There's a form like `(contract-cond-out expr stuff ...)' which uses the contracts in `stuff' IFF `expr' is true. This is easy to implement, but pretty inconvenient to use. 3. Something like the status quo, where everyone defines their own thing, but maybe with some abstraction. 4. A compiler flag. We don't have anything like this, though, currently, and it's not clear how it should work. -Ian - Original Message - From: Matthew Flatt mfl...@cs.utah.edu To: dev@racket-lang.org Sent: Sat, 24 Sep 2011 09:41:17 -0400 (EDT) Subject: [racket-dev] contract-out The `racket/contract' and `racket' modules now provide `contract-out', which is a `provide' form for contracts. Use (provide (contract-out )) instead of (provide/contract ) There's one difference between `(provide (contract-out ))' and `(provide/contract )': contract expressions in contract-out' are implicitly moved to the end of the module, which means that they can refer to variables that are defined later. For example, the following program works as you'd expect: #lang racket (provide (contract-out [mask-of (turtle? . - . color?)]) turtle? color?) (define (turtle? v) (memq v '(Leonardo Michelangelo Donatello Raphael))) (define (color? v) (memq v '(blue orange purple red))) (define (mask-of t) (match t ['Leonardo 'blue] ['Michelangelo 'orange] ['Donatello 'purple] ['Raphael 'red])) The `contract-out' form is implemented as a provide pre-transformer, which is a new kind of `provide' form that is now supported by `racket/provide-transform'. _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
IMO, a better approach for disabling contracts is to have the client decide whether it wants the contracted version or the plain one -- which is a rough mirror of how unsafe operations are done (with the choice being made by requiring one file or another). Then, there could be a facility that associates a safe identifier with an unsafe version, so you could write (unsafe foo) -- which will be the unsafe operation for builtins that have one, and in case of a contracted function it will be the uncontracted one. (Finally, there could be a sub-namespace facility where an identifier can have multiple bindings, and (unsafe foo) would actually expand to the unsafe sub-binding. This is a solution to a bunch of other things that are hard to get at the moment, like match pattern identifiers and more.) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
On Sun, Sep 25, 2011 at 8:14 PM, Eli Barzilay e...@barzilay.org wrote: IMO, a better approach for disabling contracts is to have the client decide whether it wants the contracted version or the plain one -- which is a rough mirror of how unsafe operations are done (with the choice being made by requiring one file or another). Then, there could be a facility that associates a safe identifier with an unsafe version, so you could write (unsafe foo) -- which will be the unsafe operation for builtins that have one, and in case of a contracted function it will be the uncontracted one. This wouldn't work for the Typed Racket use case, where I want to flip one switch for contracts throughout the TR code base. -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
An hour and a half ago, Sam Tobin-Hochstadt wrote: On Sun, Sep 25, 2011 at 8:14 PM, Eli Barzilay e...@barzilay.org wrote: IMO, a better approach for disabling contracts is to have the client decide whether it wants the contracted version or the plain one -- which is a rough mirror of how unsafe operations are done (with the choice being made by requiring one file or another). Then, there could be a facility that associates a safe identifier with an unsafe version, so you could write (unsafe foo) -- which will be the unsafe operation for builtins that have one, and in case of a contracted function it will be the uncontracted one. This wouldn't work for the Typed Racket use case, where I want to flip one switch for contracts throughout the TR code base. (define-for-syntax contracts-on? #t) (define-syntax (switch stx) (syntax-case stx () [(_ id) (if contracts-on? #'id #'(unsafe id))])) -- ((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay: http://barzilay.org/ Maze is Life! _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
Re: [racket-dev] contract-out
On Sun, Sep 25, 2011 at 9:36 PM, Eli Barzilay e...@barzilay.org wrote: An hour and a half ago, Sam Tobin-Hochstadt wrote: On Sun, Sep 25, 2011 at 8:14 PM, Eli Barzilay e...@barzilay.org wrote: IMO, a better approach for disabling contracts is to have the client decide whether it wants the contracted version or the plain one -- which is a rough mirror of how unsafe operations are done (with the choice being made by requiring one file or another). Then, there could be a facility that associates a safe identifier with an unsafe version, so you could write (unsafe foo) -- which will be the unsafe operation for builtins that have one, and in case of a contracted function it will be the uncontracted one. This wouldn't work for the Typed Racket use case, where I want to flip one switch for contracts throughout the TR code base. (define-for-syntax contracts-on? #t) (define-syntax (switch stx) (syntax-case stx () [(_ id) (if contracts-on? #'id #'(unsafe id))])) But now I have to change all the places that use these identifiers. The turn on and off internal contracts and give me unchecked access to this library use cases are genuinely different. -- sam th sa...@ccs.neu.edu _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev
[racket-dev] contract-out
The `racket/contract' and `racket' modules now provide `contract-out', which is a `provide' form for contracts. Use (provide (contract-out )) instead of (provide/contract ) There's one difference between `(provide (contract-out ))' and `(provide/contract )': contract expressions in contract-out' are implicitly moved to the end of the module, which means that they can refer to variables that are defined later. For example, the following program works as you'd expect: #lang racket (provide (contract-out [mask-of (turtle? . - . color?)]) turtle? color?) (define (turtle? v) (memq v '(Leonardo Michelangelo Donatello Raphael))) (define (color? v) (memq v '(blue orange purple red))) (define (mask-of t) (match t ['Leonardo 'blue] ['Michelangelo 'orange] ['Donatello 'purple] ['Raphael 'red])) The `contract-out' form is implemented as a provide pre-transformer, which is a new kind of `provide' form that is now supported by `racket/provide-transform'. _ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/dev