actors: Remove define-simple-actor, add define-actor.
[8sync.git] / doc / 8sync-new-manual.org
index dd8ad505261fc725a2c257f0647b7546635d23b2..bd6bb319fad467e154d23b77122209099d523d22 100644 (file)
@@ -161,22 +161,22 @@ yet.  Time to fix that!
                   (channels '("##botchat")))
   (define hive (make-hive))
   (define irc-bot
                   (channels '("##botchat")))
   (define hive (make-hive))
   (define irc-bot
-    (hive-create-actor* hive <my-irc-bot> "irc-bot"
-                        #:username username
-                        #:server server
-                        #:channels channels))
+    (bootstrap-actor* hive <my-irc-bot> "irc-bot"
+                      #:username username
+                      #:server server
+                      #:channels channels))
   (run-hive hive (list (bootstrap-message hive irc-bot 'init))))
 #+END_SRC
 
 Actors are connected to something called a "hive", which is a
 special kind of actor that runs all the other actors.
 Actors can spawn other actors, but before we start the hive we use
   (run-hive hive (list (bootstrap-message hive irc-bot 'init))))
 #+END_SRC
 
 Actors are connected to something called a "hive", which is a
 special kind of actor that runs all the other actors.
 Actors can spawn other actors, but before we start the hive we use
-this special "hive-create-actor*" method.
+this special "bootstrap-actor*" method.
 It takes the hive as its first argument, the actor class as the second
 argument, a decorative "cookie" as the third argument (this is
 optional, but it helps with debugging... you can skip it by setting it
 to #f if you prefer), and the rest are initialization arguments to the
 It takes the hive as its first argument, the actor class as the second
 argument, a decorative "cookie" as the third argument (this is
 optional, but it helps with debugging... you can skip it by setting it
 to #f if you prefer), and the rest are initialization arguments to the
-actor.  hive-create-actor* passes back not the actor itself (we don't
+actor.  bootstrap-actor* passes back not the actor itself (we don't
 get access to that usually) but the *id* of the actor.
 (More on this later.)
 Finally we run the hive with run-hive and pass it a list of
 get access to that usually) but the *id* of the actor.
 (More on this later.)
 Finally we run the hive with run-hive and pass it a list of
@@ -426,12 +426,12 @@ Redefine run-bot like so:
                     (repl-path "/tmp/8sync-repl"))
     (define hive (make-hive))
     (define irc-bot
                     (repl-path "/tmp/8sync-repl"))
     (define hive (make-hive))
     (define irc-bot
-      (hive-create-actor* hive <my-irc-bot> "irc-bot"
-                          #:username username
-                          #:server server
-                          #:channels channels))
+      (bootstrap-actor* hive <my-irc-bot> "irc-bot"
+                        #:username username
+                        #:server server
+                        #:channels channels))
     (define repl-manager
     (define repl-manager
-      (hive-create-actor* hive <repl-manager> "repl"
+      (bootstrap-actor* hive <repl-manager> "repl"
                           #:path repl-path))
 
     (run-hive hive (list (bootstrap-message hive irc-bot 'init)
                           #:path repl-path))
 
     (run-hive hive (list (bootstrap-message hive irc-bot 'init)
@@ -552,7 +552,7 @@ IRC> /query examplebot
 
 Horray!
 
 
 Horray!
 
-** Writing our own actors and sending messages between them
+** Writing our own actors
 
 Let's write the most basic, boring actor possible.
 How about an actor that start sleeping, and keeps sleeping?
 
 Let's write the most basic, boring actor possible.
 How about an actor that start sleeping, and keeps sleeping?
@@ -573,7 +573,7 @@ How about an actor that start sleeping, and keeps sleeping?
       (8sleep 1)))
 
   (let* ((hive (make-hive))
       (8sleep 1)))
 
   (let* ((hive (make-hive))
-         (sleeper (hive-create-actor hive <sleeper>)))
+         (sleeper (bootstrap-actor hive <sleeper>)))
     (run-hive hive (list (bootstrap-message hive sleeper 'loop))))
 #+END_SRC
 
     (run-hive hive (list (bootstrap-message hive sleeper 'loop))))
 #+END_SRC
 
@@ -642,7 +642,7 @@ reference other actors.
                            (work-on-this worker-work-on-this))))
 
   (define (worker-work-on-this worker message difficulty)
                            (work-on-this worker-work-on-this))))
 
   (define (worker-work-on-this worker message difficulty)
-    ""
+    "Work on one task until done."
     (set! (worker-task-left worker) difficulty)
     (display "worker> Whatever you say, boss!\n")
     (while (and (actor-alive? worker)
     (set! (worker-task-left worker) difficulty)
     (display "worker> Whatever you say, boss!\n")
     (while (and (actor-alive? worker)
@@ -650,20 +650,19 @@ reference other actors.
       (display "worker> *huff puff*\n")
       (set! (worker-task-left worker)
             (- (worker-task-left worker) 1))
       (display "worker> *huff puff*\n")
       (set! (worker-task-left worker)
             (- (worker-task-left worker) 1))
-      (8sync (/ 1 3)))
-    (display "worker> Looks like I'm done!  Can I go home yet?\n"))
+      (8sleep (/ 1 3))))
 #+END_SRC
 
 The worker also contains familiar code, but we now see that we can
 #+END_SRC
 
 The worker also contains familiar code, but we now see that we can
-call 8sync with non-integer real numbers.
+call 8sleep with non-integer real numbers.
 
 Looks like there's nothing left to do but run it:
 
 #+BEGIN_SRC scheme
   (let* ((hive (make-hive))
 
 Looks like there's nothing left to do but run it:
 
 #+BEGIN_SRC scheme
   (let* ((hive (make-hive))
-         (worker (hive-create-actor hive <worker>))
-         (manager (hive-create-actor hive <manager>
-                                     #:direct-report worker)))
+         (worker (bootstrap-actor hive <worker>))
+         (manager (bootstrap-actor hive <manager>
+                                   #:direct-report worker)))
     (run-hive hive (list (bootstrap-message hive manager 'assign-task 5))))
 #+END_SRC
 
     (run-hive hive (list (bootstrap-message hive manager 'assign-task 5))))
 #+END_SRC
 
@@ -675,7 +674,6 @@ worker> *huff puff*
 worker> *huff puff*
 worker> *huff puff*
 worker> *huff puff*
 worker> *huff puff*
 worker> *huff puff*
 worker> *huff puff*
-worker> Looks like I'm done!  Can I go home yet?
 #+END_SRC
 
 "<-" pays no attention to what happens with the messages it has sent
 #+END_SRC
 
 "<-" pays no attention to what happens with the messages it has sent
@@ -701,7 +699,8 @@ into a micromanager.
     (<- (manager-direct-report manager)
         'work-on-this difficulty)
 
     (<- (manager-direct-report manager)
         'work-on-this difficulty)
 
-    ;; call the micromanagement loop
+    ;; Wait a moment, then call the micromanagement loop
+    (8sleep (/ 1 2))
     (manager-micromanage-loop manager))
 
   ;;; And add the following
     (manager-micromanage-loop manager))
 
   ;;; And add the following
@@ -709,25 +708,26 @@ into a micromanager.
   (define (manager-micromanage-loop manager)
     "Pester direct report until they're done with their task."
     (display "manager> Are you done yet???\n")
   (define (manager-micromanage-loop manager)
     "Pester direct report until they're done with their task."
     (display "manager> Are you done yet???\n")
-    (let ((still-working
-           (msg-val (<-wait (manager-direct-report manager)
-                            'done-yet?))))
-      (if still-working
+    (let ((worker-is-done
+           (mbody-val (<-wait (manager-direct-report manager)
+                              'done-yet?))))
+      (if worker-is-done
+          (begin (display "manager> Oh!  I guess you can go home then.\n")
+                 (<- (manager-direct-report manager) 'go-home))
           (begin (display "manager> Harumph!\n")
           (begin (display "manager> Harumph!\n")
-                 (8sleep 1)
+                 (8sleep (/ 1 2))
                  (when (actor-alive? manager)
                  (when (actor-alive? manager)
-                   (manager-micromanage-loop manager)))
-          (begin (display "manager> Oh!  I guess you can go home then.\n")
-                 (<- (manager-direct-report manager) 'go-home)))))
+                   (manager-micromanage-loop manager))))))
 #+END_SRC
 
 We've appended a micromanagement loop here... but what's going on?
 "<-wait", as it sounds, waits for a reply, and returns a reply
 message.
 In this case there's a value in the body of the message we want,
 #+END_SRC
 
 We've appended a micromanagement loop here... but what's going on?
 "<-wait", as it sounds, waits for a reply, and returns a reply
 message.
 In this case there's a value in the body of the message we want,
-so we pull it out with msg-val.
+so we pull it out with mbody-val.
 (It's possible for a remote actor to return multiple values, in which
 (It's possible for a remote actor to return multiple values, in which
-case we'd want to use msg-receive, but that's a bit more complicated.)
+case we'd want to use mbody-receive, but that's a bit more
+complicated.)
 
 Of course, we need to update our worker accordingly as well.
 
 
 Of course, we need to update our worker accordingly as well.
 
@@ -746,15 +746,54 @@ Of course, we need to update our worker accordingly as well.
   ;;; New procedures:
   (define (worker-done-yet? worker message)
     "Reply with whether or not we're done yet."
   ;;; New procedures:
   (define (worker-done-yet? worker message)
     "Reply with whether or not we're done yet."
-    (<-reply message
-             (= (worker-task-left worker) 0)))
+    (let ((am-i-done? (= (worker-task-left worker) 0)))
+      (if am-i-done?
+          (display "worker> Yes, I finished up!\n")
+          (display "worker> No... I'm still working on it...\n"))
+      (<-reply message am-i-done?)))
 
   (define (worker-go-home worker message)
     "It's off of work for us!"
 
   (define (worker-go-home worker message)
     "It's off of work for us!"
-    (display "worker> Whew!  Free at last.")
+    (display "worker> Whew!  Free at last.\n")
     (self-destruct worker))
 #+END_SRC
 
     (self-destruct worker))
 #+END_SRC
 
+(As you've probably guessed, you wouldn't normally call =display=
+everywhere as we are in this program... that's just to make the
+examples more illustrative.)
+
+Running it is the same as before:
+
+#+BEGIN_SRC scheme
+  (let* ((hive (make-hive))
+         (worker (bootstrap-actor hive <worker>))
+         (manager (bootstrap-actor hive <manager>
+                                   #:direct-report worker)))
+    (run-hive hive (list (bootstrap-message hive manager 'assign-task 5))))
+#+END_SRC
+
+But the output is a bit different:
+
+#+BEGIN_SRC scheme
+manager> Work on this task for me!
+worker> Whatever you say, boss!
+worker> *huff puff*
+worker> *huff puff*
+manager> Are you done yet???
+worker> No... I'm still working on it...
+manager> Harumph!
+worker> *huff puff*
+manager> Are you done yet???
+worker> *huff puff*
+worker> No... I'm still working on it...
+manager> Harumph!
+worker> *huff puff*
+manager> Are you done yet???
+worker> Yes, I finished up!
+manager> Oh!  I guess you can go home then.
+worker> Whew!  Free at last.
+#+END_SRC
+
 "<-reply" is what actually returns the information to the actor
 waiting on the reply.
 It takes as an argument the actor sending the message, the message
 "<-reply" is what actually returns the information to the actor
 waiting on the reply.
 It takes as an argument the actor sending the message, the message
@@ -779,6 +818,15 @@ Ka-poof!
 ** COMMENT Websockets
 
 * Addendum
 ** COMMENT Websockets
 
 * Addendum
+** Recommended .emacs additions
+
+In order for =mbody-receive= to indent properly, put this in your
+.emacs:
+
+#+BEGIN_SRC emacs-lisp
+(put 'mbody-receive 'scheme-indent-function 2)
+#+END_SRC
+
 ** 8sync and Fibers
 
 One other major library for asynchronous communication in Guile-land
 ** 8sync and Fibers
 
 One other major library for asynchronous communication in Guile-land