Hacker News new | ask | show | jobs
by Tainnor 2179 days ago
I don't think that the average of an empty list being zero is semantically correct, but I can accept that it may not be so bad in practice (e.g. if it shows up like that in a UI and you display the number of elements anyway).

But I still think in other situations I'd want to be yelled at for trying to divide by zero. E.g. imagine I'm trying to compute the slope of a secant between two points. If both points are the same, I'd like the compiler to yell at me (the problem either makes no sense here, indicating a problem somewhere else in my code, or that I should instead compute the derivative) - in most cases, 0 would be the wrong answer. I think the issue here is that with division by zero you lose continuity (unless you use +Inf) which can contradict intuition.

I'm not saying it doesn't work for Pony, maybe it does, but I don't think I would feel comfortable with that behaviour.

Silent wrapping around on overflow is arguably even worse, that I could definitely see leading to logic errors.

2 comments

The compiler is unlikely to yell at you, the runtime normally will. Runtime errors are not usually very helpful, you are better off testing every division yourself (the Pony checked division model). Note that most non Intel CPUs don't have runtime exceptions for division by zero, Arm returns 0 and AFAIK Risc-V returns -1 but I might have misremembered. Intel is unusual in having an exception.
Yes, you're obviously correct, the compiler won't yell at me. I wasn't thinking clearly when I wrote that. I did mean the runtime. :)

But I disagree that runtime errors aren't helpful. They are very helpful to surface logic errors (if you have proper logging). If you catch a semantic error as early as possible, you have a better chance of making sure it doesn't propagate somewhere else, and it will be easier to debug the eventual issues. This is why I generally like assertions.

In practice I guess it's quite complicated. Even in a safety-critical environment where you don't want any errors, halting on an exception often seems not the best idea. For example in an air plane, a halting flight controller could be worse than some incorrect values. I generally agree that raising exceptions and logging them is the way to go if your budget allows, though the default behavior (crash, give 0, a large positive number, w/e) seems less clear (as often when choosing between lesser harms).

Another example: if your system is autonomous and re-initializing it will likely lead to the same "dirty" state (i.e. the division by zero), then recovery would not be possible after a crash. Could be a simple game, or perhaps a Mars rover for instance. In that case 1/0 = 0 is a solid choice.

Halting on exceptions of course means that you need to have some fault recovery mechanism, there are many patterns for that.

I'm not saying that 1/0 should just lead to a hard crash. Ideally you can identify subsystems and somehow handle unexpected errors at the boundaries and use some fallback behaviour.

But I agree that it's not easy and very dependent on the specific situation. I wrote a whole whitepaper about error handling and error recovery about the last system I was working on, because it's such a complex topic. It's just that "you should never raise runtime errors" or "all errors need to be handled at the level they are raised" are answers that sound good, but are impractical in certain situations. And as said, you need to deal with potential crashes anyway due to OOM, etc.

The Mars rover thing is completely different, because the engineering standards at NASA are so insanely high as to exactly prevent dumb errors like that. They can develop like that, but most other companies can't even begin to afford such a process heavy development and need to accept that programming errors are going to happen and there needs to be some recovery mechanism.

You could also argue that 0^0=1 is also not semantically correct, but it is the most widespread convention among mathematicians.
It IS semantically correct. The number of functions from a set of 0 elements to a set of 0 elements is exactly 1. No parallel argument exists for division by zero. The two situations are not analogous at all.
Mathematics is full of cases where the same notation means different things. You’ve kind of dodged the question of what 0^0 is by talking about set theory, because it is (in some sense) arbitrary that X^Y means Y -> X or its size (cardinal exponentiation), and in analysis may mean exp(y log x). We accept that for natural X,Y except (0,0) these must agree but that does not imply that they should agree at (0,0), because the definitions are simply not the same.

If you are serious about math, which it seems you are, I would be a bit more careful about “transporting” notation from one field from another and arguing about correctness.

The usual way to transport a definition from a discrete domain to a continuous one is a technique called analytic continuation. I am curious if there is an analytic continuation of the discrete X^Y which contains 0^0=1, and what that would look like, but at that point you’re definitely not talking about exponentiation any more.

See: https://en.wikipedia.org/wiki/Zero_to_the_power_of_zero

See: https://math.stackexchange.com/questions/11150/zero-to-the-z...

> it is (in some sense) arbitrary that X^Y means Y -> X or its size (cardinal exponentiation)

Are you referring to the notation? I don’t think notation is what’s being contested.

> in analysis may mean exp(y log x)

Doesn’t work with a base of 0.

> We accept that for natural X,Y except (0,0)

Why “except”?

> that does not imply that they should agree at (0,0), because the definitions are simply not the same.

The definition of exponentiation of reals typically starts with exponentiation of naturals as a given (see Baby Rudin).

> The usual way to transport a definition from a discrete domain to a continuous one is a technique called analytic continuation. I am curious if there is an analytic continuation of the discrete X^Y which contains 0^0=1

Analytic continuation refers to something else, but I get what you’re trying to say.

The answer is simple: Real exponentiation is an extension of natural exponentiation. Hence, it should have the same value as the latter wherever the latter is defined.

Yes, I’ve read that SE question before. It’s good that you brought it up. I recommend reading the comments under the accepted answer and the other answers as well.

Mathematicians not working in type theory generally agree that 1/0 is undefined (or if anything, they would set it to infinity, but even saying that would probably be too cavalier for most mathematicians). They do not necessarily for 0^0. There are good algebraic and combinatorial reasons for 0^0=1, while analysts will complain about non-continuity.
I think that’s missing the point. What I’m saying is “this is a convention, and because it is a convention, it may be reasonable to follow a different convention at times”. Different conventions are convenient for mathematicians working in different fields. Whether a convention is “semantically correct” is not a question that even makes sense, because when you define something, your definition is true by definition. The only real question here is whether you can reasonably expect people to understand you if you use different definitions.
This is a view of mathematics and programming that just completely ignores intuition. Of course, what you say is technically correct, yet mathematicians debate definitions all the time, precisely because it matters to them to get them "right" (of course, there's rarely one true answer).

This is even more true in programming. Yes, you can also learn all the type conversion rules of JavaScript, but many people agree that they are insane because they violate the principle of least surprise. Expectations matter, especially when you're fixing a bug at 3am.

Intuition is mostly an internalized notion of convention, and I don’t think that we can appeal to intuition to resolve much.

For students learning division, the fact that 1/0 is undefined is not an intuitive result and must be learned. This is their first time encountering something which is “not defined”.

We'll just have to disagree about this. I think intuition is incredibly important both in mathematics and in programming.