Just following up to say thank you. I especially appreciated seeing several iterations of this to clarify things.
On Mon, Jul 30, 2018 at 6:40 AM Philip McGrath <[email protected]> wrote: > Since #t and #f can be used as contracts that recognize only themselves, > you can get a step better in terms of concision: > > #lang racket > > (module+ test (require rackunit)) > > ; Normalizes sneetches depending on belly-star demand. > (define/contract (convert-sneetches stars-upon-thars? sneetches) > (->i > ([demand boolean?] > [inputs (demand) (non-empty-listof (not demand))]) > [_ (demand inputs) > (and/c > (non-empty-listof demand) > (compose (curry = (length inputs)) length))]) > (map (lambda (s) stars-upon-thars?) sneetches)) > > (module+ test > (check-equal? (convert-sneetches #true (list #false)) (list #true)) > (check-equal? (convert-sneetches #false (list #t #t)) (list #f #f))) > > Also, using `_` instead of `result` means that "the range contract > expressions are evaluated when the function is called instead of when it > returns." My recollection is that this can be desirable for performance > reasons. > > -Philip > > On Mon, Jul 30, 2018 at 4:30 AM, Matthias Felleisen < > [email protected]> wrote: > >> >> Here is a version that is slightly more concise than yours (due to the >> use of `curry`) and expresses a stronger property. As our introduction to >> contract illustrates (used to illustrate?) contracts can express a spectrum >> of properties, all the way from type-like ones to full-fledged correctness. >> Developers need to acquire a sense of taste to pic the right level of >> defensiveness. In the end, contracts are really about factoring out the >> defensive part of modules from the functionality ones and you need to know >> how defensive you must be in your context. — Matthias >> >> >> >> #lang racket >> >> (module+ test (require rackunit)) >> >> ; Normalizes sneetches depending on belly-star demand. >> (define/contract (convert-sneetches stars-upon-thars? sneetches) >> (->i >> ([demand boolean?] >> [inputs (demand) (non-empty-listof (and/c boolean? (curry boolean=? >> (not demand))))]) >> (result (demand inputs) >> (and/c >> (non-empty-listof (and/c boolean? (curry boolean=? demand))) >> (compose (curry = (length inputs)) length)))) >> (map (lambda (s) stars-upon-thars?) sneetches)) >> >> (module+ test >> (check-equal? (convert-sneetches #true (list #false)) (list #true)) >> (check-equal? (convert-sneetches #false (list #t #t)) (list #f #f))) >> >> >> On Jul 29, 2018, at 7:45 PM, Sage Gerard <[email protected]> wrote: >> >> Continuing study of contracts, specifically ->i. >> >> I am trying to model the machine from *The Sneetches* with the most >> fleshed out contract possible. Assuming a Sneetch is reduced to a boolean >> as per the story's problem statement, we can model McBean's machine as: >> >> (define (convert-sneetches stars-upon-thars? sneetches) >> (map (lambda (s) stars-upon-thars?) sneetches)) >> >> The demand for stars upon thars or the contrary is a separate parameter >> to make the problem applicable to ->i, because in the story the machine >> is only configured to accept Sneetches of the opposite persuasion. That is, >> if the demand is for stars upon thars, only Plain-Bellies enter the >> machine. So applications like (convert-sneetches #t '(#t #t #f)) are >> violations. >> >> Here's my attempt at handling this: >> >> #lang racket >> >> ; Normalizes sneetches depending on belly-star demand. >> (define/contract (convert-sneetches stars-upon-thars? sneetches) >> (->i >> ([demand boolean?] >> [inputs (demand) >> (non-empty-listof >> (and/c >> boolean? >> (lambda (b) (equal? b (not demand)))))]) >> (result (demand inputs) >> (non-empty-listof >> (and/c boolean? (lambda (b) (equal? b demand)))))) >> (map (lambda (s) stars-upon-thars?) sneetches)) >> >> It *appears* to work, but is this correct? I'm not 100% on the binding >> rules inside a contract body. If this is correct, was there a simpler way >> to do this? >> >> Thanks, >> Sage >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> >> >> -- >> You received this message because you are subscribed to the Google Groups >> "Racket Users" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

