To preface I love rolling my own, this is an exercise for learning purposes, but I want to take the information from this exercise eventually and implement some macros encapsulating the behaviors here. Thats why im using alot of let
because nothing is finalized yet and defines are too "heavy".
So you can use call/cc to implement all kinds of different cooperative threading constructs, and the model for a thread that im using is generally:
(let ((generic-thread
(lambda (cc)
(let loop ((cc cc))
(printf "doing stuff~N")
(loop (call/cc cc)))))) ;this is the magic, it calls the calling continuation
(let loop ((its 0) ;and then loops with the result of that
(cc generic-thread)) ;so when its resumed, it still has its new state
(if (< its 10)
(loop (+ its 1) (call/cc cc))))) ;just repeats the procedure for the demonstration
And so far this works really well actually.
So in my problem, I feel ive identified a few base cases, threads with an exit clause, those without them, and threads that cannot be resumed, or one shots (essentially just a function call, but I want to be consistent so it has to be in a "thread" and not just a function call)
(let ((spawn-thread
(lambda (it . args)
(call/cc (apply it args))))
(main
(lambda (label reps . sequence)
;for consistency, main is also a thread, but does not need to be
;this will take a number of repetitions, and a sequence of continuations
;to call, pushing the continuation returned from the top continuation in
;sequence to the end, and then calling the loop again
(lambda (cc)
(let loop ((sequence sequence) (state 0))
(printf "IN MAIN THREAD STATE: ~A~N---" state)
(if (< state reps) ;this is essentially a queue but without assignment
(loop `(,@(cdr sequence) ,(call/cc (car sequence)))
(+ state 1)))))))
(with-exit
(lambda (label data)
;thread with exit case
(lambda (cc)
(let loop ((cc cc) (done (lambda () #f)) (state 0))
(cond ((done) (cc data)) ;if done was replaced with something else that
;could at some point return true, this is where
;the thread would exit
(else
(printf "IN THREAD ~A TYPE: WITH-EXIT STATE: ~A~N" label state)
(loop (call/cc cc) done (+ state 1))))))))
(no-exit
(lambda (label data)
;no exit case, can be resumed arbitrarily
(lambda (cc)
(let loop ((cc cc) (state 0))
(printf "IN THREAD ~A TYPE: NO-EXIT STATE: ~A~N" label state)
(loop (call/cc cc) (+ state 1))))))
(no-reps
(lambda (label data)
;breaks it for some reason?
;would be called, do its stuff and then
;go back to the calling continuation
(lambda (cc)
(printf "IN THREAD ~A TYPE: NO-REPS~N" label)
(call/cc cc)))))
(spawn-thread main 'main 10
(spawn-thread with-exit 1 '())
(spawn-thread no-exit 2 '())
(spawn-thread with-exit 3 '())
;(spawn-thread no-reps 4 '())) uncomment to see error
))
So whats up with no-reps? why does running it as one of the threads in main lead to an infinite loop?
output from example with commented line:
IN THREAD 1 TYPE: WITH-EXIT STATE: 0
IN THREAD 2 TYPE: NO-EXIT STATE: 0
IN THREAD 3 TYPE: WITH-EXIT STATE: 0
IN MAIN THREAD STATE: 0
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1
IN MAIN THREAD STATE: 1
---IN THREAD 2 TYPE: NO-EXIT STATE: 1
IN MAIN THREAD STATE: 2
---IN THREAD 3 TYPE: WITH-EXIT STATE: 1
IN MAIN THREAD STATE: 3
---IN THREAD 1 TYPE: WITH-EXIT STATE: 2
IN MAIN THREAD STATE: 4
---IN THREAD 2 TYPE: NO-EXIT STATE: 2
IN MAIN THREAD STATE: 5
---IN THREAD 3 TYPE: WITH-EXIT STATE: 2
IN MAIN THREAD STATE: 6
---IN THREAD 1 TYPE: WITH-EXIT STATE: 3
IN MAIN THREAD STATE: 7
---IN THREAD 2 TYPE: NO-EXIT STATE: 3
IN MAIN THREAD STATE: 8
---IN THREAD 3 TYPE: WITH-EXIT STATE: 3
IN MAIN THREAD STATE: 9
---IN THREAD 1 TYPE: WITH-EXIT STATE: 4
IN MAIN THREAD STATE: 10
Uncommented:
IN THREAD 1 TYPE: WITH-EXIT STATE: 0
IN THREAD 2 TYPE: NO-EXIT STATE: 0
IN THREAD 3 TYPE: WITH-EXIT STATE: 0
IN THREAD 4 TYPE: NO-REPS
IN MAIN THREAD STATE: 0
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1
IN MAIN THREAD STATE: 1
---IN THREAD 2 TYPE: NO-EXIT STATE: 1
IN MAIN THREAD STATE: 2
---IN THREAD 3 TYPE: WITH-EXIT STATE: 1
IN MAIN THREAD STATE: 3
---IN MAIN THREAD STATE: 0
---IN THREAD 1 TYPE: WITH-EXIT STATE: 1
......... ;profit????