6 ms·
My comment from when this came up on Reddit, slightly edited for context: `/`-by-0 is just an operation and it tautologically has the semantics assigned to it.
by Veedrac 8y ago
My comment from when this came up on Reddit, slightly edited for context:
`/`-by-0 is just an operation and it tautologically has the semantics assigned to it. The question is whether the specific behaviour will cause bugs, and on glance that doesn't sound like it would be the case.
Principally, division is normally (best guess) used in cases where the divisor obviously cannot be zero; cases like division by constants are very common, for example. The second most common usage (also best guess) is to extract a property from an aggregate, like `average = sum / count` or `elem_size = total_size / count`. In these cases the result is either a seemingly sane default (`average = 0` with no elements, `matrix_width = 0` when zero-height) or a value that is never used (eg. `elem_size` only ever used inside a loop iterated zero times).
It seems unlikely to me that `/` being a natural extension of division that includes division by zero would be nontrivially error-prone. Even when it does go wrong, Pony is strongly actor-based, has no shared mutability and permits no unhandled cascading failures, so such an event would very likely be gracefully handled anyway, since even mere indexing requires visible error paths. This nothing-ever-fails aspect to Pony is fairly unique (Haskell and Rust are well known for harsh compilers, but by no means avoid throwing entirely), but it gives a lot more passive safety here. This honestly doesn't seem like a bad choice to me.
- innagadadavida 8y agoWhat happens for 0 / 0? Is this also 0?
- taneq 8y agoIt's extra zero.
- nwmcsween 8y agoinf 0
- spacehunt 8y agoIs this the same as 0 * 1 / 0?
- innocentoldguy 8y agoIt returns a larger value of 0.
- red_admiral 8y agoAll zeroes are equal, but some are more equal than others.
- 2038AD 8y agoε
- semi-extrinsic 8y agoAn example well-defined use case is if you want to compute a harmonic mean, e.g. x = 2/(1/a +1/b) This is a form of average where you are giving increased importance to the smaller number. It frequently pops up in science/engineering, e.g. in hydrology when you are computing flow of water underground. In this case, it's "obvious" that when e.g. a is zero, you want 1/a to be zero so you simply return b. There's typically a clear, big distinction between "smallest realistic number", for instance 1e-3, and a zero, whether actual zero or 1e-34. For instance Numpy offers a nice way of doing this: def safeInv(a): tol = 1e-16 return np.division(1.0,a,out=np.zeros_like(a),where=np.where(a>tol)) This tells numpy to put the result of division into an array of zeros shaped like a, but only do the divide where a>tol, so it returns 0 where a<tol. In this case, though, the programmer understands this division is somehow special and should allow div-by-zero, so it is handled specially.
- binarycoffee 8y agoQuite the opposite I would say: the harmonic mean can be seen as a very good justification for `1/0=inf` as the pragmatic choice. If, say, `a` is mathematically very small (and `x` is accordingly expected very small`) but `a` become zero due to rounding behavior, then having `1/a=inf` results in `x=0` which is arguably closer to the expected result than e.g. `x=2b`. As someone involved with numerical methods, I have very often relied on `1/0=inf` because it would ultimately warrant the proper behavior in case of rounding errors in the denominator.
- Veedrac 8y agoI think for floating point 1/0=Inf makes a lot of sense, because divisions are frequently done with continuously-varying properties. Division by integers is different, since you do a different kind of work with it; there is no "very small" integer.
- jibal 8y ago"In this case, it's "obvious" that when e.g. a is zero, you want 1/a to be zero so you simply return b" b obviously isn't what you want from this harmonic mean when a is 0. And in any case x will be 2b if 1/a is 0, not b.
- pps43 8y ago> `average = 0` with no elements Imagine a Mars lander program that looks at the average of altitude measurements to decide when it's ok to jettison the parachute, sees no measurements, and decides that altitude is zero.
- Veedrac 8y agoYou have a point, but I think this is a difference in the target markets. NASA can afford to have a thoroughly-tested, redundant, quickly-accessible failure path that restarts and reinitializes the process, and their processes are so thoroughly tested that they can expect their production instances not to have any software failures. Pony is made for a more typical scenario where every failure case is a new, untested error path, and history shows that general developers handle errors badly. Pony makes a heroic effort to remove the error path from the language semantics entirely: every failure is explicitly annotated in the code, and has to be handled there. This is much better for the typical developer, allowing them to produce very robust code without NASA's degree of investment towards it. Giving Pony a special unwinding mode just for division by zero would be very dangerous, because this is a new path that only exists for a rarely-encountered sort of error; you cannot assume a sudden shutdown is going to do less damage. Having Pony present the error cases inline on division by zero would certainly be safer, but there is a degree of disproportionality here: most divisions are impossible to go wrong in this way, and I suspect most of the rest are benign or would be quickly caught by the check after. Since Pony aims to compete against incumbents that are generally less safe in this regard (C++ has UB, Python has exceptions but makes it hard to handle them correctly, etc.), a compromise seems sensible.
- pps43 8y agoIt's not only NASA. Zero is just not a reasonable default value for an average. Imagine average credit card balance for FICO score, average blood pressure, average temperature in a freezer, etc. UB is not the only way. You can have NULLs (they come with their own sets of problems, but still). In many cases no value is better than incorrect value.
- 8y ago
- deleted 8y ago[deleted]
- fjsolwmv 8y agoPony requires programmer to handle everything case of every function...except this one case where it will just pick an arbitrary value to handle a case the progrmammer forgot, hiding the very error Pony was designed to guarantee gets solved. Why not allow partial functions everywhere and have them default to 0 where undefined?
- vmchale 8y agoThat's a terrible default for an average function lol. Once again in nearly all cases, taking the average of a list without elements is an error.