let-method. In general, current Sagittarius adds generic method globally even whenever it's defined. So if the
loadloads a script with
define-methodthen the generic method is added to the global binding. Thus the effect is globally done even though it's loaded in child thread.
This is not a good behaviour I believe so I've changed it. Current head has following behaviour;
- If a method is defined in main thread - adds method globally
- If a method is defined during importing a library - ditto
- If a method is defined in child thread and not library importing period - adds thread local storage.
- Generic functions are inherited from parent thread but child thread can't contaminate parent.
compute-methods. There are slight change of slot accessor of generic function as well but this is trivial.
The change of
compute-methodsis not a big one. It now just considers generic methods of current thread. Like I mentioned above, generic methods are located two places, one is generic function's methods slot and the other one is thread local storage. Thus
compute-methodsneeds to get all methods both the slot and storage.
remove-methodare a bit more tricky. First it needs to detect whether or not it's running on main thread or during library importing period. If the definition is executed on that term then it adds the methods to generic function's slot. If not, then it adds thread local storage with some more information. (currently maximum required argument number.)
Now following piece of code runs as I expected.
(import (rnrs) (clos user) (srfi :1) (srfi :18) (srfi :26)) (define-generic local) (define (thunk) (thread-sleep! 1) (let-method ((local (a b c) (print a b c))) (thread-sleep! 1) (local 1 2 3)) (local "a" "b" "c")) (let ((ts (map thread-start! (map (cut make-thread thunk <>) (iota 10))))) (for-each thread-join! ts)) ;; may prints some of the value ;; then raises an error.The solution itself might be a bit ugly (treating generic function specially) but behaving properly is more important.