[racket] rudimentary Q. about lambda + contracts
If I were making something like case-lambda/contract, which would be
better/make more sense?
#lang racket
(require test-engine/racket-tests)
;; this one takes a contract within each case, and puts in in a case->
for you:
(define-syntax-rule (case-lambda/contract-1 [args c e0 e ...] ...)
(let ()
(define/contract f
(case-> c ...)
(case-lambda
[args e0 e ...]
...))
f))
;; example for case-lambda/contract-1:
(define report-cost-1
(case-lambda/contract-1
[(lo hi) (integer? integer? . -> . string?)
(format "between $~a and $~a" lo hi)]
[(desc) (string? . -> . string?)
(format "~a of dollars" desc)]))
(check-expect (report-cost-1 5 8)
"between $5 and $8")
(check-expect (report-cost-1 "millions")
"millions of dollars")
(check-error (report-cost-1 "thousands" "millions"))
(check-error (report-cost-1 5))
;; this one takes a contract for the whole thing, and lets you do the
case-> yourself:
(define-syntax-rule (case-lambda/contract-2 contract-expr [args e0
e ...] ...)
(let ()
(define/contract f
contract-expr
(case-lambda
[args e0 e ...]
...))
f))
;; example for case-lambda/contract-2:
(define report-cost-2
(case-lambda/contract-2
(case->
(integer? integer? . -> . string?)
(string? . -> . string?))
[(lo hi) (format "between $~a and $~a" lo hi)]
[(desc) (format "~a of dollars" desc)]))
(check-expect (report-cost-2 5 8)
"between $5 and $8")
(check-expect (report-cost-2 "millions")
"millions of dollars")
(check-error (report-cost-2 "thousands" "millions"))
(check-error (report-cost-2 5))
(test)
Which one is better/makes more sense?
(define report-cost-1
(case-lambda/contract-1
[(lo hi) (integer? integer? . -> . string?)
(format "between $~a and $~a" lo hi)]
[(desc) (string? . -> . string?)
(format "~a of dollars" desc)]))
(define report-cost-2
(case-lambda/contract-2
(case->
(integer? integer? . -> . string?)
(string? . -> . string?))
[(lo hi) (format "between $~a and $~a" lo hi)]
[(desc) (format "~a of dollars" desc)]))
On Nov 17, 2013, at 12:43 PM, Matthias Felleisen wrote:
>
> I would choose option 2, because I have a strong preference for
> seeing specs first and ignoring implementations if I can. You may
> wish to ask on the list; others may have other ideas. -- Matthias
>
>
>
>
>
> On Nov 16, 2013, at 11:05 AM, Alexander D. Knauth wrote:
>
>> If I were making something like this for case-lambda, which would
>> be better/make more sense?
>>
>> #lang racket
>>
>> (require test-engine/racket-tests)
>>
>> ;; this one takes a contract within each case, and puts in in a
>> case-> for you:
>> (define-syntax-rule (case-lambda/contract-1 [args c e0 e ...] ...)
>> (let ()
>> (define/contract f
>> (case-> c ...)
>> (case-lambda
>> [args e0 e ...]
>> ...))
>> f))
>>
>> ;; example for case-lambda/contract-1:
>> (define report-cost-1
>> (case-lambda/contract-1
>> [(lo hi) (integer? integer? . -> . string?)
>> (format "between $~a and $~a" lo hi)]
>> [(desc) (string? . -> . string?)
>> (format "~a of dollars" desc)]))
>>
>> (check-expect (report-cost-1 5 8)
>> "between $5 and $8")
>> (check-expect (report-cost-1 "millions")
>> "millions of dollars")
>> (check-error (report-cost-1 "thousands" "millions"))
>> (check-error (report-cost-1 5))
>>
>>
>> ;; this one takes a contract for the whole thing, and lets you do
>> the case-> yourself:
>> (define-syntax-rule (case-lambda/contract-2 contract-expr [args
>> body ...] ...)
>> (let ()
>> (define/contract f
>> contract-expr
>> (case-lambda
>> [args body ...]
>> ...))
>> f))
>>
>> ;; example for case-lambda/contract-2:
>> (define report-cost-2
>> (case-lambda/contract-2
>> (case->
>> (integer? integer? . -> . string?)
>> (string? . -> . string?))
>> [(lo hi) (format "between $~a and $~a" lo hi)]
>> [(desc) (format "~a of dollars" desc)]))
>>
>> (check-expect (report-cost-2 5 8)
>> "between $5 and $8")
>> (check-expect (report-cost-2 "millions")
>> "millions of dollars")
>> (check-error (report-cost-2 "thousands" "millions"))
>> (check-error (report-cost-2 5))
>>
>>
>> (test)
>>
>>
>> Which one is better/makes more sense?
>>
>> (define report-cost-1
>> (case-lambda/contract-1
>> [(lo hi) (integer? integer? . -> . string?)
>> (format "between $~a and $~a" lo hi)]
>> [(desc) (string? . -> . string?)
>> (format "~a of dollars" desc)]))
>>
>> (define report-cost-2
>> (case-lambda/contract-2
>> (case->
>> (integer? integer? . -> . string?)
>> (string? . -> . string?))
>> [(lo hi) (format "between $~a and $~a" lo hi)]
>> [(desc) (format "~a of dollars" desc)]))
>>
>>
>> On Nov 13, 2013, at 2:45 PM, Matthias Felleisen wrote:
>>
>>>
>>> Do you want something like this :
>>>
>>> #lang racket
>>>
>>> (define-syntax-rule
>>> (lambda/contract (x ...) c e0 e ...)
>>> ;; ==>
>>> (let ()
>>> (define/contract (f x ...) c e0 e ...)
>>> f))
>>>
>>> ;;
>>> -----------------------------------------------------------------------------
>>>
>>> (define g (lambda/contract (x) (integer? . -> . integer?) (* pi x)))
>>>
>>> (void (= (g 0) 0))
>>> (with-handlers ([exn:fail:contract? void])
>>> (g 1))
>>>
>>>
>>>
>>>
>>>
>>> On Nov 13, 2013, at 1:12 PM, Matthew Butterick <mb at mbtype.com>
>>> wrote:
>>>
>>>> Having gotten in the habit of writing function contracts, I
>>>> prefer define/contract to (provide (contract-out ...)) because it
>>>> keeps the contract near the function.
>>>>
>>>> Is there an analogous idiom for lambda? I see there is no lambda/
>>>> contract, and the docs on contracts for case-lambda [1] uses the
>>>> (provide (contract-out ...)) style.
>>>>
>>>> [1] http://docs.racket-lang.org/guide/contracts-general-functions.html#(part._contracts-case-lambda)
>>>> ____________________
>>>> Racket Users list:
>>>> http://lists.racket-lang.org/users
>>>
>>>
>>> ____________________
>>> Racket Users list:
>>> http://lists.racket-lang.org/users
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20131118/85430aa2/attachment-0001.html>