Friday, February 11, 2011

Week 2 : Assignments and Homework

1. Why do languages provide the switch statement, when we can achieve the same thing with multiple if... elseif statements? Show one example of how you might use the switch statement.
         The 'if... elseif' statements work fine when a few conditions are to be tested but become cumbersome when   many conditions are to tested. On the other hand, 'switch' statements ensures better readability and easier understanding of the code. Switch executes much faster than if..elseif(from wikipedia). Also, switch statement is far more efficient in cases where one value has to tested against a number of values. However, when different pairs of values are to be tested, if..elseif is a obviously better option.
       An example:  I am writing example 2.5 of Eloquent Javascript with the help of switch-
                            var ans=prompt("What is 2+2?","");
                            switch(prompt):
                                      {  case "4": alert("Bravo!!");
                                                      break;
                                        case "3":
                                        case "5": alert("Almost!!");
                                                      break;
                                        default:   alert("Stupid!!");
                                                      break;
                                        }
  
2. What is encapsulation, and what do functions encapsulate?
         Going by the OOP concept, encapsulation is simply packaging data and functions into a single unit. It is used to hide a object from outside of the object's definition. In Javascript, functions are used to encapsulate both variables and other functions. Whatever is defined within a function is not available outside it. However, blocks within curly brackets are merely chunks of code, they do not encapsulate.


3. What is a pure function? Is the function show() provided in Eloquent Javascript a pure function?
         In the book, pure function is defined as functions that always return the same value given the same arguments and never have side effects. That is, it produces no adverse effect on the program other than just taking some arguments and providing some values.
            The function show() is not a pure function as it has a side-effect, i.e., providing an output to the console. Thus, it produces an adverse effect other than returning a value.

4. What do we mean when we say a variable in a function is shadowing a top level variable?
          Suppose we create a variable inside and there is another variable of the same name outside that function. Now whenever that variable is referred inside the function, JS always checks its local environment( i.e., the function) and uses that value and only when nothing is found inside is the outside environment checked.  But when there is no variable of that name inside the function, it always shadows the top level variable.
          However, suppose we create 2 variables of same name- inside and outside the function. When inside the variable is used inside the function, the value inside the function is used. But when the variable is used outside the function, the value outside the function is used!!! Let me give an example:
           var myvar="I am outside the function.";
            function myFunc()
            {   var myvar="I am inside the function.";
                 print(myvar);
             }
           myFunc(); //function called
           print(myvar);
      Output:      
                   I am inside the function.
                   I am outside the function.
    
5. A recursive function, must have some sort of an end condition. Why would we get a "out of stack space" error message if a recursive function does not have an end condition?
   This is an interesting concept. Whenever a function is called, the control flows to the function i.e. execution of the function body starts. However, after the function body ends, the execution of the program resumes. So, there must be some place where the location within the function where the control broke-off can be "bookmarked"(i.e., the place where the function was called) so that normal execution can resume. This place where the "bookmark" is stored is called the stack.
   Recursive functions are functions which can call itself. This is possible with the help of stack. Every time a function is called, a new context is stored in the stack(i.e., a new function is placed over a stack of contexts). When a function returns, the context on top of the stack is taken off and resumed.
   If a recursive function doesn't have an end condition, it is supposed to run infinitely. Hence the stack grows bigger and bigger and when we reach the threshold of the stack, the "out of stack space" error is shown and further execution is prevented. Had this not been the case, there was a chance the system might end up crashing due to overloading.

6. Reflect about the difference between object inheritance and class inheritance
      Javascript supports prototypal inheritance. There are no classes in JS. Instead, we have objects which can be customized to create new objects. Whenever an object is created, it contains a secret link to another object. When access to the object fails, the link is used to refer to the linked object. In class inheritance, one class inherits from one or many classes and then, objects of that class has to be created to take advantage of the inherited properties. However, in JS, since there are no classes, objects directly inherit from other objects.
(For reference see, prototype based vs class based inheritance.)    
        Both types of inheritance are useful. Object inheritance is effective for code reuse while class inheritance can be used to create references of similar references.
      However, I do have a doubt(question to Parag) : In the video, Crockford says that an object can contain a link to only another object. Does this mean multiple inheritance is not supported in Javascript? Is there any way to make it work?

7. What is object augmentation, and how do we do it?
       This is great concept in Javascript. Unlike static object oriented languages, new members(functions or variables) can be added to objects without creating new classes. Only a simple assignment is required to add new members. This is undoubtedly a very powerful feature and helps us write smarter code.
example: say we have an object myHouse and want to add a new member 'rooms' which signify no. of    
              rooms. We simply use:
               myHouse[rooms]= 6

8. There is a way to add a method to String, such as any new String we create will have that augmented method (this is a bit different from object augmentation). How would you do this?
     I found the answer to this question on www.crockford.com.
To add a method to any function prototype, we have to do this:
              function.prototype.method=function(name,func){ this.prototype[name]=func;
                                                                                         return this;};  // new function func is added to it by                              
                                                                                                                 using name
So, for a string I will use:        String.prototype.augment=newFunc(){.......//function body};
Now to use this new function newFunc() on a string variable say str, we can write:
                      str.newFunc();
          
9. What is garbage collection?
        Garbage collection refers to the deallocation of memory by collection of variables,functions,etc. that are no longer in use. It's an important part of any language and ensures that the memory is not blocked by unwanted variables. It seems JS uses the mark and sweep method of garbage collection.(courtesy google). Garbage variables, objects, etc. can also be delted using the 'delete' operator.
    For more on the mark and sweep method, refer this

10.What is the difference between an array and an object? 
        In Javascript, arrays are also objects(and inherits from objects). In objects, the keys can be names or strings. However, in arrays the data is numerically indexed. Arrays also have a property called 'length' which gives its size(i.e., 1 more than the last index). This helps in traversing an array with the help of a loop and perform various operations on the data. Also, in arrays we use [] as container as opposed to {}. We can also perform interesting fuctions on arrays like concat, join, splice, pop, push, sort.
        Arrays, like objects are secretly linked to array.prototype. However, arrays should not be used as prototypes as the object produced will contain the data but lose the array nature(i.e., length operator cannot be used). Like objects, arrays can be augmented by assigning methods to it.
example of array:
                        var arr=['one','two','three'];
                   Now, document.write(arr[0]) gives 'one'.
example of object:
                        var obj={first:'one',second:'two',third:'three'};
                   Now, document.write(obj.first) gives 'one'.
        Finally, to classify a variable as object or array, use '==='.
             if var.instance===array is true, it's an array.

Homework:


1. Exercises 3.1 from chapter 3 of Eloquent Javascript
Answer:    easy one:
                     function absolute(num)
                     {    if(num<0)
                                return -num;
                           else
                                 return num;
                        }

2. Exercises 3.2 from chapter 3 of Eloquent Javascript
Answer:     function greaterThan(x):
                   {      return test(y)
                           { return y>x;
                                     };
                                         }
                   var greaterthanTen=greaterThan(10);
                   show(greaterThan(8));

3. Shown below is some code which does something useful. The function 'iterateAndOperate' is the one which accomplishes something useful. The remaining code helps this function. Try to understand what the function accomplishes and solve the problems in part a, b, and c. The code can be done inside the console in Javascript, or in the web browser. Please see this comment, for hints on how you may do it inside a web page(remember, HTML has special codes for spaces and newlines).
  1. Use the function iterateAndOperate to draw an image which looks like this
  2. ++++@++++ +++@@@+++ ++@@@@@++ +++@@@+++ ++++@++++
  3. Use the function iterateAndOperate to draw a triangle which looks like this
  4. * *** ***** *** *
  5. In your code which invokes iterateAndOperate() without any parameters, as shown. An Exception will be thrown. Catch the Exception show an Alert to the user with a user friendly error message.
Answer: Now seriously, it would be cooler if instead of using an array, we could use a loop to print this out but since that is what is wanted, here goes:

<script type="text/javascript">           
 /A constant to hold the String "null". To be used in typeof checks
NULL_VAL = "null";
//A constant to hold the String "undefined". To be used in typeof checks
UNDEFINED_VAL = "undefined";

/*
 * This function checks if the specified parameter is null or undefined
 * @param something The specified parameter to check for a null or undefined value
 * @param name The name of the parameter. This will be used in the error message
 * If the value 'something' is found to be null or undefined, then this method
 * will throw an Error
 */
function checkNullOrUndefined(something, name) {
 if(UNDEFINED_VAL == typeof(something)) {
 throw new Error(name + " cannot be undefined");
  }
  if(NULL_VAL == typeof(something)) {
    throw new Error(name + " cannot be null");
  }
}


/*
 * This function accepts an array object and a function reference.
 * It iterates through the array and invokes the specified function
 * for every element of the array. In each invocation the current
 * array element is given to the function as a parameter.
 * @param arr The array
 * @param func The function to invoke for every element of the array
 * This method does not return any specific value.
 * This method throws an Error if 'arr' is null, undefined, or is not an array
 * This method throws an Error if 'func' is null, undefined, or is not a function
 */
function iterateAndOperate(arr, func) {
  checkNullOrUndefined(arr, "arr");
  checkNullOrUndefined(func, "func");
  // Verify that arr is an array
  if(!(arr instanceof Array)) {
    throw new Error("arr does not seem to be an array");
  }
  // Verify that arr is an array
  if("function" != typeof(func)) {
    throw new Error("func is not a function");
  }

  catch(err)
  {alert("Oops!! Seems like there is an error:"+err);
  }
  for(var i=0; i<arr.length; i++) {
    func(arr[i]);
  }
}
var arr1=["++++@++++","+++@@@+++","++@@@@@++","+++@@@+++","++++@++++",];
var  arr2=["*","***","*****","***","*"];
function print(var)
{ document.write(var); //to print the value
   document.write(<br/>);   //to add line break
}
iterateAndOperate(arr1, print); //for part a
iterateAndOperate(arr2, print); //for part b
iterateAndOperate();  ///for part c
</script>


.Note: It would be really helpful if someone could get clarify the multiple inheritance issue.
      

2 comments:

  1. I'm willing to bet that multiple inheritance is not supported in JS, but your question got me thinking...

    See this link concerning mixins

    *Note: this must be an old article, because the the arguments property found in the code is no longer supported. However, I was able to successfully test the code with that part of it omitted.

    I hope you find this as useful as I did.

    banks

    ReplyDelete
  2. @darryl: thanks, it was a useful article. You can also check out this blog on multiple inheritance using JS Adapter:
    http://blogs.sun.com/sundararajan/entry/multiple_inheritance_in_javascript
    Sorry, couldn't reply earlier; had two hectic weeks; got a lot of catching up to do.

    ReplyDelete