Le dimanche 7 mai 2017 23:14:17 UTC+2, Daniel Prager a écrit :
> Thanks for the explanation on 2. Pragmatically, it's just another contributor 
> to the cost of contract checking.

I suppose you meant point 3, instead of point 2? The thread I linked to 
indicates that with ->d, the double-checking does not occur. Although the docs 
mention ->d is left only for backward compatibility, it is still available.

> On 1, I'm (naïvely) baffled as to why the contract should regard an optional 
> argument as unsupplied when it comes from the default rather than an explicit 
> passing. 

#lang racket
(define my-contract
  (->i () ([x (>=/c 1)]) [result real?]
       #:post (x result) (>= result (sqr x))))

(define (my-sqr [y 10]) (* y y))
(define (my-cub [z 20]) (* z z z))

(define/contract my-sqr-contracted my-contract my-sqr)
(define/contract my-cub-contracted my-contract my-cub)

Contracts are values. In the example above, the default value for the first 
optional argument (named x in the contract) is not the same for the first and 
second functions (10 and 20 respectively).

To emphasise the separation between the contract and the functions, I used 
different variable names in the contract (x) and the functions (y and z, 
respectively). I also defined the functions separately, so that when the 
contract is attached, the function's source is not syntactically within 
define/contract (the functions could even be defined in another module).

I'm not sure it is even possible to access the default value for an argument 
once the function is created. If it is possible (but I doubt it), then the 
contract could extract the default expression (which could refer to a global 
mutable value) when a check occurs. It would be nice indeed if this magic 
occurred, but it seems non-trivial to implement.

Furthermore, an poorly designed contract could incorrectly pre-compute the 
default expression, and pass it to the function (e.g. pass 11 instead of 10, 
due to a bug in the contract implementation). The simple fact that this is 
technically possible to make it impossible for the contract generated by ->i to 
be a chaperone, instead it would have to be an impersonator.

You can easily enough define a leaky abstraction with a macro which copies the 
default expression in the contract and in the function signature (but this 
would cause multiple evaluations). I tired to think about caching the value, 
but can't find a way to do so without breaking the blame mechanism (e.g. by 
wrapping the function, the inner one with the contract + mandatory arguments, 
and the outer one with optional arguments + no contract).

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to