Open Side Menu Go to the Top

07-29-2012 , 05:32 PM
"It's because there's no purpose to it and it just splits people apart, that is why the JS community who doesn't use CS is against it."

I'm picturing a unified world of assembly programmers. Nothing adds capabilities to assembly.
Learning Javascript Thread Quote
Learning Javascript Thread
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
Learning Javascript Thread
07-29-2012 , 08:24 PM
Quote:
Originally Posted by jtollison78
"It's because there's no purpose to it and it just splits people apart, that is why the JS community who doesn't use CS is against it."

I'm picturing a unified world of assembly programmers. Nothing adds capabilities to assembly.
Maybe 20 years ago, but today it's much different. There's no need to hand write asm unless you're working on crazy low level systems.

The v8 engine (Google's JS engine) compiles JS directly into asm. Why write that by hand when a machine can likely write better asm than most humans?

Surely you're not comparing writing JS to asm and thinking people are being stubborn by not using something else to write JS?
Learning Javascript Thread Quote
07-30-2012 , 12:12 AM
You know, recently someone did say "JavaScript is the Assembly language of the web." :P
Learning Javascript Thread Quote
07-30-2012 , 12:53 AM
interesting discussion. my interest in coffeescript is from a long-term code maintainability concern. javascript is not yet that cumbersome in my modest codebase.
Learning Javascript Thread Quote
07-30-2012 , 09:23 AM
Quote:
Originally Posted by RICHI8
You know, recently someone did say "JavaScript is the Assembly language of the web." :P
And by recent you mean over a year ago and most real JS developers disagree with him?
Learning Javascript Thread Quote
07-31-2012 , 05:11 PM
Quote:
- If you plan to do any open source work you're instantly cutting off a huge majority of people who would use or contribute to your project. The JS that CS generates is JS in the end but it's really verbose and definitely doesn't resemble how most people would write JS by hand.
Wouldn't people just work with CS themselves instead of hacking on the output JS? At least that's how I'd do it.

Quote:
Yeah I do want you to explain why because it's hard to disagree with github and stackoverflow's stats. Those are both extremely popular and extremely developer oriented web sites.
I'd say the average quality of people interested in CS may be higher than that of people interested in JS. I cannot prove it nor do I want to but CS seems to be a pretty hackish kind of idea and should thus attract people with that mindset.
I'd also say at the top JS has the higher skill level people.

I mean your argument is "more people use it" which I don't think is a particularly good argument.

The tough gotchas require JS skill anyways is a pretty good argument for learning JS though.

(obviously way off topic-ish but an interesting debate nontheless imo)

Last edited by clowntable; 07-31-2012 at 05:18 PM.
Learning Javascript Thread Quote
07-31-2012 , 08:17 PM
People working on CS would use it, yes. I was talking about working on open source projects and contributing to open source projects. You can't just say "oh get a coffee to JS compiler and then read the JS!", because the JS it outputs is ridiculous. Also that's an unreasonable thing to ask someone to do in the first place.

I only brought stats in to show that it's not wildly popular. Those were the first 2 sites that popped into my head to get stats from.
Learning Javascript Thread Quote
08-01-2012 , 12:56 AM
Quote:
Originally Posted by Shoe Lace
Surely you're not comparing writing JS to asm and thinking people are being stubborn by not using something else to write JS?
I was suggesting that if people hadn't been free to try different things for fear of somehow fracturing the group, then we'd still be stuck there. It doesn't really bother me that people use JS even though my preference is CS. It seems to bother you, and it's not clear, to me, why it should. I guess you have some line in mind as to what constitutes enough additional capability, but for me coffeescript is compelling enough.

Out of curiosity, would you consider Clojurescript a legitimate switch? I'm still just dipping my toes into the clojure world, but I'd probably be moving that way a lot quicker if it weren't for coffeescript. If not clojurescript, then what would constitute the addition of real capabilities?
Learning Javascript Thread Quote
08-01-2012 , 01:39 AM
Quote:
Originally Posted by Shoe Lace
And by recent you mean over a year ago and most real JS developers disagree with him?
Good catch on the time. My does time fly by. Btw, you are aware that Brandon Eich and Douglas Crockford both agreed with that statement to a certain extent right?

jtollison basically hit the nail on the head. I'm pretty much done with this debate as I've lived through these debates with people so much over the last year. It really doesn't bother me that not everyone embraces CS.
Learning Javascript Thread Quote
08-01-2012 , 07:31 AM
Didn't even know there was Clojurescript...that seems to be something to add onto my list of cool stuff to check out (below Clojure I guess heh)
Learning Javascript Thread Quote
08-01-2012 , 08:58 AM
It doesn't bother me. You guys just came into the thread trying to convince someone new to JS to immediately switch without listing the downsides or even giving a single concrete reason to switch.
Learning Javascript Thread Quote
08-01-2012 , 09:41 AM
Quote:
Originally Posted by clowntable
Didn't even know there was Clojurescript...that seems to be something to add onto my list of cool stuff to check out (below Clojure I guess heh)
http://********/clojure/rich-hickey-...script-5399498

Clojurescript doesn't seem quite as compelling to me as clojure itself, but still worthwhile.
Learning Javascript Thread Quote
08-01-2012 , 09:45 AM
wtf, seriously? Can I not link to free instructional videos here? I know I don't post enough to be up on the rules, but... blip dot tv slash clojure = lots of good clojure videos including the clojurescript introduction from Rich Hickey.

edit: I immediately followed up here with the address partly out of frustration, but partly assuming this link wouldn't actually be breaking any rules. Maybe it is. I'm sure someone will take it down if that's the case. If this is a violation of some rules policy, it seems like a bad policy to me and, fwiw, will motivate me to spend less time here. I don't like feeling like I'm in prison while visiting programming forums.

Last edited by jtollison78; 08-01-2012 at 09:55 AM. Reason: additional thoughts/explaination
Learning Javascript Thread Quote
08-01-2012 , 01:10 PM
Before Reading, note the difference: Clojure ; Closure.

I love Lisp and I love Clojure, but I'm not loving ClojureScript. The reason is that ClojureScript compiles down to Closure, not bona fide javaScript. Closure is Google's JS framework/boilerplate/whatever, which in turn compiles down to fast-compiling JS.

The issue with Closure, as I understand it, is that Closure was created to solve Google's problems, not the world's problems per se, thus, to get Closure to work well, you have to dip into the JS or use ordinary JS. So, with ClojureScript, you are dealing with a sort of pre-processor to a pre-processor, and you have to understand not only the limitations of Clojure --> JS, but also the limitations of Clojure --> Closure, and Closure --> JS. Obviously the big one is taking a programming language with concurrent / streaming built-in and converting that to single-line applications. Then there's apparently some key words that ClojureScript decided to remove from JS. Not sure how important this is, but apparently eval() is the one everyone fusses about.

Anyways, I'm not saying it isn't viable, but that I'm not too plussed by it yet. Of course, I'm not a JS maestro either.

Now, as far as back-end programming: as someone who isn't a maetro on that subject, I think Clojure is amazing.
Learning Javascript Thread Quote
08-01-2012 , 06:08 PM
Quote:
Originally Posted by jtollison78
wtf, seriously? Can I not link to free instructional videos here? I know I don't post enough to be up on the rules, but... blip dot tv slash clojure = lots of good clojure videos including the clojurescript introduction from Rich Hickey.

edit: I immediately followed up here with the address partly out of frustration, but partly assuming this link wouldn't actually be breaking any rules. Maybe it is. I'm sure someone will take it down if that's the case. If this is a violation of some rules policy, it seems like a bad policy to me and, fwiw, will motivate me to spend less time here. I don't like feeling like I'm in prison while visiting programming forums.
Don't worry about it. I have no idea, but I presume someone (more likely an endless stream of gimmicks) has been hardcore spamming blip at some point in the past in one of the super popular forums, NVG would be my guess. Enough to get it added to the censor, which is just an easy way to invalidate all previous spam and make any future spams not work so they just give up, if account and IP bans prove ineffective in stopping it. I'd expect is was more likely for their specific videos, not anything to do with the site itself.
Learning Javascript Thread Quote
12-28-2012 , 03:23 AM
Code:
function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
  return result;
}

function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}

testList();
This flawed code is from http://www.javascriptkit.com/javatutors/closures2.shtml and is meant to show some gotchas with javascript's closures. After a few months of not touching javascript outside of a bit of jquery I want to dive back in so I attempted to fix the above code using a self invoking anonymous function,

Code:
function buildList(list) {
  var result = [];
  for (var i = 0; i < list.length; i++) {
    (function(listitem) {
      var item = 'item' + listitem;
      result.push( function() {alert(item + ' ' + listitem)} );
    })(list[i]);
  }
  return result;
}

function testList() {
  var fnlist = buildList([1,2,3]);
  // using j only to help prevent confusion - could use i
  for (var j = 0; j < fnlist.length; j++) {
    fnlist[j]();
  }
}

testList();
it works but I'm going off a fading memory of a crockford lecture I watched over the summer and it still feels alien to me. hows this look?
Learning Javascript Thread Quote
12-28-2012 , 06:58 PM
e i pi,

Your code does work, but I think there may be a better way to do it. If you JSHint your code, it will return an error that says "Don't make functions in a loop." Here is an outstanding explanation of that error.

A basic rule to follow is that if a function is only supposed to execute once (like on page load), an immediately invoked function expression is the way to go.

If the function is needed multiple times, there is a performance penalty for running the IIFE multiple times (like in a loop). For that, function declarations are better.

Here's my rewrite:

Code:
function testList(arr) {
  var size = arr.length,
    result = [],
    resultItem,
    i;
  
  // Make sure value is an array (practice like you play!)
  if ( Object.prototype.toString.call( arr ) !== '[object Array]' ) {
    return false;
  }
  
  for (i = 0; i < size; i++) {
    resultItem = build(arr[i]);
    result.push(resultItem);
  }
  
  function build(listNum) {
    var item = 'item' + listNum + ' ' + listNum,
        fnc = function () { alert(item); };
    return fnc;
  }
  
  return result;
}

var test = testList([1,2,3]);

test[1](); // test with the second item in the array
Functions should return values, and Javascript is no different. This one returns an array of functions that alert the "itemX X" string.

Also, it's generally a good idea to declare variables at the top, especially if you're calculating a value that will be used in a loop. In your code, you have this:

Code:
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
That requires the length of the list array to be re-calculated at the beginning of every iteration of the loop. It's far more efficient to calculate it first, cache it in a variable, and then do the loop:

Code:
  var size = list.length,
      i;

  for (i = 0; i < size; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
Learning Javascript Thread Quote
12-29-2012 , 01:13 AM
Quote:
Originally Posted by sdturner02
e i pi,

Your code does work, but I think there may be a better way to do it. If you JSHint your code, it will return an error that says "Don't make functions in a loop." Here is an outstanding explanation of that error.
That explanation doensn't have much to do with the error. Thinking of functions as being recreated is fine if you're trying to analyze semantics, but it's not correct if you're trying to analyze performance. The only thing being recaptured in the "function expression" is the closure object, which essentially consists of the pointer to the scope and the pointer to the compiled object code. There's very little performance implication for any reasonable implementation. It's not ever going to matter unless this is in some critical inner loop, in which case you'd want to completely flatten it out and not generate functions at all.

The real reason not to generate closures inside of a loop has to do with what the previous poster said - loops (or any javascript blocks for that matter) don't create a new scope, so unless you specifically create another level of scope (which his fix does with functions), you're creating the same closure over and over again, which is almost certainly not what's intended.

Quote:
Originally Posted by sdturner02
Also, it's generally a good idea to declare variables at the top, especially if you're calculating a value that will be used in a loop. In your code, you have this:

Code:
  for (var i = 0; i < list.length; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
That requires the length of the list array to be re-calculated at the beginning of every iteration of the loop. It's far more efficient to calculate it first, cache it in a variable, and then do the loop:

Code:
  var size = list.length,
      i;

  for (i = 0; i < size; i++) {
    var item = 'item' + list[i];
    result.push( function() {alert(item + ' ' + list[i])} );
  }
This is premature optimization. Javascript arrays are not lists - the length doesn't have to be calculated, it's a stored property. I suppose it can be slightly faster to access a local variable than a stored property, but this is just not something you should be concerned about in most cases.


As for how to cleanly rewrite the original code, this should work:

Code:
function buildList(arr) {
  return arr.map(function(item) { return function() { alert('item' + item + ' ' + item) } })
}
Learning Javascript Thread Quote
12-29-2012 , 02:28 AM
Quote:
Originally Posted by candybar
That explanation doensn't have much to do with the error. Thinking of functions as being recreated is fine if you're trying to analyze semantics, but it's not correct if you're trying to analyze performance. The only thing being recaptured in the "function expression" is the closure object, which essentially consists of the pointer to the scope and the pointer to the compiled object code. There's very little performance implication for any reasonable implementation. It's not ever going to matter unless this is in some critical inner loop, in which case you'd want to completely flatten it out and not generate functions at all.

The real reason not to generate closures inside of a loop has to do with what the previous poster said - loops (or any javascript blocks for that matter) don't create a new scope, so unless you specifically create another level of scope (which his fix does with functions), you're creating the same closure over and over again, which is almost certainly not what's intended.
Doesn't have much to do with the error? Seriously?

Quote:
SO answer:

Partially it depends on whether you're using a function expression or a function declaration. They're different things, they happen at different times, and they have a different effect on the surrounding scope.

...

1. Function expressions are evaluated where they're encountered in the program flow. Declarations are evaluated when control enters the containing scope (e.g., the containing function, or the global scope).
You're correct that neither the SO answer nor the one I posted took the time to explicitly point out that variable scope doesn't change within a loop. eipi's post made it pretty clear that he knows this.

More to the point, he never asked that. He wanted to hear opinions on the quality of his code. I pointed out the JSHint error, which actually is related to coding practices -- his code still works.

The SO answer I pointed to is in response to precisely that JSHint message and mentions variable scope, performance, provides alternate solutions, and so on. Furthermore, it's been upvoted 25 times. Anyone on SO for more than 5 minutes understands what that means.

Quote:
Originally Posted by candybar
This is premature optimization.
Wrong. It is not a premature optimization. Far from it. There is no risk of an unintended negative effect, readability does not suffer, and any extra time required is no more than a few seconds at most, if any at all.

Quote:
Originally Posted by candybar
Javascript arrays are not lists - the length doesn't have to be calculated, it's a stored property.
I love how you dismissed "semantics" earlier and then followed up with this gem in the exact same post.

Quote:
Originally Posted by candybar
I suppose it can be slightly faster to access a local variable than a stored property, but this is just not something you should be concerned about in most cases.
You're making groundless assumptions.

For Internet Explorer -- the most important performance consideration -- benchmarks show that performance enhancements of up to 244% are achievable by caching the array length. See for yourself:

http://jsperf.com/caching-array-length/4

Yes, obviously if that's the only thing our JS code does, then it isn't going to matter. But for applications that rely heavily on highly complex JS code, in the aggregate, it can and does matter. Especially for older versions of IE for users with slow computers.

Also, the primary reason for declaring variables at the top is for code readability and organization. I honestly thought that was too obvious to point out, and decided to offer a less apparent consideration instead. Clearly, I was mistaken.

Quote:
Originally Posted by candybar
As for how to cleanly rewrite the original code, this should work:

Code:
function buildList(arr) {
  return arr.map(function(item) { return function() { alert('item' + item + ' ' + item) } })
}
If "cleanly" means seeing how many statements you can fit onto one line, then yes, nice job.

Btw, you're missing some semicolons.
Learning Javascript Thread Quote
12-29-2012 , 01:18 PM
Quote:
Originally Posted by sdturner02
The SO answer I pointed to is in response to precisely that JSHint message and mentions variable scope, performance, provides alternate solutions, and so on. Furthermore, it's been upvoted 25 times. Anyone on SO for more than 5 minutes understands what that means.
In this case, this means most people who've visited that page have little idea what's going on. I've written interpreters and compilers for languages with nearly identical semantics. Performance-wise, this is not something you'd be concerned about. Capturing the wrong closure (than what the user may intend) has nearly 100% to do with why that's a JSLint error. JSLint isn't that finicky about potential performance problems otherwise. And if it was truly about performance, your code and my code both generate closures in a loop, but JSLint doesn't care for a reason.

See:

https://groups.google.com/forum/?fro...rs/BbvL5qFG_uc

Quote:
Wrong. It is not a premature optimization. Far from it. There is no risk of an unintended negative effect, readability does not suffer, and any extra time required is no more than a few seconds at most, if any at all.
You're adding boilerplate trying to save nanoseconds.

Of course the readability suffers - extra lines of boilerplate are going to add up. This isn't the only place you're going to cache, is it? If you make the equivalent caching decisions for all potentially slow operations in javascript, it's going to add up tremendously. It's extremely rare to be writing performance-critical code in any language and even rarer in javascript. And if you're going to care about performance, you don't create closures this way. You'd preallocate arrays and use them for most things and try hard to get the compiler not to box your primitives and try your hardest to never allow any objects to be created dynamically. Unless you're doing this and using javascript essentially as C, it's very likely that something else you're doing will be so slow to make this optimization entirely meaningless. And theoretically, it's easier to optimize the original code. What's worse, I think in many cases, the extra bytes transmitted cost more than the time you save in the loop.

Quote:
I love how you dismissed "semantics" earlier and then followed up with this gem in the exact same post.
I'm not sure what you mean by "semantics" here - the "gem" is also absolutely correct. Array lengths are very obviously stored, the only performance penalty you're looking at is looking up an object property versus using a local variable. Do you cache all object property references that occur multiple times in a loop?

Quote:
For Internet Explorer -- the most important performance consideration -- benchmarks show that performance enhancements of up to 244% are achievable by caching the array length. See for yourself:

http://jsperf.com/caching-array-length/4
You should look at that table more carefully. There are a bunch of browsers where your version of caching (caching outside the loop) is slower than not caching at all. Furthermore, in the unoptimized case, your version uses more memory, so the cost may be paid elsewhere, in terms of cache misses and heap allocation. If the compiler properly optimizes both, you're looking at the same code. Besides, % gain is the wrong way to think about performance, when you're dealing with nano/microseconds. It's much important to make something that takes half a second 1% faster than to make something that takes a microsecond 100000% faster.

The chance is, you've probably never written code where this performance difference ever mattered. This is so cheap compared to rampant object/closure creation and ajax calls that go on in javascript that it's not worth thinking about, unless you're writing the inner most loop in some framework/libraries that are going to be heavily used. Even then, this is dubious. Profilers will tell you where you need to optimize.

Quote:
Yes, obviously if that's the only thing our JS code does, then it isn't going to matter. But for applications that rely heavily on highly complex JS code, in the aggregate, it can and does matter. Especially for older versions of IE for users with slow computers.
This is also a wrong way to think about performance. In large complex software, an extremely small percentage of the codebase is responsible for almost all of the performance problems. You want to address the problems where they occur, not by preemptively adding boilerplate code to all the code. And be ware of things like this:

https://gist.github.com/2841832

So that you can design for performance.

Quote:
Also, the primary reason for declaring variables at the top is for code readability and organization. I honestly thought that was too obvious to point out, and decided to offer a less apparent consideration instead. Clearly, I was mistaken.
You're declaring an extra variable. This has nothing to do with top declaration. Javascript's poor scoping rules dictate that top declaration be a fairly good rule in general.

Quote:
If "cleanly" means seeing how many statements you can fit onto one line, then yes, nice job.
It's cleaner and much simpler even if you add the line breaks.

Quote:
Btw, you're missing some semicolons.
Those are optional.
Learning Javascript Thread Quote
12-29-2012 , 02:28 PM
Quote:
Originally Posted by sdturner02
Code:
function testList(arr) {
  var size = arr.length,
    result = [],
    resultItem,
    i;
  
  // Make sure value is an array (practice like you play!)
  if ( Object.prototype.toString.call( arr ) !== '[object Array]' ) {
    return false;
  }
  
  for (i = 0; i < size; i++) {
    resultItem = build(arr[i]);
    result.push(resultItem);
  }
  
  function build(listNum) {
    var item = 'item' + listNum + ' ' + listNum,
        fnc = function () { alert(item); };
    return fnc;
  }
  
  return result;
}

var test = testList([1,2,3]);

test[1](); // test with the second item in the array
And I think you decided to start randomly nitpicking because you got mad for some reason, but in case you do like sharing code criticism, there are a few problems in the above code:

1) You use arr.length before you check whether arr is an array, rendering the check largely worthless.

2) Using .push to append to an array when you know the exact length is much worse than not caching .length. You want to preallocate the array and populate as you go.

3) Your check is worse than not having it in the first place in most cases. If you don't want it to blow up, return an empty array. If you want it to blow up, then there's no need for a check. The caller can just as easily check his argument type as he can check the return type.

Overall, your code is slow, much slower than mine, despite your "caching." And I ran some performance tests and my code is about twice as fast on chrome23 (50 seconds versus 100 seconds) and almost infinitely faster on IE10 (7 seconds versus it's been a few minutes and it still hasn't finished probably because it's running into some memory issues). This is after removing your check for an apples-to-apples comparison.

Code:
function buildBigArray(n) {
  var array = new Array(n);
  for (var i = 0; i < n; i++) {
    array[i] = "blah";
  }
  return array;
}

var blahArray = buildBigArray(1000000);
var start = (new Date).getTime();
var hey;
for (var i = 0; i < 100; i++) {
  hey = testList(blahArray);
}
var diff = (new Date).getTime() - start;
If you want to write performant code, you need to pay attention to what matters, not start microptimizing everywhere while missing the big stuff.
Learning Javascript Thread Quote
12-29-2012 , 07:57 PM
Quote:
Originally Posted by candybar
In this case, this means most people who've visited that page have little idea what's going on. I've written interpreters and compilers for languages with nearly identical semantics. Performance-wise, this is not something you'd be concerned about. Capturing the wrong closure (than what the user may intend) has nearly 100% to do with why that's a JSLint error. JSLint isn't that finicky about potential performance problems otherwise. And if it was truly about performance, your code and my code both generate closures in a loop, but JSLint doesn't care for a reason.

See:

https://groups.google.com/forum/?fro...rs/BbvL5qFG_uc
You're still missing my point. The reason that I believe that it's a good answer, which is clearly a sentiment shared by many others, is that it's a more complete answer that touches on multiple reasons for the JSHint message.

Here's some friendly advice, though -- You don't earn any credibility by making claims about your knowledge and experience. No one read that you've written a compiler and decided to give you more credibility. Particularly on 2p2, credentials mean nothing; actual evidence of ability means everything.

Quote:
Originally Posted by candybar
You're adding boilerplate trying to save nanoseconds.

Of course the readability suffers - extra lines of boilerplate are going to add up. This isn't the only place you're going to cache, is it? If you make the equivalent caching decisions for all potentially slow operations in javascript, it's going to add up tremendously. It's extremely rare to be writing performance-critical code in any language and even rarer in javascript. And if you're going to care about performance, you don't create closures this way. You'd preallocate arrays and use them for most things and try hard to get the compiler not to box your primitives and try your hardest to never allow any objects to be created dynamically. Unless you're doing this and using javascript essentially as C, it's very likely that something else you're doing will be so slow to make this optimization entirely meaningless. And theoretically, it's easier to optimize the original code. What's worse, I think in many cases, the extra bytes transmitted cost more than the time you save in the loop.
I'm not sure what any of this has to do with anything. You fired off the single most overused programming mantra in the history of the universe, and I succinctly explained why I think you're incorrect.

You're also arguing a strawman. At no point did I say anything about caching in any other situation than this one specific scenario. You're putting words in my mouth and then lecturing me on why they're wrong.

Quote:
Originally Posted by candybar
I'm not sure what you mean by "semantics" here - the "gem" is also absolutely correct. Array lengths are very obviously stored, the only performance penalty you're looking at is looking up an object property versus using a local variable. Do you cache all object property references that occur multiple times in a loop?
Ok, I'll explain. Here is my original statement:
Quote:
That requires the length of the list array to be re-calculated at the beginning of every iteration of the loop.
And here is your response:
Quote:
Javascript arrays are not lists - the length doesn't have to be calculated, it's a stored property.
The irony that I was pointing out is that you dismissed an earlier point as semantics, and then later argued that I was wrong because I used the term "calculated" when in fact the length value is a stored property and doesn't need to be actually "calculated".

It's a gem b/c you didn't realize you were arguing semantics, when you clearly were, in the same post where you accused me of arguing semantics (which, btw, I was not).

Here's how you can spot an argument based on semantics: If you're contradicting the principle of another's argument based on their use of similar but not 100% technically accurate terms, and the principle of the argument remains even if the terms are swapped, you're doing it wrong.

Quote:
Originally Posted by candybar
You should look at that table more carefully. There are a bunch of browsers where your version of caching (caching outside the loop) is slower than not caching at all. Furthermore, in the unoptimized case, your version uses more memory, so the cost may be paid elsewhere, in terms of cache misses and heap allocation. If the compiler properly optimizes both, you're looking at the same code. Besides, % gain is the wrong way to think about performance, when you're dealing with nano/microseconds. It's much important to make something that takes half a second 1% faster than to make something that takes a microsecond 100000% faster.
Did I not specifically point out that Internet Explorer is (a) what I was referring to, and (b) the most important browser for performance analysis (b/c it's slow and still widely used)?

Quote:
Originally Posted by candybar
The chance is, you've probably never written code where this performance difference ever mattered.
This is by far the most telling statement you've posted. I'm actually just going to stop right here. I suspect that this decision will be a mystery to you, but I have no doubt that the 2p2 Programming crowd understands why without any further explanation.
Learning Javascript Thread Quote
12-29-2012 , 08:26 PM
Quote:
Originally Posted by candybar
And I think you decided to start randomly nitpicking because you got mad for some reason, but in case you do like sharing code criticism, there are a few problems in the above code:
I always appreciate criticism and feedback on my code. Unfortunately, this feedback is terrible.

Quote:
Originally Posted by candybar
1) You use arr.length before you check whether arr is an array, rendering the check largely worthless.
Wrong. Using arr.length before checking type has absolutely no impact on the value of the check. The length property is not exclusively for arrays. If a string was passed to the function, the length property would return the number of characters in the string, and the check will catch the error.

Quote:
Originally Posted by candybar
2) Using .push to append to an array when you know the exact length is much worse than not caching .length. You want to preallocate the array and populate as you go.
Wrong. In Javascript, there is no value to be obtained from preallocating arrays. That's b/c arrays in Javascript aren't actually arrays, they're a type of object. And, in point of fact, preallocating arrays in JS is nearly always going to result in slower execution. See for yourself:

http://jsperf.com/pre-allocated-arrays
http://stackoverflow.com/a/1295671/1091949

Quote:
Originally Posted by candybar
3) Your check is worse than not having it in the first place in most cases. If you don't want it to blow up, return an empty array. If you want it to blow up, then there's no need for a check. The caller can just as easily check his argument type as he can check the return type.
Wrong. This is absolutely horrible advice, perhaps even worse than the other two, and those were objectively wrong. Why don't you try to figure this one out on your own, I'd be interested to see what you come up with.

Quote:
Originally Posted by candybar
Overall, your code is slow, much slower than mine, despite your "caching."
...
This is after removing your check for an apples-to-apples comparison.
lol
Learning Javascript Thread Quote
12-29-2012 , 09:03 PM
Quote:
Originally Posted by sdturner02
You're still missing my point. The reason that I believe that it's a good answer, which is clearly a sentiment shared by many others, is that it's a more complete answer that touches on multiple reasons for the JSHint message.
But you're still wrong. Of the many possible explanations, that SO answer doesn't include the most important explanation, while giving off the impression that multiple copies of the object code may have to be made, while hedging that he's not sure if it can be optimized away, when it's simply a couple of pointers that share the same object code underneath. In fact, we know that he didn't know this when he answered the question, because he's the same guy who later asked here (provided earlier, in case you haven't noticed):

https://groups.google.com/forum/?fro...rs/BbvL5qFG_uc

Otherwise, you should submit a pull request here:

http://jslinterrors.com/dont-make-fu...within-a-loop/



Quote:
Here's some friendly advice, though -- You don't earn any credibility by making claims about your knowledge and experience. No one read that you've written a compiler and decided to give you more credibility. Particularly on 2p2, credentials mean nothing; actual evidence of ability means everything.
Your only argument was appeal to popularity. Which also means nothing. I've given you a technical explanation and I've also shown that the guy who wrote that answer didn't know certain obvious things about how javascript engines (or any reasonable langauge implementations) work. I understand that you're mad and you've communicated that clearly, but at no point have I seen anything resembling a correct technical explanation from you.


Quote:
You're also arguing a strawman. At no point did I say anything about caching in any other situation than this one specific scenario. You're putting words in my mouth and then lecturing me on why they're wrong.
But in this specific scenario, your verbose, "caching" solution is much slower than the quick & dirty one-liner that I came up with zero consideration for performance. In this specific scenario, your Array.push is so bad performance-wise that it completely dwarfs any effect your cache has. So again, I'm not sure what you're getting at. Should I cache all repeated property references before entering a loop or should I not?

Btw, your solution is also slower than the original in Chrome, marginally faster in IE9. Yeah, I'm sure that's what JSLint/Hint was warning you about. They're really worried that you may write code that runs slightly faster in Chrome but slightly slower in IE.


Quote:
The irony that I was pointing out is that you dismissed an earlier point as semantics, and then later argued that I was wrong because I used the term "calculated" when in fact the length value is a stored property and doesn't need to be actually "calculated".
This is where you're going off the rails hard, because you're wrong on both ends. Semantics is a technical term when you're discussing programming languages. I didn't accuse anyone of engaging in semantics, I said he was correct to think that way when it comes to analyzing language semantics. In other words, I wasn't saying that someone was nitting it up using semantic distinctions, but that his argument was correct when it comes to discussing programming language semantics (how programs are supposed to behave according to language specifications) but that's not how programming languages are implemented, thus his semantic understanding cannot be used to infer how code will perform.

This has nothing do with this argument here, where you used the term "calculated" as though it's a costly operation. It's a lookup. The reason this distinction matters is that there data structures where this property must be calculated and in those cases you'd be advised to cache the result. This is not semantics, this is you trying to get away with incorrect inference (calculation -> must be expensive -> must cache). If it's a stored property, the argument for caching becomes quite thin. If it's not an expensive calculation, why are you caching it? Do you routinely cache references to object properties?


Quote:
Did I not specifically point out that Internet Explorer is (a) what I was referring to, and (b) the most important browser for performance analysis (b/c it's slow and still widely used)?
Again, this is not how you do performance analysis and this is why your code is slow. You don't assume things like this without data. Yes, it's possible that in some cases you may be forced to use the precise workaround you did, but you don't go around putting in boilerplate before you see evidence of this. And it's completely ridiculous for make-believe code examples.
Learning Javascript Thread Quote
12-29-2012 , 09:41 PM
Quote:
Originally Posted by sdturner02
Wrong. Using arr.length before checking type has absolutely no impact on the value of the check. The length property is not exclusively for arrays. If a string was passed to the function, the length property would return the number of characters in the string, and the check will catch the error.
What happens if I pass undefined or null?

Quote:
Wrong. In Javascript, there is no value to be obtained from preallocating arrays.
I think I owe you an apology here, it seems like this is implementation-dependent and depends on the array size. From more tests, it seems like preallocation helps up to a certain size, but in some cases it just gives up. And it varies depending on the browser. This doesn't seem like a clear-cut win in either direction but you're right that this isn't a huge win - this is much more like the .length property caching than real performance killer.

Quote:
That's b/c arrays in Javascript aren't actually arrays, they're a type of object.
But this is not a correct explanation. Arrays are generalized as objects, but in many cases, it can be optimized to use an array (really a vector) underneath and lookups are much faster than property lookups on objects. Part of the problem here is that we're storing objects, not primitives (again, all javascript values are objects, but this isn't how it is to compilers), which means aggressive optimization isn't possible and part of the issue is that javascript compilers can preallocate even if you're using .push for each element

Quote:
Wrong. This is absolutely horrible advice, perhaps even worse than the other two, and those were objectively wrong. Why don't you try to figure this one out on your own, I'd be interested to see what you come up with.
No, this is completely correct. If you want to enforce constraints, use assertions and fail instead of silently returning some random value you've designated as "failure" value. If you don't want to enforce constraints, you want to return a valid value. If you have to return an invalid value, use null or undefined, not false.


Quote:
lol
But the performance test is correct. Your code is still slow. But the reason why it's slow is because it precomputes the alert message, which creates memory problems.

Last edited by candybar; 12-29-2012 at 09:47 PM.
Learning Javascript Thread Quote
Learning Javascript Thread
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
Learning Javascript Thread

      
m