1 (import srfi-69 matchable)
7 (define actor-table (make-hash-table))
9 (define (make-actor-with-address address behaviour)
10 (hash-table-set! actor-table address behaviour)
13 (define next-actor-address 1)
15 (define (make-actor behaviour)
16 (make-actor-with-address next-actor-address behaviour)
17 (let ((address next-actor-address))
18 (set! next-actor-address (+ next-actor-address 1))
25 (define (dispatch-message address message)
26 (print "Dispatching message " message " to " address)
27 (let* ((behaviour (hash-table-ref actor-table address))
28 (value (behaviour address message)))
30 ('done (hash-table-delete! actor-table address))
33 hash-table-set! actor-table address value))))
36 ;;; FIFO queue implementation
40 (define (cell val prev next)
43 (define cell-prev cadr)
44 (define cell-next caddr)
45 (define (set-cell-prev! cell prev-cell)
46 (set-car! (cdr cell) prev-cell))
47 (define (set-cell-next! cell next-cell)
48 (set-car! (cddr cell) next-cell))
54 ((empty?) (null? head))
55 ((push) (if (not (= (length args) 1))
56 (error "Wrong number of arguments to push.")
57 (if (not (null? head))
58 (let ((old-head head))
59 (set! head (cell (car args) '() old-head))
60 (set-cell-prev! old-head head))
63 (set! head (cell (car args) '() '()))
65 ((pop) (if (not (= (length args) 0))
66 (error "Wrong number of arguments to pop.")
69 (let ((old-tail tail))
70 (set! tail (cell-prev old-tail))
73 (set-cell-next! tail '()))
74 (cell-val old-tail)))))))))
76 (define (fifo-push fifo x)
79 (define (fifo-pop fifo)
82 (define (fifo-empty? fifo)
90 (define message-queue (make-fifo))
92 (define (next-addressed-msg)
93 (if (fifo-empty? message-queue)
95 (fifo-pop message-queue)))
97 (define (send-message actor message)
98 (print "Queued message " message " to " actor)
99 (fifo-push message-queue (cons actor message)))
102 (let ((addressed-msg (next-addressed-msg)))
103 (if (null? addressed-msg)
105 (let ((address (car addressed-msg))
106 (message (cdr addressed-msg)))
107 (dispatch-message address message)
116 (lambda (self message)
118 ((n) (send-message self (list n 1)) 'sleep)
119 ((0 acc) (print acc) 'done)
120 ((n acc) (send-message self (list (- n 1) (* acc n))) 'sleep)))))
122 ;(send-message factorial '(5))