Friday, January 15, 2016

Closures

Friday, January 15th 2016
  • Closures are typically referred to a variable, not a function, (closure variables) because they refer to values that are outside of their own native scope.
    • var createCounter = function () {
      • var counter = 0;
      • return function () {
        • counter+= 1;
        • return counter;
      • };
    • };
    • var myCounterX = createCounter();
    • myCounterX();
    • myCounterX();
    • var result1 = myCounter();
    • //What is the value of resutl1? Answer: 3. Why?
      • Does NOT fire on declaration.
      • First call, counter = 1;
      • Second call, counter = 2;
      • when assigned to result1, it is fired for a 3rd and final time, equating to 3.
    • var result = 0;
    • for(var i=0; i < 3; i++) {
      • setTimeout(function() {
        • result += i;
      • }, 1000);
    • }
    • What is the result of result? Answer: 9. Why?
      • SetTimeout stores values in some invisible event loop behind the curtains until the code has fully finished running. Afterwards, the for loop (not the event loop!) finished iterating, i is 3, upon which the 3 saved setTimeout functions then fire, adding 3 + 3 + 3 = 9.
    • var x = 10;
    • function inc () {
      • return x + 1;
    • }
    • How many closures? Answer: 1. Why?
      • function window () {
      • var x = 10;
      • function inc () {
        • return x + 1;
        • }
      • }
      • inc closes over window (through variable x);
    • var x = 10;
    • function inc (x) {
      • return x + 1;
      • }
    • How many closures? Answer: 0. Why?
      • No reference is made to the outside scope. All variables within the function in are native.
    • var add = function (x, y) {
      • return x + y;
    • };
    • var  double = function (x) {
      • return add(x, x);
    • };
    • How many closures? Answer: 1. Why? Think of it as:
      • function double (x) {
        • function add (x, y) {
          • return x + y;
        • }
      • return add(x, x);
      • add is nested within double via x, because add is accessing double's (x) parameter in the computation.
    • var x = 10;
    • var add = function (y) {
      • return x + y;
    • };
    • var double = function (x) {
      • return add(x);
    • };
    • How many closures? Answer: 2. Wtf why? 
      • Don't let add() fool you. The parameter names never have, never will matter. 
      • The x variable in add is being taken from the global scope, whereas y is the value of x from the double scope. 
  • Ok, enough of closures. I'm going to redo my post for yesterday to do a brief summary on the first two of four advanced data structures. I'll cover the last two here.
  • Hashed functions.
    • There was a lot of confusion over this topic for the entire class, including me, due to miscommunication in the program. Anyways, after a day, we all got it. 
    • So arrays are awesome because they are O(1) for accessing (arr[54];  //'cat'; BAM), but are not so awesome for inserting (unless push), searching, or deleting values because the entire collection is contiguous. 
    • Can we make is such that the entire process is, more or less, constant? Yes we can! 
    • Turns out that obj's key:value pair isn't the BEST way to store information. Arrays got the right ideas. Why? Because computer can iterator through numbers much more quickly than strings, and keys in objs are converted to strings! Hence the obj['key']. 
      • Knowing this, we can translate the key, using some hash function, into an address via sequence of numbers and then store the key:value pair into a point in storage using that address. If we want that value, we simply use the hash function to convert our key to retrieve the value. BAM! Constant! 
      • But what if our hash function sucks? What if I give it a key for some value, but then another value gets return? 
        • 'theCatGoes': 'Meow!'; -> hash f(x) -> Address: 1212
        • 'theCowGoes': 'Moo!'; -> hash f(x) -> Address: 1212
        • request 'key1' -> hash f(x) -> 1212 -> 'theCatGoesMoo!' //Wait, wtf?! 
          • Hint: cat's don't moo.
        • So what happened? We didn't adjust our hash table (the place that stores all of the key-value pairs and addresses) to deal with 'collisions'. A collision takes place when you give the hash function a key, and get the wrong value back (the key shares the same address as another). To avoid this, we next our [k, p] in another [], and add a condition whereby the system checks if there is another existing value in the collection and if so, simply adds the additional [k, p] to the address. (Notice its nest in an array). Accessing the right value for a key is done via checking each nested array.value for the same value, since we know what the value is...hence why we know the key:value pair was wrong in the first place.
        • OKAY, so what does all that shit mean? It means that 99% of the time, hash functions will be O(1), but when there is a collision, it is O(n) because it has to iterator through an array of arrays to check for each [k,v].
    • BAM! Examples of using hash functions are:
      • Encryption
        • Think about it. The hash function is the encryption device that 'encrypts' or 'translates' some value into some other value. In this case, it's done to boost efficiency (via numerical index vs. str-based index).
      • google (results are instantaneous and I think someone said they use hash functions)

No comments:

Post a Comment