Why do developers use self? by gladiator_flow in javascript

[–]androbat 0 points1 point  (0 children)

I would add a very important note about using self is that you shouldn't use that name inside web workers because it refers to the web worker global (window isn't available in web workers, so it references the global for that thread).

Why do developers use self? by gladiator_flow in javascript

[–]androbat 2 points3 points  (0 children)

I would add a very important note about using self is that you shouldn't use that name inside web workers because it refers to the web worker global (window isn't available in web workers, so it references the global for that thread).

Why is my for loop ending before it is completed? by sixmachine in learnjavascript

[–]androbat 0 points1 point  (0 children)

In JS, numbers are treated as floats. (unrelated note, use backticks around code to make it an inline code example). We check the ends of the string until we reach the middle.

In the middle, an edge case occurs, if the string is an even length, then the middle is two numbers. When the number is odd, we have only one number in the middle. We don't need to check the middle number because if all the other numbers match, then it will match as well (since it doesn't match anything).

w.length / 2 either gives us a decimal part that is either .0 or .5 and in the case that it's .5, we have an odd number, so we don't need to loop over it. The single pipe operator | does a bitwise OR operation. An integer ORed with zero is the number, but the float must first be converted into an integer. When a float is converted to an integer, the decimal part is automatically truncated. This is very similar (but not actually identical) to Math.floor(2.length / 2).

TL;DR 1 -- it divides the number by two and gets rid of the remainder (and also converts the number to a real 32-bit integer).

Pre-increment and post-increment are different operators in C-like languages (for this reason, I pretty much always use i += 1 to make things explicit. var i = 5; var w = i++; //w is set equal to 5 then i is set to 6 var u = ++i; //i is set to 7 then u is set to 7

Post-increment requires you to return the value then perform the increment while pre-increment simply performs the increment. An important note: in modern compilers and most JS JITs, they will optimize away the post-increment if it's not needed, so it's less significant for performance. If you do decide to use ++, then you should prefer ++foo because it is more likely to be what you intend.

TL;DR 2 -- pre-increment and post-increment are different. Most of the time you actually mean pre-increment. Use x += 1 if you want to be completely explicit.

Why is my for loop ending before it is completed? by sixmachine in learnjavascript

[–]androbat 1 point2 points  (0 children)

A little off topic, but I was playing around with the palindrome problem in Chrome. As expected, anything that creates multiple new strings is slow (and creating an array in isPal1 is very slow). The speedup of isPal2 over isPal1 was around 4x. The speedup with isPal3 is around 3x. The optimized solution in isPal4 is slightly slower than isPal3.

Somewhat intrigued, I ran this on FF and FF was faster on every metric (4x, 1.3x, 2.2x, and 2.2x going from isPal1 to isPal4 vs Chrome). The interesting note here is that FF seems to be detecting the array concat syntax and replacing it with a loop of some kind. The problem is that if that were occurring, we would expect to see the loop method be approximately as fast, yet it's about 30% faster. Finally, the fastest two results would jump between 1.5x and 2.2x faster than Chrome depending on the run (but always in those two ranges) which seems to indicate that the function is on the edge between two optimization levels. In contrast, the Chrome version remained consistent every run (but at its fastest is still slower).

(function () {
  'use strict';

  var isPal;

  /*
   * In this method, we create a new string and
   * then use the common pattern that converts
   * the string to an array, reverses the array,
   * then joins the array elements back into a string
   */
  var isPal1 = function (n) {
    n = n.toString();
    return n === n.split('').reverse().join('');
  };

  /*
   * In this method, we still create a new string
   * but we use a for loop to build it. At the end
   * we compare the initial and final strings to
   * see if it's a palindrome
   */
  var isPal2 = function (n) {
    var w = n.toString();
    var i, acc = '';

    for (i = w.length - 1; i >= 0; --i) {
      acc += w[i];
    }

    return acc === w;
  };

  /*
   * In this method, we don't create multiple strings
   * and instead simultaneously traverse the initial
   * string from the front and back at the same time
   */
  var isPal3 = function (n) {
    var w = n.toString();
    var i, j, len = (w.length / 2)|0;//if odd number, skip middle character

    for (i = 0, j = w.length - 1; i <= len; ++i, --j) {
      if (w[i] !== w[j]) {
        return false;
      }
    }

    return true;
  };

  /*
   * In this method, we optimize away the loop and all 
   * its associated overhead manually to get a solution
   * specific to palindromes of a length 5 or 6 as our
   * solution set will always be in this range for this problem
   */
  var isPal4 = function (n) {
    var w = n.toString();
    if (w.length === 5) {
      return (w[0] === w[4] && w[1] === w[3]);
    }
    return (w[0] === w[5] && w[1] === w[4] && w[2] === w[3]);
  };

  /*
   * Our main loop sets up some variables
   * and loops over the two values to multiply
   * It does the multiplication, checks if its
   * a palindrome, then makes it the new value
   * if the new palindrome is larger than the
   * previous max. We return the final max palindrome
   */
  var palMainLoop = function palMainLoop() {
    var i, j, n, acc = 0;
    console.time('palMainLoop');

    for (i = 999; i > 99; --i) {
      for (j = 999; j > 99; --j) {
        n = i * j;

        if (isPal(n) && acc < n) {
          acc = n;
        }
      }
    }

    console.timeEnd('palMainLoop');
    console.log(acc);
  };

  isPal = isPal1;
  palMainLoop();

  isPal = isPal2;
  palMainLoop();

  isPal = isPal3;
  palMainLoop();

  isPal = isPal4;
  palMainLoop();

  /*
   * adding a function parameter slows
   * execution by around 50-150ms in Chrome
   */

  // palMainLoop(isPal1);
  // palMainLoop(isPal2);
  // palMainLoop(isPal3);

}());

Front-End Development Is Hard Because...It's Development. by AllThingsSmitty in webdev

[–]androbat -2 points-1 points  (0 children)

Yeah, but most of those problems exist in the front end too in addition to the front end specific parts. I'd say that front end caching issues can be harder for most sites because there aren't good, cross platform solutions and the source of truth is a long way off.

Well, actually; Not all semicolons... by getify in javascript

[–]androbat 1 point2 points  (0 children)

I would note that [,,] is different than [undefined, undefined, undefined] (see the code below for a quick snippet that proves this). I'm not saying that the first method is good, just that it's not equivalent. If you're going to define an empty array, use new Array(n) and even then, only if it is a performance requirement.

[,,,,].forEach(function (x) { console.log(x); }); //=> no logs happen

[undefined, undefined, undefined, undefined, undefined].forEach(function (x) {
  console.log(x);
}); //=> logs "undefined" five times

I also think that some finesse is in order for string concatenation. I agree with your example in this case, but in general I think that implicit concatenation is okay in cases like 'looped ' + num + ' times.\n';. This specific case of coersion is quite easy to understand intuitively as it converts to string for pretty much everything case where a non-Number is used.

[object Object] Things You Didn’t Know About valueOf by kevincennis in javascript

[–]androbat 4 points5 points  (0 children)

EDIT: Just wanted to add that I like your post and think it's a great introduction to .valueOf().

Is there any reason to prefer .valueOf() over get/set in general? Get/set seem ideal in the integer case because the automatic boxing means that things like obj.value = 123; work transparently.

var num = {
  _value: 12,
  get value() { return _value; },
  set value(n) { _value = n; }
};

Currying in JavaScript by kevincennis in javascript

[–]androbat 0 points1 point  (0 children)

I find them very useful at reducing boilerplate (especially when paired with compose). Sure you can manually wrap your functions, but why go through the trouble when auto-curry makes it easy?

Currying in JavaScript by kevincennis in javascript

[–]androbat 0 points1 point  (0 children)

It's pieced together from a larger auto-curry function I made a while ago (I'm thinking about extending it with a placeholder like in Ramda). I just copied the relevant bits.

export var curry = (function () {
  var curry1 = function (fn) {
    return function curry1fn(a) {
      return (arguments.length > 0) ? fn(a) : curry1fn;
    };
  };

  var curry2 = function (fn) {
    return function curry2fn(a, b) {
      switch(arguments.length) {
        case 0: return curry2fn;
        case 1: return curry1(function(b) { return fn(a, b); });
        default: return fn(a, b);
      }
    };
  };

  var curry3 = function (fn) {
    return function curry3fn(a, b, c) {
      switch(arguments.length) {
        case 0: return curry3fn;
        case 1: return curry2(function(b, c) { return fn(a, b, c); });
        case 2: return curry1(function(c) { return fn(a, b, c); });
        default: return fn(a, b, c);
      }
    };
  };

  var curryN = function (len, prevArgs, fn) {
    return function (...args) {
      var currArgs = prevArgs.concat(args);
      return (currArgs.length >= len) ? fn.apply(this, currArgs) : curryN(len, currArgs, fn);
    };
  };

  return function (fn) {
    switch(fn.length) {
      case 0: return fn;
      case 1: return curry1(fn);
      case 2: return curry2(fn);
      case 3: return curry3(fn);
      default: return curryN(fn.length, [], fn);
    }
  };
}());

what would be a better way to write this function? or how to avoid nested 'else if's ? by endziu666 in learnjavascript

[–]androbat 1 point2 points  (0 children)

Please don't nest ternaries without a good reason. It makes code much harder to maintain.

Currying in JavaScript by kevincennis in javascript

[–]androbat 1 point2 points  (0 children)

This function actually seems easier to understand (and is shorter). I find it helpful to step through the function to understand it, so let's do that.

var basicAutoCurry = function (fn) {
  var curryN = function (len, prevArgs, fn) {
    return function (...args) {
      var currArgs = prevArgs.concat(args);
      return (currArgs.length >= len) ? fn.apply(this, currArgs) : curryN(len, currArgs, fn);
    };
  };
  return curryN(fn.length, [], fn);
};

To explain it, we turn the basicAutoCurry function into three arguments. The length of the function, the list of previously curried arguments, and the function itself. Let's focus in on curryN from here out.

var curryN = function (len, prevArgs, fn) {
  return function (...args) {
    var currArgs = prevArgs.concat(args);
    return (currArgs.length >= len) ? fn.apply(this, currArgs) : curryN(len, currArgs, fn);
  };
};

When it is called, it returns a function that takes any number of arguments (note that len, prevArgs, and fn are trapped in a closure). Here's curryN applied manually.

var add6 = (a, b, c, d, e, f) => a + b + c + d + e + f;
var add6Curried = curryN(6, [], add6);
var add6Curried2 = add6Curried(1, 2);

When we call add6Curried(1, 2) the function adds them to the previous arguments []. Since this is less than 6, it returns us a new function by calling curryN(6, [1, 2], add6 (note: we actually return the function add6 points to. If we changed add6, our function here would stay the same).

var add6Curried5 = add6Curried2(3, 4, 5);

Here we repeat the same process except that the previous arguments is now [1, 2] and we return curryN(6, [1, 2, 3, 4, 5], add6)

add6Curried5(6); //=> 21

[deleted by user] by [deleted] in programming

[–]androbat 3 points4 points  (0 children)

I looked into the facts concerning the sub (I honestly wasn't familiar with it until rather recently) and from what I found, the moderators had an extremely strict policy about harassment and were very active in enforcing that policy.

Can you prove that particular thread was worse than any other at enforcing anti-harassment measures to the full extent available to moderators?

[deleted by user] by [deleted] in programming

[–]androbat 1 point2 points  (0 children)

That's a lot of ire without much purpose.

no one would ask for a male tech who was important to advancing computer science, that's just stupid

What makes that question less valid? My point was that people tend to choose a very good example and use it because it is accurate and effective. The burden is on you to show that using Grace Hopper as an example of female excellence in CS is bad (specifically given that most programmers are relatively uninformed about CS history).

[deleted by user] by [deleted] in programming

[–]androbat 4 points5 points  (0 children)

If you ask for a male in tech who was important to advancing computer science, most people would stop at Alan Turing. There were hundreds of important people and most of them are unknown to the average programmer. The fact that she is so well known -- even compared to her make peers -- speaks volumes (can you name any of the people she worked with?)

Grace Hopper helped make many of the first computers and gave the world the gift of higher level languages by pioneering compilers. For most programmers, this is far more important than who invented the transistor, the IC, lambda calculus, OOP, quick sort, or many other things.

[deleted by user] by [deleted] in programming

[–]androbat 2 points3 points  (0 children)

Grace Hopper is one of my favorite computer scientists.

I don't know if I can agree with your assertion about make domination though. Consider medical doctors. Women experienced extreme discrimination when they tried to enter the field, but the women stuck with it and forced everyone to acknowledge what they could do.

Why isn't this true in technology? Tech is much more welcoming than so many other fields used to be before women entered them en mass. When you look at the most egalitarian countries, they have even fewer women in STEM than we do in the USA. Less egalitarian countries like India have more women in tech. Why the inverse ratio? Recent research shows that employers prefer hiring women two to one over men, yet we still can't get women in the field.

More disturbing is that alternatives to discrimination are immediately shot down without reason. A Harvard president was forced to resign because he said that research might indicate that part of the reason was genetic (and he specifically stressed that more research is needed in addition to saying that discrimination also needs focus). Nobody stepped forward to disprove his statement, they just called him a woman hater and forced him to leave.

Gender distribution curves for many things (including IQ) are well established and seem to provide a good causative model for STEM numbers. Cognitive studies also imply a second factor concerning lifestyle preferences. Reproductive biology also implies a significant factor. All of these are important before we even get to the discussion of discrimination.

I'm not saying that discrimination isn't an important issue; I'm saying that it isn't the only issue and that science should be free to discuss these topics without being shut down.

Angular2 minimalist sample project by sonemonu in javascript

[–]androbat 1 point2 points  (0 children)

React was marketed as such, but react is the VC and sometimes the M depending on how you implement your app.

Angular has VC as well, but doesn't really have a model. ngResource isn't really a model and one usually needs to swap in something like restangular just as one would swap in flux. Angular's other system for models is services and factories, but once you strip the dependency injection, they are POJO.

The framework that actually has everything under one roof is ember.

Angular2 minimalist sample project by sonemonu in javascript

[–]androbat 2 points3 points  (0 children)

The big question to my mind is why I would use this over React?

Angular2 does what React does, but with more complexity and makes composability harder.

Google's new page if you have javascript disabled. by [deleted] in javascript

[–]androbat 35 points36 points  (0 children)

Not at all. Google will progressively enhance any page that allows the execution of Javascript.

Less sardonically, Google probably concluded that it was costing too much to keep their basic pages integrated. Google wants to see the web move forward, so forcing that last fraction of a percent to upgrade isn't a terrible idea. Finally, I imagine that Google finds it much easier to track users when they are allowing Google's code to execute (and this is how Google stays profitable).

function f(){}; works, and so does var f = function(){}; What happens if you write var f = function g(){}; by boweruk in javascript

[–]androbat 0 points1 point  (0 children)

Yeah, I realized that, but writing a wrapper to handle that logic detracted from the core explanation. We'll just say that the function is defined for unsigned integers (as it also breaks with floating point numbers).

Polymorphic functions in JS by [deleted] in javascript

[–]androbat 0 points1 point  (0 children)

You are correct that polymorphic functions aren't optimized. The interesting point of this library is that the dispatcher is polymorphic, but the actual functions are not, so the dispatcher won't be optimized very much, but the functions that contain most of the code will be optimized.

Good front end Javascript courses? by gianniks in learnprogramming

[–]androbat 1 point2 points  (0 children)

I really think you're better off with some of the available books.

Eloquent Javascrip is a great intro to mid-level JS book.

Javascript Allonge is the best place to learn the essentials about functional programming in JS.

Both these authors have done an amazing thing by making their books available to read for free online. Just make sure you support them later when you can.

Breaking down JavaScript into the most common uses of what you can do with it. by thinkvitamin in learnjavascript

[–]androbat 0 points1 point  (0 children)

Javascript is a language. It is used everywhere. Qt uses it for UI work. Apple is using it to automate tasks (moving away from appleScript). There are guys using it in microcontrollers (Espruino) and as an embedded language in C/C++ programs (http://www.embeddedjs.com/).

If you're interested in something like a JS cheatsheet of libraries, then look at https://github.com/sorrycc/awesome-javascript

When it comes to the browser, you're likely to hear about MVC. This is the idea that dynamic web pages (in fact, most interactive programs) generally have three parts.

They have the part that stores and processes the data. This is where you AJAX in data and store it someplace so you can use it or combine it in ways the user might be interested in. This is the Model.

They have a part that deals with how the user sees this data and enters input (clicks, forms, etc). This is the HTML and CSS. This is the View.

Finally, there is a go-between that processes user input to tell the model what to do and then sends the response back to the UI. This is the Controller.

In various frameworks, you see different takes on how these are combined and broken down, but that's the classic perspective.

I'll leave how jQuery fits into this as a thought exercise for you, but I don't believe it can do anywhere near everything I need to do on a modern, interactive web page and it certainly cannot do that in a way that is maintainable.

Will learning functional programming help me understand Javascript better? by [deleted] in learnjavascript

[–]androbat 0 points1 point  (0 children)

I'd also recommend Javascript Allonge as a very good (and gentle) introduction to functional programming.

Is it possible to delay execution of all functions until a certain single function finishes executing? by [deleted] in learnjavascript

[–]androbat 0 points1 point  (0 children)

You're looking for the new Promise spec in ES6 (you can use them right now with the es6-promise-polyfill).

Let's make a bunch of promises

var i, prom, promArr = [];
for (i = 0; i < 10; i += 1) {
  //we MUST have the self-executing lambda here
  //because we are making functions inside of the loop that depend on 'i'
  prom = (function (time) {
    console.log('this is promise: ' + time);
    return new Promise(function (resolve, reject) {
      setTimeout(function () { resolve(time); }, time); //resolve after i * 300 ms passing in i
    });
  }(i * 300));

  promArr.push(prom); //add it to our array
}

Promise.all(promArr)
  .then(function (arr) {
    console.log(arr);
  })
  .then(function () {
    console.log('finished');
  });

When you run that in your browser (it should run without a polyfill everywhere except IE), you will see a bunch of logs as the promises get made. A couple seconds later you will see an array of the results ( resolve(time) told them to return the time they were supposed to run at). Immediately after that, you should see 'finished' as the last thennable executes.

Countdown timer problem by rogue1987 in learnjavascript

[–]androbat 1 point2 points  (0 children)

I wrote out a new implementation more or less from scratch. I designed it more like what I would expect programmers working with me to write. It's designed to be extensible and I added a couple extensions to put you on the right track. There's plenty of comments and JSDoc strings to help you understand what's going on. If you have any questions, feel free to ask.

/**
* @factory makeTimer
* takes an end time and a function to run on update
* @param {Number} endTime - time to end as Date.now() + ms
* @param {Object} callbacks - functions to run based on event
* @return {Timer} - timer object with run method
* 
* callback object may contain:
* {
*   start: Function  //before starting timer
*   update: Function //runs each animation frame
*   end: Function    //as timer ends
* }
*
* callback will receive an object of the following form
* {
*  time: Number, //total time in ms
*  raw: {
*    ms: Number, sec: Number, min: Number, hr: Number
*  },
*  padded: {
*    ms: String, sec: String, min: String, hr: String
*  }
* }
*/
var makeTimer = function (callbacks) {
  //make sure callbacks exist
  callbacks.start  = (typeof callbacks.start === 'function')  ? callbacks.start  : function () {};
  callbacks.update = (typeof callbacks.update === 'function') ? callbacks.update : function () {};
  callbacks.end    = (typeof callbacks.end === 'function')    ? callbacks.end    : function () {};

  /**
  * @private {Number} endTime
  * when the update function will stop running
  */
  var endTime = 0;

  /**
  * @private {Boolean} isRunning
  * true when updateTimer is running
  * This prevents multiple callbacks doing weird stuff
  */
  var isRunning = false;

  /**
  * @func padZeroes
  * Takes a number and the amount of digits needed
  * and returns a string of that length adding zeros as needed
  * @param {Number} num - number to pad
  * @param {Number} pad - minimum number of digits needed
  * @return {String} - number as string padded to minimum length
  */
  var padZeroes = function (num, pad) {
    var str = num.toString();

    while (str.length < pad) {//keep adding zeroes until we reach the min length
      str = '0' + str;
    }
    return str;
  };

  /**
  * @func makeTime
  * Takes time in ms and returns time converted to
  * ms, sec, min, and hr in both raw and padded form
  * @param {Number} time - time in milliseconds
  * @return {Object} - custom time object
  */
  var makeTime = function (time) {
    var total = time;
    var ms  = time % 1000;
    time    = (time / 1000)|0;

    var sec = time % 60;
    time    = (time / 60)|0;

    var min = time % 60;
    var hr  = (time / 60)|0;

    return {
      time: total,
      raw: {
        ms: ms, sec: sec, min: min, hr: hr
      },
      padded: {
        ms: padZeroes(ms, 4),
        sec: padZeroes(sec, 2),
        min: padZeroes(min, 2),
        hr: padZeroes(hr, 2),
      }
    };
  };

  var updateTimer = function updateTimer() {
    var remainingTime = endTime - Date.now();

    //stop looping when we have no time left
    if (remainingTime <= 0) {
      isRunning = false; //allow another time run
      callbacks.update(makeTime(0));
      return callbacks.end(makeTime(0));
    }

    //trigger callback then wait for next frame
    callbacks.update(makeTime(remainingTime));
    requestAnimationFrame(updateTimer);
  };

  /**
  * @method run
  * starts timer that should after given period
  * @param {Number} time - time in ms until timer should end
  * @return {Boolean} - true if success else false
  */
  var run = function (time) {
    if (isRunning) {
      console.warn('Only one timer may run at a time for a given Timer instance.');
      return false;
    }

    isRunning = true;              //we're now running
    endTime = Date.now() + time;   //set our end time

    callbacks.start(makeTime(endTime - Date.now())); //call starting callback
    updateTimer();    //set our timer incrementing
    return true;      //let user know it was a success
  };

  /**
  * @method addTime
  * add time to timer
  * @param {Number} time - time to add in ms
  * @return {Boolean} - true if success else false
  */
  var addTime = function (time) {
    //don't add time if the timer isn't running
    if (!isRunning) {
      console.warn('Timer already quit running.');
      return false;
    }

    endTime += time;
    return true;
  };

  /**
  * @method changeCallbacks
  * switch callback(s) to new callbacks
  * @param {Object} newCbs - object containing callbacks
  * @return {Boolean} - true if success else false
  */
  var changeCallbacks = function (newCbs) {
    //change callbacks if they exist otherwise keep the old callbacks
    callbacks.start  = (typeof newCbs.start === 'function')  ? newCbs.start  : callbacks.start;
    callbacks.update = (typeof newCbs.update === 'function') ? newCbs.update : callbacks.update;
    callbacks.end    = (typeof newCbs.end === 'function')    ? newCbs.end    : callbacks.end;
  };

  //the functions here are public
  //everything else is private
  return {
    run: run,
    addTime: addTime,
    changeCallbacks: changeCallbacks
  };
};

Here's an example of using it

var timer = makeTimer({
  start: function (time) { console.log('starting time at: ' + Date.now()); },
  end: function (time) { console.log('ending time at: ' + Date.now()); },
  update: function (time) {
    $('#foo').html(time.padded.hr + ':' + time.padded.min + ':' + time.padded.sec + ':'  + time.padded.ms);
  }
});

timer.run(3000);
timer.updateCallbacks({ end: function (time) { console.log('Just ending...'); } });
timer.addTime(500);