Itās not a problem if you are planning on it and expecting it. But itās easy enough to overlook. In JS, I mostly use the equivalent technique for internal functions and not those I expose to others, for precisely this reason.
JavaScript Example
One classic example in JavaScript involves the parseInt
function and array.map
method. JS has parseFloat
, which converts a string like "867.5309"
into the floating-point (decimal-ish) number 867.5309
. Thereās a similar parseInt
function which converts, say "42"
to 42
. When we combine parseFloat
with map
, we get:
["1.1", "2.2", "3.3"].map(parseFloat) //=> [1.1, 2.2, 3.3]
just as expected, because map
runs the supplied function on each element of the array, and returns a new array with all those results.
But if we try the equivalent with parseInt
, we have a real problem:
["1", "2", "3"].map(parseInt) //=> [1, NaN, NaN]
where NaN
is the special value NotANumber
, used where a number is expected but a non-numeric value is found.
The reason is two-fold.
First, the signature of parseInt
is (string, radix?) -> number
; there is an optional small-integer parameter radix
, which defaults to 10
if not supplied. This allows us to parse binary or hexadecimal number, like so
parseInt('cab123', 16) //=> 13283619
But since base 10
is by far the most common, it is assumed if you donāt supply an argument, or, for some weird reason, if you supply 0
. This parameter defaults to 10
Second, map
is slightly more complex than assumed. The function you pass to map
is called each time not just with the item, but with two other arguments. We also get the index in the array of the item, and the whole array as well. So,
['a', 'b', 'c'].map((value, index, array) => name + index) //=> ['a0', 'b1', 'c2']
// (We declare `array` for demonstration purposes, but we ignore it here.)
Combining the map
behavior with parseInt
, we get that ['1', '2', '3'].map(parseInt)
is equivalent to
[parseInt('1', 0), parseInt('2', 1), parseInt('3', 2)]
-
parseInt('1', 0)
for an odd reason is treated as if it were parseInt('1
, 10), which is just
1`.
-
parseInt('2', 1)
is illegitimate, as 1
is an illegal base for number. So we get NaN
.
-
parseInt('3', 2) has a legitimate radix, but
3is an illegal digit in binary. Again we get
NaN`.
This, of course, is just an example. But his behavior has perplexed any people.
Iām not even slightly suggesting that people donāt use this; the problems are less likely than in raw JS, I believe. I would just suggest that users of this technique be aware of the possibility.
(With all due appreciation for your pun on the parameter vers
!)
Well, you know what they say, āA good pun is its own reword.ā