Blast from the past: E02

masak on 2010-02-04T14:47:06

SF took my challenge to heart and started producing a "modern Perl 6" version of the example code in E02. His thought process can be seen here, and here.

After being a bystander for a few hours, I coulndn't restrain myself anymore: I produced my own version. I should say at once that it's quite different from SF's: while he keeps close to the original E02 (which, in turn, sets out to prove that Perl 6 is/was not very different from Perl 5), my version is a bit more liberal in its interpretation. I do mix in some of my personal preferences into it. Some examples:

  • We don't do $ARGS prompts("Search? ") anymore, but there's a nice &prompt function which I used instead, together with a while loop.
  • The &show function now uses gather/take, rather than printing directly.
  • Also, I avoided the statement-modifying mess from the original E02 &show code.
  • Also, E02's &show makes a point of using a slurpy @_ rather than naming the paramters. I don't. (Neither does SF.)
  • It just makes sense to use a given/when construct in the &insert function. To its credit, E02 tantalizingly hints of it, but then does a MIB mind-wipe. (You don't recall that bit? Oh well...)
  • In the same function, E02 puts undef to initiate the child nodes to some empty value. Both SF and I independently realized that just any undefined value won't work if &insert is to have %tree in the signature, because %tree only binds to an Associative value. SF solved it by putting Hash (an undefined Hash type object) in the child nodes, and changed it to Hash.new in the later version. I used {}, which should be equivalent to Hash.new, but IMHO more idiomatic.
  • The whole traits business hadn't solidified in 2002, but I believe that the end result is both more realiable, more useful, and prettier. You'll have to judge for yourself.

I believe rewriting the exigeses in modern form is a very worthy activity. I hope we'll see more of that. Perl 6 suffers a bit from stale, outdated documentation, and having these in new versions would be valuable.

It's also a very interesting historical activity to read the old apocalypses and exigeses, as I increasingly find. Perl 6 has come a long, long way since 2001.


refining the "show" function

dpuu on 2010-02-04T16:32:58

Nice work, but still something lacking in the "show" function: both your version and SF's have too much repetition. What we really want to to say that there's a list of three actions to perform in one of three orders, with only one of the blocks moving. something like:

sub show(%tree, Traversal $method) {
    return unless %tree;
    my @actions = (
        { show %tree<RIGHT>, $method },
        { show %tree<LEFT>, $method },
    );
    @actions.=splice( $method.value, 0 ) <== { take %tree<VALUE> };
    @actions>>.();
}

Perhaps losing a bit of readability ... but I think we can remove even the last bit of repetition here:

sub show(%tree, Traversal $method) {
    return unless %tree;
    my @actions = <RIGHT LEFT>.map: -> $way { show %tree<$way>, $method }.assuming( $^way );
    @actions.=splice( $method.value, 0 ) <== { take %tree<VALUE> };
    @actions>>.();
}

Re:refining the "show" function

masak on 2010-02-04T17:07:24

It's clearly a matter of taste of where you want to end up on the readability/non-repetitiousness scale. :) I simply chose to err on the side of readability this time around.

Re:refining the "show" function

dpuu on 2010-02-04T20:23:46

And actually I made a horrible error in my code: the way I wrote it the traversal order is actually undefined, because the order of iteration of hyper operators is undefined. So, although I'd say that having a concurrent traversal ordering would be a nice addition, the last line of my sub should probably be something like: ".() for @actions;"

Re:refining the "show" function

geoffrey on 2010-02-04T18:17:14

Am I the only one whose OCD goes on overdrive everytime he sees a fixed-function tree traversal sub?

I immediately want to refactor &show into a general traversal sub:

sub traverse(%tree, Traversal $order, &function) { ... &function(%tree<VALUE>); ... }

and a trivial driver:

sub show(%tree, Traversal $order) { traverse(%tree, $order, &take) }

I guess that gets away from keeping the same overall form as the E02 code. Of course, I had the same reaction the first time I read the original code in E02 ....

Re:refining the "show" function

masak on 2010-02-04T22:18:01

Heh. The reaction I got on #perl6 was that I had changed the function too much by replacing print by take, essentially turning the &show function into an iterator generator.