[plt-scheme] 203.9

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Apr 22 21:18:08 EDT 2003

The exp-tagged code in CVS for MzScheme and MrEd is now version 203.9.

You may have noticed that 203.8 appeared yesterday without an
announcement. That's because, in the process of composing an
announcement, I relized that the 203.8 change was broken. Version 203.9
reverts the 203.8 change, and also provides a workable solution to the
problem that 203.8 tried to solve.

203.9 removes some `yield' calls that were built into MrEd, such
as a `yield' in the callback that blinks an editor caret. The `yield's
were not necssary, and we now know that they're harmful.

There's a larger lesson for using `yield', so I'll try to explain in
more detail. Consider the following program:

  (define x "hello")

  (define f (make-object frame% ...))
  (make-object button% "Use X" f (lambda (b) ... x ...))
  (make-object button% "Config X" f (lambda (b) (set! x (get-new-x))))

  (define (get-new-x)
    (let* ([d (make-object dialog% ...)]
           [t (make-object text-field% ...])
     (make-object button% "Ok" d (lambda (b e) 
                                   (set! v (send t get-value))
                                   (send d show #f)))
      (send d show #t)
      v))

The intent of this code is that when the "Config X" button is pushed,
the user can change the value of `x' in a dialog. After the dialog is
closed, pushing the "Use X" button uses the new value.

In 203.7 and previous versions, additional events in the frame `f'
might be handled after the dialog `d' is hidden, but before `get-new-x'
returns. If an intermediate event is to push "Use X", it will see the
old value of `x', even though the dialog is closed.

Here's how it happens, where "->" means an event is handled:

  (send d show #t)
     yields -> handle some event...
            -> handle another event...
            -> prepare to blink the caret
                 yields -> handle "Ok" click
                              (send d show #f)
                        -> handle "Use X" click     <<< !!!
               blink the caret
     set! x to returned v

The solution in 203.9 is to eliminate the `yield' in the caret-blink
event handler (and other such handlers).

The more general lesson is that you shouldn't use `yield' without
either opening a dialog (hence constraining the set of events that can
be handled) or knowing the context of the `yield'.

Matthew



Posted on the users mailing list.