4 ms·
> 23n + 2 is a TypeError even though "23" + 2 isn't? The former is banned because it's error prone the latter is allowed because of backwards compatibility.
by hdhzy 9y ago
> 23n + 2 is a TypeError even though "23" + 2 isn't?
The former is banned because it's error prone the latter is allowed because of backwards compatibility.
- delinka 9y agoI'm going to need an explanation for how error prone it can be to add two numbers. Automatically promote the '2' to a '2n' and carry on. Where's the problem?
- deleted 9y ago[deleted]
- sillysaurus3 9y agoIf you do 23n + x, you probably want it to raise an error if x isn't a bigint. Otherwise you end up with more situations similar to NaNs appearing in unexpected places. It's arguable. There are at least two schools of thought, and both of them are valid. It just depends what you want to do. If you're using arbitrary precision, you're probably in a situation where it's better to be explicit than to have implicit coercion. For example, what should happen if you do 23n + 0.5? You can't have 23.5n, since it's not an integer. You could convert it back to a Number, but you can't do that if it's 9007199254740992n + 0.5. It's logical to throw an error, if a bit counterintuitive. Comparisons on the other hand probably shouldn't throw errors.
- delinka 9y agoI don't see this as any different than coercion with other pairs of types.
- sillysaurus3 9y agoI mean, sure, you can have that view. But again, what would you say should happen for 23n + 0.5? And for 9007199254740992n + 0.5? If you don't throw an error, you have to do something, and in those situations returning anything would be incorrect. You could return 23.5 in the former case, but then you'd no longer have an Integer. You could throw an error in the latter case, but that'd be a lot slower for JIT tracing compilers to execute than simply verifying that the types are the same.
- yladiz 9y agoTreat it as a arbitrarily large floating point value, rather than an integer.
- sillysaurus3 9y agoGood point, though in that case using arbitrary precision values anywhere in your program might tank performance. Execution speed still matters, especially now that we're at the physical limits of single cores, and automatically promoting to arbitrary floats seems like a poor trade of speed vs flexibility. It's way too tempting to "simply use arbitrary floats and be done with it", even in financial software, and then be in a situation where the entire program is slow. But it would be good to quantify how much slower it'd be. Animats pointed out a potentially more serious issue, which is that you can DoS a program by sending it an arbitrary precision number whose size is gigabytes. But that's true of any arbitrary precision number, not just floats.
- yladiz 9y agoI think in that case, internally it can handle smaller values differently than larger values (like Ruby). If the performance of large values is truly important, something using the FFI can be written to a program using something like C or Fortran.
- BerislavLopac 9y ago"You could return 23.5 in the former case, but then you'd no longer have an Integer." This works rather well in Python. >>> a = 10 >>> b = 1.1 >>> c = a + b >>> type(a) <class 'int'> >>> type(b) <class 'float'> >>> type(c) <class 'float'>
- sillysaurus3 9y agoThere's a solution to all of this: TAoCP has thought through these issues carefully, and it would probably be best to study the tradeoffs Knuth presented. Python handles common cases, but it breaks when you push it too far: >>> 1e100 1e+100 >>> 1e100+0.1 1e+100 >>> 1e100+0.1 == 1e100 True >>> 9007199254740992 + 0.5 9007199254740992.0 >>> 9007199254740992 + 0.5 == 9007199254740992 True >>> 9007199254740992 + 0.5 + 1 9007199254740992.0 >>> x = 9007199254740992 >>> y = x >>> y += 1 >>> x == y False >>> x = 9007199254740992 + 0.5 >>> y = x >>> x += 1 >>> x == y True You could argue that handling the common cases is all that's needed, but stuff like this pops up in e.g. writing software rasterizers. It might also be one reason why PyPy can't quite match the speed of native programs, though that's just a guess.
- BerislavLopac 9y agoActually, I'd argue that the former is also because of backward compatibility: if it wasn't, it would be easy to treat all literal integers as Integers and everything else as Numbers, similarly to what exists in Python. I would dare say that even with this approach it would be possible to maintain backward compatibility with smart conversion, although I'm not familiar enough with ES internals to be more decided on that.
- hdhzy 9y agoPersonally I think JavaScript is already full of "smart" conversions and the trend now is to make new things simple instead of fueling XXI century's WTF.js (see http://brian.io/slides/dotjs-2012/ http://brian.io/slides/dotjs-2012/ ).