I have observed that the current Perl 6 spec and implementations seem deficient in regards to representing some special values or conditions, in particular the concept of the two linear directional infinities or otherwise special values that naturally sort before and after everything else.

Moreover, some discussion I saw on the matter shows that these issues had been punted, so here I'm trying to propose a resolution or process to that end.

Here are some links for context:

* http://irclog.perlgeek.de/perl6/2014-08-20#i_9217322
* https://docs.perl6.org/type/Range#method_infinite
* https://github.com/rakudo/rakudo/blob/nom/src/core/Range.pm

Here are some proposals and comments:

1. I think the best way to represent various special values like this is as singleton types, basically in the same way various Failure or Exception are handled, such as the various X::Foo classes. So for example, we should add X::NegInf and X::PosInf, or alternately per Larry's comment in the first link, something like X::BeforeEverything and X::AfterEverything or X::BE and X::AE. Actually we may want both the infs and the BE/AEs where distinguishing them is useful. Similarly I recommend adding such singletons for various other math concepts such as X::DivByZero and X::ZeroToTheZero etc.

2. In the case of NegInf/PosInf (alternately read as BE/AE from now on), generic ordering sensitive operators like cmp would have signatures defined such as (NegInf, Any), there would be 4 combos of those, which would be defined to always return FALSE or TRUE as appropriate; as such, all values would be comparable with these singletons automatically. Also, any dyadic min/max operators would use these singletons as their identity values.

3. Regular types such as Int or Rat or Str etc should be pure and just include normal values, that is just actual numbers for the numeric types etc. Then, contexts that might produce or want to recognize failure conditions alternately accept or return the appropriate Failure singletons mentioned, as if a type union were defined over the regular types and the failure types; users can choose whether they want to allow the special values explicitly by either including or excluding them from signatures, so naming eg just Int will only accept actual numbers.

4. Independent of the above points, the current Range class has a problem in that it doesn't distinguish which endpoint is infinite. Just as it currently distinguishes whether each endpoint is open or closed, it needs to distinguish whether each endpoint is infinite or finite. All 4 of these cases need to be distinguished: 5..10, -Inf..10, 5..Inf, -Inf..Inf and I hope it should be self-evident why that is important. For starters, it is completely valid to ask whether a value is in any of the given ranges; for half-infinite ranges, it is a generalized form for asking if the value is larger or smaller than the finite end; for fully-infinite ranges, the answer is always TRUE. Another way to think about it is that a Range is just a concise way of expressing a set. The current Range class simply has a boolean attribute that says is the Range infinite, yes or no, and that needs fixing.

5. A generic solution to representing Ranges properly is to use the two special singletons I mentioned be the endpoint values. A lot of comparing operations would then just work. Using the range to generate a list of member values would also work in some cases, depending where the infinities are and in what direction we are enumerating.

So what are the thoughts on this? Can we get appropriate improvements into Perl 6d and implementations etc? Also, is any of what I said actually already done? Certainly some key parts at least are not.

Thank you.

-- Darren Duncan

Reply via email to