Hacker News new | ask | show | jobs
by jitl 1772 days ago

    Math.max(...list)
3 comments

Got to be careful with the argument spread, since depending on the JS engine and how large the `list` is, you can end up with a RangeError

e.g.,

    Math.max(...Array(100_0000).fill(0))
results in:

    Uncaught RangeError: Maximum call stack size exceeded
Bizarre. on V8 this seems to be an underlying limit on Function.prototype.apply -- and in the REPL, it's not even deterministic, somewhere in the neighborhood of 123,125. (side effect of optimization?) It's enforced on the caller side as well, the empty function with no arguments still throws when apply'd too large an array.

It's not at all clear to me why this would be a necessary limit to exist, as functions can't reasonably have more than a few hundred formal parameters so passing 100,000 would always imply using unspread or arguments on the receiver, which could surely trivially handle arbitrarily sized arrays.

In V8 I believe it's limited by the stack size and when you get a stack overflow that gets converted to a RangeError in JS land.

OTOH, Webkit and Firefox have arbitrary limits 65537, and 500k args.

https://bugs.webkit.org/show_bug.cgi?id=80797 https://github.com/mozilla/gecko-dev/blob/1475b3b0cb274b2a71...

Huh, I had no idea that function had variable arity. Thanks.
Funnily enough, that variable arity is mentioned in the article as a nuisance:

> ... wincing slightly at the lambda notation you need to avoid running afoul of JavaScript’s variadic Math.max()...

It is a typical language-comparison strawman. He is writing

   list.reduce((x,y)=>Math.max(x,y)) 
To get the max number in a list. And he is "winching" because he can't write:

    list.reduce(Math.max)
Because the variable arity of max does not play well with reduce. But because of the variable arity he can write:

    Math.max(...list)
Which is even simpler.

So he deliberately writes overly complex JavaScript code to show how the other language is more concise.

IIRC the spread syntax only works with relatively small arrays, because it's function application at the end of the day.

So worthwhile keeping in mind that the nice JS code falls apart.

Fair point. In any case, if you wanted to do more than trivial array processing in JS, you would use a library like lodash which have an array max function.

And if you think lodash is still to verbose, you can define your own:

  const å = list => list.reduce((x,y) => Math.max(x, y));
Now you can write å(list) to get the max value of an array!
well yeah I could also write a function in C that does that. I don't think that's the point.
Enum.max(...list) ;)