Wednesday, October 23, 2013

EMCA Sub Arrays - An Interesting Technique

Dealing with javascript arrays can be a breeze, or it can be bothersome. The array.length property having the ability to change the array is VERY difficult to replicate. You almost cannot make your own typed arrays. At least you can get pretty close. Take the following code snippet I am investigating.

Running this code will make a ZOMBIE array (as I call it.)

(Warning, I am not responsible for unintended "features" your code exhibits.)

function SubArray(length){
   Array.call(this); //"Magic"
   if(typeof length == "number" && length%1==0&&arguments.length==1){
     this.length = length; //Length has to be set manually for some reason.
   }
   else{
     var _len = arguments.length;
     this.length = _len;
     for(var i = 0; i<_len; i++)
        this[i] = arguments[i];
   }
}

SubArray.prototype = [];

var x = new SubArray();

Presto Change-o!

Suddenly you have a strongly typed array, albeit with a few small caveats.

//Evaluate the following
var x = new SubArray();

typeof x; //"object" -- Just like when you declare a new Array....
Object.prototype.toString.call(x); //"[object Object]" -- To be expected
x instanceof Array;//true -- This is the way the Array functionality would be identified

x.push(1); //2
x;//[undefined, 1]
x[2] = "test";

//Drum roll please....
x;//[undefined, 1]

Wait... what? The property wasn't even set! It just disappeared. Or did it? Check console.log(x[2]); . So what really happened is the .length property wasn't set and the array wasn't updated. However, if this particular limitation does not hold you back, it's very easy to work with it because you haven't done ANYTHING to modify a native prototype.

I would probably use this technique for some fun stuff, but what you really wanted was an Array in the first place... so just return an array and add some properties to it instead. It's lame, but it works.

Or you could simply wait for Native Object inheritance in some later version of EMCAscript that is coming down the pipeline.

In functional health, Josh

Tuesday, October 22, 2013

Hello Nodewebkit!

Have you ever wondered what it would be like to package up node modules and run them in a windowed desktop environment using HTML and Javascript?

Well, nows your chance!

Node Webkit

Node-Webkit is by far one of the coolest runtime environments ever synthesized by man. Ever. It's currently in 0.8.0-rc1 and is actively being developed by Roger Wang. Let's take a closer look at some of the concepts that were introduced by this framework.

Here is a presentation to get you up to speed if you have not heard of it yet.

Node as a Desktop Runtime Environment

Node webkit takes the Chrome-web-browser and fuses it to the node runtime environment. (Actually the module, require, and global variables are hoisted into a chrome window, but that's too technical. Let's just get started already!)

Getting Started

If you haven't downloaded node.js yet, you may want to download Version v0.10.17. Follow node's instructions on installing it. Or if you are running linux, have git, and make installed...


git clone https://github.com/joyent/node.git
cd node
./configure
sudo make
sudo make install

After that, install grunt. Open a command terminal and type:


npm install -g grunt-cli

Grunt will help streamline your publishing process. Feel free to check out this tutorial on grunt if you are worried about using grunt. Also, make sure to put sudo before the install command if you are running linux.

Next, create a project folder and open a terminal instance to it.

npm init
(package.json)
{ //follow the instructions on creating the file and edit it yourself afterwards
  "main": "index.html",
  "name": "nw-demo",
  "description": "demo app of node-webkit",
  "version": "0.1.0",
  "keywords": [ "demo", "node-webkit" ],
  "window": {
    "title": "node-webkit demo",
    "icon": "link.png",
    "toolbar": true,
    "frame": false,
    "width": 800,
    "height": 500,
    "position": "mouse",
    "min_width": 400,
    "min_height": 200,
    "max_width": 800,
    "max_height": 600
  },
  "devDependencies":{
    "grunt-node-webkit-builder":"~0.1.11"
    //Feel free to add coffeescript and your favorite libraries here
  },
  "js-flags": "--harmony_proxies --harmony_collections",
  "webkit": {
    "plugin": true
  }
}

It will spit out a package.json file for you. This package configures your node-webkit application.

From that folder run...

npm install

...create an index.html file...

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <h1>Hello Node-Webkit!</h1>
</body>
</html>

...and a gruntfile... (gruntfile.js)

module.exports=function(grunt){
    grunt.initConfig({
      nodewebkit: {
        options: {
            build_dir: './webkitbuilds', // Where the build version of my node-webkit app is saved
            mac: true, // We want to build it for mac
            win: true, // We want to build it for win
            linux32: false, // We don't need linux32
            linux64: false // We don't need linux64
        },
        src: ['./*','./js/*','./css/*'] // Your node-wekit app
      }
    });
    grunt.loadNpmTasks('grunt-node-webkit-builder');
    grunt.registerTask('default',['nodewebkit']);
}

... and finally run grunt.

grunt

Whew! That was a lot.

While everything finishes up, (and downloads all the binaries needed to make this happen) we will discuss what you have just created. Essentially, nodewebkit packages up all of your source files into a virtual directory/zip file and delivers them like normal html pages from a web server... (oops, I mean your desktop.)

Once everything is built, look in the \webkitbuilds\releases\{appname} - {timestamp}\win\{appname} folder to find your exe waiting.

Feel free to use require('node-module') right in the window. In fact, node-webkit has it's own native UI library, and the Window object is an instance of node's EventEmitter object. Which means you can listen to native window events by using Window.on().

Conclusion: Get developing already!

In functional health, Josh

Monday, October 21, 2013

Partial Functions and Currying

Functions should be fun.

In fact, functions should be the reason you love javascript. Applying the knowledge of using functions as objects should be on the top of your to-do list. Of course, sometimes it benefits us to write reusable or partial functions for later use.

Take the following code example.

function partialSum(a, b){
 if(b)
   return a+b;
 return function(b){
    return a+b;
 }
}

In the case of partialSum(2), it returns a function. You don't even need to know what b is until it gets called again.

Calling partialSum(2)(3) returns 5.

This approach is limited however. How about taking it a step further?

function Partial(func, bound){
   //Convert the arguments to an array
   var args = [].slice.call(arguments, 2);
   //Return a function
   return function(){
       //function.apply takes a object and an array
    var localArgs = args.slice();
    [].push.apply(localArgs, arguments)
       return func.apply(bound, localArgs);
    //apply all arguments supplied at this 
    //point to func, call it, and return it's value
   }
}

This function returns a partial definition of the supplied function func. Seems complicated, until you realize exactly what it's doing. It's just concatenating a list of arguments and passing it to the supplied function. This approach is still limited by the number of times you can call it however.

Wouldn't it be nice to create a function that could accept any number of calls until enough parameters have been supplied to it? Ask, and ye shall receive:

//Function, Arity, BoundTo
function Curry(func, length, bound){
 //Declare initial stuff
    var args = slice.call(arguments, 3), len = length||func.length;
 //The "Magic"
    function curriedFunction(func, bound, args){
        if(len <= args.length) //then the function is ready to be called...
            return func.apply(bound,args);//pass the arguments to the function
        return function(){ //otherwise pass back a function
            var localArgs = args.slice(); //local copy...   
            push.apply(localArgs, arguments); //Concatenate arguments
            return curriedFunction(func, bound, localArgs); //and call itself
        };
    }
    return curriedFunction(func,bound,args);
}

Take a moment to really read what is going on in this function. It actually knows when to return a partial function. Function.length does a good job of determining the amount of arguments required to complete the function. This function has LOADS of practical applications.

function sum(a,b){
 return a+b;
}
var add2 = Curry(sum)(2);
console.log(add2(4));
//6
console.log(add2(6));
//8
var add10 = Curry(sum)(10);

function template(jsonObject, templateString){
 //do something here
}

var cachedJSONtemplate = Curry(template, 2, {}, JSONGetWrapper());

var result = cachedJSONtemplate("template string here...");
var result2 = cachedJSONtemplate("template2 string here...");

As you can see, the potential is great. Highly configurable code that makes reusability easy (and encouraging) is the great work of the javascript language in action!

In functional health, Josh.