I have a function that requires a parameter be set to a value satisfying
a particular contract, but I don’t see any direct way to specify that
constraint using the contract system. It seems possible to emulate using
#:pre from ->* and ->i, but this has two problems: it doesn’t produce
very good error messages, and it doesn’t let me provide an arbitrary
contract.

The latter issue seems a little trickier to implement, since I don’t
think there’s any specific support in Racket’s existing interposition
layer. Neither impersonate-procedure nor impersonate-procedure* provide
any control over the dynamic extent of the call, so it isn’t possible to
adjust the parameterization. It’s possible to create an extremely simple
contract that creates an entirely new procedure instead of a chaperone
or impersonator:

  (define (parameterization-> param-name param val/c)
    (make-contract
     #:name `(parameterization-> ,param-name
                                 ,(contract-name val/c))
     #:projection
     (λ (blame)
       (let ([blame* (blame-add-context
                      blame #:swap? #t
                      (format "the value of (~a)" param-name))])
         (λ (val)
           (λ args
             (parameterize ([param (((contract-projection val/c) blame*)
                                    (param))])
               (apply val args))))))))

…but this seems like it probably has some drawbacks. Is there a better
way to do this? And in any case, would this be something useful to add
to ->* or ->i?

Alexis

-- 
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