Closed fuxoft closed 11 months ago
No real answers, but I found that changing the end of the code to be [1]:
(def wait
(do
(def render-fun
(do
(def cor (:renderer-coroutine track1))
(fn [] (resume cor))))
(fn []
(repeat 600
(render-fun)))))
(repeat 6
(:note-on track1 60)
(wait))
yields the output:
_00000y
_00000z
_00000A
_00000B
_00000B
_00000C
So it looks like gensym
values are not constant the whole time.
Neither does the repetition seem to be from some point onwards.
$ janet
Janet 1.31.0-7b4c3bdb linux/x64/gcc
Script below for archival purposes [2]
(defn generator [] (def factory @{}) (def generator-fun (fn [output] (ev/give output :stream-start) (ev/give output 0) (ev/give output :stream-end))) (put factory :generate (fn [self batch] (def stream-out (ev/chan 1)) (def generator (ev/chan)) (ev/spawn (generator-fun generator)) (assert (= :stream-start (ev/take generator))) (ev/give stream-out (ev/take generator)) (assert (= :stream-end (ev/take generator))) stream-out)) (put factory :new (fn [&] (def object (thaw factory)) object)) factory) (def sinetone (generator)) (def track1 @{:generators @{} :note-on (fn [self note-num] (print (gensym)) (def generator (:new sinetone)) (put (self :generators) :just-one generator)) :renderer-coroutine (fn [self] (coro (forever (map (fn [gen] (:generate gen 1)) (self :generators)) (yield 0))))}) (def wait (do (def render-fun (do (def cor (:renderer-coroutine track1)) (fn [] (resume cor)))) (fn [] (repeat 600 (render-fun))))) (repeat 6 (:note-on track1 60) (wait))
[1] So the 10000
has been replaced with 600
and the forever
loop has been replaced with a repeat 6
loop.
[2] Formatting somehow gets messed up when rendered...looks ok raw...how strange.
You have discovered the garbage collector cleaning up the old symbols :). If you keep references to the old symbols around in the program, our turn off gc via (gcsetinterval 0xFFFFFFFF)
, the issue disappears. Specifically, you will find you can't have gensym generate a symbol that is currently interned. When a symbol is garbage collected, it is uninterned. Sort of like how when you allocate memory, then free the memory, later allocations could return the same pointer.
During my Janet experiments with coroutines, fibers and channels, I found out that
gensym
does not always generate unique values (even when my script does not use threads).I managed to isolate the problem in this 50-line script.
When you run it, it endlessly prints
(gensym)
values (at line 30), which are constant:When I attempt to simplify the code further, the printed values become unique again.
When I change the constant
10000
at line 46 to10
, the printed values also become unique.I am using
Janet 1.31.0-c31314be linux/x64/gcc
.