Thursday, September 25, 2014

My struggle with JSON

We all use developer tools. Console is of tremendous help when it comes to trying JavaScript snippets. Sometimes however something relatively simple e.g. like typing in JSON throws errors for apparently no reason. I had one of these moments and as usual started digging to see why it was happening. Ok, hit F12 in Chrome and type in:

{ “name” : “homer” }

Plain, old JSON it seems, nothing fancy. However you will be greeted with:



It is valid JSON so what gives? First thing that came to my mind was hidden characters. It’s (not so) well know fact that JSON is not quite a subset of JavaScript. JSON allows certain characters in a String and JavaScript doesn't. Given that one of the strings above contain Line Separator (line feed, carriage return etc.) this would sure spell trouble. Even though “Unexpected token :” would point problem to “:” rather than anything else I decided to check strings for any whitespace characters.

Fired up my trusted Notepad++ to see what Chrome doesn't show, but with no luck. No hidden characters of any type.

To make the matter worse running:

{ name:”homer”}

worked just fine. Almost fine actually, as the line was returning a “string” rather than object:



Why string though? Let me explain.. Using curly braces in console the way I originally did, creates a block statement. It is not parsed in expression context and so it does not create an Object. It does very much the same as I would execute:



It produces exactly same output so error pointing to “:”. If you look at this however it suddenly stops making sense. We simply creating here a string, followed by a colon, followed by another string. Clearly wrong.

Now, { name:”homer”} however was working. It was returning string rather than object, and for a good reason. Curly braces create block statement and so lets strip those and run:



You should see the problem by now. Obviously what I was trying to do here is to create a label followed by string “homer” and so “homer” was spit out to console as expected. If you are not familiar with labels in JS they are used e.g. to break out of loops e.g.:

var i, j;

loop1:
    for (i = 0; i < 3; i++) { //The first for statement is labeled "loop1"
        loop2: for (j = 0; j < 3; j++) { //The second for statement is labeled "loop2"
            if (i == 1 && j == 1) {
                continue loop1;
            }
            console.log("i = " + i + ", j = " + j);
        }
    }

// Output is:
// "i = 0, j = 0"
// "i = 0, j = 1"
// "i = 0, j = 2"
// "i = 1, j = 0"
// "i = 2, j = 0"
// "i = 2, j = 1"
// "i = 2, j = 2"
// Notice how it skips both "i = 1, j = 1" and "i = 1, j = 2"


So there it is. I was creating block statement with invalid syntax hence the error. Mistake that I won’t do again.

Tuesday, September 9, 2014

Help children and get healthy! its almost too easy!

I thought I should share it everywhere as it is for a good cause, helping children..  I encourage everyone to participate in Steptember, its easy and makes a big difference in lives of children and their families. At least have a look what Steptember is all about and participate if you can!

Monday, September 1, 2014

Memoize like a boss (part 2)

Memoization is fun and if you read my previous post you should have fair idea of how memoization can be easily implemented in JavaScript. Previous examples were using very simple function and now you might wonder how to deal with recursion and still get all the benefits. Last time around we end up with:

Function.prototype.memoized = function(a) {
if (typeof this.cache === "undefined") this.cache = [];
if (this.cache[a]) {
return this.cache[a];
} else {
this.cache[a] = this(a);
return this.cache[a];
}
}

Function.prototype.memoize = function() {
var t = this;
return function() {
return t.memoized.apply(t, arguments);
}
}

myTest = (function superLongCalculation(someArg) {
    return someArg * 3;
}).memoize();

console.log(myTest(2));


So to recap.. myTest function once called will call memoized method on original function object t:

t.memoized.apply(t, arguments);

memoized method will do the check if the value for argument ("2" in our example) has already been precalculated and if so will returned whatever is stored in cache. Otherwise will call original function, do the magic and return new value. If this doesn't quite make sense have a look at my original post where I went into details of my basic memoization implementation.

So now you might wonder what will happen if instead of something overly simple as above we will use recursive function to do the work. Calculating fibonacci numbers seems to be "Hello World" of memoization and so lets plug this thing into our memoization code:

Function.prototype.memoized = function(a) {
if (typeof this.cache === "undefined") this.cache = [];
if (this.cache[a]) {
return this.cache[a];
} else {
this.cache[a] = this(a);
return this.cache[a];
}
}

Function.prototype.memoize = function() {
var t = this;
return function() {
return t.memoized.apply(t, arguments);
}
}

myTest = (function fibonacci(n) {
return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}).memoize();

console.log(myTest(2));

Works like a charm. Returns correct values, however we can make it better. It still does unnecessary work and given our current code there is easy way to improve it.

Notice how the fibonacci function object itself is memoized, however internal calls to itself are not. This means that in this case we do half-assed optimization only and anything half-assed is not cool. Lucky for us the Function object has memoized method already that we can directly call as in the very first examples in part one:

Function.prototype.memoized = function(a) {
if (typeof this.cache === "undefined") this.cache = [];
if (this.cache[a]) {
return this.cache[a];
} else {
this.cache[a] = this(a);
return this.cache[a];
}
}

Function.prototype.memoize = function() {
var t = this;
return function() {
return t.memoized.apply(t, arguments); }

}

myTest = (function fibonacci(n) {
return n < 2 ? n : fibonacci.memoized(n - 1) + fibonacci.memoized(n - 2);
}).memoize();

console.log(myTest(2));

I also put few tests that are available here so you can see the difference. I also realise that there are other, more efficient ways of calculating fibonacci numbers, I believe however that examples above are simple enough to see how memoization can be used with recursive functions.