Posts in this category

Sun, 21 Jun 2009

Trying to implement new operators - failed

Permanent link

This isn't a success story - it's only almost a success story.

On we had a Golf challenge (ie writing code in as little characters as possible): write an implementation of the Euclidian algorithm in Perl 6.

I proposed a solution which I liked very much, but which didn't work in Rakudo yet, because it used the series operator infix:<...> (yes, three literal dots) which isn't yet implemented in Rakudo. D'oh!.

I like Perl 6 discussions on Perlmonks, but every solution that shows a NYI-feature encourages the "Perl 6 is vapor-ware" thoughts and comments. So I decided to make it work, and decided to JFDI and implement the missing operator.

In general implementing a new operator in Rakudo is not much harder than implementing a function: all you have to do more is to add it to src/parser/ including precedence and associativity (both of which can be found in the spec.

For quite a while now built-in functions and methods can be written in Perl 6 now, so I also decided to write the new operator in Perl 6. Since lazy lists aren't implemented yet, I decided not to care about the lazy version, and did the eager version instead. This is what my code looked like:

multi sub infix:<...> (@lhs, Code $generator) {
    my $c = $generator.count;
    if $c > @lhs {
        fail 'the closure wants more parameters than given on the LHS';
    my @result = @lhs;
    my @r;
    # XXX work around
    # this is a bit ugly.. since @a[1..1] returns a single item and not 
    # an array, |@result[$one-item-range] throws the error
    # "argument doesn't array"
    while @r = $generator(|@(@result[*-$c..*-1])) {
        @result.push: @r;
    return @result;

This works... partly. It works only in the file it is defined in, not if it's defined in the setting library.

So to summarize: I have an implementation ready, but due to Rakudo bugs it can't go into mainstream Rakudo right now. JFDI, partly failed.

[/perl-6] Permanent link