diff --git a/collects/scribblings/reference/chaperones.scrbl b/collects/scribblings/reference/chaperones.scrbl index 6fdeac3a8f..bb378252d5 100644 --- a/collects/scribblings/reference/chaperones.scrbl +++ b/collects/scribblings/reference/chaperones.scrbl @@ -330,9 +330,9 @@ or override impersonator-property values of @racket[hash].} [prop-val any] ... ...) (and/c continuation-prompt-tag? impersonator?)]{ -Returns an impersonator of @racket[prompt-tag], which adds intercession -to the handler of @racket[call-with-continuation-prompt] and to -@racket[abort-current-continuation]. +Returns an impersonator of @racket[prompt-tag], which redirects +the @racket[call-with-continuation-prompt] and +@racket[abort-current-continuation] operations. The @racket[handle-proc] must accept the values that the handler of a continuation prompt would take and it must produce replacement @@ -344,7 +344,22 @@ values, which are aborted to the appropriate prompt. Pairs of @racket[prop] and @racket[prop-val] (the number of arguments to @racket[impersonate-prompt-tag] must be odd) add impersonator properties -or override impersonator-property values of @racket[prompt-tag].} +or override impersonator-property values of @racket[prompt-tag]. + +@examples[ + (define tag + (impersonate-prompt-tag + (make-continuation-prompt-tag) + (lambda (n) (* n 2)) + (lambda (n) (+ n 1)))) + + (call-with-continuation-prompt + (lambda () + (abort-current-continuation tag 5)) + tag + (lambda (n) n)) +] +} @defthing[prop:impersonator-of struct-type-property?]{ @@ -553,7 +568,34 @@ or override impersonator-property values of @racket[evt].} Like @racket[impersonate-prompt-tag], but produces a chaperoned value. The @racket[handle-proc] procedure must produce the same values or chaperones of the original values, and @racket[abort-proc] must produce -the same values or chaperones of the values that it is given.} +the same values or chaperones of the values that it is given. + +@examples[ + (define bad-chaperone + (chaperone-prompt-tag + (make-continuation-prompt-tag) + (lambda (n) (* n 2)) + (lambda (n) (+ n 1)))) + + (call-with-continuation-prompt + (lambda () + (abort-current-continuation bad-chaperone 5)) + bad-chaperone + (lambda (n) n)) + + (define good-chaperone + (chaperone-prompt-tag + (make-continuation-prompt-tag) + (lambda (n) (if (even? n) n (error "not even"))) + (lambda (n) (if (even? n) n (error "not even"))))) + + (call-with-continuation-prompt + (lambda () + (abort-current-continuation good-chaperone 2)) + good-chaperone + (lambda (n) n)) +] +} @; ------------------------------------------------------------ @section{Impersonator Properties} diff --git a/collects/scribblings/reference/contracts.scrbl b/collects/scribblings/reference/contracts.scrbl index e94d634abd..8f5f4dff61 100644 --- a/collects/scribblings/reference/contracts.scrbl +++ b/collects/scribblings/reference/contracts.scrbl @@ -502,6 +502,21 @@ call to @racket[call-with-continuation-prompt]. If all of the @racket[contract]s are chaperone contracts, the resulting contract will also be a @tech{chaperone} contract. Otherwise, the contract is an @tech{impersonator} contract. + +@examples[#:eval (contract-eval) + (define/contract tag + (prompt/c (-> number? string?)) + (make-continuation-prompt-tag)) + + (call-with-continuation-prompt + (lambda () + (number->string + (call-with-composable-continuation + (lambda (k) + (abort-current-continuation tag k))))) + tag + (lambda (k) (k "not a number"))) +] } diff --git a/src/racket/src/fun.c b/src/racket/src/fun.c index 3762b3fa39..6970740a05 100644 --- a/src/racket/src/fun.c +++ b/src/racket/src/fun.c @@ -6052,9 +6052,9 @@ static Scheme_Object **chaperone_do_control(const char *name, int is_prompt, Sch * as the number of aborted values */ if (num_args == 1 && num_args != argc) - scheme_wrong_return_arity(name, argc, 1, vals[0], "application of proxy function"); + scheme_wrong_return_arity(name, argc, 1, vals[0], "use of redirecting procedure"); else if (num_args != argc) - scheme_wrong_return_arity(name, argc, num_args, vals, "application of proxy function"); + scheme_wrong_return_arity(name, argc, num_args, vals, "use of redirecting procedure"); if (!(SCHEME_CHAPERONE_FLAGS(px) & SCHEME_CHAPERONE_IS_IMPERSONATOR)) { for (i = 0; i < argc; i++) {