PyJS

2 views
Skip to first unread message

Steve Wedig

unread,
Mar 28, 2007, 5:23:54 PM3/28/07
to moch...@googlegroups.com
Hi,

I'm just getting started with MochiKit, and it reminds me of a project I pursued last year. I wrote "PyJS", which had the goal of turning javascript into python 1.4 as much as possible. Due to JavaScript's flexability, I was able to get surprisingly close. I presented PyJS to the socal python user group, and people found it interesting. However I probably won't have time to develop it further. I'm wondering if some of my ideas would be useful to future MochiKit development though. I'd love to discuss it with anyone interested :)

You can find the source at (start with the readme):
http://www.stevewedig.com/files/pyjs.zip

Basically PyJS adds:
- Python multi-inheritance (plus support for explicit interfaces)
- Python style exception handling
- Lots of core Python functions, all based on iterators
- JS Array is extended to implement Python's List interface (including slicing)
- JS String is extended to implement (some of?) Python's String interface
- new Dict object which distinguishes between String and Number keys
- ~40k when crunched
- its all tested with JsUnit

Here's some sample code...

// ------------------------
// multiple inheritance
// ------------------------

var Dict = pyclass( Table, I_Mapping, {
    get: function (k, x) {
        if( isin(k, this) )
            return this._get(k);            // can't say this.get() here (infinite recusion!)
        else if( arguments.length >= 2 )    // can't say notNone(x), none is valid
            return x;
        raise(KeyError, k);
    },
});

// ------------------------
// iterators and python style exceptions
// ------------------------

function takewhile(keepTaking, i_iterable) {
    var taking = true;
    return ifilter(
        function (x) {
            if( taking )
                if( keepTaking(x) )
                    return true;
                else
                    taking = false;
            raise(StopIteration, 'from takewhile');
        },
        i_iterable
    );
}

// ------------------------
// here's a fun section of code...
// ------------------------

Python.iFunToAFun = function (iterFun) {
    return function () {
        return Array.fromIter( apply(iterFun, arguments) );
    };
};

var ilc = curry( construct, ListComprehensionIterator );

var izip = curry( ilc, None, None );
var imap = curry( ilc, None );
var ifilter = curry( flip(ilc), None );

var zip = Python.iFunToAFun ( izip );
var map = Python.iFunToAFun( imap );
var filter = Python.iFunToAFun( ifilter );
var lc = Python.iFunToAFun( ilc );

function forin (fun) {
    apply( lc, compose(Fun.falseFun, fun), None, ARGS(1) );
}

// ------------------------
// getting a mutable array of the arguments
// ------------------------

function caller () {
    // x . y . z
    // x = this function
    // y = caller of x (so caller of this function)
    // y = caller of y (so caller of the function that called x)
    return caller.caller.caller; // yeyah!
}

function ARGS () {
    var callerArgs = Array.fromArray( caller().arguments );
    return arguments.length == 0 ? callerArgs :
        callerArgs.slice.apply( callerArgs, arguments );
}

function curry(fun) {
    var curriedArgs = ARGS(1);
    return function() {
        return apply( fun, curriedArgs.concat(ARGS()) );
    }
}


Reply all
Reply to author
Forward
0 new messages