(ajax-get "example.scm" (lambda (result) (alert result)))
The more interesting change is a simple concurrency library giving lightweight threads that run in the browser. The API loosely follows that of Termite, a concurrent Scheme. It uses ‘!’ for sending a message to a process and ‘?’ to receive.
To use the library click on the ‘currency’ button. This will load the source via Ajax. Then press ‘eval’. Once loaded you can start using it. There are some examples in the concurrency.scm file.
For example, a ‘logger’ process:
(define logger (spawn (lambda () (let loop ((msg (?))) (if (string? msg) (begin (process-msg msg) (loop (?))))) (process-msg "Logger exiting"))))
This loops waiting for a message in the process queue. When it appears it displays it and then waits for more messages. Any non-string message quits the process. An example of using it:
(define (logger-test) (spawn (lambda () (! logger "Hello") (! logger "World") (! logger 'quit))))
I’ve also done an example of concurrency using Ajax. An ‘ajax-process’ waits for requests of the form ‘(FROM URL). When received it will retrieve the URL using Ajax and send the result to the FROM process:
(define ajax-process (spawn (lambda () (let loop ((msg (?))) (let* ((from (car msg)) (url (cadr msg))) (ajax-get url (lambda (result) (! from result)))) (loop (?))))))
Using it is simple:
(alert (!? ajax-process `(,current-process "example.scm")))
This uses ‘!?’ which sends a message and immediately waits for the result. You don’t have to send to the current process. The next example instructs the Ajax process to send it to the log window:
(define (ajax-test2) (spawn (lambda () (! ajax-process `(,logger "example.scm")) (! ajax-process `(,logger "concurrency.scm")))))
All this runs within the browser. Unfortunately it’s not fast as it’s interpreted. The JIT compiler does not work on Firefox and even if it did, it does not work with continuations which the concurrency system is based on. I’ll look into improving this over time.