svn: r143

This commit is contained in:
Jono Spiro 2004-08-05 06:16:33 +00:00
parent a2c214098c
commit 37099e292b
5 changed files with 476 additions and 187 deletions

View File

@ -0,0 +1,4 @@
Add this to the demos section of the main doc.
demos/djikstra/dijkstra-test.ss - debugs a buggy implementation of
Dijkstra's algorithm

View File

@ -0,0 +1,162 @@
(module heap mzscheme
(require (lib "etc.ss")
"base-gm.ss"
"dv.ss")
(provide make-heap heap-empty? heap-size heap-insert heap-pop
heap-peak heap-remove heap-find
heap-contains heap-resort heap-tostring)
(define-struct t (sorter equality data))
;; sorter: elements which have the most trueness according to
;; the sorter pop out first
(define (make-heap sorter equality)
(let ((data (dv:make 5)))
(dv:append data 0)
(make-t sorter equality data)))
(define (heap-size heap)
(- (dv:length (t-data heap)) 1))
(define (heap-empty? heap)
(= (heap-size heap) 0))
(define (heap-last heap)
(- (dv:length (t-data heap)) 1))
(define (heap-parent i)
(floor (/ i 2)))
(define (heap-left i) (* i 2))
(define (heap-right i) (+ 1 (* i 2)))
(define (heap-has-right heap i)
(<= (heap-right i) (heap-last heap)))
(define (heap-has-left heap i)
(<= (heap-left i) (heap-last heap)))
(define (heap-insert heap item)
(let* ((sorter (t-sorter heap))
(data (t-data heap)))
(dv:append data item)
(let ((d (let loop ((prev (heap-last heap))
(current (heap-parent (heap-last heap))))
(cond ((= current 0) prev)
((sorter item (dv:ref data current))
(dv:set! data prev (dv:ref data current))
(loop current (heap-parent current)))
(#t prev)))))
(dv:set! data d item))))
(define (heap-peak heap)
(if (= (heap-size heap) 0) (error "heap-peak: empty")
(dv:ref (t-data heap) 1)))
(define (heap-pop heap)
(if (= (heap-size heap) 0) (error "heap-pop: empty")
(let ([result (dv:ref (t-data heap) 1)])
(heap-remove-pos heap 1)
result)))
(define (heap-remove-pos heap pos)
(let* ((data (t-data heap))
(sorter (t-sorter heap)))
(cond ((= 0 (heap-size heap)) (error "heap: removing from empty"))
((= pos (heap-last heap)) (dv:remove-last data))
(#t (let ((item (dv:ref data (heap-last heap))))
(dv:remove-last data)
(let loop ((current pos))
(dv:set! data current item)
(let* ((left (heap-left current))
(right (heap-right current))
(best-1 (if (and (heap-has-left heap current)
(sorter (dv:ref data left) item))
left current))
(best-2 (if (and (heap-has-right heap current)
(sorter (dv:ref data right)
(dv:ref data best-1)))
right best-1)))
(if (not (= best-2 current))
(begin (dv:set! data current (dv:ref data best-2))
(loop best-2))))))))))
;; return false if the object is not found
(define (heap-remove heap item)
(let ((pos (heap-find heap item)))
(if (not pos) false
(begin (heap-remove-pos heap pos) true))))
(define (heap-contains heap item)
(if (heap-find heap item) true false))
(define (heap-find heap item)
(let ((data (t-data heap))
(equality (t-equality heap))
(sorter (t-sorter heap)))
(let loop ((current 1))
(let ((current-item (dv:ref data current)))
(cond ((equality item current-item) current)
((sorter item current-item) #f)
(#t (or (and (heap-has-left heap current)
(not (sorter item (dv:ref data (heap-left current))))
(loop (heap-left current)))
(and (heap-has-right heap current)
(not (sorter item (dv:ref data (heap-right current))))
(loop (heap-right current))))))))))
(define (heap-resort heap item)
(heap-remove heap item)
(heap-insert heap item))
(define (heap-tostring heap . fns)
(let* ((data (t-data heap))
(data-list (let loop ((i 1))
(if (> i (heap-last heap)) empty
(cons (dv:ref data i) (loop (+ i 1)))))))
(string-append "heap: sz " (number->string (heap-size heap)) ", "
(apply to-string (cons data-list fns)))))
(define (test)
(define f (make-heap > eq?))
(define d (t-data f))
(heap-insert f 99)
(debug "A " d)
(heap-remove-pos f 1)
(debug "B " d)
(for-each (lambda (x) (heap-insert f x)) '(1 2 3 4 5 6 7 8 9 10 11 12 13 14))
(debug "C " d)
(heap-remove f 10) (debug " " d)
(heap-remove f 5) (debug " " d)
(heap-remove f 8) (debug " " d)
(heap-remove f 13) (debug " " d)
(debug (heap-contains f 11))
(debug (heap-contains f 123))
(heap-pop f)
(heap-pop f)
(heap-pop f)
(heap-pop f) (debug " " d)
(debug (heap-contains f 11))
(debug (heap-contains f 4))
(debug (heap-tostring f))
(heap-remove f 2)
(debug (heap-tostring f))
(heap-remove f 3)
(debug (heap-tostring f))
)
)

View File

@ -15,16 +15,18 @@
every time the code at line 3, column 4, is reached.
|#
(printf-b "runtime elapsed: ~a" (process:runtime/seconds radar-program))
;; Prints how long the program has been running, in seconds
(printf-b "current speed: ~a" (hold values-of-speed))
;; Prints the current speed being recorded
(printf-b "last ten speeds: ~a" (history-b 10 values-of-speed))
;; prints a FIFO list of the last 10 speeds seen
(map-e (lambda (a-speed) (when (>= a-speed 55) (pause radar-program)))
values-of-speed)
;; pauses the program for inspection when a speed is too fast
;; produces a list of shapes to draw/animate, taking in a number for speed
(define (make-speed-gauge speed)
(let ([center (make-posn 200 200)])

View File

@ -62,4 +62,4 @@
(start/resume p)
;; Start the process for montecarlo.ss
;; Start the process for montecarlo.ss

View File

@ -10,12 +10,16 @@ also let you interact with a paused program and
inspect its state.
MzTake scripts are written in the FrTime programming
language, which is bundled with DrScheme. FrTime is
similar to Scheme with the additions of time-varying
values and real-time event streams. With these two
constructs, it is possible to respond to outside
events concisely (without using callbacks). Consider
the following MzTake script:
language, which is bundled with DrScheme. The purpose of
FrTime is to support the implementation of reactive systems
in a functional style. The key abstraction it adds is a type
of value called a 'signal', which can change over time. FrTime
infers dataflow dependencies between signals and automatically
recomputes them when necessary.
With siglans (implemented as "event streams" and "behaviors"),
it is possible to respond to outside events concisely (without
using callbacks). Consider the following MzTake script:
(debug-process radar-program
("highway.ss" [values-of-speed 3 4 bind 'speed]))
@ -24,7 +28,7 @@ the following MzTake script:
This code actually executes a target module in the file
"highway.ss" after installing a _trace point_ (also known
as a _watch point_) just before Scheme syntax on the third
as a _watch point_) just before the Scheme syntax on the third
line (at the fourth column) of "highway.ss". "values-of-speed"
is is a FrTime event stream that always contains the *current*
value (and potentially every past value) of the variable named
@ -33,21 +37,21 @@ value (and potentially every past value) of the variable named
"printf-b" works like Scheme's printf" function, consuming a
format-string and fill-values, printing the result in
DrScheme's interaction pane. Whereas "printf" accumulates
outdated text on the screen, "printf-b" will constantly replace
the old text with a newer one if any of the fill-values change.
In this invocation, it prints the current speed to screen,
throughout the execution of "highway.ss".
outdated text on the screen, "printf-b" will replace old text
with updated text if any of the fill-values change. In this
invocation, it prints the current speed to screen, throughout
the execution of "highway.ss".
MzTake scripts are also powerful tools for building external
test suites. Whereas typical test cases can only assert that
test suites. Whereas typical test cases may only assert that
the result of a computation is correct, MzTake scripts
can dynamically break open an execution, record inner state,
and *compute* with it. This allows you to confirm that the
intermediate steps which lead to a correct answer were
also correct. In the example below, we use a version of map
that works over events in an event stream. We assert that
all recorded speeds are less than 55, otherwise we raise
an exception:
that operates over events in an event stream, instead of
elements in a list. We assert that all recorded speeds are
less than 55, otherwise we raise an exception:
(map-e (lambda (a-speed)
(when (>= a-speed 55) (raise 'too-fast!!)))
@ -56,108 +60,217 @@ an exception:
Of course, like most test suites, this only tells you
something went wrong. Perhaps knowing the last ten speeds that
led to this would prove useful. You could "printf" the value
onto a new line each time, but too many of these updates and
the screen quickly starts to fill up with useless data -- we are
only interested in the last ten speeds, afterall. Instead, why
don't we "pause" the program when this happens, and interactively
review only the ten recorded speeds we care about:
onto a new line each time, but after ten updates the screen
is already starting to fill up with useless data -- we are
only interested in the last ten speeds, afterall.
One possible solution:
(printf-b "last ten speeds: ~a" (history-b 10 values-of-speed))
(map-e (lambda (a-speed)
(when (>= a-speed 55) (pause radar-program)))(semaphore-wait run-semaphore)
(when (>= a-speed 55) (raise 'too-fast!!)))
values-of-speed)
"history-b" consumes a number and an event stream
("values-of-speed") and returns a FrTime behavior containing
a FIFO ordered list of the last ten values
seen emitted on that event stream. In this case, it contains
the ten most recent "speed"s seen during execution. DrScheme
displays this list in the interaction pane, where you can use
it to confirm (or refute!) that your program is working correctly.
a FIFO ordered list of the last ten values emitted on that
event stream. In this case, a list of the ten most recent
"speed"s seen during execution, up until the exception is raised.
This is an improvement, though, we still can't *use* that list
to see what led to the exception -- we just display them.
One possible solution:
Finally, FrTime provides a rich animation
library. Combined with the MzTake debugger, it takes
only a few lines to animate your algorithms and see
them in action.
(define last-ten (history-b 10 values-of-speed))
(printf-b "last ten speeds: ~a" last-ten)
(map-e (lambda (a-speed)
(when (>= a-speed 55) (pause radar-program)))
values-of-speed)
MzTake allows you to "pause" a target program anytime during
execution. Once paused, it becomes trivial to interactively
explore and compute with script variables (such as "last-ten")
in the interaction pane. Once satisfied, you can easily resume
execution by typing "(start/resume radar-program)", or end it
with "(kill radar-program)".
Finally, FrTime provides a rich animation library. Combined
with the MzTake debugger, it takes only a few lines to animate
your algorithms and see them in action, easily letting you
confirm (or refute!) that they are working correctly.
(display-shapes (make-speed-gauge (hold values-of-speed)))
============================================================
Running MzTake
Installing MzTake
MzTake is a DrScheme tool. DrScheme will look for
MzTake in the "collects" directory and load it
automatically, if found. Make sure you select the
"MzTake" language from DrScheme's language dialog, in
the "Experimental Languages" section. If your language
dialog does not contain "MzTake", you can install it by
downloading the ".PLT" distribution file, then
selecting "Install .PLT File..." from the "File" menu
in DrScheme.
http://www.cs.brown.edu/~gmarceau/files/mztake.PLT
MzTake is a DrScheme tool distributed as a self-installing
".PLT" file from the PLaneT Package Reposityory.
http://planet.plt-scheme.org/
============================================================
Demos
The demos subdirectories contains examples for
different uses of MzTake. You should be able to run
them in DrScheme by switching to the MzTake language
and clicking the "Run" button.
You can find demos of a few different uses of MzTake (including
the "highway.ss" example) in the following directories:
demos/highway/highway-test.ss - a small MzTake example, used above
On Linux:
$PLTHOME/collects/mztake/demos/
On Windows (typically):
c:\Program Files\PLT\collects\mztake\demos\
demos/sine/sine-test.ss - plots values extracted from the
You should be able to run them in DrScheme by switching to the
"MzTake" language from the "Experimental Languages" section
of DrScheme's language dialog, and then selecting "Run"
(or "Execute") from the DrScheme tool bar.
./demos/highway/highway-test.ss - a small MzTake example, shown above
./demos/sine/sine-test.ss - plots values extracted from the
running program
demos/djikstra/dijkstra-test.ss - debugs a buggy implementation of
Dijkstra's algorithm
demos/montecarlo/montecarlo-test.ss - visualizes Monte Carlo integration
./demos/montecarlo/montecarlo-test.ss - visualizes the Monte Carlo integration
used to derive the value of pi
demos/random/random-Xs-test.ss - tests the quality of Scheme's random
./demos/random/random-Xs-test.ss - tests the quality of Scheme's random
number generator with a histogram
./demos/misc/exception-test.ss - demonstrates how MzTake catches exceptions
./demos/misc/first-class-test.ss - demonstrates how you can add multiple traces
to the same variable in a file to 'record' its
evolution, and how you can trace first-class
functions, such as those passed to map.
============================================================
Functions
In order to use MzTake, you will first have to learn
the FrTime language. FrTime's own "doc.txt" explains
how to use time-varying values and event streams, and
also describes the many functions that operate on them.
The demos demonstrate many ways to debug with MzTake using
FrTime, even if you are not very familiar with the language.
That said, in order to become more proficient in using MzTake,
you will want to learn more about the FrTime language.
You can refer to FrTime's own documentation by searching for
"frtime" in DrScheme's Help window. It explains how to use
time-varying behaviors and event streams in greater depth, and
also describes the many useful functions FrTime provides to work
with them.
============================================================
_Debugging with MzTake_
The model of the debugger is as follows:
* A single debugging script file contains all the MzTake
processes, traces, bindings, animations, and other FrTime
code fragments that do the debugging and program monitoring.
* This script file is run in the MzTake language in DrScheme.
Interaction and textual print-outs are provided in the
interaction pane.
* A MzTake process is like an operating system that runs a bunch of
programs, installs hooks into them to monitor their execution,
and provides FrTime with these hooks to do computations.
* Each MzTake process is independent of the other MzTake processes.
One will not affect the other, only their traces can interact in
the script.
* A MzTake process accepts a number of target-files as "clients" to
debug and monitor. Each client should contain a module program,
of the form:
(module mod-nam mzscheme
(... module body ...))
MzTake does not support debugging anything other than modules.
* The first client defined for each process is *always* the main module.
That is, "start/resume" runs the *first* client module (in the same way
that you run it in DrScheme in the "module..." language), assuming there
will be side-effects that start the debugging.
The rest of the files traced in a mztake-process are typically
modules used *by* the main-module, allowing you to see
what is going on deeper than the main module. For example:
(mztake-process p1
("my-stack-tests.ss")
((lib "my-stack.ss" "my-stack") [s-push-p1 3 29 bind 'insert-value]
[s-pop-p1 10 16 bind 'return-value]))
"my-stack-tests.ss" uses functions from "my-stack.ss". You want to
make sure "my-stack.ss" is working properly in the context of
running the module in "my-stack-tests.ss" for side-effects.
* The same file can be traced differently in different processes, even with
different main clients using them:
(mztake-process p2
("more-my-stack-tests.ss")
((lib "my-stack.ss" "my-stack") [s-clear-p2 22 8 break]))
This installs a break-trace at the function entry point for (clear).
Every time (clear) gets called, s-clear-p2 will get a ping of "#t".
* Once all the processes are defined, (start/resume ...) is called on
each starting their execution.
* All the variables bound ("mztake-process"es, "bind"s, "break"s),
from all the different "mztake-process"es, are collected together by
MzTake so they can be all be computed with using FrTime functions
and idioms.
* Processes have certain properties and predicates which you can get,
such as runtime (in seconds or milliseconds), exceptions that are thrown,
and whether the process exited yet. See "process:runtime/(milli)seconds",
"process:exceptions", and "process:exited?".
* Lastly, proceses can be started, paused, resumed, and terminated.
See "start/resume", "pause", "kill", "kill-all".
============================================================
MzTake itself defines the following functions:
_Installing Trace Points_
Currently, MzTake offers two types of traces: "break" and "bind".
Breaks are event streams that get a "#t" event ping every time the
target program reaches the trace point. Binds are event streams that
ping the value of one or more variables when the trace point is reached.
> (mztake-process process-name
[target-filename trace-clause ...] ...)
where trace-clause is either
<1> [trace-name line-number column-number break]
<2> [trace-name line-number column-number bind 'variable-name]
or
Where trace-clause is one of the following:
<1> [trace-name line-number column-number break]
<2> [trace-name line-number column-number bind 'variable-name]
<3> [trace-name line-number column-number bind '(variable-name ...)]
mztake-process installs trace points in one or many
files, as indicated by the trace-clauses. The
target-filename can be any file specification
accepted by the standard "require" syntax for
modules:
"mztake-process" defines the variable process-name,
whose value is a MzTake process object. That object
can be passed to functions such as "start/resume", "kill",
and "process:runtime/milliseconds", documented in the next
section.
"mztake-process" installs trace points in one or many files,
as indicated by the trace-clauses. The target-filename can
be any file specification accepted by the standard "require"
syntax for modules:
* Absolute path:
(mztake-process p [(file "/home/me/test.ss") [brk 10 7 break]])
@ -168,25 +281,6 @@ _Installing Trace Points_
* Library path:
(mztake-process p [(lib “test.ss” “file-lib”) [brk 10 7 break]])
Each target-filename should define a module (MzTake
does not support debugging top-level
definitions). mztake-process defines the variable
process-name, whose value is a MzTake process
object. That object can be passed to the process
functions documented in the next section. In
particular, start/resume is a function that consumes
a MzTake process and starts its execution and debugging.
That is, start/resume calls a "require" on the *first* of
the target-files (the main-module) given in the call
to mztake-process, assuming there will be side-effects
that run the program in the main-module.
The rest of the files for a mztake-process are typically
modules used *by* the main-module, allowing you to see
what is going on deeper than the main module. For instance,
you want to debug my-vector.ss in the context of
my-vector-test-cases.ss using functions from my-vector.ss.
For each trace-clause in the call to mztake-process,
the trace-name is a variable name bound at the
top-level, whose value is a FrTime event
@ -194,35 +288,41 @@ _Installing Trace Points_
reaches the given line-number and column[*], the
debugger emits an event on that stream. The value of
that event depends on which of the three kinds of
trace-clause was used, as follow:
trace-clause was used, as follows:
<1> the value of the event is #t (a "break" trace)
<1> The value of the event is #t (a "break" trace).
<2> the value of the event is the value of variable-name,
in the target program, at the location of the
trace point (a "bind" trace).
<2> The value of the event is the value of variable-name,
in the target program, at the location of the
trace point (a "bind" trace).
<3> the value of the event is a list containing one
element for each variable name given. The value
of each element is taken from the variable of
that name in the target (as in <2>)
<3> The value of the event is a list containing one
element for each variable name given. The value
of each element is taken from the variable of
that name in the target (as in <2>).
Trace points do not themselves pause the
program. Unless a MzTake process is suspended using
the pause function (below), execution resumes after
the MzTake script processed the event.
[*] All valid syntax begins to the left of "(", "["
or the before the first character of a symbol/name.
See Known Issues for more information.
[*] Valid locations to add traces to are almost
always one character to the left of open-parentheses, "(",
open-square-braces, "[", or to the left of the first
character of a symbol/name ("let" is a special exception,
see Known Issues for more information on tracing "let"):
(code [more-code ...] ...)
^^ ^^ ^
[*] To obtain accurate line/column information when
setting up trace points, make sure you turn off
DrScheme's "Wrap Text" feature under the "Edit"
menu. Alternatively, you can click MzTake's
"Syntax Location" button, on the toolbar, to
obtain the line and column number for the
position under the cursor.
menu. Alternatively, you can position your cursor
at the location where you want to add a trace,
and click MzTake's "Syntax Location" button on the
main DrScheme toolbar. A message-box will tell
the correct line and column numbers to use.
_Operations on MzTake Processes_
@ -240,9 +340,9 @@ can be used interactively in the interactions pane.
Script statements are executed top-down, sequentially.
In general, you want to call start/resume at the end of
the script, or in the interactions pane after you
started the script -- in either case, after you have done
all processing. Otherwise your script may miss events
from the beginning of the evaluation.
start running the script. Otherwise, a race condition may
develop, and your script may miss events from the beginning
of the execution.
> (pause process)
@ -255,13 +355,14 @@ can be used interactively in the interactions pane.
it used -- you cannot start/resume after a kill.
Closing a FrTime animation/graphics window will *not*
kill a running program, you must kill it by hand in the
interaction pane.
kill a running MzTake process. If it does not terminate
on its own, you may kill it with "(kill p-name)" or
"(kill-all)" in the interaction pane.
> (kill-all)
kill-all kills all the processes currently running
under MzTake - use this when it seems a process is
under MzTake -- use this when it seems a process is
out of control and needs to be stopped immediately.
Has the same effect of calling kill on each process
you defined and start/resume'd in the script.
@ -281,7 +382,7 @@ can be used interactively in the interactions pane.
> (process:runtime/milliseconds process)
Returns a FrTime time-varying value which count the
Returns a FrTime time-varying value which counts the
number of milliseconds elapsed in the execution of the
given process (not counting time spent suspended by
"pause"). Includes garbage-collection time.
@ -309,12 +410,12 @@ that are particularly useful when debugging.
Counts number of event pings on an eventstream,
regardless of whether the value changes or not
(used often with "break" traces).
(often used with "break" traces).
> (count-b b)
Counts number of times a behavior's value
updates/changes (used often with "bind" traces).
updates/changes (often used with "bind" traces).
> (sequence-match? seq evs)
@ -331,66 +432,58 @@ that are particularly useful when debugging.
Known Issues
* This is rather subtle, but very important:
- You have a struct, my-struct, and a function, do-fun
(do-fun takes a my-struct) in prog.ss.
* In general, you should not "require" or use any methods
in your MzTake script that were defined in any of the files
you are putting bind-traces on:
- You are debugging the same prog.ss, and add a trace that
binds to the latest my-struct in some test cases at the
end of prog.ss.
ORIGINAL FILE:
(define (my-fun some-struct) ...)
- In the script, you want to use do-fun on the the binding,
so you (require "my-prog.ss") at the top of the script.
MZTAKE SCRIPT:
(require "original-file.ss")
(mztake-process p ("original-file.ss" [val 10 12 bind 'my-struct]))
(my-fun (hold val))
- When you try to run this, you get an error that there are
conflicting structs called my-struct.
- This is a known problem, and currently there is no solution.
If this is an issue, we recommend performing the operation
with do-fun within the test cases and binding to the result,
or putting traces into do-fun itself, to watch it work.
- Technical reason:
The debugger executes code in a different (protected)
namespace than the script is executed in. So even though
*you* know the structs are the same, Scheme plays it safe
and says they are different, because though they have the
same format, they come from two different namespaces.
Sometimes this causes unusual errors. These problems usually only
show up if you are binding to structs (defined in the same file) and
passing those bindings to functions (defined in the same file).
You have been warned.
* The break button will *not* kill runaway client processes.
You must type (kill process-name) or (kill-all).
* Some valid join points, such as ("->"):
(define x 12)
(->let ->(->[>x (add1 x)]) x)
do *not* produce any values for the bindings, just an empty
eventstream -- particularly in "let"s.
Legal (recommended) bind points ("->"):
(define x 12)
->(let ([x ->(->add1 ->x)]) ->x)
* Some legal syntax locations, to add trace points to, do *not*
get triggered during execution, produce empty eventstreams.
These show up often in "let"s (the trace point being one line
above, and one character to the left of the carrot):
* Don't rely completely on bind to complain when you change
target code and your line/col offsets are out of date in a
script. Sometimes you may write a bunch of code and the
values will still be on valid syntax join points, albeit
not the correct ones, so you get the wrong values.
(define x 12)
(let ([x (add1 x)]) x)
^ ^^^
Recommended syntax locations to use for trace points:
(define x 12)
(let ([x (add1 x)]) x)
^ ^^ ^ ^
* Don't rely completely on MzTake to complain when you change
target code and your line/col locations in the script are out
of date. It will only raise an error if the locations are invalid.
* Order matters -- if you have more than one kind of trace at
an identical syntax location, the order events occur is
undefined.
- You may have a bind that when updated draws a graphic,
and a breakpoint, you may want the breakpoint to happen
before the bind happens.
an identical syntax location, the order that trace events get
updated is currently undefined.
- For now, the hack is to bind one at (“->”) ->(code...)
and the other at (code...->(more-code...))
immediately following at the next open parentheses.
Often, not much happens on the same line between two
valid trace points, so this gives you a definite order.
For now, the hack is to add traces as follows:
* Has not been tested for stability if the target is using
First trace: Second trace:
(code ... (more-code ...)) (code ... (more-code ...))
^ ^
Because of how Scheme is evaluated, usually nothing happens on
the same line of between two "open" parentheses as they are
traversed from left to right; this gives you a definite trace order.
* MzTake has not been tested for stability if the target is using
multiple threads. This only applies to threaded modules
*with* traces on them -- other 'require'd modules will work
as expected.
@ -404,6 +497,12 @@ Known Issues
actively, running. It might be useful to you, and will
be in the next release.
* On particularly fast computers, when running scripts with a
very high trace point density (traces are hit constantly,
potentially hundreds in a second, like in the Monte Carlo,
random-xs, and sine demos), the FrTime animation window may
appear unresponsive because of how fast it is redrawing.
============================================================
@ -415,41 +514,61 @@ Tips and Tricks
(see Known Issues).
For instance, if you trace 'x and 'y separately:
'x and 'y are up to date, then 'x updates, 'y is out of date,
then 'y updates, and both are up to date.
* First 'x and 'y are up-to-date.
* Then 'x updates and 'y is out-of-date.
* Then 'y updates, and both are up-to-date.
But code that draws x and y locations will draw in two places,
one for each update.
But code that draws using a position derived from x and y
will draw twice, in two locations, one for each update,
the second one being correct.
* You can trace the *same* file in different ways by using
multiple processes on the same file, under different
contexts, and compare results.
contexts, and compare results. For example, in
"demos/misc/first-class-test.ss":
(mztake-process p ("first-class.ss" [x-before-let 3 29 bind 'x]
[x-in-let 4 25 bind 'x]
[x-after-let 5 11 bind 'x]))
(... code omitted ...)
(start/resume p)
is functionally equivalent to:
(mztake-process p1 ("first-class.ss" [x-before-let 3 29 bind 'x]))
(mztake-process p2 ("first-class.ss" [x-in-let 4 25 bind 'x]))
(mztake-process p3 ("first-class.ss" [x-after-let 5 11 bind 'x]))
(... code omitted ...)
(start/resume p1) (start/resume p2) (start/resume p3)
All the variable bindings can still be used as they were before.
* Code such as (when (= num 100) (pause p)) pauses *after*
num reaches 100, the next time a trace point is hit.
However, the next point is not processed until you
"start/resume". See the random-xs demo.
"start/resume". See the random-xs demo.
* When you pause a mztake-process, you can play with
* When you pause a MzTake process, you can play with
current bindings and explore script code interactively.
You *may* dynamically evaluate/add FrTime code to do
things like pause or kill a mztake-process based on runtime,
etc. You can even define new mztake-processes dynamically
things like pause or kill a MzTake process based on runtime,
etc. You can even define new MzTake processes dynamically
and start/resume them, integrating and exploring the traces.
You cannot add or change existing traces dynamically.
* You can add trace points to first-class functions, and they
will send events from no matter where they are evaluated.
will send trace update from anywhere they are passed to and
evaluated.
* FrTime has two methods for drawing graphics. One runs in
constant time, and is fast, because it simply accumulates
pixels on the screen and doesn't redraw a list of objects.
See the Monte Carlo, or random-xs demo for this in action.
See the "Monte Carlo" or "random-xs" demos for this in action.
The other method is primarily for animations which need
redrawing because things move. It slows down pretty quickly
after you have more than 1000 objects to the shape list.
See the sine demo for this in action.
See the "sine" or "highway" demos for this in action.
For more information, refer to the FrTime documentation.
@ -458,17 +577,19 @@ Tips and Tricks
Authors and Thanks
You can reach the authors of MzTake at the following
email addresses. MzTake is an experimental debugger. It
should enable new debugging approaches that were not
possible (easily) before. We are eager to hear about
how you are using MzTake.
MzTake is an experimental debugger. It should enable new
debugging approaches that were not possible (easily) before.
Please send feedback to the PLT-Scheme mailing list:
http://www.plt-scheme.org/maillist/
Jonathan Spiro: jspiro@cs.brown.edu
Guillaume Marceau: gmarceau@cs.brown.edu
Shriram Krishnamurthi: sk@cs.brown.edu
We are eager to hear about how you are using MzTake!
Jonathan Spiro
Guillaume Marceau
Gregory Cooper
Shriram Krishnamurthi
Icons for MzTake come from the Gnome Project: Nautilus
Emblems, used under the GPL license.
---
Icons for MzTake come from the Gnome Project: Nautilus Emblems
These are provided under the GPL license.
http://jimmac.musichall.cz/ikony.php3