[plt-scheme] Parameters and Eventspaces Question

From: Doug Williams (m.douglas.williams at gmail.com)
Date: Tue Oct 28 21:01:52 EDT 2008

Ok, I got that working, but don't understand something.  Here is the code
with two different instantiations of my-frame% - two with the instantiate
within a parameterize and two using a let and current-frame call.  [I have
two to test that it works for multiple frame instances.]

#lang scheme/gui

(define current-frame
  (make-parameter #f))

(define my-frame%
  (class frame%
    (super-instantiate ())
    (field (text-field
            (instantiate text-field%
              ("Press test button to update:" this))))
    (instantiate button%
      ("Clear" this)
      (callback
       (lambda (b e)
         (send text-field set-value ""))))
    (instantiate button%
      ("Test" this)
      (callback
       (lambda (b e)
         (update-text-field))))))

(define (update-text-field)
  (send (get-field text-field (current-frame))
        set-value (send (current-frame) get-label)))

(define (call-in-other-eventspace e thunk)
  (let ([ch (make-channel)])
    (parameterize ([current-eventspace e])
      (queue-callback (lambda ()
                        (channel-put ch (thunk)))))
    (channel-get ch)))

(call-in-other-eventspace
 (make-eventspace)
 (lambda ()
   (parameterize ((current-frame (instantiate my-frame%
                                   ("Frame 1"))))
     (send (current-frame) show #t))))

(call-in-other-eventspace
 (make-eventspace)
 (lambda ()
   (parameterize ((current-frame (instantiate my-frame%
                                   ("Frame 2"))))
     (send (current-frame) show #t))))

(call-in-other-eventspace
 (make-eventspace)
 (lambda ()
   (let ((frame (instantiate my-frame%
                  ("Frame 3"))))
     (current-frame frame)
     (send (current-frame) show #t))))

(call-in-other-eventspace
 (make-eventspace)
 (lambda ()
   (let ((frame (instantiate my-frame%
                  ("Frame 4"))))
     (current-frame frame)
     (send (current-frame) show #t))))

The last two do exactly what I want.  The first two give the effect I was
looking for.  The first wo give "get-field: expected an object, got #f" when
the Test button is clicked.  What is the difference?

Doug

P.S.  I'm not sure I would ever have come up with the solution.  Thanks for
the answer.


On Tue, Oct 28, 2008 at 6:20 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:

> At Tue, 28 Oct 2008 12:41:08 -0600, "Doug Williams" wrote:
> > I assume the problem is with my mental model of parameters and
> eventspaces.
> > I had assumed that each eventspace would have, in addition to its event
> > queues, etc,  its own execution thread, and copies of any parameters.
>
> That's correct.
>
> > Since
> > it allows me to parameterize or set the current-frame in a new
> eventspace, I
> > assume the eventspace 'knows about' my current-frame parameter.  What I
> > don't understand is why a call to update-text-field by a frame that I
> think
> > is running under 'new' eventspace doesn't get a value for the
> current-frame
> > parameter.
>
> In
>
>  (parameterize ([current-eventspace E])
>    B)
>
> the `parameterize' sets the `current-eventspace' parameter to `E' while
> evaluating `B', it still evaluates `B' in the current thread --- not
> the handler thread of `E'. So if you mutate a parameter within `B',
> then it still mutates the parameter for the current thread, not for the
> thread of `E'.
>
> Use `queue-callback' to jump to another eventspace's handler thread.
> The `queue-callback' function uses the `current-eventspace' parameter
> (of the current thread) to determine where to queue the callback, and
> the callback is invoked in that eventspace's handler thread.
>
>  (define (call-in-other-eventspace e thunk)
>   (let ([ch (make-channel)])
>     (parameterize ([current-eventspace e])
>       (queue-callback (lambda ()
>                         (channel-put ch (thunk)))))
>     (channel-get ch)))
>
>
>  (call-in-other-eventspace
>  (make-eventspace)
>  (lambda ()
>     (parameterize ((current-frame (instantiate my-frame%
>                                               ("Frame 2"))))
>      (send (current-frame) show #t)
>       (update-text-field))))
>
>  (call-in-other-eventspace
>  (make-eventspace)
>  (lambda ()
>     (let ((frame-3 (instantiate my-frame%
>                                ("Frame 3"))))
>      (current-frame frame-3)
>      (send (current-frame) show #t)
>       (update-text-field))))
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20081028/b71ffd7d/attachment.html>

Posted on the users mailing list.