On Tue, Jul 20, 2010 at 07:31:14PM -0400, Aaron Sherman wrote:

> 2) We deny that a range whose LHS is "larger" than its RHS makes sense, but
> we also don't provide an easy way to construct such ranges lazily otherwise.
> This would be annoying only, but then we have declared that ranges are the
> right way to construct basic loops (e.g. for (1..1e10).reverse -> $i {...}
> which is not lazy (blows up your machine) and feels awfully clunky next to
> for 1e10..1 -> $i {...} which would not blow up your machine, or even make
> it break a sweat, if it worked)

There is no reason why for (1..1e10).reverse -> $i {...} should *not* be lazy.

After all, Perl 5 now implements

    @b = reverse sort @a

by directly sorting in reverse. Note how it's now an ex-reverse:

$ perl -MO=Concise -e '@b = reverse sort @a'
c  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v ->3
b     <2> aassign[t6] vKS ->c
-        <1> ex-list lK ->8
3           <0> pushmark s ->4
-           <1> ex-reverse lK/1 ->-
4              <0> pushmark s ->5
7              <@> sort lK/REV ->8
-                 <0> ex-pushmark s ->5
6                 <1> rv2av[t4] lK/1 ->7
5                    <#> gv[*a] s ->6
-        <1> ex-list lK ->b
8           <0> pushmark s ->9
a           <1> rv2av[t2] lKRM*/1 ->b
9              <#> gv[*b] s ->a
-e syntax OK

Likewise

    foreach (reverse @a) {...}

is implemented as a reverse iterator on the array, rather than a temporary
list:

$ perl -MO=Concise -e 'foreach(reverse @a) {}'
d  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 2 -e:1) v ->3
c     <2> leaveloop vK/2 ->d
7        <{> enteriter(next->9 last->c redo->8) lKS/REVERSED ->a
-           <0> ex-pushmark s ->3
-           <1> ex-list lKM ->6
3              <0> pushmark s ->4
-              <1> ex-reverse lKM/1 ->6
-                 <0> ex-pushmark s ->4
5                 <1> rv2av[t2] sKR/1 ->6
4                    <#> gv[*a] s ->5
6           <#> gv[*_] s ->7
-        <1> null vK/1 ->c
b           <|> and(other->8) vK/1 ->c
a              <0> iter s/REVERSED ->b
-              <@> lineseq vK ->-
8                 <0> stub v ->9
9                 <0> unstack v ->a
-e syntax OK



If it's part of the specification that (1..1e10).reverse is to be implemented
lazily, I'd (personally) consider that an easy enough way to construct a lazy
range.


This doesn't answer any of your other questions about what ranges of
character strings should mean. I don't really have an opinion, other than
it needs to be simple enough to be teachable.

Nicholas Clark

Reply via email to