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 <m...@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



____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to