NekoVM is a project I already knew before but since not a single host I know supports it, I have never investigated too much about its features but apparently NekoVM is a damn fast Virtual Machine for Neko code which is basically JavaScript with few differences/limitations. It is still a prototypal based programming language, and we all love it, isn't it, plus some better rule about static types, bytes management, closures, goto statement with portable scope, operator overload for objects, ability to compile C files into ndll, Apache module, MySQL, Zlib, on and on ... truly interesting!
Reading quickly the entire language specs, I tried to figure out if it is possible to reproduce Neko via JavaScript in order to use one language for both server and client: Jaxer style (I do not link Jaxer 'cause AFAIK it seems to be a failed project).
Well, I think without a sandbox it is possible to reproduce 70% of language specs. Via sandbox probably 85%, but 100% is quite utopia due to operator overload not that easy to manage via JavaScript and valueOf in a cross browser way (with firefox it is more simple thanks to "number" string as first argument if the operation is a plus so __add rather than __radd could be partially possible ... never mind).
$apply and $closure from NekoVM
These two functions are both simple and useful in our daily JS tasks. $closure is usually known as delegate or bind, while $apply is some fun we could have in a flexible language as JavaScript is.
function $apply(fn){
// WebReflection from NekoVM
var length = fn.length,
args = []
;
return (function $apply(){
args.push.apply(args, arguments);
return length <= args.length ? fn.apply(this, args) : $apply;
}).apply(this, args.slice.call(arguments, 1));
};
Test case from the source?
var f = function(x,y) { return x + y };
alert(
f(1,2) === $apply(f,1)(2) &&
f(1,2) === $apply(f,1,2) &&
f(1,2) === $apply(f)(1)(2)
); // true
I like the multi bracket style and thanks to its nature it is possible to split a function up to some parameter and inkect different scopes:
var f = function(b, c) {
return this.a + b + c;
};
var o1 = {a:1},
o2 = {a:2},
k = 2, // constant ...
sum = $apply(f)
;
o1.sum = sum(k);
o2.sum = o1.sum.call(o2); // injected
// o2.sum = sum(k); // equivalent
alert(o1.sum(3)); // 1 + 2 + 3 == 6
alert(o2.sum(3)); // 2 + 2 + 3 == 7
I am not sure if "this" should be that malleable, probably a version with static "this" during first call could be better?
function $apply(fn){
// WebReflection V2 from NekoVM
var length = fn.length,
args = [],
self = this === window ? null : this
;
return (function $apply(){
args.push.apply(args, arguments);
return length <= args.length ? fn.apply(self || this, args) : $apply;
}).apply(self, args.slice.call(arguments, 1));
};
In above case if we call $apply() the scope will be malleable, otherwise it will be fixed $apply.call(o2, a).
The other one is less problematic, since it is a common bind.
var $closure = (function(){
// WebReflection from NekoVM
var slice = Array.prototype.slice;
return function $closure(fn, self){
var args = slice.call(arguments, 2);
return function $closure(){
return fn.apply(self, args.concat(slice.call(arguments, 0)));
};
};
})();
The idea is to be able to trap directly the scope in order to make it safe whenever and however it is executed.
var add = function(x,y) { return x + y };
var plus5 = $closure(add, null, 5);
alert(
plus5(2)
); // 7
var add = function(y){return this.x + y};
var plus5 = $closure(add, {x:5});
alert(
plus5(2)
); // 7
Easy? Let's see what else I could create from NekoVM specs 8-)
No comments:
Post a Comment