fun remove(elt, lst): cases(List) lst: | empty => empty | link(f, r) => if f <=> elt: r else: link(f, remove(elt, r)) end end end data Box: | box(ref v) end set-box = lam(b, v): b!{v:v} end get-box = lam(b): b!v end cur-thread-index = box(-1) cur-thread-stacks = box([list:]) cur-main-stack = box("dummy") fun start(t): call-cc(lam(main-stack): set-box(cur-main-stack, main-stack) tb = box("dummy") set-box(cur-thread-stacks, link(tb, get-box(cur-thread-stacks))) set-box(cur-thread-index, 0) result = t() thread-to-join = tb set-box(cur-thread-stacks, remove(thread-to-join, get-box(cur-thread-stacks))) get-box(cur-main-stack)(result) end) end fun pause(v): call-cc(lam(thread-stack): thread-list = get-box(cur-thread-stacks) tb = thread-list.get(get-box(cur-thread-index)) set-box(tb, thread-stack) get-box(cur-main-stack)(v) end) end fun restart(): call-cc(lam(main-stack): thread-list = get-box(cur-thread-stacks) if thread-list.length() == 0: "done" else: thread-to-rs = random(thread-list.length()) cur-thread-stack = thread-list.get(thread-to-rs) set-box(cur-thread-index, thread-to-rs) set-box(cur-main-stack, main-stack) get-box(cur-thread-stack)(nothing) end end) end fun thread1(): for map(i from range(0, 5)): pause(i) i end end fun thread2(): for map(i from range(10, 15)): pause(i) i end end