Saturday, 26 October 2013

Of Random Seeds and Other Random Bits

Baba Gyani Triviani said:
"If you believe in fate and destiny, then the randomness in this world is pseudo-randomness"

Random Number Seed
I am sure most of you would have used a Random number generating piece of code in your program at some point of  time or another. And when you were looking up code, you would have noticed the word 'seed' but would have ignored it. Some of you would have even noticed a word called pseudo-random number generator. Well, I did. And I didn't know what this seed was until a few days back.

Let's try out an experiment. I will use Python in this post, but you can use any other language - Java, Ruby and they will all behave in the exact same way.
>>> import random
>>> random.random()
0.23108685984562283
>>> random.random()
0.017276293409835386
If you try this piece of code on your machine, your results will be different from mine. Isn't that obvious? It IS a random number generator after all, you might say. Now let's do something a little different. Try out the following code...
>>> import random
>>> random.seed(5)
>>> random.random()
0.6229016948897019
>>> random.random()
0.7417869892607294
The only difference is  that I have written an extra line with seed and I am passing 5 as the parameter. If you try out this piece of code now, you will see that the random numbers that you are getting is the same as what I am getting. ! So that means that random numbers are not as random as we think they are. You can try by opening another terminal and issuing same commands and your results will match.

Variable arguments in Javascript
Most of you are familiar with varargs - If you want a function to accept variable number of arguments,  you use the standard ellipsis notation - works in C, Java... But does it work in Javascript? No. So how do you do it? I was browsing through Coffeescript and I noticed the varargs ellipsis notation. On checking the generated Javascript code, I noticed something interesting.

So this is what you should try. Fire up your console in Google Chrome and type the following:

function test() {
   console.log(arguments);
}

test('hey');
test('hi', 'hello', 'howdy');
test();

And the outputs are:
["hey"]
["hi", "hello", "howdy"]
[]

As you can see, though the function test doesn't look like it is accepting any arguments, arguments can be passed and accessed using a special 'arguments' variable. It is basically an array and you can use it to check if arguments were passed or not, how many were passed and which argument is what. Fancy, huh?

Closures in Javascript
Apparently, to be called some kind of an expert in Javascript, you should be able to talk intelligently about Closures. For a long time, I used to stare blankly at the word. Eventually I decided to see what all the fuss was about. 

But before I tell you what closures are, I wanted you to know this simple piece of code. If you know it, go ahead. Otherwise try it out. Functions in Javascript can be written in two ways:

function sayHello(name) {
   console.log("Hello " + name);
}

sayHello = function(name) {
   console.log("Hello " + name);
};

Both work - The difference is that, the first one is available the moment your scripts begins to execute, the second one is available only after that line gets executed. What it means is that, I can call sayHello in a line that precedes the actual function definition in the first case. However, if I write it in the second way, it is available only after that line. An attempt to call it before will make your program to crash out - You are attempting to use it before defining it.

The advantage of the second style is that you can change the entire function behaviour but retaining the same name. Here's an example:
chameleon = function() {   console.log("I am green in colour");}; 
chameleon(); 
chameleon = function() {   console.log("I am brown in colour");} 
chameleon();
As you can see, the functions entire behaviour changes. This happens if you define it in the other style as well, but since this is like a variable, you can use this style to accept functions that get returned from other functions. The following example clarifies this point while also explaining closures.

So here's a simple example for closure.
function outer(x) {
    this.x = x;
    return function(y) {
        console.log(x + y);   
    }
} 

a = outer(5);
b = outer(10);

a(10);
b(10);


So essentially, we have a function called outer that accepts one parameter - x, and it returns a function (That's one feature I love about JS - the ability to pass functions around like any other variable). So, a and b will store the returned functions. But these two functions are not exactly identical. Since the 'x' parameter was different, the 'x' inside the returned functions are different too. To clarify, the 'x' inside the console.log gets hard-coded to whatever was passed - 5 for the a, 10 for b.

So when we call a and b with 10 as argument, the sum becomes 5 + 10 = 15 for a  and 10 + 10 = 20 for b. That's how you can a single function to behave differently depending on arguments.

Object oriented programming in Javascript
I thought of writing a bit about prototypes here - but then I thought that, rather than doing that, you should give CoffeeScript a chance. It's very easy to learn and you can do things in a better way. Like class definition is much cleaner in it and it takes care of the dirty work behind the scenes for you. It eventually generates Javascript and you don't have to worry about it.

No comments: