There has been some discussion recently about lazy-evaluated semi-infinite 
lists.  The biggest point of disagreement is over lists of the form (..n) 
and (..), i.e., semi-infinite lists bounded from above and semi-infinite 
lists which are unbounded.

I believe there are some reasonable semantics which can be had with such 
lists, and that these semantics are reasonably perlish.

Several proposals have mentioned an extended form of the .. operator that 
is capable of accepting increments, like so:

@a = (1..100:10) # @a = (1,11,21,...,91).

This notation makes it easier to work with ranges, and makes it easier to 
show the sematics I see for semi-infinite lists.

Many people have stated that @positives=(1..) is acceptable, but 
@negatives=(..-1) is not, because @positives has a beginning and @negatives 
does not.  As such, operations like map(), grep(), reduce(), etc, working 
on @negatives are nonsensical.

Nonsense...

Perl provides methods of accessing each end of a list.  For a normal list 
@digits=(0..9), expressions like shift(@digits), unshift(@digits,@list), 
and $digits[5] are all defined, and access @digits from the 
right.  Similarly, pop(@digits), push(@digits,@list), and $digits[-5] are 
all defined and access @digits from the left.  There is no reason why this 
property can't be extended to semi-infinite lists either.

I think this table of results makes sense...

@a =               (k..l:n)       (k..:n)       (..l:n)    (..:n)
----------------------------------------------------------------
$a[i] (i>=0)     k+i*n, if <l      k+i*n         ERROR      ERROR
$a[-i] (i>0)      $a[$#a-i+1]      ERROR        l-(i-1)*n   ERROR
shift(@a)        @a=(k+n..l:n)  @a=(k+n..:n)     ERROR      ERROR
unshift(@a,0)    @a=(0,k..l:n)  @a=(0,k..:n)     ERROR      ERROR
pop(@a)          @a=(k..l-n:n)     ERROR      @a=(..l-n:n)  ERROR
push(@a,0)       @a=(k..l:n,0)     ERROR      @a=(..l:n,0)  ERROR
reverse(@a)        see below     @a=(..k:n)    @a=(l..:n)   ERROR

The issue with reverse (k..l:n) is that the last element is not l, but the 
largest k+i*n <= l, so it's reversal can't be written as generally as the rest.

Please note:  (..) still is not meaningful, because it can't be indexed.

map() and grep() are also meaningful:

@doubles    = map { 2*$_ } (1..)  # @doubles is (2,4,6,8,...)
@ndoubles   = map { 2*$_ } (..-1) # @ndoubles is (...-8,-6,-4,-2)
@primes     = grep {isprime($_)} (1..) # @primes is (2,3,5,7,11,...)
@nprimes    = grep {isprime(-$_)} (..-1) # @nprimes is (..-5,-3,-2)

I am not sure if reduce makes sense in the context of semi-infinite lists 
of either flavor.

Reply via email to