这一节介绍怎样改变 MzScheme 的 REPL (Read Eval Prit Loop)。
(current-prompt-read [proc])
可以使用 current-prompt-read 来改变读取命令的函数。这个函数 必须是一个不需要参数的函数,它负责显示提示符,读取输入,然后 把输入做成一个 syntax 对象返回给解释器。
如果不带参数就返回当前的 Read 函数。
通常读取输入可以使用 read-syntax 函数来帮助。比如,下面这个 例子,把提示符换成了 "wangyin:",而输入方式不变。
(current-prompt-read (lambda () (display "wangyin:") (read-syntax (current-input-port))))
(current-eval [proc])
使用 current-eval 可以把当前的解释器换成另一个函数。这个函数 接受一个 syntax 对象,返回它的值。
proc 接受一个对象,然后显示它。
(current-print [proc])
可以在这里加入解释器退出时的善后处理。比如:
(define e1 (exit-handler)) (exit-handler (lambda (x) (display "exit")(newline) (e1 #t)))
(thread thunk)
thunk 是一个不需要参数的函数,返回一个线程对象。
(thread (lambda () (sleep 2) (display 7) (newline))) ; => athread descriptor
(thread-suspend thread) (thread-resume thread) (kill-thread thread)
使用
(thread/suspend-to-kill thunk)
生成的线程是 kill 不死的。如果它被 kill,就会 suspend.
(thread-wait thread) ; 等待一个线程终止 (thread-dead-waitable thread) ; 制造一个 waitable,当线程完成时才 unblock (thread-resume-waitable thread) ; 制造一个 waitable,当线程恢复运行时才 unblock (thread-suspend-waitable thread) ; 制造一个 waitable,当线程被停止时才 unblock
sleep 函数使线程至少睡眠 x 秒。如果不提供 x,缺省为 0,也就 是把处理器让给其它线程。
(sleep [x])
(make-semaphore [init-k]) (semaphore? v) (semaphore-post sema) ;增加信号量 (semaphore-wait sema) ;阻塞直到信号量不为0,然后减少信号量,返回 void. (semaphore-try-wait? sema) ;就像 semaphore-wait,只是从来不阻塞。 (make-semaphore-peek sema) ;返回一个 waitable, 当 sema unblock 时就 unblock.
通道是连接线程的管道。一些线程可以往通道写东西,另一些线程把 通道里的东西读出来。如果读不到东西,线程就会阻塞。或者使用了 channel-try-get 就不会阻塞而返回 #f.
(make-channel) (channel? v) (channel-get channel) (channel-try-get channel) (channel-put channel v) (make-channel-put-waitable channel v)
使用 object-wait-multiple 可以同时等待多个同步对象。这有点像 C 函数 select。它的语法是:
(object-wait-multiple timeout waitable ...)
可以设置一个时间 timeout 作为超时时间。如果在 timeout 之内有 某个对象得到了输入,那么返回这个输入。如果没有对象能得到输入 那么返回 #f。
timeout 如果是 0, 那就马上返回,这相当于轮询。timeout 如果 是 #f 就永远不超时。
举一个例子:
(define th1 (thread (lambda () (let ((ch (object-wait-multiple 5 ch1))) (if ch (begin (display ch) (newline)) (display "No input\n")))))) (channel-put ch1 "haha")
如果在第一个 sexp 执行之后 5 秒之内执行第了第二个。那么线程 th1 就会显示 "haha",否则显示 "No input"。
(current-thread) (thread-running? thread) (thread-dead? thread) (thread? v) (break-thread thread)
可以使用 errortrace:
(require (lib "errortrace.ss" "errortrace"))
有这些函数可用:
(instrumenting-enabled) (profiling-enabled) (profiling-enabled #t) (profiling-record-enabled) (profile-paths-enabled #t) (get-profile-results) (output-profile-results #f #t) (execute-counts-enabled #t) (get-execute-counts)
到 http://sourceforge.net/projects/schematics/ 下载 srfi. 然后使用
(require (lib "N.ss" "srfi"))
就行了。
可以使用 Swindle(http://www.barzilay.org/Swindle/).
然后在 MzScheme 里:
(require (lib "swindle.ss" "swindle"))
就可以使用 Tiny-CLOS 了。
Swindle 不止提供 CLOS。还有很多强大的功能。比如: