As suggested by Jan Dvořák.
The event created by `replace-evt` is a kind of event-gated
version of `guard-evt`. In particular,
(guard-evt thunk)
could be expressed as
(replace-evt always-evt (lambda (_) (thunk)))
Use `replace-evt` as a shortcut for the case when you want to
synchronize on either A or C, but you need to wait for B to get C.
You could wait on A+B and then, if B is selected, wait on A+C;
wrapping B with `replace-evt` to generate C is a kind of shortcut that
is eaiser to write and avoids tear-down and re-setup of A.
The `replace-evt` constructor is more than a shortcut in the sense
that it builds the pattern A+B->A+C into `sync`, which enables
abstractions that need a B->C transition. So, `replace-evt` adds
expressiveness, but (perhap reassuringly) it does not add any new
rendezvous capability.
Naturally, the procedure given to `replace-evt` can produce
another `replace-evt`, and the event argument to
`replace-evt` could also be a `replace-evt`.
optional and add a contract that calls the 'draw' argument to make
sure it restores the dc state.
The call to the 'draw' function happens right when 'dc' is called and
it tests the property that 'draw' doesn't abuse the state only that
one time and only with x=0 and y=0. This seems likely to catch common
errors, however, since the mismanagement of the state is unlikely to
be related to the values of 'x' and 'y' and also unlikely to depend on
the timing of the the call (i.e., if it happens at all, it probably
always happens).
Another way we could enforce this contract would be to wrap the `draw'
argument so that each time it is called, we grab the state of the dc
and compare it to afterwards. The current strategy is less expensive
and also catches errors earlier (in the case of slidehow specifically,
we'll get the errors during the startup of the presentation instead of
when we try to render a slide (in the middle of the presentation,
typically)).
This change slows down calls to 'dc'. For example, this program:
#lang racket/gui
(require pict)
(define brush (send the-brush-list find-or-create-brush "black" 'solid))
(define (circ w h)
(dc (λ (dc dx dy)
(define orig-pen (send dc get-pen))
(define orig-brush (send dc get-brush))
(send dc set-pen "black" 1 'transparent)
(send dc set-brush brush)
(send dc draw-ellipse dx dy w h)
(send dc set-pen orig-pen)
(send dc set-brush orig-brush))
w h))
(void
(time
(for/fold ([b (blank)]) ([i (in-range 10000)])
(vc-append (circ (random 1000)
(random 1000))
b))))
goes from
cpu time: 16 real time: 17 gc time: 0
to
cpu time: 2166 real time: 2172 gc time: 224
on my machine.
Still, that cost, when measured in a per-call-to-dc way is
only .21 msecs, which seems reasonable given the pain of
tracking down the kinds of bugs that this contract
helps detect.
Include documentation that was part of the installer, because a package catalog
may want to show documentation links independent of whether the package
was included in a distribution.
The `tt` and `racketfont` functions treat their arguments strangely,
applying styles only to immediate strings and symbols.
Add `racketplainfont`, which is a non-strange version of `racketfont`.
The `at-exp` reader now delays picking up the current readtable until
`read`/`read-syntax` is called. Also, it uses the new 'dynamic configuration
of readers for the command and datum parts of an @-form, which delays a
decision of readtable on each part until reading the part.
Thanks to Alexander Knauth for sorting out pieces of the puzzle.
A size expression N+M for a literal integer N was parsed as just N.
Report an error when that case happens (since it's difficult to
handle) instead of mishandling it.
Merge to v6.1
This bug (in xform, really) appears to be responsible for recent "JIT
buffer overflow" crashes. It could also cause other memory-corruption
crashes.
The bug could be triggered by any program that uses operators like
`+`, `<`, and `bitwise-ior` on more than 2 and less than 6 operands
(which is a lot of programs), but only if a certain allocation and
GC pattern happens at just the right time (which is why a crash was
relatively rare).
Merge to v6.1
in the code that decides what to put in DrRacket's pop up
menu that opens file dialogs for the subdirectories of
the place where the current file is saved
closes PR 14634
The issue was that when `values` was used with a single input, that input was being forced too early.
Now code such as:
(! (letrec-values ([(x) (values (list y))] [(y) (values 1)]) (car x)) )
should produce 1 instead of #<undefined>.
Some simple test cases were also added.
The `vector->values` function set up multiple return values
badly in the case that the given vector is chaperoned.
The problem could lead to NULL as results for `vector->values`.
Merge to v6.1
Applying to a large number of arguments once causes the run-time
system to maintain a too-large buffer for managing tail calls in
the future. Decay the buffer size as it is reallocated.
Gemeralize Gustavo's change so that immediately-used right-hand sides
can be moved into any position that (like the binding context) enforces
single-valuedness --- for arbitrary right-hand expressions.