Of what, IEEE-754? Given how poorly most languages implement it (and how many shortcuts are taken in the same of speed), I'm not sure IEEE-754 is the problem.
johnsonjo 21 hours ago [-]
Other than the IEE-754 he might mean the Wat talk [1] by Gary Bernhardt which is kind of famous for poking fun at JavaScript (and it's unpredictability with things like NaN. As a JS developer myself I find it hilarious.) Though I don't know why it would need to be remade he at least referenced the talk, it seems, with the word Wat, so it's worth mentioning at least I guess
I believe the other poster is correct, that OP is referencing the video "Wat" (https://www.destroyallsoftware.com/talks/wat), but I think that if most implementations of a standard are poor, the standard is probably the problem. It's likely to be either unclear or too complicated.
adrian_b 18 hours ago [-]
I do not agree that IEEE 754 is unclear or complicated. I think that it is one of the simplest standards that I have ever seen.
It is certainly orders of magnitude simpler than specifications for things like HTML, CSS, C++ or Vulkan.
The source of the problem is elsewhere. Unlike in the first 2 or 3 decades after the invention of automatic computers, nowadays there are much more than a half of the programmers who never encounter in their jobs the need to solve problems where complicated numeric computations are important and where the knowledge of mathematics branches like arithmetic and algebra is important.
Moreover, the programmers that happen to work on compilers or standard libraries for programming languages are even more likely to belong to the class of programmers who are not interested in computational applications.
This has led to the current situation, when almost all programming languages, especially the most popular of them, have bad defaults for the IEEE 754 options and they provide very awkward means to access all the facilities specified by the standard.
A decent programming language should have 2 distinct types for floating-point numbers, one for those that cannot be NaNs (to be used only in a program that enables and handles invalid operation exceptions) and one for floating-point numbers that may be NaNs (to be used in programs that disable the invalid operation exception, like most programming languages wrongly do by default).
Moreover, a decent programming language should have 14 relational operators, to enable the correct use of partially-ordered sets, e.g. also for user-defined data types, not only for floating-point numbers.
With a standard programming language, which has only 6 relational operators, if one insists on keeping disabled the invalid operation exception, then every floating-point comparison must be preceded by testing the operands for being a NaN, which is tedious.
t-3 18 hours ago [-]
> Moreover, a decent programming language should have 14 relational operators, to enable the correct use of partially-ordered sets, e.g. also for user-defined data types, not only for floating-point numbers.
Is this a well-known set that I've never heard of? What are the other 8? Subset, superset, structural equality? Logical equivalence?
dzaima 18 hours ago [-]
> A decent programming language should have 2 distinct types for floating-point numbers, one for those that cannot be NaNs (to be used only in a program that enables and handles invalid operation exceptions) and one for floating-point numbers that may be NaNs (to be used in programs that disable the invalid operation exception, like most programming languages wrongly do by default).
You've already explained why such a type separation is a bad idea - those types being only usable with specific setup; so, completely utterly breaking composability.
Never mind this making float ops impure & stateful (also forbidding autovectorizing anything with more than one potentially-NaN-producing op if you don't want to break semantics).
Perhaps if hardware supported embedding exception behavior in individual instructions this'd not be insane, but I haven't heard of any architecture having such, making it a complete non-option for sane languages designed to be used.
(there is the option of making compilers insert the necessary fp state transitions, though then you'll have the desire to embed it into calling conventions & function types to avoid transitions when a certain state is expected to stay for a prolonged period of time, which, while certainly possible and would be quite neat to have (also for rounding modes, FTZ/DAZ, etc), is very much in the territory of something almost noone will bother doing, and as such things would just quietly be slower)
While partially-ordered types are neat, what can you really sanely do with a comparison over such? Seems like a rather pointless thing to have.
whatever1 1 days ago [-]
Just store what you mean to store for gods sake. We have been fighting with over-designed bs for decades.
Zero is not absence of a value. It has a value, it happens to be 0. Same for undefined/infinity. They exist.
Let the hardware engineers figure out an efficient way to deal with it. If it costs more, well if we add up all of the costs of bugs due to zero/null conversions, maybe it was worth it.
bazoom42 23 hours ago [-]
This article is not about null but about NaN, a special case floating-point value which is the result of diving by zero.
aragilar 21 hours ago [-]
Specifically, 0/0 (or inf/inf), not any division by 0.
boulos 21 hours ago [-]
0 x inf is also NaN. It's not just division.
adrian_b 19 hours ago [-]
> Equality comparison should be reflexive
Equality comparison must be reflexive for things on which it is defined.
It is wrong to say that NaN is not equal to Nan (because a NaN is neither equal nor not equal with a NaN).
When the invalid operation exception is disabled, because the programmer is too lazy to write a SIGFPE handler or for whatever other mechanism is provided by the operating system to report hardware exceptions, then the set of floating-point numbers is extended with NaNs and the resulting extended set is no longer a totally-ordered set, but only a set on which a partial order is defined.
While floating-point number with NaNs are the best known because they are standardized, there are a lot of real sets that are best modeled as partially-ordered sets, so programming languages should have supported this and programmers should have been taught that partial order relations are something normal and natural, not something weird.
In any partially-ordered set there are elements like the NaNs, on which the relations of order and of equality may be undefined.
Thus NaN is neither equal nor not equal with NaN, but this relationship is undefined.
While for totally-ordered sets 6 relational operators are sufficient, for partially-ordered sets 14 relational operators are necessary.
When the 6 ALGOL relational operators (inherited by all later programming languages) are extended to 14, 6 new operators are provided by the negation of the 6 ALGOL operators, because in a partially-ordered set none of the 6 negations is equivalent with one of the 6 standard operators (like it happens in totally-ordered sets, where e.g. "not less" is the same as "greater or equal"). (In this statement, I considered among the 6 standard operators "less or greater", like in BASIC or SQL "<>", instead of "not equal", like in C "!=".)
The remaining 2 extra relational operators are "less or equal or greater", which could be written "<=>" or ">=<", which may be true only when no operand is a NaN, and its negation, which is equivalent with "one of the operands is a NaN".
I wish there were a recent remake of it.
[1]: https://www.destroyallsoftware.com/talks/wat
It is certainly orders of magnitude simpler than specifications for things like HTML, CSS, C++ or Vulkan.
The source of the problem is elsewhere. Unlike in the first 2 or 3 decades after the invention of automatic computers, nowadays there are much more than a half of the programmers who never encounter in their jobs the need to solve problems where complicated numeric computations are important and where the knowledge of mathematics branches like arithmetic and algebra is important.
Moreover, the programmers that happen to work on compilers or standard libraries for programming languages are even more likely to belong to the class of programmers who are not interested in computational applications.
This has led to the current situation, when almost all programming languages, especially the most popular of them, have bad defaults for the IEEE 754 options and they provide very awkward means to access all the facilities specified by the standard.
A decent programming language should have 2 distinct types for floating-point numbers, one for those that cannot be NaNs (to be used only in a program that enables and handles invalid operation exceptions) and one for floating-point numbers that may be NaNs (to be used in programs that disable the invalid operation exception, like most programming languages wrongly do by default).
Moreover, a decent programming language should have 14 relational operators, to enable the correct use of partially-ordered sets, e.g. also for user-defined data types, not only for floating-point numbers.
With a standard programming language, which has only 6 relational operators, if one insists on keeping disabled the invalid operation exception, then every floating-point comparison must be preceded by testing the operands for being a NaN, which is tedious.
Is this a well-known set that I've never heard of? What are the other 8? Subset, superset, structural equality? Logical equivalence?
You've already explained why such a type separation is a bad idea - those types being only usable with specific setup; so, completely utterly breaking composability.
Never mind this making float ops impure & stateful (also forbidding autovectorizing anything with more than one potentially-NaN-producing op if you don't want to break semantics).
Perhaps if hardware supported embedding exception behavior in individual instructions this'd not be insane, but I haven't heard of any architecture having such, making it a complete non-option for sane languages designed to be used.
(there is the option of making compilers insert the necessary fp state transitions, though then you'll have the desire to embed it into calling conventions & function types to avoid transitions when a certain state is expected to stay for a prolonged period of time, which, while certainly possible and would be quite neat to have (also for rounding modes, FTZ/DAZ, etc), is very much in the territory of something almost noone will bother doing, and as such things would just quietly be slower)
While partially-ordered types are neat, what can you really sanely do with a comparison over such? Seems like a rather pointless thing to have.
Zero is not absence of a value. It has a value, it happens to be 0. Same for undefined/infinity. They exist.
Let the hardware engineers figure out an efficient way to deal with it. If it costs more, well if we add up all of the costs of bugs due to zero/null conversions, maybe it was worth it.
Equality comparison must be reflexive for things on which it is defined.
It is wrong to say that NaN is not equal to Nan (because a NaN is neither equal nor not equal with a NaN).
When the invalid operation exception is disabled, because the programmer is too lazy to write a SIGFPE handler or for whatever other mechanism is provided by the operating system to report hardware exceptions, then the set of floating-point numbers is extended with NaNs and the resulting extended set is no longer a totally-ordered set, but only a set on which a partial order is defined.
While floating-point number with NaNs are the best known because they are standardized, there are a lot of real sets that are best modeled as partially-ordered sets, so programming languages should have supported this and programmers should have been taught that partial order relations are something normal and natural, not something weird.
In any partially-ordered set there are elements like the NaNs, on which the relations of order and of equality may be undefined.
Thus NaN is neither equal nor not equal with NaN, but this relationship is undefined.
While for totally-ordered sets 6 relational operators are sufficient, for partially-ordered sets 14 relational operators are necessary.
When the 6 ALGOL relational operators (inherited by all later programming languages) are extended to 14, 6 new operators are provided by the negation of the 6 ALGOL operators, because in a partially-ordered set none of the 6 negations is equivalent with one of the 6 standard operators (like it happens in totally-ordered sets, where e.g. "not less" is the same as "greater or equal"). (In this statement, I considered among the 6 standard operators "less or greater", like in BASIC or SQL "<>", instead of "not equal", like in C "!=".)
The remaining 2 extra relational operators are "less or equal or greater", which could be written "<=>" or ">=<", which may be true only when no operand is a NaN, and its negation, which is equivalent with "one of the operands is a NaN".