(import scheme (srfi 18) test) ;; (cond-expand (chicken-5 (import (chicken type) (only (chicken fixnum) fx= fx+ fx- fxmod) (only (chicken bitwise) integer-length) (only (chicken random) pseudo-random-integer) ) (define platform-random pseudo-random-integer) ) (chicken-4 (use (only chicken arithmetic-shift fx= fx+ fx- fxmod) (only extras random)) (define platform-random random) (define (integer-length n) (if (negative? n) (add1 (integer-length (abs n))) (do ( (i 1 (add1 i)) (n (arithmetic-shift n -1) (arithmetic-shift n -1)) ) ((zero? n) i) ) ) ) ) ) (: vector-shuffle! ((vector-of *) #!optional (procedure (fixnum) fixnum) -> void)) ; (define (vector-shuffle! vec #!optional (rnd platform-random)) (let ( (len (vector-length vec)) ) (define (swap-adj! i) (let ( (i+1 (fxmod (fx+ i 1) len)) (tmp (vector-ref vec i)) ) (vector-set! vec i (vector-ref vec i+1)) (vector-set! vec i+1 tmp) ) ) (do ((n (integer-length len) (fx- n 1))) ((fx= n 0)) (swap-adj! (rnd len)) ) ) ) (: shuffle ((list-of *) #!optional (procedure (fixnum) fixnum) -> (list-of *))) ; (define (shuffle ls #!optional (rnd platform-random)) (let ( (vec (list->vector ls)) ) (vector-shuffle! vec rnd) (vector->list vec) ) ) ;; (define (eof-object) #!eof) ;; SRFI 121 (define (make-coroutine-generator proc) (define return #f) (define resume #f) (define yield (lambda (v) (call/cc (lambda (r) (set! resume r) (return v))))) (lambda () (call/cc (lambda (cc) (set! return cc) (if resume (resume (if #f #f)) ; void? or yield again? (begin (proc yield) (set! resume (lambda (v) (return (eof-object)))) (return (eof-object)))))))) ;; srfi-154 (define (current-dynamic-extent) (call-with-current-continuation (lambda (return) (call-with-values (lambda () (call-with-current-continuation (lambda (c) (return (lambda (thunk) (call-with-current-continuation (lambda (k) (c k thunk)))))))) (lambda (k thunk) (call-with-values thunk k)))))) (define-syntax dynamic-lambda (syntax-rules () ((dynamic-lambda formals body ...) (let ((dynamic-extent (current-dynamic-extent))) (lambda formals (dynamic-extent (lambda () body ...))))))) ;; (define (count-to-coroutine lim #!optional (initial 0)) (make-coroutine-generator (lambda (yield) (let loop ((state initial)) (when (< state lim) (let ((value state)) (yield value) (loop (add1 state)) ) ) ) ) ) ) ;lambda vs dynamic-lambda (define (count-to-iteration lim #!optional (initial 0)) (dynamic-lambda (proc) (let loop ((state initial)) (when (< state lim) (let ((value state)) (proc value) (loop (add1 state)) ) ) ) ) ) ;; (define *run-in-threads* '()) (define-syntax run-in-thread (syntax-rules () ((run-in-thread body ...) (let ((th (make-thread (lambda () body ...)))) (set! *run-in-threads* (cons th *run-in-threads*)) ) ) ) ) (define (start-run-in-threads) (for-each thread-start! *run-in-threads*)) (define (join-run-in-threads) (for-each thread-join! *run-in-threads*)) (define (randomize-run-in-threads) (set! *run-in-threads* (shuffle *run-in-threads*))) (define (run-in-threads) (randomize-run-in-threads) (start-run-in-threads) ;(thread-yield!) (randomize-run-in-threads) (join-run-in-threads) ) ;; Test (define *statement* #<