Wednesday, March 29, 2006

Factor Space Invaders Updated

I've updated my space invaders emulator written in Factor to work with the new Factor GUI system. This means that Space Invaders can run in a seperate window from the main Factor GUI and you can even run multiple instances at a time.

While the emulator is running you can still use the Factor GUI to browse, run code, etc. You could even browse the 8080 CPU emulator data structures and memory while it is running.

A screenshot of two running space invaders instances is here.

As the emulator is a Factor gadget, hopefully it will run unchanged on Mac OS X and Windows. The updated emulator will be available in the upcoming Factor 0.81 or you get can get it from my darcs repository at: http://www.bluishcoder.co.nz/repos/factor

The code is in contrib/space-invaders/cpu-8080.factor and contrib/space-invaders/space-invaders.factor. Don't forget to read the help file.

Screenshot of Space Invaders Emulator

Categories:

Generators in Common Lisp

Matthew Swank posted an example of generators using Common Lisp in comp.lang.lisp.

His implementation contains a monadic implementation of continuations and call/cc which is quite nice, and the resulting thread has a dicussion on the some implementation variations. A simple example of using the call/cc implementation from later in the thread:

;; Scheme version
(call/cc (lambda (k) (k 42)))

;; Common Lisp
(run (call/cc (lambda (k) (funcall k 42))))


Categories:

Tuesday, March 21, 2006

Patent on continuation based web servers

It looks like Paul Graham has a patent on continuation based web servers: Patent 6,205,469.
In particular, the invention relates to the use of continuations to simulate subroutine calls in a program that interacts with the user through successive Web pages.

Paul Graham mentions it on his weblog. Found via Lambda the Ultimate.

Categories:

Sunday, March 19, 2006

Javascript Partial Continuations

I've been playing around with Rhino, a Javascript interpreter written in Java, using it as a server side scripting language. Rhino supports continuations so I thought I'd try and port the bshift and breset implementation I ported to Factor to Javascript.

My initial attempt is in partial-continuations.js.This can be loaded into the Rhino interpreter using:
load("partial-continuations.js")

Rhino's 'load' understands URL's so you can even do:
load("http://www.bluishcoder.co.nz/code/partial-continuations.js")


A simple use of the 'range' example in Javascript is:

function range(rc, from, to) {
return bshift(rc, function(pcc) {
while(from <= to) {
pcc(from++);
}
return undefined;
});

function test1() {
breset(function(rc) {
print(range(rc, 1, 5));
return 0;
});
}

This works fine printing the number from 1 to 5. I've struck a bit of wierdness with the attempt to translate the CLU-iterator idiom mentioned in my previous post. My Javascript translation was:
function test3() {
var sum = 0;
breset(function(rc) {
var tmp = range(rc, 1, 10);
sum += tmp;
});
print(sum);
}

This works, printing '55'. But if I change it to the following it prints 10:
function test3() {
var sum = 0;
breset(function(rc) {
sum += range(rc, 1, 10);
});
print(sum);
}

For some reason the range call is not calling the entire breset scope. It's only calling from the 'range' onwards. Can anyone spot what's wrong with my implementation?

Categories:

Factor Partial Continuation Updates and Iterators

I've made some changes to the parser combinator library I wrote for Factor. The changes were to make the usage of the library to be more consistent with good Factor style.

The first change was to ensure that items on the stack are accessable in an intuitive manner from within the quotations passed to breset and bshift. When writing combinators in Factor it's important that the internals of the combinator implementation do not affect the callers view of items on the stack. For example:
20 [ drop 2 * ] breset

Recall that the quotation passed to breset has stack effect ( r -- v ). Once the 'r' is dropped the '*' should be expected to operate on the '2' and the '20'. The '20' is accessable as if it was directly under the 'r' on the stack from within the quotation.

In a prior implementation of breset I called the quotation using 'call' after creating a 'dup' of the 'r':

: breset
... ( quot r -- )
dup rot call ( r v -- )

The problem with this is that from within the quotation there is an extra 'r' above items on the stack before the quotation is called:
20 [ drop 2 * ] breset

The stack on entry to the quotation here is ( 20 r r -- ). Changing the breset implementation to use 'keep' instead of call fixes this problem:

: breset
... ( quot r -- )
swap keep ( v r -- )

Notice also that the return item from the quotation, 'v', is now below the 'r' and I didn't need to 'dup' it. In general, usage of words like 'keep' will enable combinators to more intuitively access stack items from outside the quotation.

Another way of solving this problem is to use the return stack words '>r' and 'r>' to move items temporarily off the stack so that the quotation being called is imediately above the relevant stack items supplied by the caller.

The second major change was to remove the use of 'with-scope' and namespaces to store the continuation delimiter. I previously stored this in a 'mark' and 'mark-old' variable. Now the implementations of breset and bshift manage these on the stack.

Storing variables in namespaces is seductive. It enables you to avoid sometimes complicated stack management by giving you named variables. Unfortunately it comes with a price. When setting the value of a variable in a namespace it is stored in the top most namespace on the namespace stack. This can be seen with code like this:

SYMBOL: myvar
5 myvar set
myvar get .
=> 5
10 [ myvar set ] keep drop myvar get .
=> 10

As expected setting the myvar variable in the quotation passed to 'keep' results in the global myvar value being set to 10. But if this is run inside a 'with-scope' you get caught by the fact that a new namespace is at the top of the stack:

myvar get .
=> 10
20 [ [ myvar set ] with-scope ] keep drop myvar get .
=> 10

Notice the value is still 10. This is because the variable is set in the new namespace which is dropped off the namespace stack when the 'with-scope' exits. Normally you would be aware of this when you write code, but if you use a combinator that uses 'with-scope' in its implementation, and it then calls your quotation from within that scope then all your variable sets will be lost at the end of the combinator call.

This may be desired, and the reason why the combinator is in a scope, but for many cases it's not the desired behaviour. So as a general rule I try to avoid using variables and with-scope in combinator implementations.

There was also a minor bug in my 'range' example in that it didn't give the correct range if the starting number was anything but '1'. The corrected 'range' implementation is:

: range ( r from to -- n )
over - 1 + rot [
-rot [ over + pick call drop ] each 2drop f
] bshift 2nip ;

Note the '2nip' at the end. 'bshift' and 'breset' operate like other continuation combinators in that they restore the stack to what they were before they were called. In this case the 'from' and 'to' were on the stack and we need to 'nip' them off. Simple usage works as before:

[ 1 5 range . f ] breset drop
=> 1
2
3
4
5

Nested usage works correctly now:

[ dup 1 3 range swap 10 12 range + . f ] breset drop
=> 11
12
13
12
13
14
13
14
15

It can be hard to reason about what usage of words like 'range' does. Think of it as returning a single value 'n', and calling the breset multiple times with the value of 'n' for each 'n' in the range. So you'll see that after the first 'range' call I 'swap' to swap the result of the range and get the continuation mark passed to breset back to the top of the stack to call the second 'range'.

You'll notice that the result of calling these snippets always returns 'f' on the stack. This is because the range implementation leaves 'f' on the stack at the end of the bshift quotation. This results in 'breset' exiting with that value.

A question was raised on the Factor mailing list about CLU-style iterators. An example of the usage from one of the links in that message is:

sum: INT := 0;
loop sum := sum + 1.upto!(10); end;
#OUT + sum + '\n'; -- Prints sum of integers from 1 to 10

This has a very direct translation in Factor using range and breset as:

SYMBOL: sum
0 sum set
[ 1 10 range sum get + sum set f ] breset drop
sum get .
=> 55


Categories:

Saturday, March 18, 2006

DabbleDB on TechCrunch

DabbleDB gets a mention again on TechCrunch along with a lot of positive comments.
In just a few minutes, the video will show how you can start with simple, flat spreadsheet data, use Dabble DB to search and explore this data right away, then gradually evolve into a full conference-planning application (with drop-down lists, calendar views, relations, and more). While this demo shows that full app development can take place in only a few minutes, in practice it would usually happen organically over a period of time as the app editors further expand their apps.

DabbleDB is written in Squeak Smalltalk using the continuation based web framework Seaside.

Categories:

Augment

If you think that we've made great progress in computer systems over the last ten years, take a look at Brad Neuberg's screencast of the Augment system developed in the 60's.

Augment is the first system developed with groupware, email, outlining and interaction with the computer. Many of the 'new' features we see today are evident in the Augment system. It must be a gold mine of prior art for some patent cases!

Mentioned in the screen cast (but not demonstrated) is audio visual conferencing, embedded graphics in documents, 'applet' style programs running within documents, etc.

The documents themselves are all outline based and reminded me a lot of the Userland's outlining facilities. Only developed 30 years ago of course.

Demonstrated are using the outliner, displaying documents, conferencing, and email. Very cool.

Keep an eye on the hyperscope project which is attempting to bring some of this to the web.

Categories:

Friday, March 17, 2006

Partial Continuations and Factor

I've written some partial continuation support and put it in the Factor contrib directory. It implements bshift and breset as outlined by Oleg's post on comp.lang.scheme.

It's in contrib/partial-continuations.factor and can be pulled from my repository until it makes it to the official Factor repository:
darcs pull http://www.bluishcoder.co.nz/repos/factor

It should be relatively easy to convert Oleg's Scheme examples to Factor. Just remember that the partial continuation has stack effect ( a -- b ) and the quotations passed to bshift and breset have stack effect ( pcc -- v ) and ( -- v ) respectively.

'breset' marks the scope of the partial continuation. If 'bshift' is not used then the value returned by the quotation is left on the stack:
[ drop 5 ] breset
=> 5

An example with 'bshift':
[
1 swap [ 5 swap call ] bshift +
] breset
=> 6

In this case the partial continuation passed to the 'bshift' quotation represents the computation '1 X +' where 'X' is replaced by the value passed to the partial continuation. In this case 5, resulting in a result of 6. Additional calls can be made to the same continuation:
[
1 swap [ 5 over call swap call ] bshift +
] breset
=> 7

This calls the '1 X +' partial continuation twice. First with '5' returning the value '6'. Which is then passed to it again, returning '7'. The partial continuation does not need to be called. Values that 'fall through' cause the result to be returned from the 'breset' quotation:
[
1 swap [ drop 5 ] bshift +
] breset
=> 5

Here's a fun example translated from Oleg's posting. The following 'range' function has some interesting properties:
 : range ( r from to -- )
rot [ ( from to pcc -- )
-rot [ over + pick call drop ] each 2drop f
] bshift ;

It uses the standard 'each' call on a 'from' and 'too' number to call a quotation on each number between 'from' and 'too' inclusive. The quotation called is the partial continuation provided by 'bshift'. This can be used in code like:
[ 1 5 range . ] breset drop
=> 1
2
3
4
5

For each item in the range it executed the partial continuation which is 'X .', printing that item in the range. So given a function that knows nothing about the special capability of 'range' can still work with it. The following prints the first five factorials:
: fact ( n -- n ) dup 1 = [ 1 ] [ dup 1 - fact ] if * ;

[ 1 5 range fact . ] breset drop
=> 1
2
6
24
120

I'm not sure how useful delimited continuations are in Factor but it gives something to play with to see how they work.

Categories:

Wednesday, March 15, 2006

Io Garbage Collector

Steve Dekorte has made the garbage collector used in Io a seperate library and released as open source. It's available at the libgarbagecollector page.

Categories:

Friday, March 10, 2006

Erlang SMP Benchmarks

Joe Armstrong has started a weblog and on it he has posted results of some testing of the Erlang SMP snapshot.
Program 1 spawned N (typically 1000) processes on 4 processors. Each process then pings all the other processes. This an 3.6 times faster on 4 CPUs than on a single CPU.
...
Program 2 is a SIP stack - this ran 1.8 times faster on 4 processors than on 1 processor.
...
These result are pretty good - to start with the Erlang system is unoptimized, as is the application. Despite this fact the application runs almost twice as fast on a four CPU system as it ran on a single CPU system.

Categories:

Friday, March 03, 2006

Erlang SMP support

Snapshots of the upcoming Erlang release with SMP support are available from the Erlang site.

As mentioned by this post on the Erlang mailing list, any of the P11B snapshots have SMP support and should be built with the following flags to enable it:
./configure --enable-smp-support --disable-lock-checking

Remember that this is a snapshot and as it says from the post:
Don't expect huge performance gains, or any performance gains at all for that matter. Almost all of our work so far has been focused on stability.
A later post to the list further notes that this is a snapshot and should not be used for production:
Our snapshots are only meant to be used for evaluation and testing purposes, not to be used in production use. We do consider the SMP emulator "stable enough" for that purpose.
SMP support in Erlang provides multiple native threads that run Erlang processes. The use of native threads allows machines with multiple CPU's to make effective use of the additional CPU's.

In current non-SMP versions of Erlang all Erlang processes run in a single thread which results in only one CPU on SMP machines being used. This has been an often raised barrier regarding non-native threading mechanisms in alternative langauges. By providing SMP support it lowers one of the barriers of entry for people wanting to create highly scalable applications on multi-CPU machines.

More information on the upcoming SMP version is available in this powerpoint presentation.

Categories:

DabbleDB Under the Radar

Ajaxian reports that Dabble DB gets a good review at Under the Radar:
They also have a calendar view of database data, where they parse out date-like values and plot them on a calendar — and you can apply the same searches against the calendar view, too. It’s a really fast, compelling interface — better than some of the When calendaring apps we saw in the last session.
...
The audience was very complementary, and both Michael and Rael on the panel seemed impressed. A great product.
Dabble DB is written in Smalltalk using Seaside, a continuation based web framework.

Categories: ,