Thursday, April 17, 2014

A trip into Clojure, lesson learned

In my current job I had the chance to learn and use Clojure (this is the experience reported by a former collegue). Having worked with Python and Javascript I had consided myself well skilled in functional programming. But working with a more opinionated functional programming language was an eye opener. The benefits? robustness, better code reuse, a more organic workflow.

My main takeaway is that I can apply the lesson learned to Python and Javascript (and many others) as well. Let's see how.

Languages

Many languages enforce a specific point of view. Java for example with its pervasive object orientation enforce to model problems in objects. Python tries to please everyone with a solid OO implementation and a good deal of functional constructs. Javascript is similar (but with a different OO implementation).
Clojure, from this point of view, is more like Java: it enforces a specific way to model problems: a functional model.

Functions

Of course functions are first class citizen in a functional language so they can be stored in variables, passed as argument etc.
This allows a lot of useful programming patterns. These are just few examples:

  • Passing a callback: in event oriented programming (like events in browser or node.js) it's useful to pass a specific callback to run after an event
  • Decorator: you wrap a function in another function (useful for access control, memoization etc.). In Python there is a programming feature called "decorator" that makes easier to use this pattern.
  • Lazyness and partials: a function retuning not the actual result but another function that return the result. Useful to defer the actual task and if you need only a part of the result.

A brilliant example of what functional programming allows are wsgi middlewares (in the Python world) and Connect middlewares (in the node.js/Javascript world). As a matter of fact you can find a similar pattern in Clojure ring.

No objects - nothing enforce a local state

While the classic OO tries to encapsulate logic and state in the same entity (objects) a functional language keeps the two things well separated. This seems to be weird if you are used to OO but it has a lot of sense.
It is easy and more predictable to test the code because you are sure there is no mutation of the local state during the method calls. Any function has arguments and output: there is no side effect based on value of "this". Actually in Clojure you can have side effects (mutating atoms for example) but this is an exception, not the rule. And this is clearly explicit.

Types and common interface

Standard maps/lists offer a common and simple interface to a lot of generic functions. In the classic OO every object has a different interface requiring specific code to interact with.

In Javascript there are fantastic libraries like underscore, lodash to interact with standard arrays, objects (intended as maps in this case). You can also use hash maps and sets (Ecmascript 6). If you use  field descriptor you can access getters and setters using the usual semantic.

If you use Python, you should use more list an dict and less custom objects. Python can help you to keep the interface simpler using field descriptors and operators overloading. There are a lot of functional built in (like zip, map, filter, list comprehensions ...) and the fantastic itertools library.

(Im)Mutability

An immutable object cannot be changed. Any change creates a new object.
Mutable objects are a dangerous source of bugs. It's very easy to change an object passed as argument or by another function call without realizing that you are changing permanently the original object. This is a classic python gotcha.
It's not only a newbie's mistake: I have spotted the same nasty bug in Backbone.js.

In this case Clojure shines because everything is immutable by default.
If you use Python, you should never mutate an object/dictionary/list passed as argument. If you really need to do that, clone it before. Remember that list comprehensions, slice operator, and many built-ins return a brand new object and are safe. But it is better to check the doc because for example the "sort" method mutate the original list and the "sorted" built-in no.

The same advice is valid for Javascript too. Check the usual underscore and lodash for  clone and deepClone method. Remember that some array method returns a brand new array. This is a shallow clone but sometimes is good enough. A fantastic option is to use mori a library to use Clojure(script) data type and sequences in Javascript.

Lazyness

Working with sequences in Clojure is amazing because any operation is deferred. This is memory and computational efficient. This is not a new thing if you use Python generators, itertools or the new Javascript iterators and the for-of statement (ES 6). You can also use the Clojure sequence library with the aforementioned Mori library.

Development process

The functional approach (in my personal opinion) allows to develop in a more gradual way. While in the OO you have better results deciding the object model upfront, this is a bit complex in the long run. Some changes will require to move methods around the class hierarchy, create common base classes. And this kind of refactoring often invalidates a lot of unit tests too. So you often ends with small patches and code duplication.
The evolution of a functional program can be a bit chaotic but changes are more granular and it's easier to reuse code without doing a lot of impact.


This is the lesson learned: be more functional!

P.S. This is a nice book if you want to improve your Functional Javascript skills

Sunday, March 23, 2014

When scripts should run?

A quick walkthrough on when executing a script in the browser.

A lot of examples on the internet show to wrap the code inside the jQuery "ready" event handler. It is not always the case. As a matter of fact you can execute a script in three different fashions:
  • immediately
  • in the ready event handler
  • in the load event handler
  • under another event handler (but this is a different story though)

Immediately

You can execute a script immediately if your script doesn't rely on the DOM, or rely on a fragment of DOM that is already been loaded (because is placed before your script).
I think this is often the preferred case.

JQuery ready

The jQuery ready event handler uses the  domcontentloaded event but is guaranteed to be executed right away if this event is already been fired.
"The handler passed to .ready() is guaranteed to be executed after the DOM is ready"
You should execute your script here if it runs before the fragment of DOM targeted by the script. Given this, if you are loading synchronously you should definitely put the script at the bottom of the HTML and just execute it immediately.

On load

There are rare cases when you need the CSS and images loaded before executing the script. A suggestion: avoid it if you can! For example you could (and definitely should) add the width and height attribute on any img and you can use a bit of inline css styling (in some edge case).
In the few cases you really need this you can use the load event handler.

Asynchronous loading

If you use requirejs you really don't have a clue on when your script is executed. Luckily enough executing it immediately or inside a jQuery ready event is always safe. It's not so using the load event.
Your script could be loaded after the load event is already been fired. For this reason is a good idea to check it and, in case, executing the script immediately.

function mycode(){
   ...
}

if (document.readyState == "complete"){
    mycode();
}
else {
    $(document).load(mycode);
}

Ajax fragments

When you load or create a new fragment of html sometimes you need to run the some code against the new fragment. This can be avoided the vast majority of time using event delegation adding your event handlers to a wrapper node (or to the document itself). If you really need to manage this I suggest to generate a custom event to manage these cases. For example:

// loading a fragment
var $result = $("#result")
$result.load("ajax/test.html", function (){
    ...
    $result.trigger('nodeloaded');
    ...
});

...
// trigger on the document ready 
// for the whole document
$(document).ready(function (evt){
    $(document).trigger('nodeloaded');    
});

...

// manage the event
$(document).on("nodeloaded", function (evt){
    $('.your-class', evt.target).yourplugin();
});

You can find something similar used in jquery mobile.


Sunday, January 26, 2014

Requirejs: edge cases


I have already written about requirejs in this post.
In this new post I'm going to explain something you should know using require in complex environments.

You definitely should use the optimizer

Not using the optimizer in a production environment is highly discouraged.

To explain why, it can be useful thinking about how requirejs works:
All the modules together form a dependency tree. The process of loading this tree is not completely parallel because requirejs is aware of specific dependencies only after loading a module.
Requirejs optimizes this process executing a module only once and caching its result.
The optimizer simply merges a group of modules in a single file and this makes the process much faster.

Inline scripts

Sometimes you'll need to add online scripts to the HTML. Doing this you should consider that your module could be not loaded yet. To fix this problem you can "require" your bundle as a dependency before running the code:

require(["app"], function (){ // app is the name of the bundle
    require(["yourdependency"], function (){
        //inline script
    });
});

But there is another problem!
Many examples shows to put your requirejs configuration inside the first module.
Sometimes you'll need a specific configuration to load your module (for example the baseUrl). But the configuration could not be available in your inline scripts (it's async!).

There is a trick for this: requirejs allows to load the configuration in a synchronous way. You just need to define a global object "require" with the configuration right before loading requirejs script.

<script>
var require = {
    "baseUrl": "http://example.com/js/lib",
    "paths": {
      "app": "main/app"
    },
    "shim": {
        ...
    }
};
</script>
<script data-main="scripts/main.js" src="scripts/require.js"></script>

Mixing synchronous and asynchronous scripts

Performance wise all the scripts should be loaded asynchronously but real world applications need some compromise.
A typical case is using the infamous document.write that wipes out the page when executed asynchronously.

In this slideshow @slicknet explains why loading scripts in different positions.

But mixing synchronous and asynchronous script can be tricky. How can do it safely?

First of all be careful where you load the requirejs script in the page. Many libraries check for the presence of the "define" global variable to be loaded asynchronously (using the UMD pattern):

(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['b'], factory);
    } else {
        // Browser globals
        root.amdWeb = factory(root.b);
    }
}(this, function (b) {
    //use b in some fashion.

    // Just return a value to define the module export.
    // This example returns an object, but the module
    // can return a function as the exported value.
    return {};
}));


Jquery for example is AMD compatible so, if you load requirejs before jquery, this will behave in a different way.
My suggestion is to concatenate all the synchronous files of your application in a single script, putting requirejs in the last position.

Second problem: what happen if you are requiring a module and, in this particular page, this module is already loaded synchronously ?
Requirejs will download the module again, this time as a module. This is not ideal so you need to trick requirejs prepending to our main module something like this:

define('jquery', [], function() { // jquery is loaded synchronously before this code
    return jQuery;
});

With the previous code requirejs will use the global jquery instead of requiring a new jquery module to the server.
I am not advocating to load jQuery syncronously. This is just an example!
Another issue: the optimizer will include all the scripts that in your particular case are synchronous.
You need to exclude these files from the optimization (this is an example using the grunt-contrib-requirejs task):

    requirejs: {
      dev: {
        options: {
        "appDir": "www",
        "baseUrl": "js/lib",
        ... other options ...
        "modules": [
            {
                "name": "app",
                "exclude": [
                    "jquery",
                    ... other exclusions ...
                ]
            },
            ... other bundles ...
          ]      
        }
      },

Loading dynamically

In some case you'll want to download a different group of modules in a more dynamic way. Based on a certain configurations or user event (like in this example)
For doing this you can create one or more different bundles (with the optimizer).
You need to remember to exclude from the bundles the resource that should be already loaded in the page (use the previous option).

Scripts not bundled

In some case you don't want to include your file in a bundle because is served by a CDN or directly from your application (for example socket.io). The requirejs optimizator uses the "empty:" option to manage this:

    requirejs: {
      compile: {
        options: {
          mainConfigFile: "static/js/main.js",
          baseUrl: "static/js",
          name: "main",
          paths: {
            'socketio': 'empty:',
            'backboneio': 'empty:'
          },
          out: "static/js/main-built.js"
        }
      }
    }

Requirejs is a very good choice to manage scripts loading and dependencies. I hope to have brought light in some of the dark spots of using this in a complex environment.