Friday, June 24, 2011

JavaScript Hypertext Preprocessor

well, the doctor said I can remove the tutor that was blocking my painful dislocated shoulder so here I am to test a "writing session" under pain killers from my bed!
With such post title you may think that doctor was a shrink ... well, I let you figure it out after reading ;)


About Hybrid Programming Languages

We all know CoffeScript, right? As well as Traceur Compiler ... right? These are what I call Hybrid Programming Languages, or better, those kind of pseudo representation of the programming language we use, in this case still JavaScript, passing through a more abstract, enhanced, "improved" syntax (Coffee) or language features (Traceur) .

About PHP And JavaScript

If you follow me since years you may have noticed how many times I have tried to make PHP more JavaScriptish. JavaScript like Object class is the first example from 2008, while [js.php] A JavaScript Object Like PHP Class was surely a better attempt, thanks to new PHP 5.3 features, as well as PHP JavaScript like Number class, this time based on PECL operator overloads.

I Am Not Alone

What I could not expect is that such "wanna write PHP as if it is JavaScript" topic is an obsession for many other developers such Tantek Çelik with his CASSIS or Stoyan Stefanov via JavaScript-style object literals in PHP.
As somebody commented already in one or more related posts, "why on earth do not use simply node.js ?".
Well, if node.js had even half of PHP hosts support, I am pretty sure many of us would have already solved this problem ... unfortunately node.js is "not that ready yet" and for some reason hosters prefer whatever version of PHP rather than a faster and more fashionable node.js.

JHP: JavaScript Hypertext Preprocessor

The name JHP is not new for me. I have used the same name many months before projects like php.js were announced.
While latter project aim is to bring to JS functionalities from PHP, I have revolutionized a bit my own concept of JHP trying to bring into native PHP world all JS possibilities ... here some example:

// $Object and $Function
$o = $Object();
$o->name = 'JHP';
$o->toString = $Function(function ($self) {
return $self->name;
});
echo $o; // JHP

$Object->prototype->toString->call($o); // [object Object]

$me = $Object();
$me->name = 'WebReflection';
$me->hasOwnProperty('name'); // true

$o->toString->call($me); // WebReflection
$o->toString(); // JHP

$f = $o->toString;
$f($me); // WebReflection

// $String
$str = $String('abc')->concat('d', 'ef', $String('g'));
echo $str; // abcdefg

echo $Object->prototype->toString->call($str); // [object String]

// $String is an object
// so it's possibe to define properties (this is a getter)
$Object->defineProperty($str, 'name', (object)array(
// just recicle the method inherited from $String->prototype
'get' => $str->toString,
// set propeties
'enumerable' => false,
'writable' => false,
'configurable' => false
));

echo $o->toString->call($str); // abcdefg
// invoking $str->name as getter
// passing then through $str->toString callback

$a = $Array();
$a->push(1, 2, 3);
echo $a->length; // 3

$a->forEach(function ($value, $i, $arr) {
echo $value.PHP_EOL;
});

// uh, and require as well ...
$require('sys')->print('Hello World');



XMLHttpRequest Example

This is just what's already possible to extend some global.

// sync only ... well, it's PHP
$XMLHttpRequest = $Function();
$XMLHttpRequest->prototype->open = $Function(function ($self, $mode, $uri, $async = false) {
$self->_uri = $uri;
$self->_mode = $mode;
});
$XMLHttpRequest->prototype->send = $Function(function ($self, $data = null) {
// actually with curl we may emulate post, get, etc ...
$self->responseText = file_get_contents($self->_uri);
});

$xhr = $XMLHttpRequest();
$xhr->open('get', 'http://webreflection.blogspot.com/', false);
$xhr->send();
echo $xhr->responseText; // this blog ... somehow


$Array, $Boolean, $Function, $Number, $Object, $String

This is almost all I have so far and everything is absolutely in a prototype/experimental status.
This is why I have not created a repository yet, also because this project was abandoned but just recently I have read the post from phpied.com so I thought ... well, why not talk a bit about my good old experiments as well? Maybe there is something to learn, surely there is a lot to improve, also thanks to latest PHP SPL and ... well, I let you decide what to do with this folder well forgotten in my good old netbook. You tell me if it makes sense, if you like the idea, and accordingly with feedbacks I will eventually consider to re-think from the scratch the whole pile of code in order to make it better, faster, usable, etc etc ... ok?

What's Missing


First of all ... to refactor everything, since at the beginning I remember I was trying to obtain a fresh new environment, or better, its globals, but I trapped myself without bringing the possibility to reuse current globals in a proper way.
Said that, the thing that I have never even started to do, as example, is a Narcissus based parser able to transform for me all JavaScript into JHP, bringing via use all nested scopes so that everything will be automatically available and we can really write JS and deploy on a PHP host ... this sound cool, uh? Well, let me tell you something, PHP is not that bad but such alien cannot surely be fast ;)
Last, but not least, the require uses eval and I hate eval, even if it's damned handy in some case.

How To Test / Where Is JHP


Well, it's here: have fun with JHP!

Sunday, June 5, 2011

ES5 and use strict

Update
There was another article about it which has less examples but more complementary points or descriptions.
Moreover, that page links to a specific use strict compatibility page, right now green only with Firefox Aurora and Google Chrome Canary.
However, another page shows more use strict cases as well and Canary seems to miss one check while Webkit Nightly shows all green YES. Opera Next is not there yet while IE10 surprisingly scores all of them except Function declaration in statements.
Well done guys!


on page 233 of the ECMAScript 5th Edition we can read details about "use strict" activation and what it means for our code.
Somebody believes this ES5 feature can help developers to write less errors ... well, I think not everything is that good as it looks.
This post is about all those points with concrete examples.

No OctalIntegerLiteral or OctalEscapeSequence


Base 8 has not many use cases on daily JS tasks. As example, to obtain the number 8 in base 8 we can write something like 010 where:

alert(010 === 8);

The problem is that 01 is not enough to force the engine to consider that number a base 8 and it will be interpreted as 1 indeed. Fair enough, I personally don't give a hack about base 8 so this does not hurt, it's just slightly simplified numbers parsing.
Same story for OctalEscapeSequence, no "octal magic" anymore.

No Global Variables

If our closure has a reference not defined in the outer scope, there is no global variable but a ReferenceError.

(function(){"use strict";
for(i = 0; i < 2; i++) {
// never executed due "i" ReferenceError
}
}());

Above example is a classic one ... or better, a classic for newcomers with PHP or Python background, as example, where local variables are implicit and global one should be explicit.
While Python has a sort of implicit scope lookup with classes, PHP introduced closures only recently (well, 5.3 which should be right now the default minor version in every bloody server).
Since after 1 day of JavaScript development you should have got it (use var for local scope variables) I do believe this is more a limit, rather than a feature.
First of all, the current situation is quite naif since FireFox does not throw anything, it just stop working, while other browsers may nicely ignore this "feature".
Moreover, the moment we want to define a global reference we need to have in our closure a safe reference to the global context or we are simply screwed.
The second part of this point is that if the reference has been defined as writable:false, aka read only as undefined is, a TypeError should be thrown.

(function(){"use strict";
undefined = 123;
// throw TypeError
}());

Funny enough, if we have nested scope that relies in undefined but the outer one has something like:

(function(){"use strict";
var undefined = 123;
// other nested functions
}());

nothing will happen, undefined is still not trustable.

Safer arguments and eval

... but wasn't eval evil? Anyway, in the forth point of use strict specifications we have errors whenever we try to reassign arguments or eval.
Fine for eval, but a kinda common arguments trick won't be usable anymore.

// this will not work anymore
(function (context){"use strict";
arguments = [].slice.call(arguments, 1);
// some operation with arguments as Array
outerCallback.call(context, arguments);
}());


Goodbye arguments caller and callee

Once again, arguments.callee is gone. Moreover, arguments.callee.caller is done as well but in this case it's not about the caller property, the whole callee concept is gone.

(function anonymous(){"use strict";
alert(anonymous.caller); // throws TypeError
arguments.callee; // throws TypeError
}());

They call it "graceful migration", I call it WTF. If arguments is still there and it's a bloody object similar to an Array, why this object should throw an error with an undefined property?
OK, it's about migration, but actually what use strict introduced here is caller and callee as new reserved words, at least for properties of arguments or whatever function ... well done ...

arguments indexes

Whenever you have noticed or not, if you change a named argument value the arguments object will be affected at the same time. Here a basic example:

// before
(function (a, b){
var c = a;
a = b;
b = c;
alert([].slice.call(arguments));
// b, a
}("a", "b"));

// after
(function (a, b){"use strict";
var c = a;
a = b;
b = c;
alert([].slice.call(arguments));
// a, b
}("a", "b"));

To be honest, whenever it helps or not, I wonder who the hell ever used the first dynamic shared arguments indexed property value case on any sort of logic code ... was it an ES3 gotcha? Well, in such case I agree, it does not make fucking sense so ... thanks, I am sure somebody in this world will have problems about this new entry.
However, somebody that does not know JavaScript and programming principles as well may have problems ( nothing personal man, you just did it wrong 'till now ).
Sarcasm a part, it's good to have this clarification on specs.

Bindings and arguments

For strict mode functions, if an arguments object is created the binding of the local identifier arguments to the arguments object is immutable and hence may not be the target of an assignment expression. (10.5).
Well, if you get anything different form what I have said already about redefining the arguments reference/object, please do not hesitate to wake me up in the middle of the night while I am on vacations since seriously I cannot figure out what's this point about.

Unique Object Property Name

With ES3 we could have done something like:

(function (){
var o = {
one: 1,
one: 2
};
alert(o.one); // 2 ???
}());

Now, since properties order is not granted at all even in a classic for(var key in obj){} loop, this point is about being not ambiguous and do the right assignment once. As summary, with use strict above example will produce an error: property name "one" appears more than once in object literal.
Once again, if you ever tried to assign same property more than once ... well, I can just say it's good they made this less ambiguous but I do believe this won't improve anybody code quality (being a mistake every Unit Test would have spot in any case).

arguments and eval as reserved identifiers

It's just like that, an argument cannot be called eval or arguments otherwise we gonna have a SyntaxError.

(function (){"use strict";
function testEval(eval){}
function testArguments(arguments){}
var o = {
get test(eval) {}
set test(eval) {}
};
}());

All cases will throw an error so, once again, hwew ES5 is introducing partial reserved keywords and this is wrong, imho.

Strict eval

I am not sure I got the next point, but here some behavior:

var evil = (function anonymous(){"use strict";
return function (o_O) {
var result = eval(o_O);
alert(b);
return result;
};
}());

evil("function b(){}");
// function b(){'use strict';}


// example 2
var evil = (function anonymous(){"use strict";
var a = 123;
return function (o_O) {
var result = eval(o_O);
alert(b());
return result;
};
}());

evil("function b(){return a}"); // 123
Apparently eval has been maden a bit safer but I can see its evil nature all over the place without problems. Kinda good that function defined through eval inside a strict function are automatically strict as well so I guess this point is about strict inheritance through evaluation.

Strict this

There are different behaviors completely changed and it's not all about undefined === this.
Actually, it's not about this as undefined at all, it's about not changing the reference to something different.
There is a classic trick to obtain the global object in the most secure possible way:

var global = function(){return this}();
alert(global); // [object Window]
// [object global] in node.js

Above example is the equivalent of this function:

function Global() {
return this;
}

window == Global.call() == Global.call(null) == Global.call(undefined);
// true

Untill now, the this reference has always been changed into the global object if the context was null or undefined.
Moreover, the reference has been changed into a proper object reference with primitives values such boolean, number, and string.

// ES3
function previousHello() {
// primitive converted into new Primitive
// e.g. this reference is a new String(s)
alert("Hello " + this); // Hello World

// we can add properties to new String
this.test = 123;
alert(this.test); // 123
}
var s = "World";
previousHello.call("World");
alert(s.test); // undefined
// since properties cannot be attached to a primitive

I don't remember I have ever defined properties runtime when the callback was about primitives values.
To me is like using objects as trash bin since nothing can be possibly reused after the function has been invoked.
This is what is changed in ES5 and use strict, there is no magic anymore when call or apply are used.
A primitive value will be primitive, an undefined one will be undefined and null will be null.
Here the test case:

// ES5
function sayHello() {"use strict";
alert("Hello " + this); // Hello World
this.test = 123;
alert(this.test); // undefined
}
sayHello.call("World");


function nullThis() {"use strict";
alert(this); // null
}
nullThis.call(null);


function undefinedThis() {"use strict";
alert(this); // undefined
}
undefinedThis.call();
// same as
undefinedThis.call(undefined);

It must be said that all these changes make life easier for engines behind the language since call and apply are widely used and all those checks about the context type and its eventual convertion are gone.
At the same time I would have reserved null as only exception to retrieve the global context since we have no more any safe way to do it and this is in my opinion bad.

More greedy delete

While before we could have tried to delete variables, and without success:

(function test(a){
var b = "b";
delete a;
delete b;
delete test;
alert([a, b, test]);
// a,b,function test(){...}
}("a"));

We cannot do this kind of mistake anymore since a SyntaxError will occur.

(function test(a){"use strict";
var b = "b";
delete a;
delete b;
delete test;
alert([a, b, test]);
}("a"));
// SyntaxError
// applying the 'delete' operator to an unqualified name

The fact this was not possible was clear in ES3 specs but ,,, hey, now we know it better.
Only object properties with a configurable option equal to true can be deleted and nothing else.

TypeError on delete

Even if a property is not writable, we can still delete it since it is considered a configuration option.

(function test(a){"use strict";

var o = Object.create(null, {
deletable: {
value: 123,
configurable: true,
writable: false,
enumerable: true
}
});
alert(o.deletable); // 123
// o.deletable = 456; // Error: read-only

// bye bye property
delete o.deletable;
alert(o.deletable); // undefined

// free to manipulate
o.deletable = 456;
alert(o.deletable); // 456

}());

To seal/froze the property and to avoid delete operation all we need to do is to mark it as not configurable.

(function test(a){"use strict";

var o = Object.create(null, {
deletable: {
value: 123,
configurable: false,
writable: false,
enumerable: true
}
});

delete o.deletable;
// Error: property o.deletable is non-configurable
// and can't be deleted

}());

Since to be able to set properties as non configurable we need ES5 already, I think this was a mistake in the use strict rules because I would expect the same behavior for something introduced in ES5 as well as Object.defineProperty is.

Goodbye with statement

Whenever you like it or not, the with statement is gone.
I seriously do not want to spend more than I have done already about it so ... forget it, be happy about the choice and shut up or Mr Crockford and all minifiers will come out the dark wardrobe and punch you in the face.

Reserved arguments and eval identifiers

Everything else about use strict is related to arguments and eval keywords.
These cannot be used in function expressions, declarations, as variables, these cannot be reassigned, these must be used exclusively for what these are ... got it?

Summary

ES5 introduced use strict to let developers be familiar with things that will disappear soon in the next version of JavaScript.
I am not happy about many choices, specially regarding the caller property which was a must have for debugging and introspective purpose but ... hey, engines are not clever enough to activate these things when necessary but these engines are able to swap runtime a totally different behavior between a non strict function and a strict one.
In few words we still do not have full JavaScript potential here because of this transition that is apparently revolutionary behind the scene, surely not the best present ever for all developers that got JavaScript and used few tricks when necessary to improve their application logic and, why not, security.
Well ... deal with "use strict" and put it there by default or shut up for all new version of JavaScript ... this is the way in any case.

Friday, June 3, 2011

Partial Polyfills

This is a quick one already discussed during my recent workshop in Warsaw, a concept rarely considered or adopted from JS developers.

What Are Polyfills

If we are updated enough to know ECMAScript 5th Edition, we probably know all possible shims and fallbacks for Array extras as well (e.g. Array.prototype.forEach).
Polyfills are simply snippets able to bring features already available for most recent browsers into those not updated yet.

Why Polyfills

If we develop with present and future in mind, we can take advantage of most recent techniques and solutions in order to both speed up via native support, where available, and maintain our application just stripping out code once all target browsers support them natively ... isn't this cool ?!

Polyfills Side Effects

The most common side effect of a polyfill is performances impact. The Array::forEach is already a good example of decreased performances.
If we think about a forEach, it's nothing different than a classic for loop, except we can reuse a function and eventually inject a different context.
As summary, while the code size will be reduced and all "Array loops gotcha" resolved nicely, old browsers already slower will be even slower due simulated native behavior implemented through JavaScript.
The second most important side effect is that sometimes we cannot possibly reproduce the new native behavior via old JavaScript, which means we are compromising logic and potentials of our application in order to support "not there yet" browsers.

Partial Polyfills

Once we have defined a "full specs simulated" polyfill we can forget problems and use it whenever we want. Unfortunately, we have to agree with all other external libraries as well, libraries that would like to be dependencies free and that most likely will re-implement or re-check over and over if that polyfill is present or not.
On the other hand, there are many situations were we do not need the full implementation of a missed feature and in these cases the advantage of a partial polyfill will result in reduced and safer code.

What Is A Partial Polyfill

Let's take the classic Array.prototype.indexOf as example and check the size and the "complexity" of the full spec proposal in MDC ... done?

// our main library closure
(function () {

// all we may need to indexOf
var indexOf = [].indexOf || function (value) {
for (var i = this.length; i-- && this[i] !== value;);
return i;
};

// wherever we need ...
var index = indexOf.call(arrayLikeObject, value);

// end of our main closure
}());

If we deal with properly defined arrays, arguments, or DOM collections, and if we use indexOf simply to avoid duplicated entries in a generic stack, ask yourself if it makes sense to implement the full specs there rather than those two lines of JS showed above.
As somebody noticed, that snippet is more similar to Array.prototype.lastIndexOf, due reversed loop, but why bother if our indexOf use case is specific?
Why pollute the global Array.prototype causing potential problems for other libraries?
Why make the "search into array" routine more expensive for already slower browsers?
In few words we can reuse few extra bytes in every closure we want to obtain a simplified indexOf behavior compatible with every browser, isn't it ?!

Why Safer

Unless we are not sure 100% that the Array.prototype.indexOf has been replaced with a full specs version and since we may lazy load extra code that may be greedy or change again that prototype, we can address that callback and use call as much as we want being sure that no library will ever change our expected performances and/or behavior.

Why Smaller

Not only we can copy and paste those two lines of code in many places without impacting code size, we can also take advantage of most popular minifiers, able to make each call smaller.

// minified indexOf through prototype
a.indexOf(b);

// minified addressed indexOf
x.call(a,b);

Last, but not least, using call we can automatically use by default the indexOf with objects and every other ArrayLike variable.

Conclusion

There are many cases where we may need one or more ES5 feature but not all of them will be used 100% of their potentials. A partial polyfill can ensure better performances and easier access in the private scope.
Surely we may avoid this technique if by default we normalize all behaviors but once again, we all know we don't like much core functionalities dependencies that may be broken or extremely slow for what we need in our specific cases.