4 ms·
There are so many good WTFs in JS, but this is not one. parseInt expects 2 arguments and Array.prototype.map provides 3 to the callback it is given. Both of the
by just2n 12y ago
There are so many good WTFs in JS, but this is not one. parseInt expects 2 arguments and Array.prototype.map provides 3 to the callback it is given. Both of these facts are very well documented and known.
var mappableParseInt = function(str){
return parseInt(str, 10);
};
['10', '10', '10'].map(mappableParseInt);
I'd suspect this snippet is more a snipe at people who don't know JS very well and expect parseInt to be base-10 only.
- CatMtKing 12y agoYou could say it's a snipe at the weak type system that Javascript has. I dunno, as someone without much experience with Javascript, it is a little odd that arrays return the index alongside the value by default.
- xiaomai 12y agoarrays don't do that, but map() does. Normally in js you can just ignore arguments you don't care about, but it does lead to surprises like this one.
- anaphor 12y agoIt has little to do with the type system. Variadic arguments can be typed given a type system that supports it.
- deleted 12y ago[deleted]
- hcarvalhoalves 12y agoI don't think `parseInt` accepting an optional second argument is the surprising behavior there. The real WTF is `map` passing more than one argument, and the loose behavior of JS regarding argument passing overall.
- briantakita 12y agoIt's only WTF because it's not the same as other implementations of map. Once you can internalize the map implementation, it's no longer WTF & actually makes sense.
- rplnt 12y agoThat's the weird part. Why does array provide three arguments? But I agree, that's something you can learn. I guess. But it's WTF anyway. I have a function that takes either one or two arguments, I provide three, and everyone seems to be OK with that.
- just2n 12y agoWell that decision is pretty necessary when you realize that JS has no syntax to indicate a function is variadic (we use the arguments magic variable, but use of it does not necessarily indicate that a function is variadic) and that implementation supplied functions are not required to have their arity exposed via Function.prototype.length (http://es5.github.io/#x15.3.5.1 http://es5.github.io/#x15.3.5.1). There's no way to know, even at run-time, whether a function is being called with too few or too many arguments, since that's equivalent to the halting problem. So the sensible alternative is just to default everything to undefined, and silently ignore extraneous arguments. But yes, if JS was strict with how it handled argument definition lists and had support for indicating infinite arity, I'd agree, this would be a WTF, or at least strange. But I think it makes a lot of sense, all things considered.
- meowface 12y agoIt makes sense but it still strongly violates the principle of least surprise. No other language I know of does this, nor do I think this would be a particularly desirable feature.
- gnuvince 12y agoSo much for abstraction if you need to understand the implementation of every function you'll every use in JavaScript.
- clebio 12y agoAlternatively, if a function expects two arguments, the language could take exception at the fact that three were handed in. Quietly accepting arbitrary arguments could be considered breaking contract. It does have a wtf-ey whiff.
- oscargrouch 12y agowith a function named "parseInt" anyone would expect the inputs as base 10.. otherwise this shoud be called "parseHex" for 15 or at least "parseBytes(input, base)" The programmers are not the ones to blame on that.. this is really a bad contract between the language and the programmer Its the equivalent of a function named "getStone()" to return you a " Paper{} " :)
- djur 12y ago"int" doesn't imply anything about the base.
- deleted 12y ago[deleted]
- Iftheshoefits 12y agoIt does for human beings. We use base-10 for basically everything. This is true even for most programmers in most situations. Human beings aren't computers, and we aren't abstract math processing units who by default consider numbers abstracted (e.g. as elements of Rings). This goes double for string representations of numbers--in the majority of cases a number represented by a string is a number meant for human consumption in a normal human context; not some machine running in base-2 (or -8 or -16). It is certainly reasonable to expect "parseInt" to parse an integer out of a string in base-10 by default, and entirely unreasonable to expect to be required to provide a base as anything except an optional argument, and certainly it is unreasonable to expect that that second optional argument is treated as not optional in a composition operation.
- ajanuary 12y ago> It is certainly reasonable to expect "parseInt" to parse an integer out of a string in base-10 by default It does. > and entirely unreasonable to expect to be required to provide a base as anything except an optional argument It is optional. > and certainly it is unreasonable to expect that that second optional argument is treated as not optional in a composition operation I don't understand what you're saying here. It's never treated as required, it's just map supplies a parameter in that position, so it get's used. That's how optional parameters work. The wat (if there is one) is that map provides extra arguments.
- ahoge 12y agoA bit less annoying with ES6: >>> ['10', '10', '10'].map(x => parseInt(x, 10)) [10, 10, 10]