Bluish Coder

Programming Languages, Martials Arts and Computers. The Weblog of Chris Double.


2006-08-04

Factor web framework

I'm working on a new web framework for Factor. My plan is to have web applications built as a collection of concurrent processes running on the server and the client browser. Processes on the server can send messages to the browser (using a 'comet' style connection) and vice versa.

Client processes are implemented using the lightweight concurrency system I built using Narrative Javascript. An example process that runs on the browser looks like:

function alerter() {
  while(true) { 
    var msg = receive->();
    document.getElementById("messages").value += (msg + "\n")
  }
}
register_process("p1", spawn(alerter));

This spawns a process named in the registry as 'p1'. It blocks waiting for a message. When one is received it will add the message string to an text area with the Id 'messages' and then resume waiting.

The message can come from other client side processes or from the server if a comet connection is established. From the Factor server you can get access to the client side process with 'get-process-on-page'. Each page connected to the server has an 'id'. 'get-process-on-page' takes this id and returns a process which can be used to send messages to the client process:

"1234" "p1" get-process-on-page "Hello" over send "World" over send

This example gets the 'p1' process on the client with the id '1234' and sends it two messages. One 'hello' and then 'world'. These will result in the 'p1' process shown above running on the browser waking up and adding the text to the textarea.

Most Factor objects can be sent as messages and they are serialised to JSON when sent to the client. I'm currently writing a JSON parser for Factor which will allow client processes to send messages to server processes.

The framework so far works up to this point and runs on Opera, Safari, Firefox and Internet Explorer. Once the JSON parser is written and working I'll make the code available.

I'm keen to see how this style of web programming compares to continuation based web servers, and how they can be combined (using cont-responder in Factor). I hope to also write other back ends (Scala, Erlang, etc) to compare the different technologies.

Tags: concurrency 

2006-08-04

Factor libraries updated

I've updated a number of the libraries I contributed to Factor so they run with the latest version. These include:

  • cont-responder, the continuation based web server
  • Parser Combinators (the lazy list library I wrote was kindly updated by 'Yuuki' from the #concatenative IRC channel)
  • sqlite and tuple-db, the database libraries
  • concurrency (Erlang style messaging)
  • Space Invaders Emulator

The Factor module system in the latest release is very nice. It makes loading space invaders as simple as:

"space-invaders" require

There have been a number of great features added to Factor recently, so it's worth a look if you haven't tried it out for a while.

Tags: factor 

2006-07-20

Slipwave Javascript libraries

I came across slipwave today which has a number of interesting Javascript libraries. Of interest to me is js.lang.Recompiler which does a CPS transform of Javascript code, similar it seems to Narrative Javascript. On top of this is built a thread library including thread groups and semaphores. Other libraries include a Javascript interpreter written in Javascript.

Tags: javascript 

2006-07-19

Scala, futures and lazy evaluation

On the Scala wiki there is an implementation of futures, promises and lazy evaluation modelled after the same features in the Alice programming language. Implemented as a library, without changes to the Scala implementation, it seems quite seamless.

After importing the library you can create futures, etc quite easily. The examples below use this definition of the fibonacci function:

object FibTest {
  def fib(n: int): int = n match {
    case 0 => 0
    case 1 => 1
    case _ => fib(n-1)+fib(n-2)
  }
}

Lazy evaluation is done using the 'lazy' function on the Future object in scalax.futures:

/* Import the future names */
import Future._

/* Lazily compute the 42nd fibonacci number. The computation will
   not start running until the value of 'a' is actually requested. */
var a = lazy({ FibTest.fib(42) })

/* This does not attempt to get the value of 'a' so does not start
   the computation */
Console.println(a)
  => Lazy(?)

/* This will start the computation, and add 1 to the value. There is
   a delay as it computes the 42nd fibonacci number. */
a+1
 => 267914297

/* No delay to compute the following as it has already been calculated */
a+2
 => 267914298

Futures are different in that they immediately start computing the value in a background thread. When the value is retrieved it will block, waiting for the computation to complete, and then return the value, or return it immediately if it is available.

/* Compute the 42nd fibonacci number in a background thread. */
var a = spawn({ FibTest.fib(42) })

/* This will block, waiting for the computation to complete, and add 1 to the value. If it
   has already completed there is no delay as it is returned immediately. */
a+1
 => 267914297

The Alice programming language gives an example of an 'enum' function that returns a lazy list of incrementing integers:

fun enum n = lazy n :: enum (n+1)

I translated this to the following Scala code:

/* A LazyList type that has a head and a tail. The tail being a 
   lazily computed lazy list itself */
case class LazyList[a](head: a,tail: Future[LazyList[a]])

/* Given a number, return a lazy list that where succesive
   elements are that number incremented */
def enum(n: int): Future[LazyList[int]] = { 
  lazy(LazyList(n, enum(n+1)))
}

/* Notice that 'a' is a Lazy value which has not yet been computed */
var a = enum(10)
  => Lazy(?)

/* Computes the lazy value and returns the head */
a.head
  => 10

/* Display 'a' now shows that it has been partially calculated */
a
  => Lazy(LazyList(10,Lazy(?)))

/* Go further down the list... */
a.tail.tail.tail.head
  => 13

/* Again we can see how much has been computed */
a
  => Lazy(LazyList(10,Lazy(LazyList(11,Lazy(LazyList(12,Lazy(LazyList(13,Lazy(?)))))))))

Promises are variables with no initial value. When a thread attempts to retrieve the value they block. Some other thread can set the value of it and the original thread will then resume with that value.

/* Create two promises to hold integer types */
var a = promise[int]
  => Promise(?)

var b = promise[int]
  => Promise(?)

/* A future computation that uses them */
var c = spawn({ Console.println("Result is: " + (a + b)) } )
  => Spawn(?)

/* The future computation completes when 'a' and 'b' get their values */
a.set(1)
b.set(2)

/* Future completes now that it has the values it needs */
Result is: 3

What is nice about the library, and that Scala allows it, is that the future values are be used exactly as if they were normal values. There is no need to call a 'get' or 'compute' to get at the value stored by the future.

A post on the Scala mailing list demonstrates how Cells style computation (automatic updating of variables when others change) can be done with the library.

Tags: scala 

2006-07-19

Javascript continuation based webserver

Tony Garnock-Jones has taken the server-side Javascript example I did and built a continuation based web server framework around it. His blog posting demonstrates the Seaside counter example in Javascript.

To test it out, get it from Tony's darcs repository:

darcs get http://www.lshift.net/~tonyg/javascript-server/

Fire up the Rhino interpreter with the jar's in the classpath:

java -classpath jetty.jar:jetty-util.jar:servlet-api-2.5.jar:xbean.jar:js.jar org.mozilla.javascript.tools.shell.Main

Load 'savannahside.js':

js> load("savannahside.js")

You can then test out the following urls:

  • http://localhost:8080/bean
  • http://localhost:8080/count
  • http://localhost:8080/
Tags: continuations 


This site is accessable over tor as hidden service 6vp5u25g4izec5c37wv52skvecikld6kysvsivnl6sdg6q7wy25lixad.onion, or Freenet using key:
USK@1ORdIvjL2H1bZblJcP8hu2LjjKtVB-rVzp8mLty~5N4,8hL85otZBbq0geDsSKkBK4sKESL2SrNVecFZz9NxGVQ,AQACAAE/bluishcoder/-61/


Tags

Archives
Links