(import srfi-69 matchable)
+(define trace-enabled #f)
+
;;;
;;; Actor creation
;;;
;;;
(define (dispatch-message address message)
- (print "Dispatching message " message " to " address)
- (let* ((behaviour (hash-table-ref actor-table address))
- (value (behaviour address message)))
- (match value
- ('done (hash-table-delete! actor-table address))
- ('sleep 'do-nothing)
- (else
- hash-table-set! actor-table address value))))
+ (if trace-enabled
+ (print "Dispatching message " message " to " address))
+ (let ((behaviour (hash-table-ref/default actor-table address '())))
+ (if (null? behaviour)
+ (print "Warning: discarded message " message " to unknown actor " address)
+ (let ((value (apply behaviour (cons address message))))
+ (match value
+ ('done (hash-table-delete! actor-table address))
+ ('sleep 'do-nothing)
+ (else
+ hash-table-set! actor-table address value))))))
;;;
;;; FIFO queue implementation
'()
(fifo-pop message-queue)))
-(define (send-message actor message)
- (print "Queued message " message " to " actor)
+(define (send-message actor . message)
+ (if trace-enabled
+ (print "Queued message " message " to " actor))
(fifo-push message-queue (cons actor message)))
-(define (run)
+(define (process-next-message)
(let ((addressed-msg (next-addressed-msg)))
(if (null? addressed-msg)
- 'done
+ '()
(let ((address (car addressed-msg))
(message (cdr addressed-msg)))
- (dispatch-message address message)
- (run)))))
+ (dispatch-message address message)))))
-;;;
-;;; Testing
-;;;
+(define (run)
+ (unless (null? (process-next-message))
+ (run)))
-(define factorial
- (make-actor
- (lambda (self message)
- (match message
- ((n) (send-message self (list n 1)) 'sleep)
- ((0 acc) (print acc) 'done)
- ((n acc) (send-message self (list (- n 1) (* acc n))) 'sleep)))))
+(define (send-and-run actor . message)
+ (apply send-message (cons actor message))
+ (run))
-;(send-message factorial '(5))