Re: generality of Range

2009-10-04 Thread Darren Duncan

Moritz Lenz wrote:

Darren Duncan wrote:
However, I still don't see how one would retrieve the distinction between say 
"1..10" and "1^..^10".  I suggest that an extra 2 methods such as 
.min_is_outside and .max_is_outside (each returns a Bool) could fit the bill, 
and in fact since I have Pugs write access I think I'll go make that addition 
myself in the above S03 section.


Great.
Rakudo currently uses from_exclusive and to_exclusive, but since ranges
now always have $.from < $.to, I see no reason to stick with "from" in
favor of "min", and "to" in favor of "max".


As seen in r28612, I went and made my change, but I decided to use shorter and 
probably better-descriptive names .min_excl and .max_excl, since both in math 
parlance as well as the existing S03 docs I was adding to, the base terms 
"include" and "exclude" were already in use.


Now I was going to ask how to represent endpoints that are "whatever" if 
"whatever" is orthogonal to type, but then I realized the answer is simply to 
use a Whatever object, which is one of the 4 "Undefined types" mentioned in S02.


For example, if someone said:

   my $r = $foo..*;
   my $min = $r.min;  # $foo's value
   my $max = $r.max;  # Whatever.new()

Now maybe it would be reasonable for .max to return +Inf if $foo was an Int, but 
I would expect that for any type where $foo doesn't have a concept of 
positive-infinity, a * would just be Whatever.new() by default.


I'd just say that Range.min and Range.max return exactly what you put
into it - (1..*).max should return * (which is a Whatever object),
(1..Inf).max should return Inf.


That sounds like exactly what I would prefer to happen.

Now, another tangent that I was going to raise ideas order-comparison-sensitive 
operations in general.


While it makes perfect sense for some type definitions to have "cmp" et al 
built-in, meaning that all order-comparison-sensitive operations such as "cmp" 
and "sort" and "before" and "minmax" and Range/interval value membership just 
work for them without extra help, I believe that it should be possible to apply 
a "cmp" at the place where any order-comparison-sensitive operations are *used*, 
not just in the type definitions of their operands.


For example, we already have:

  map { $^a mycmp $^b } @values  # spelling ?

But I believe one should be able to do that with "minmax" or Range uses or 
"before" or what-have you in a generic sense as well; for example:


  $a ∈ $b..$c ordered using { $^a mycmp $^b }  # ordered ... applies to ∈
  minmax @values ordered using { $^a mycmp $^b }

Now mind you, its possible that support for what I'm saying already exists with 
another syntax, perhaps using :trait syntax, but I don't recall.


But this is important, especially since often a type may have multiple innate 
conceptions of order, and you are best to pick one at time of use; for example, 
what collation to use for sorting text, you may not want to encode into the Str 
objects but just declare at the time of sorting/etc.


And it is important because it what lets you potentially order values of any 
types at all.


-- Darren Duncan


Re: generality of Range

2009-10-04 Thread Moritz Lenz


Darren Duncan wrote:
> However, I still don't see how one would retrieve the distinction between say 
> "1..10" and "1^..^10".  I suggest that an extra 2 methods such as 
> .min_is_outside and .max_is_outside (each returns a Bool) could fit the bill, 
> and in fact since I have Pugs write access I think I'll go make that addition 
> myself in the above S03 section.

Great.
Rakudo currently uses from_exclusive and to_exclusive, but since ranges
now always have $.from < $.to, I see no reason to stick with "from" in
favor of "min", and "to" in favor of "max".

> Now I was going to ask how to represent endpoints that are "whatever" if 
> "whatever" is orthogonal to type, but then I realized the answer is simply to 
> use a Whatever object, which is one of the 4 "Undefined types" mentioned in 
> S02.
> 
> For example, if someone said:
> 
>my $r = $foo..*;
>my $min = $r.min;  # $foo's value
>my $max = $r.max;  # Whatever.new()
> 
> Now maybe it would be reasonable for .max to return +Inf if $foo was an Int, 
> but 
> I would expect that for any type where $foo doesn't have a concept of 
> positive-infinity, a * would just be Whatever.new() by default.

I'd just say that Range.min and Range.max return exactly what you put
into it - (1..*).max should return * (which is a Whatever object),
(1..Inf).max should return Inf.

Cheers,
Moritz


Re: generality of Range

2009-10-04 Thread Darren Duncan

Minimiscience wrote:
> On Oct 4, 2009, at 12:47 PM, yary wrote:
>> There was a big discussion about this on the list recently but I don't
>> recall the resolutions.
>
> The resolution was r28344: .
> The short version is that ranges are now primarily used for testing
> inclusion in intervals; if you want a list of values in an interval, use
> ... instead.

Jon Lang wrote:

yary wrote:

I'm confused between using ranges to generate a lazy list and using
them as criteria to match against.


Indeed.  It was my understanding that there was a recent change to
Ranges so that they now exist primarily to be used as matching
criteria.  If you wish to generate a list, the preferred approach
these days is the ... infix operator:

1 .. 100 # the range of values between 1 and 100, inclusive.
1, 2 ... 100 # a list of integers.

The ability to generate a lazy list using a Range object is now of
secondary importance, and should not be a required feature anymore.
In particular, :by was removed from Range.


What Minimiscience and Jon Lang stated has been my understanding as well, 
especially since the r28344 resolution.  A Range is primarily used as an 
interval, either to simply represent a span of values of some orderable type 
(which could be any type at all in the general case), or to test whether a given 
other value is orderable between the interval's endpoints.  And this is all that 
I want to use it for, in a general context that is orthogonal to type.  So 
supporting .succ() or .prec() in the general case isn't needed.


Now, it turns out that Synopsis 3 was the place with some of the answers I 
sought:

  http://perlcabal.org/syn/S03.html#Range_and_RangeIterator_semantics

For example, .min and .max are used to read the declared endpoint values of a 
Range.

However, I still don't see how one would retrieve the distinction between say 
"1..10" and "1^..^10".  I suggest that an extra 2 methods such as 
.min_is_outside and .max_is_outside (each returns a Bool) could fit the bill, 
and in fact since I have Pugs write access I think I'll go make that addition 
myself in the above S03 section.


Now I was going to ask how to represent endpoints that are "whatever" if 
"whatever" is orthogonal to type, but then I realized the answer is simply to 
use a Whatever object, which is one of the 4 "Undefined types" mentioned in S02.


For example, if someone said:

  my $r = $foo..*;
  my $min = $r.min;  # $foo's value
  my $max = $r.max;  # Whatever.new()

Now maybe it would be reasonable for .max to return +Inf if $foo was an Int, but 
I would expect that for any type where $foo doesn't have a concept of 
positive-infinity, a * would just be Whatever.new() by default.


On a tangent, I was thinking that if Range really is meant to represent an 
interval in its general case, which is orthogonal to type, then Range should be 
as generic as Set or other element-type-orthogonal containers, and also support 
not only the Iterable role but the Associative role, like Set does.


You see, conceptually an interval is a set of values, where the member values 
are defined not in terms of an enumeration (as with Set, Bag, PairValSet, etc) 
but rather in terms of what values exist from the value domain of the interval's 
endpoints that are ordered between those endpoints.


And so, conceptually "$a ~~ 1..10" is a set membership test, and I think it 
would be reasonable to be able to use the more semantics-specific operators that 
one uses on Set or Hash or whatever to test membership, on a Range; for example:


  $val ∈ Set.new( 42, 27, 4, 36 )
  $val ∈ 20^..40

Similarly, there should be operators or methods for testing if 2 Range overlap, 
or if one is contained in the other, or to derive 1 from 2 using intersection or 
union etc.


These are operations common with mathematical intervals (those over Real say), 
but they are orthogonal to type.


It is more just using + or - etc which are specific to the maths, or rather they 
aren't orthogonal to type but just are for types that support +/-/etc.


On a tangent, if there is any thought to make S32/Temporal have specific support 
for Instant/DateTime interval objects (which are *not* the same meaning as 
durations), I would say that a suitably generic Range should fit the bill by 
itself, as far as declaring the objects goes.  For example, "Range of Instant" 
or "Range of DateTime" should be a sufficient type declaration for a date range 
type, rather than needing to come up with something special, unless that special 
thing is just an alias for the above.


So those are some thoughts.  I probably have more.

-- Darren Duncan


Re: generality of Range

2009-10-04 Thread Jon Lang
yary wrote:
> I'm confused between using ranges to generate a lazy list and using
> them as criteria to match against.

Indeed.  It was my understanding that there was a recent change to
Ranges so that they now exist primarily to be used as matching
criteria.  If you wish to generate a list, the preferred approach
these days is the ... infix operator:

1 .. 100 # the range of values between 1 and 100, inclusive.
1, 2 ... 100 # a list of integers.

The ability to generate a lazy list using a Range object is now of
secondary importance, and should not be a required feature anymore.
In particular, :by was removed from Range.

-- 
Jonathan "Dataweaver" Lang


Re: generality of Range

2009-10-04 Thread Minimiscience

On Oct 4, 2009, at 12:47 PM, yary wrote:

There was a big discussion about this on the list recently but I don't
recall the resolutions.


The resolution was r28344: .   
The short version is that ranges are now primarily used for testing  
inclusion in intervals; if you want a list of values in an interval,  
use ... instead.


-- Minimiscience


Re: generality of Range

2009-10-04 Thread yary
I'm confused between using ranges to generate a lazy list and using
them as criteria to match against.

These exclude continuous (non-countable) types-

...
>  2. There must be a successor function, so that given an object from
> the given domain, say a, successor(a) returns one and only one
> value from the same domain.
>  3. Given b = successor(a), there is no c so that b > c > a (using the
> same operator as above).

Rationals and reals can't participate in ranges by the above, which in
a sense make sense. You can't ask for all rationals/reals between two
endpoints, or the "next rational number bigger than 0". But it does
make sense to ask "is $x between 0 and 1 exclusive?"

There was a big discussion about this on the list recently but I don't
recall the resolutions.

And in Darren's example, could one declare a comparator and successor
operator for lists, and then get the example to produce ['Foo', 18],
['Foo', 19], ['Foo', 20], ['Foo', 21], ['Foo', 22], ['Foo', 23] ?

-y


Re: generality of Range

2009-10-04 Thread Michael Zedeler

Hi Darren.

Darren Duncan wrote:
In a project of mine I'm looking to use Perl 6 Range values to 
represent continuous interval values in the most generic manner 
possible, meaning that the endpoint values could literally be of any 
type at all. [...] for a realistic example:


  my $a = ['Foo', 17] ^.. ['Foo', 23];

... I would expect $a to be a Range and to be able to get those 
arrayrefs out of  it. [...]


Bottom line, is my example line with the "['Foo',17]" valid Perl 6 or 
not, and if not then what could be done about it?
The short version is that your example shouldn't be valid Perl 6, 
because  both ordering and successor functions are missing.


Look in synopsis 02 and 03 for documentation, but note that this 
particular corner of Perl 6 IMHO still is in flux.


My opinion is that for any domain (integers, real numbers, strings, 
complex numbers, two-element arrays consisting of a string and a number 
(your example) and anything else you can come up with), you have two 
requirements that must be met in order to be able to create a well 
defined Range:


  1. There must be a compare operator that can decide which of  two
 objects from the given domain is the greatest (for strings, ge and
 for numbers >). Lets call it >.
  2. There must be a successor function, so that given an object from
 the given domain, say a, successor(a) returns one and only one
 value from the same domain.
  3. Given b = successor(a), there is no c so that b > c > a (using the
 same operator as above).

And finally, if there are multiple, competing variations for the same 
domain, I say that they should be left out of Perl 6.
Also, in what Synopsis is it documented what the methods are to 
extract the endpoints et al from a Range object.  Or what are they called?
Here is some meta-help: if you ever have a Perl 6 object and need to 
know its methods and attributes, use the introspection API. There is a 
description here:


http://rakudo.org/node/51

Regards,

Michael.



generality of Range

2009-10-04 Thread Darren Duncan

A question.

In a project of mine I'm looking to use Perl 6 Range values to represent 
continuous interval values in the most generic manner possible, meaning that the 
endpoint values could literally be of any type at all.


I just wanted to confirm that that would work in the general case, where I might 
want to do nothing more than:


  my $a = $b .. $c;
  my $a = $b ^.. $c;
  my $a = $b ..^ $c;
  my $a = $b ^..^ $c;

... plus invoke methods of $a to extract the values $b,$c and indicators of 
whether $b or $c are included within the range or not (how you read the 
distinction between the presence or absence of either or both "^".


As long as I don't try to iterate the range or something, I would expect the 
above to work for any possible value of $b or $c; for a realistic example:


  my $a = ['Foo', 17] ^.. ['Foo', 23];

... I would expect $a to be a Range and to be able to get those arrayrefs out of 
 it.


On a tangent, it would be nice if Range were parameterizable like Seq say; such 
as:

  has Range of Int $foo;

... and then $foo would only accept Range values whose endpoints are Int.

Now in order for what I ask to work, Range has to be lazy enough that it won't 
for example test that $b is before $c when constructing the Range object, and 
will only complain if necessary when you try to use it where that matters.


Bottom line, is my example line with the "['Foo',17]" valid Perl 6 or not, and 
if not then what could be done about it?


Also, in what Synopsis is it documented what the methods are to extract the 
endpoints et al from a Range object.  Or what are they called?


Thank you in advance.

-- Darren Duncan