Nothing specific that I'm aware of, but others could answer this better.
If there are then they're probably related to speed.

Personally, I'm quite fond of them because they eliminate the need for a
lot of tests and make the code much more self-documenting.

Function contracts are detailed here:
https://docs.racket-lang.org/reference/function-contracts.html  In the
left-hand navbar you'll see a bunch of related topics, like data-structure
contracts.


On Mon, Jul 8, 2019 at 1:28 PM Kevin Forchione <lyss...@gmail.com> wrote:

>
>
> On Jul 8, 2019, at 8:17 AM, David Storrs <david.sto...@gmail.com> wrote:
>
> Note that in many cases it can be better to use a contract as opposed to
> an explicit check.  For example, you could replace this:
>
> (define (feed-animals cow sheep goose cat)
>     (if (not (eq? goose 'goose))
>       (raise-argument-error 'feed-animals "'goose" 2 cow sheep goose cat)
>       "fed the animals"))
>
> With this, which is precisely equivalent:
>
> (define/contract (feed-animals cow sheep goose cat)
>    (-> any/c any/c 'goose any/c any)
>     "fed the animals")
>
>
> Or maybe you want to verify that neither cow, sheep, nor cat are also
> goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>    (-> (not/c 'goose) (not/c 'goose) 'goose (not/c 'goose) any)
>     "fed the animals")
>
> Or, maybe you can accept either a symbol or a string for goose:
>
> (define/contract (feed-animals cow sheep goose cat)
>    (-> any/c any/c (or/c 'goose "goose") any/c any)
>     "fed the animals")
>
> Or maybe do that case-insensitively (I'm getting rid of the excess
> arguments for brevity):
>
> (define/contract (feed-animals goose)
>    (-> (compose1 (curry string-ci=? "goose") ~a) any)
>     "fed the animals")
>
> Same as above, but let's insist that the return value be a non-empty
> string:
>
> (define/contract (feed-animals goose)
>    (-> (compose1 (curry string-ci=? "goose") ~a) non-empty-string?)
>     "fed the animals")
>
> If you really want to get nuts then you can do all kinds of inter-argument
> checking in a contract.  Here's an actual contract that I use in my
> database layer, for the 'upsert-rows' function:
>
> (define symbol-string? (or/c symbol? string?))
> (define false-or-unsupplied? (or/c false? unsupplied-arg?))
>
> (define/contract (upsert-rows #:table             table-name
>                               #:rows              rows
>                               #:conflict-clause   conflict-clause
>                               #:db                [conn             #f]
>                               #:fields-to-update  [fields-to-update #f]
>                               )
>   (->i (#:table           [table symbol-string?]
>         #:rows            [rows (or/c  (hash/c symbol-string? any/c)
>                                        (listof (hash/c symbol-string?
> any/c)))]
>         #:conflict-clause [conflict-clause (or/c #f 'FAIL symbol-string?)]
> ; 'FAIL is redundant with `symbol-string?`. It's there for clarity.
>         )
>        (
>         #:db                 [db connection?]
>         #:fields-to-update   [fields-to-update (or/c #f (non-empty-listof
> symbol-string?))]
>         )
>        ; If conflict clause is 'FAIL then fields-to-update must be #f or
> unsupplied
>        ; If conflict clause is #f then fields-to-update must be #f or
> unsupplied
>        ; If conflict clause is NOT #f then fields-to-update must be a list
>
>        #:pre (conflict-clause fields-to-update)
>        (or  (and (equal? 'FAIL conflict-clause)
>                  (false-or-unsupplied? fields-to-update))
>             (and (false? conflict-clause) (false-or-unsupplied?
> fields-to-update))
>             (and conflict-clause (list? fields-to-update)))
>        any)
> ...code…)
>
>
> Thanks, David! I’ll have to look into using contracts in my code. Are
> there any downsides to contracts over the raising an error?
>
> Kevin
>
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAE8gKof3UkDGiYUeAh3M-tjMUw7z4ZbZQJd%2BOasnyxG9FPD7UA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to