Consider a function that takes number of retries as a parameter. Number of retries should type check as int. But maybe you want to allow an infinite number of retries. You could accomplish this by annotating retries: int | float and passing retries=float("inf") or retries=math.inf, but it would be nice if you could just pass int("inf") and not need to change the type annotation. This is punctuated by the fact that int | float is actually too broad, you don’t want to accept 3.5 (though you don’t want to accept -3 either which is indeed an int…). You really want something like int | Literal[float("inf")] or Literal[math.inf], but these are not actually valid Literal constructions. I’m not sure if there is a literal inf in the language?
I wonder if this is a bad idea because infinities are not supported by the underlying integer data structure, but I’m not sure, and I figured this would be quick to litigate either way and I’m curious to see what people think. Maybe this could somehow be handled with existing typing features or a new typing feature.
Perhaps I’m missing a better way to type annotate a parameter that accepts positive integer or positive infinite numbers. One alternative would be to introduce an infinite sentinel so that you have retries = int | InfSentinel or retries = int | type(InfSentinel) depending on how the sentinel is implemented. Or you could use None as the sentinel with the major downside that readers would interpret retries=None to be the same as retries=0.
I think integer infinity has been suggested a few times for various situations (IIRC also for min/max) but never made it into the language, because it’s just too esoteric, and there’s no good way to represent it except as a magical singleton that is treated special by both int and float objects.
Pragmatically, for your example, a max retries of 999_999_999 (or 1_000_000_000 if you’re into base-one probably works just fine.
MAXINT is equal to the highest possible integer. It is still a finite number. In Python, there is no such maximum (although as an implementation detail, the GMP library is limited to something of the order of 2**2**37 - but that number would require a stupid amount of RAM to represent), so it wouldn’t make sense to have a MAXINT.
A value of “infinity” (which, side note, doesn’t actually make sense mathematically; infinity is not a value, it’s a concept, and generally only shows up in places like limits) is one that compares greater than ANY finite integer or float. I’ve often used float(“inf”) for this purpose, though, and it’s usually not a problem to have that in a context where you otherwise are working with integers. In my opinion, this is really a typing question (“how can I annotate that this is either an integer or float(‘inf’)”) rather than a need for an actual integer that compares greater than every other integer.
I personally always used None for this purpose, i.e. retry_limit: int | None. This does ofcourse require extra code to handle, for example internally replacing None with float("inf"), but IMO it does read quite nicely.
You may be interested in my implementation of “extended integers”. If you were to use this, you would annotate your parameters ExtendedIntegral and then you can:
simply compare elements to int_inf and -int_inf or do ordinary comparisons (counter < value), and
pass integers as before and have them support instance checks.
In my opinion, your sentinel idea is roughly the same, but has slightly poorer separation of concerns.
My personal feeling is that using a sentinel is better for readers than using a really large magic number.
I’m not sure this would be a great addition to Python since it’s a fairly rare problem. Nevertheless, if it were added to Python, I think it would have to be a new class that sits between Real and Integral. I don’t think it’s fair to expect every function that accepts an int to have to support a new “infinity” object.
Thanks for the context. Yeah, I don’t claim this isn’t esoteric. The 999_999_999 strategy would be a little annoying because it forces the caller to think: “I want this to retry so many times that it will never matter for my caller, what is the biggest number I can pick here?” when the intent (and code) is really: “I want to bypass the logic for breaking out of the retry loop”.
Yes, I think this is the right take. I don’t necessarily need integers to be extended in such a way that they can handle comparisons with infinity (though that would be nice), I’m still happy to special case if the caller passes in retries=int_inf within the function. I mostly just want a way to annotate like you said.
Renaming the parameter retry_limit instead of retries makes the None semantics better for this.
Nice. I think this does accomplish everything I’m looking for.
This seems reasonable to me. I suspect extending the regular integers to include infinity would possibly break existing code that doesn’t currently worry what would become a new type of edge case.
It’s fair. retries=None meaning infinite retries is confusing, you would interpret it as retries=0 so that approach didn’t immediately sound good. But renaming the parameter to max_retries=None is better because it’s kind of like saying “there is no limit to the number of retries”.
I figured the vetting on this would be quick. I think the linked extended integers pypi package does precisely what is being request, so if I or anyone really wants something with the semantics of finite integers + an infinite integer then they can use that.
Like a lot of the ideas here, I think the existence of the extended integers package shows that it is a useful feature that people would use, it is only a question of if the usefulness warrants inclusion, and the associated costs of that inclusion, in the standard library.
Not sure what you mean. Is 2**N-1 a magic number? Or do you mean there’s some magic number that behaves like an infinity, which is completely different from MAXINT in concept? Or that there’s a magic number that, in the API in question, indicates “no limit”?
Both the concept of value as member of a type, or the common-language notion (not a mathematical concept) of value as output of a function, or particularization of a quantified variable, etc, infinity can be both.
really ARE values
Either you have a special notion of “value”, or what you are saying is devoid of meaning. What do you call “value”? Note that I don’t think you have a special notion of value, only that I think you haven’t thought carefully whether it applies and are repeating mechanically an idea that have heard others say, but that is actually incorrectly expressed.
You shouldn’t get irritated. You are really saying nonsense. As a mathematician, my intention is to educate about why that often repeated phrase “infinity is not a number” (or in this case “value”) is meaningless. So, it doesn’t bring any weight into a reasoning.