Monday, June 04, 2012

Working With Queues

Programming with queues is basically what we do in any case: it does not matter if we write code in that way, we simply think in that way.
This means that our logic flow is generally distributed in tasks where "on case X" we apply "logic/procedure Y" .. isn't it?

The Good'ol GOTO

The goto statement has been historically criticized, as well as the switch one, and in both cases is about entry and exit points in a generic workflow.
Nowadays, we can say the GOTO is not needed anymore thanks to functions, where rather than thinking "when this case occurs, goto this instruction" we call the required function in charge of that specific task providing arguments or context as we go.
We may then agree that GOTO is not really a must have while functions are, with all the power and flexibility we might need, and specially in JavaScript.

On Block-Scope

JavaScript has theoretically no block-scope concept, at least until very latest versions of ECMAScript where blocks can be written in the wild.
Blocks are cool for partially independent operations that should not affect at all the external scope/logic but if we think more about this, the usage of inline function expressions has replaced the block-scope concept for a while.
Even better, any function in JS could be considered a sort of equivalent of a block scope, with the advantage that we can re-call the same function as many times as we want, with limits in recursions, avoiding the GOTO and still using block-scopes.

All Together

What if we use as many functions as we need, in order to complete our flow, without compromising the external environment and being able to re-call segments of our flow when something goes wrong?
This can be easily done with a queue system, like the one showed below:


A Few Examples

Here a very basic example on how to use above queue system. There are two sequential things to do, waiting for some truish condition then do something.

Queue([
function (q) {
q.wait(document.body);
},
function onBodyPresent(q) {
document.body.innerHTML = "Hello queue!";
}
]);

The wait() method calls next "block" to execute, as next function, if any, only if the condition passed as argument is true, waiting otherwise "0 ms", if not specified differently, before the same "wait for" block logic is re-executed.
While this example does not show real potentials of queues based programming approach, the next one could do it.

!function () {
var
init = function (q) {
if (!result) {
number = Math.abs(prompt("factorial of:")) || 1;
result = 1;
}
q.next();
},
verify = function (q) {
if (1 < number) {
result *= number--;
q.unshift.apply(
q,
program.slice(
program.indexOf(init),
program.indexOf(verify) + 1
)
);
}
q.next();
},
showResult = function () {
alert(result);
q.next();
},
program = Queue([
init, verify, showResult
]).slice(),
result, number
;
}();

Above code is a factorial program: all logic blocks are known in advance and the queue is constantly re-populated until the condition in the middle is satisfied.
While performances are not the best, but generally speaking performances are never a problem when a queue logic is needed, since queues are awesome specially for asynchronous tasks that are rarely good for real-time programming, this factorial program does not use recursion, is quite easier to understand and debug, and it does not blow the RAM usage: functions are recycled as well as the queue which will never grow more than 3 indexes so just wait ... and the result at some point will appear ;-)

Asynchronous Example

As I have said already, queues are great for asynchronous tasks helping with indentation, never too many nested functions, logical workflow, each function does a little but it does it well, readability, functions are named in a semantic way but minifiers will simply shrink them once executed, and even if this does not look that OOP, I bet once we start getting use to this approach things will be easier than ever.

!function () {
// warning: this code is a proof of concept
// it won't work as it is ...
var
// query selector shortcut
$ = function (css) {
return document.querySelector(css);
},
// while user and pass fields are empty ...
login = function (q) {
q.wait(
$("#user").value.trim()
&&
$("#pass").value.trim()
);
},
// once user and pass are not empty anymore
verify = function (q) {
var xhr = new XMLHttpRequest;
xhr.open("post", "verify.php", true);
xhr.send([
"user=" + encodeURIComponent($("#user").value.trim()),
"pass=" + encodeURIComponent($("#pass").value.trim())
].join("&"));
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
q.result = xhr.responseText;
// call next function
q.next();
}
};
},
// verify if the user exists
authorized = function (q) {
if (q.result === "ok") {
q.push(ok);
} else {
// notify the error plus re-queue logic between
// login and authorized included
q.push.apply(q, [error].concat(program.slice(
program.indexOf(login),
program.indexOf(authorized) + 1
)));
}
q.next();
},
// end of the program
ok = function (q) {
alert("Welcome!");
// could go on with the same queue
// passing through a different program
},
// warning for the user
// plus resetting fields
error = function (q) {
alert("user or pass not recognized");
$("#user").value = "";
$("#pass").value = "";
q.next();
},
// clone of the whole program
// reused later to recycle segments
program = Queue([
login, verify, authorized
]).slice()
;
}();


Where Queues Are Used

Well, almost everywhere ... Testing Frameworks are usually based on queues, specially those with asynchronous support for different tests. Same is for JavaScript or CSS loaders, based on queues when it comes to order.
Any sort of stack/Array not representing data, is usually a queue we consume during our logic ... promises are queues too, and same is for events, these are all queues.
Should I explain more? Probably yes, but I'd prefer if you have a look at these examples, use the simple Queue function I have written, and create something awesome that makes the logic of your app cleaner and better organized.
Last, but not least, did I mention that logging a queue gives us instantly a logic workflow of what's going on and accordingly with where it's going on? console.log(q.slice()) anywhere you need and you'll see all named functions you gonna deal with after the one is executing in that moment.

Labels: , ,

Tuesday, May 29, 2012

on "manifestcontentavailable" event


Even native apps have something like a preload when it comes to launch them ... and guess what happens during that time?
Nothing that different from synchronizing content or looking for an update, isn't it?

Same Could Be For Mobile Web Apps
If you need your manifest to be loaded, in order to provide best UX ever, you might need a mechanism to be sure that everything that has to be there ... oh well, is simply there!

AppCache VS Binary
Well, one handy thing about the Application Cache Manifest for Web Apps is that you might update only a single part of your software.
As example, if you have external libraries you might decide to serve them a part, as external or independent content from the rest of the app ... and rather than download again the whole thing, the user will update only that dependency ... I mean, this is cool but rarely used due common build processes where a single changed comma of a single file will require the whole app file update, you know what I mean?

My "manifestcontentavailable" event proposal
Nothing really skilly here, simply a handy event that could be useful for any sort of app that would like to have everything available ASAP ... where everything is actually any file in the home page plus any file present in the manifest.
Conditions considered in this proposal are:
  1. the manifest has been fully downloaded, first visit in your page
  2. the manifest changed somewhere, new files have been replaced locally
  3. the manifest didn't change at all, everything is already available
  4. the user is offline, no need to even bother with new manifests or files
All other cases where the manifest is corrupted ... well, aren't a matter of this event since we all have tools to be sure that the manifest points ti existent files and everything is OK, right?

This is basically it ... a loading spinner in charge of entertainment for new users and those waiting to update their content, a basically instantly available page once users are offline.
The main point is: users download the whole thing once connected and, theoretically, never again thanks to the manifest mechanism.
The page itself doesn't do much more than show a spinner while the real stuff is being downloaded.
Once this content is available, and except for those JSONP calls to our favorite online service, the experience should be as smooth as possible without hundreds of spinners in the wild during our Web Ap interaction ... and I believe this is cool!
The script, easily minifyable in a bounce of bytes, should do the trick with all modern/mobile browsers and in a totally unobtrusive way ... if you listen to that event, you get it, otherwise nothing else will change.

Why
I believe we are not getting the full power of this manifest concept so far and a proper event able to notify what's going on there, easy to setup, use, and configure, could be a must have for many Web Apps out there but please feel free to comment here what'ya think about this approach, side effects, or problems I might have not considered, thanks!

Saturday, May 12, 2012

Rubik's Cube Analogies in IT Development World

Oh well, during my free time without laptop I came up with this talk about Rubik's Cube and Development process.

I'll let you enjoy the video, hopefully ..., and leave comments here, if necessary.

The big summary is: there's a lot to learn from the cube, so take this as a hint to learn how to solve it and find even more analogies on your daily basis tasks.



Update
if you ever wondered how I created the talk cube situation, I have simply used RGBA as clockwise or anti-clockwise approach ... if you have a solved cube, consider the Alpha as the White, and turn anti-clockwise White, Blue, Green, Red ... you'll have a quite messed up cube you can always solve easily via Red, Green, Blue, White, or you gonna solve it the way you know, the way I did, probably with 2 shortcuts in the middle I have ignored for this kind of talk.

Tuesday, April 10, 2012

Graceful Migration From ES3 to ES5

Just slides I have showed today here @ nokia for a tech talk, hope you'll enjoy them, cheers

Update
Here you can find the updated version of the Object.forEach proposal: gist 2294934
Main changes are about some inconsistent behavior in Safari, not it should work without problems.
Thanks to @medikoo for his hint.

... rock'n'roll ...

Labels: , , ,

Friday, March 16, 2012

On Obtrusive Polyfills

I'll try to make the point short and simple, starting with the tl;dr version: if you create a polyfill and during features detection you realize this cannot work, drop it and let other libs deal with it.

Broken Object.defineProperty

This is just one case really annoying. Bear in mind I am not talking about "making perfect polyfills", this is almost impossible most of the case, I am talking about broken runtime even if you did not really do anything that special.
It was the case of Object.defineProperty shimmed through es5-shim code ... this library is good but that method, as many others, are simply broken.
I was trying to add a setter/getter in IE < 9 and shit happened, more specifically a thrown exception happened ... the repository itself explains that this method and others should fail silently ... so it's OK for the developer to know about it and avoid trusting these methods ...


This Is Not OK

If I check if Object.defineProperty is there and this is all I need to know, I don't want to double check which version of IE, if IE, it is, neither I want to check anything extra.
I simply trust the fact the browser, or some library, fixed the problem for me and I can use this method as it is.

if ("defineProperty" in Object) {
// I want to use it, wouldn't check for it otherwise
}

A broken shim doesn't make anyone life easy while that simple condition in my code could redirect my logic in a completely different approach.
Since in IE < 9 that method simply does not make sense to exist, then it should not exist, period.

Remove The Broken Shim

I hope, and expect, that es5-guys will simply delete Object.defineProperty afterward, once realized it's not usable.
I would not compromise entirely theObject.create but again, if defineProperty() is not there there is no bloody point on using create() too.
Let other libraries deal with the fact this is missing in their own way since every single case could be different: someone simply need to inherit another object, someone else might need the method as it should be.

As Summary

A shim/polyfill that works 90% is OK, specially if the API is covered 100% and even if behind the scene things are not identical, but a polyfill that let a piece of code think everything is fine and the whole app breaks who knows when and why should not be exposed at all or, if you really want to bring similar functionality, it should be exposed prefixed, i.e. Object.$defineProperty() so that the rest of the code is aware that such method exists but it's limited.

Thanks for understanding

Labels: , , ,

Friday, March 09, 2012

A Tweet Sized Queue System

The Code

This is the 138 bytes version:

function Queue(args, f) {
setTimeout(args.next = function next() {
return (f = args.shift()) ? !!f(args) || !0 : !1;
}, 0);
return args;
}

While this is the 96 one:

function Queue(a,b){setTimeout(a.next=function(){return(b=a.shift())?!!b(a)||!0:!1},0);return a}


The Why

In almost every QCon London talk I have heard the word asynchronous. Well, the aim of the tweet sized function I have just written above is to make things easier.
After I have implemented builder/JSBuilder.js for wru, so that Python is not needed anymore to build the tiny library, I needed to make builder/build.js usable in a way that asynchronous calls through node won't bother, at least visually, the normal flow of the script.
After that I have thought: "why not making a generic Queue function with Promises like approach" ?

The What

It's quite straight forward, you create a queue, you use the queue. You might eventually pollute the queue or change its order, since the queue is nothing different from a generic Array with an extra method on it: next().
Here a basic example:

Queue([
function (queue) {
// do amazing stuff asynchronously
setTimeout(function () {
queue.message = "Hello Queue";
queue.next();
}, 500);
},
function (queue) {
// do something else
alert(queue.message);
// Hello Queue
queue.next(); // not necessary at the end
// does not hurt thought
}
]);


That's Pretty Much It

So, the queue argument is the array created initially to define the ordered list of function.
This means you can recycle this variable even adding custom properties but most important is that you can change the queue via Array.prototype.splice/unshift/pop/push() methods and decide the future or the next function to execute runtime, if needed.
The only extra bit is about returning true or false in case there was a next() to execute or not.

Last, but not least, of course you can create new Queue([]) inside queues ... so, this is actually more powerful than many other queue systems I have seen so far and ... hey, 96 bytes: enjoy!

Labels: , , ,

Thursday, March 08, 2012

I Heard You Like To Write Less

Update apparently this proposal is being considered in es-discuss ... not the implicit return so far but the "redundant" function keyword.
This is last draft from Brendan Eich:

FunctionDeclaration:
function Identifier ( FormalParameterList_opt ) { FunctionBody }
Identifier ( FormalParameterList_opt ) [no LineTerminator here] { FunctionBody }

ShortFunctionExpression:
Identifier_opt ( FormalParameterList_opt ) [no LineTerminator here] { FunctionBody }
Identifier_opt ( FormalParameterList_opt ) => InitialValue



I'm @qconlondon waiting for the next talk so I decided to take a couple of minutes to blog about this little experiment.
In ES-Discuss developers are still talking about function keyword, if it's needed or not.

I believe the fact CoffeeScript has no explicit function is one of the major reasons devs have been attracted so I made it even simpler.

Just Drop The Function

With current ES 3, 5, or 5.1 syntax I can't really see problems or ambiguity removing that keyword but if you find a case that could fail please let me know.
Of course if we use a keyword we should be able to understand the difference, i.e. with for, if, or others, and this simple test page is just an experiment: you write some code, you "functionize" it, and if the code does not run it's showed highlighted in red.
The RegExp is quite simple and straight forward and parsing time should never be a problem even for big projects.
The return is implicit, a bit Ruby style, but of course you can chose to return in the middle of a function.
Thing is, the very last statement will be returned and you can play with results.

I wonder if anyone would use such syntax on daily JavaScript coding. The parser needs improvements in any case so just think about it and let me know. Cheers

Labels: , ,