Series Implementation I

I’d like to jump right in with work on the implementation of the new version of the series operator for Rakudo.  It looks to me like this will end up being one of the most complicated functions in the Rakudo core, so I’m hoping this can be a good forum for discussing how to get all the details of it correct.

Without further ado, here’s what I’ve got so far:

# Temporary function that maybe should be infix:<...> once it works.
our multi sub Series(@lhs, $rhs) {
    my $next;
    if @lhs[@lhs.elems - 1] ~~ Code {
        $next = @lhs[@lhs.elems - 1];
    } else {
        given @lhs.elems {
            when 1 {
                if @lhs[0] cmp $rhs == 1 {
                    $next = { $.prec };
                } else {
                    $next = { $.succ };
                }
            }
            when 2 {
                $next = { $_ + (@lhs[1] - @lhs[0]) };
            }
            when 3 {
                if @lhs[1] - @lhs[0] == @lhs[2] - @lhs[1] {
                    $next = { $_ + (@lhs[1] - @lhs[0]) };
                } elsif @lhs[1] / @lhs[0] == @lhs[2] / @lhs[1] {
                    $next = { $_ * (@lhs[1] / @lhs[0]) };
                } else {
                    fail "Unable to figure out pattern of series";
                }
            }
            default { fail "Unable to figure out pattern of series"; }
        }
    }
    
    my $i = @lhs[0];
    gather {
        my $j = $i;
        take $j;
        my $last = $i;
        loop {
            $i = $next.($last);
            my $j = $i;
            take $j;
            $last = $i;
        }
    }
}

The basic idea here is that on the left side you’ve got zero or more list elements, maybe followed by a generating closure. On the right side, you have a limit value or possibly a Whatever to indicate going on forever (or until you hit the natural limit).

This sketchy initial version looks for the code block; if it finds it, it uses it. If it doesn’t find it, it attempts to generate one by analyzing the elements given in the list. It then iterates using the code block repeatedly, without any regard to the limit.

This doesn’t even do half of what the series operator is supposed to be able to do. Right now only arity-1 code blocks work — but any code block that generates values should work. And at the other end, the limit behavior can be pretty complex.

As I said, I’m hoping others can help me with this one. I’m pondering making a github project for it. But I don’t know at the moment how much of the project tools for Perl 6 actually work under the current Rakudo….

One Response to “Series Implementation I”

  1. Moritz Says:

    The solution clearly involves splitting up the function into several multis.

    I like the idea of a separate project, maybe ask pmichaud to move it to the ‘perl6’ account on github, I can then teach hugme to add committers to it…

Leave a reply to Moritz Cancel reply