On Mon, Oct 06, 2008 at 09:09:55AM -0700, Jon Lang wrote:
: Larry Wall wrote:
: > On Sun, Oct 05, 2008 at 08:19:42PM -0700, Jon Lang wrote:
: > : <[EMAIL PROTECTED]> wrote:
: > : > Log:
: > : > Add missing series operator, mostly for readability.
: > :
: > : Is there a way for the continuing function to access its index as well
: > : as, or instead of, the values of one or more preceding terms?  And/or
: > : to access elements by counting forward from the start rather than
: > : backward from the end?
: >
: > That's what the other message was about.  @_ represents the entire list
: > generated so far, so you can look at its length or index it from the
: > beginning.  Not guaranteed to be as efficient though.
: 
: If I understand you correctly, an "All even numbers" list could be written as:
: 
:   my @even = () ... { 2 * [EMAIL PROTECTED] }
: 
: And the Fibonacci series could be written as:
: 
:   my @fib = () ... { (pow((1 + sqrt(5))/2, [EMAIL PROTECTED]) - pow((1 - 
sqrt(5))/2,
: [EMAIL PROTECTED])) / sqrt(5)) }
: 
: Mind you, these are bulkier than the versions described in the patch.
: And as presented, they don't have any advantage to offset their
: bulkiness, because you still have to determine every intervening
: element in sequential order.  If I could somehow replace '[EMAIL PROTECTED]' 
in the
: above code with an integer that identifies the element that's being
: asked for, it would be possible to skip over the unnecessary elements,
: leaving them undefined until they're directly requested.  So:
: 
:   say @fib[4];
: 
: would be able to calculate the fifth fibonacci number without first
: calculating the prior four.
: 
: It's possible that the '...' series operator might not be the right
: way to provide random access to elements.  Perhaps there should be two
: series operators, one for sequential access (i.e., 'infix:<...>') and
: one for random access (e.g., 'infix:<...[]>').  This might clean
: things up a lot: the sequential access series operator would feed the
: last several elements into the generator:
: 
:   0, 1 ... -> $a, $b { $a + $b }
: 
: while the random access series operator would feed the requested index
: into the generator:
: 
:   () ...[] -> $n { (pow((1 + sqrt(5))/2, $n) - pow((1 - sqrt(5))/2,
: $n)) / sqrt(5)) }
: 
: I'd suggest that both feed the existing array into @_.

That's what the ++(state $) example was about in the other message.
The only downside is that it's assuming only one element is feed in
on the left.  Otherwise you need to initialize the anonymous state
variable to some larger number.  Maybe it's an idiom where you just
always initialize $n to the number of elements on the left:

    0,1,2 ... { state $n = 3; $n++ }

I don't see much need for additional relief, especially since
it's normally trivial to write such lists other ways:

    map { func($^n) } 0..*
    func($_) for 0..*
    for 0..* { .func }

: On an additional note: the above patch introduces some ambiguity into
: the documentation.  Specifically, compare the following three lines:
: 
:     X  List infix        Z minmax X X~X X*X XeqvX ...
:     R  List prefix       : print push say die map substr ... [+] [*] any $ @
: 
:     N  Terminator        ; <==, ==>, <<==, ==>>, {...}, unless, extra ), ], }
: 
: On the first line, '...' is the name of an operator; on the second and
: third lines, '...' is documentation intended to mean "...and so on"
: and "yadda-yadda", respectively.  However, it is not immediately
: apparent that this is so: a casual reader will be inclined to read the
: first line as "...and so on" rather than 'infix:<...>', and will not
: realize his error until he gets down to the point where the series
: operator is defined.

No, the second one not metasyntactic--it's the prefix:<...>, also known
as yada.  It's essentially a synonym for fail, and so takes a list
argument.  The third one is not yada--it's metasyntactic to represent
any "expect infix" block that stops the current expression such as in

    if $x { say "yup" }

Admittedly the table is rather terse.

: __________________________
: Another question: what would the following do?
: 
:   0 ... { $_ + 2 } ... &infix:<+> ... *
: 
: If I'm reading it right, this would be the same as:
: 
:   infix:<...> (0; { $_ + 2 }; &infix:<+>; *)
: 
: ...but beyond that, I'm lost.

It would never get to the +  or the * because $_ + 2 is never ().
The operator iterates each function until the function fails to
produce any list elements.  Note you can go the other way too: the
function can actually return multiple list elements at once, so you
can interleave two (or more) independent lists:

    0,1 ... { $^even + 2, $^odd + 2 }

Interestingly, since the returned list is a capture, such a list
in slice context would turn into [0,1],[2,3],[4,5]...,  In list
context it's just 0,1,2,3,4,5...

I think that's just wicked cool.

Larry

Reply via email to