[plt-scheme] suggestions on generators.ss

From: Danny Yoo (dyoo at hkn.eecs.berkeley.edu)
Date: Sun Apr 9 00:08:44 EDT 2006

> Consider a related problem: what if we wanted "yield" to work in the
> *dynamic extent* of a call to a generator, rather than just lexically
> in the generator's body? Here's how you'd do it:
>
>   (define current-yielder
>     (make-parameter
>       (lambda (value) (error 'yield "not in a generator"))))
>   (define (yield value) ((current-yielder) value)
>
> Then define-dynamic-generator wraps the generator function with
> something that sets the current-yielder parameter.

Hi Ryan,

Oh, wow!  I didn't consider using parameters in this way at all.


Let me make sure I'm understanding by rephrasing what you just said a
little.  *grin* We can use parameters to allow our functions to do
different things in the dynamic context of the running program, like this:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module play-with-parameterize mzscheme
  ;; code to play with the concepts suggested by Ryan Culpepper in
  ;; http://list.cs.brown.edu/pipermail/plt-scheme/2006-April/012463.html
  (provide say-hi allow-say-hi)
  (define-values (say-hi allow-say-hi)
    (let ([current-say-hi
           (make-parameter
            (lambda ()
              (error 'say-hi "can't call me in this context")))])
      (let ([say-hi (lambda () ((current-say-hi)))]
            [allow-say-hi
             (lambda (thunk)
               (parameterize
                   ([current-say-hi (lambda () (printf "hi!~n"))])
                 (thunk)))])
        (values say-hi allow-say-hi))))

  (define (test)
    (allow-say-hi
     (lambda () (say-hi) (printf "bye!")))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

So we can use this technique to make SAY-HI callable only within the
dynamic context of an ALLOW-SAY-HI... that's so sneaky!



> Syntax parameters work the same way. You agree on a keyword:
>
>   (require (lib "stxparam.ss"))
>
>   (define-syntax-parameter yield
>     (lambda (stx)
>       (raise-syntax-error #f "used outside of a generator" stx)))
>
> Then you when you want some code to be able to use yield, like the body
> of your generator function, you use "syntax-parameterize":

[code cut]

Thank you!  I'll look at the syntax-parameterize example closely.



Posted on the users mailing list.