archives

Questions on an improved CPS mechanism for JavaScript

To get right to the point, my main question is:

Is there any guarantee that setTimeout() calls will be executed in the order in which they are requested?

Discussion:

I believe I have made two improvements to the general CPS mechanism that was described in this forum by Anton van Straaten some time ago here. My main questions involve the 2nd adaption that I describe below.

As an amusement, I've been working on a JavaScript-based, client-side maze generator. In order to support very large mazes I've avoided recursion and adapted the aforementioned CPS mechanism in order to maintain responsiveness.

The main adaptions:

1. Using iteration instead of recursion in the loop() function. I found that the Safari browser allows such a small stack that the level of recursion made necessary caused the algorithm to run unacceptably slow.

2. To support nesting of continuations, the continuation function k() is called in the context of a setTimeout(). My implementation of the maze generator involves several passes across a multidimensional array (e.g., initialization, generation, rendering) each of which is a continuation of the previous step. I found the original example did not allow nested continuations since the hand-off to k() would normally be done before the previous stage had truly completed (i.e., before most of the setTimeout() requests had been handled).

The idea behind this change is that the setTimeout("k()", 0) would cause k() to be executed only after all the previous setTimeout requests had been handled. I'm making a huge assumption here I realize, which is that the calls to setTimeout are in essence serialized by the processor. Given the nature of the algorithm, it's guaranteed that the call to setTimeout for k() will happen after all the other setTimeouts requested by a particular stage, but does that actually guarantee that it will be *handled* after all the other requests? In my particular case it works well, but I don't know if this is just pure luck.

If there is a more general way to handle nested continuations (that does not rely on this potentially invalid assumption) I would appreciated hearing about it.

A somewhat simplified version of the iteration function I have employed in my code is shown here:

/*
 * f    - a function that takes a state parameter and returns an updated state
 * initial - the initial state
 * done - the final state that indicates that iteration is complete
 * k   - an optional continuation function that is called when processing is complete
 */
function iter(f, initial, done, k)
{
    var max   = 50; // a reasonable number
    var count = 0;    

    /* define the loop function that will manage the calls to f() */
    var loop = function (state)
    {
        while((state = f(state)) != done) {   
            if (count < max) {
                count++;
            } 
            else {
                count = 0;
                setTimeout(function() { loop(state) }, 0);
                break;
            }
        }
          
        if(k && (state == done)) {
            setTimeout(function() { k() }, 0);
        }
    }
    
    /* call the loop function with the initial state */
    loop(initial);
}

Instantiation of classes in wrong place leads to wrong structures ... (reminder)

In OOP many times I encountered a bad structured code; just because of absence of a good recommendation on it. This is asking about one of them.
So Is this a valid/useful recommendation in OOP:
[Methods must not instantiate objects of other classes (at least the classes in the same "sub-system"); but they must be declared as fields.]
(Because using objects directly in methods - not as fields - will break useful definition path of OO things. Of course this may be an old quota; but recently I saw many codes that violates this and if this is important how can we enforce it?)

Lambda: The Semantics Tool

Lambda is an interactive, graphical, pedagogical computer program that helps students of formal semantics practice the typed lambda calculus.

We discussed how the LC is used in linguistics in the past (check the archives). This tool may be useful even for those not interested in this angle, even though that's the intended use of the software.

Wrapping the Cloud with .NET

Volta is exploring innovation that empowers programmers to delay decisions about tier-splitting to the last possible responsible moment by using either code refactoring or declarative annotations.

Erik Meijer: Volta - Wrapping the Cloud with .NET - Part 1 [Channel 9 Video, 25 minutes]

Erik Meijer: Volta - Wrapping the Cloud with .NET - Part 2 [Channel 9 Video, 32 minutes]

LINQ 2.0: Democratizing the Cloud (pdf)