=head1 NAME

Exegesis_02 - Bits and Pieces

=head1 AUTHOR

Damian Conway <damian@conway.org>

=head1 VERSION

  Maintainer: Allison Randal <al@shadowed.net>
  Date: 15 May 2001
  Last Modified: unknown
  Number: 2
  Version: 1

I<exegesis: n. an interpretation and explanation of a text, esp. Holy
Writ>

This is the first of a series of articles paralleling Larry's
"Apocalypse" encyclicals (it's numbered 2 to keep it in sync with
those Revelations). These articles will take each unveiled piece of the
design for Perl 6 and demonstrate the new syntax and semantics in an
annotated program.

So, without further ado, let's write some Perl 6:

        # bintree - binary tree demo program 
        # adapted from "Perl Cookbook", Recipe 11.15
        use strict;
        use warnings;
        my ($root, $n);
        while ($n++ < 20) { insert($root, int rand 1000) }
        my int ($pre, $in, $post) is constant = (0..2);
        print "Pre order:  "; show($root,$pre);  print "\n";
        print "In order:   "; show($root,$in);   print "\n";
        print "Post order: "; show($root,$post); print "\n";
        $*ARGS is chomped;
        $ARGS prompts("Search? ");
        while (<$ARGS>) {
            if (my $node = search($root, $_)) {
                print "Found $_ at $node: $node{VALUE}\n";
                print "(again!)\n" if $node{VALUE}.Found > 1;
            }
            else {
                print "No $_ in tree\n";
            }
        }
        exit;
        #########################################
        sub insert (HASH $tree is rw, int $val) {
            unless ($tree) {
                my %node;
                %node{LEFT}   = undef;
                %node{RIGHT}  = undef;
                %node{VALUE}  = $val is Found(0);
                $tree = %node;
                return;
            }
            if    ($tree{VALUE} > $val) { insert($tree{LEFT},  $val) }
            elsif ($tree{VALUE} < $val) { insert($tree{RIGHT}, $val) }
            else                        { warn "dup insert of $val\n" }
        }
        sub show {
            return unless @_[0];
            show(@_[0]{LEFT}, @_[1]) unless @_[1] == $post;
            show(@_[0]{RIGHT},@_[1])     if @_[1] == $pre;
            print @_[0]{VALUE};
            show(@_[0]{LEFT}, @_[1])     if @_[1] == $post;
            show(@_[0]{RIGHT},@_[1]) unless @_[1] == $pre;
        }
        sub search (HASH $tree is rw, *@_) {
            return unless $tree;
            return search($tree{@_[0]<$tree{VALUE} && "LEFT" || "RIGHT"}, @_[0])
                unless $tree{VALUE} == @_[0];
            $tree{VALUE} is Found($tree{VALUE}.Found+1);
            return $tree;
        }

=head1 It's Perl, Jim, and quite like we know it

The program gets off to a familiar start:

        use strict;
        use warnings;
        my ($root, $n);
        while ($n++ < 20) { insert($root, int rand 1000) }

Nothing new here. And, in fact, despite the many new features it
illustrates, overall this program looks and feels a great deal like
Perl 5 code.

That shouldn't really be surprising, given that Perl 6 is growing out
the of suggestions of hundreds of devoted Perl 5 programmers, filtered
through the mind that invented Perl 5.

As RFC 28 suggested, Perl is definitely going to stay Perl.

=head1 Any variables to declare?

Variable declarations in Perl 6 can be as simple as those for C<$root>
and C<$n> above, but they can also be much more sophisticated:

        my int ($pre, $in, $post) is constant = (0..2);

Here we declare three variables that share a common type (C<int>) and a
common property (C<constant>). Typed lexicals are a feature of Perl 5
too, but having names for Perl's built-in types is new.

The type specification tells the compiler that C<$pre>, C<$in>, and
C<$post> will only ever be used to store integer values. And because
C<int> is in lower-case, the specification also tells the compiler that
it's okay to optimize the implementation of the variables, because we
promise not to C<bless> them or ascribe any run-time properties to
them. Making this promise and then breaking the rules later in the
program will get you a compile-time or run-time error (depending on
whether the compiler can detect the malfeasance statically).

If we had not been willing to live without the blessing of C<bless>-ing
or the useful run-time properties of run-time properties, we would have
written:

        my INT ($pre, $in, $post) is constant = (0..2);

in which case we'd get three less-optimized, but fully-functional, Perl
scalars.

In this particular case, the C<int>/C<INT> distinction makes very
little practical difference. However, there's a significant advantage
to writing:

        my int @hit_count is dim(100,366,24);

compared to:

        my INT @hit_count is dim(100,366,24);

and thereby replacing nearly a million chunky scalars with svelte raw
integers.

=head1 La propriE<eacute>tE<eacute> c'est le vol

The C<is constant> and C<is dim> bits of the above declarations are
compile-time property specifications. These particular properties are
standard to Perl 6, but you can also roll-your-own. The C<is dim>
property tells Perl the (fixed!) dimensions of the array in question.
The C<is constant> property specifies that the preceding variables
cannot be assigned to, nor have their values otherwise modified, once
they're initialized.

Moreover, the C<constant> property is a hint to the compiler that it
may be able to optimize the variables right out of existence, by
inlining their values directly. Of course, that's only feasible if we
don't ever treat them like a real variable (e.g. take a reference to
them, or bless them).

The C<is> keyword is optional where its absence is unambiguous, so we
could have written:

        my int ($pre, $in, $post) constant = (0..2);

Larry's also still mulling over a suggestion that C<are> be provided as
a synonym for C<is>, so you might even be able to write the declaration
as:

        my int ($pre, $in, $post) are constant = (0..2);

An important feature of the C<is> operator that we'll make use of
shortly, is that it returns its I<left> operand. So:

        $submarine is Colour('yellow')

evaluates to C<$submarine>, not C<'yellow'>.

=head1 More of the same

The three calls to C<show> are also exactly as they were in Perl 5:

        print "Pre order:  "; show($root,$pre);  print "\n";
        print "In order:   "; show($root,$in);   print "\n";
        print "Post order: "; show($root,$post); print "\n";

Happily, we're going to see that a lot throughout this series of
articles.

=head1 Biting off less so you can chew

Do you ever get tired of writing:

        while (<>) {            # Common Perl 5 idiom
                chomp;
                ...

Wouldn't it be nice if input lines were automatically chomped? In Perl
6, they can be. We just set the C<chomped> property on the input handle
referred to by the global variable C<$*ARGS>:

        $*ARGS is chomped;

This causes any normal read on the handle (see Inputs that output) to
automatically pre-C<chomp> the string it returns. Of course, like most
other global punctuation variables, C<$/> has been banished from Perl
6, so the trailing character sequence to be chomped is specified by the
handle's own C<insep> (B<in>put B<sep>arator) property instead.

The asterisk in C<$*ARGS> indicates that the variable is the one from
the special global namespace. If the asterisk is omitted, it's probably
I<still> the one from the special global namespace -- unless you
declared a lexical or package variable of the same name. You can
pronounce C<*> as "standard", if that helps.

By the way, it's called C<$*ARGS> because it lets us access the files
passed as a Perl 6 program's I<arguments> (just as the Perl 5 C<ARGV>
filehandle provides access to the program's...err...I<argumentv>).

=head1 Inputs that output

In the original I<Cookbook> version of this program, the next line was:

        for (print "Search? "; <>; print "Search? ") {

This highlights a common situation for which there is no satisfactory
solution in Perl 5. Namely: repeatedly prompting for input and reading
it into C<$_>, until EOF. In Perl 6, there's finally a clean way to do
this -- with another property:

        $ARGS prompts("Search? ");
        while (<$ARGS>) {

The first thing you'll notice is that reports of the diamond operator's
death have been greatly exaggerated. Yes, even though the Second
Apocalypse foretold its demise, Rule #2 has since been applied and the
angle brackets live!

Of course, they're slightly different in Perl 6, in that they
I<require> a handle object inside them (normally stored in a variable),
but that's already possible in Perl 5 too.

Meanwhile, what about that prompt? Well, the Perl 6 solution is to
allow input handles to have an associated character string that they
print out just before they attempt to read in data.

I<Wait a minute!>, I hear you object, I<Input handles that do
output???> Actually, you've been using handles like that for decades.
In most languages, every time you do a read from standard input, the
first thing the input operation does is flush the standard output
buffer. That's why something like:

        print "nuqneH? ";
        $request = <>;

pre-prints the prompt correctly, even though it doesn't end in a
newline.

So input and output mechanisms are already carrying on a secret
relationship. The only change here is that now you're allowed to have
the input handle add a little something to the output before it flushes
the buffer. That's done with the C<prompts> property. If an input
handle has that property, its value is written to C<$*OUT> just before
the input handle reads. So we can replace:

        for (print "Search? "; <>; print "Search? ";) {         # Perl 5 (or 6)

with

        $ARGS prompts("Search? ");                              # Perl 6
        while (<$ARGS>) {

Technically, that should of course be:

        $ARGS is prompts("Search? ");

but that grates unbearably. Fortunately the C<is> is optional in
contexts -- such as this one -- where it can be inferred.

Note that, because the C<is> operation returns its C<left> operand
(even when the C<is> is invisible!), we could also use the rather
elegant:

        while (<$ARGS prompts("Search? ")>) {

In fact, this one-line version may often be preferable, since the value
of the C<prompts> property might be changed somewhere inside the loop
and this resets it on each iteration.

The exact semantics of the prompting mechanism aren't nailed down yet,
so it may also be possible to use a subroutine reference as a dynamic
prompt (the handle would call the subroutine before each read and
pre-print the return value).

=head1 Haven't we met before? (part 1)

Having requested and read in a value, the search-and-report code is
almost entirely familiar:

            if (my $node = search($root, $_)) {
                print "Found $_ at $node: $node{VALUE}\n"
                print "(again!)\n" if $node{VALUE}.Found > 1;
            }
            else {
                print "No $_ in tree\n"
            }
        }

The only lurking Perl6ism is the use of the user-defined C<Found>
property to report repeated searches.

The call to C<$node{VALUE}.Found> would normally be a method call (in
Perl 6 C<< -> >> is spelled C<.>). But since C<$node{VALUE}> is just a
regular unblessed int, there is no C<Found> method to call. So Perl
treats the request as a property query instead and returns (an alias
to) the corresponding property.

=head1 Take that! And that!

In Perl 6, subroutines can -- optionally -- specify proper parameter
lists (as opposed to the not-evil-just-misunderstood argument context
prototypes that Perl 5 allows).

For instance the C<insert> subroutine, declares itself to take two
parameters:

        sub insert (HASH $tree is rw, int $val) {

The first parameter specifies that the first argument must be a
reference to a hash and is to be assigned to the lexical variable
C<$tree>. Defining the first parameter to be a hash reference means
that any attempt to use it in some other way (e.g. trying to do an
subroutine call through it, trying to pass it an explicit array
reference, etc.) can be caught and punished -- at compile-time.

It's important to understand that, by default, named parameters are
I<not> like the elements of C<@_>. Specifically, even though each
argument is passed to its corresponding parameter by reference (for
efficiency), the parameter variable itself is automatically declared
C<constant>, so any attempt to assign to it results in a compile-time
error. This is intended to reduce the incidence of people accidentally
people shooting themselves in the foot.

Of course, this being Perl, when we really do need to draw a bead on
those metatarsals, we can. To allow assignments to a named parameter --
assignments that I<will> propagate back to the original argument -- we
need to to declare the parameter with the standard C<rw>
(B<r>ead-B<w>rite) property. It then becomes an fully assignable alias
for the original argument, which in this example allows us to
autovivify it (see We don't need no stinking backslashes).

The C<@_> argument array I<is> still available in Perl 6, but only when
we declare subroutines in the Perl 5 manner -- without a parameter
list. See A good, old-fashioned show).

The second parameter of C<insert> is defined to take an integer value.
By using the type C<int> instead of C<INT>, we're once again explicitly
promising not to do bizarre things with the referent (at least, not
within the body of C<insert>). The compiler might be able to use this
information to optimize the subroutine's code in some way.

=head1 A sigil is for life, not just for value type

Long ago, when the Earth was new and Perl was young and clean, the type
of sigil (C<$>, C<@>, or C<%>) that was associated with a variable
described what it evaluated to. For example:

        print $x;                       # $x evaluates to scalar
        print $y[1];                    # $y[1] evaluates to scalar
        print $z{a};                    # $z{a} evaluates to scalar
        print $yref->[1];               # $yref->[1] evaluates to scalar
        print $zref->{a};               # $zref->{a} evaluates to scalar
        print @y;                       # @y evaluates to list
        print @y[2,3];                  # @y[2,3] evaluates to list
        print @z{'b','c'};              # @z{'b','c'} evaluates to list
        print @{$yref}[2,3];            # @{$yref}[2,3] evaluates to list
        print @{$zref}{'b','c'};        # @{zyref}{'b','c'} evaluates to list
        print %z;                       # %z evaluates to hash

Regardless of the actual type of the variable being referred to, a
leading C<$> on the access meant the result would be a scalar; a
leading C<@> meant a list; a leading C<%>, a hash.

But then the serpent of OO entered the garden, and offered Perlkind the
bitter fruit of subroutine and method calls:

        print $subref->();
        print $objref->method();

Now the leading C<$> no longer indicated the type of value returned.
And in beginners' Perl classes across the land there arose a great
wailing and a gnashing of teeth.

Perl 6 returns us to a state of grace -- albeit a state of I<different>
grace --in which each variable type has One True Sigil, from which it
never strays.

In Perl 6, a scalar I<always> has a leading C<$>, an array I<always>
has a leading C<@> (even when accessing its elements or slicing it),
and a hash I<always> has a leading C<%> (even when accessing its
entries or slicing it).

In other words, the sigil no longer (sometimes) indicates the type of
the resulting value. Instead, it (always) tells you exactly what kind
of variable you're messing about with, regardless of what kind of
messing about you're doing.

The C<insert> subroutine has several examples of this new syntax. The
most obvious are in the autovivification of an empty subtree at the
start of the subroutine:

            unless ($tree) {
                my %node;
                %node{LEFT}   = undef;
                %node{RIGHT}  = undef;
                %node{VALUE}  = $val

Even though we're accessing the C<%node> hash's entries, the variable
retains its C<%> sigil and the hash access braces are simply appended
to the complete variable name.

Likewise, to access the element of an array, we simply append the
array-access square brackets to the variable name: C<@array[1]>. This
is a significant departure from Perl 5 syntax. In Perl 5, C<@array[1]>
is a one-element slice of the C<@array> array; in Perl 6, it's a direct
single element access (no slicing involved).

This means, of course, that Perl 6 will require some revised
array-slicing semantics. Larry's planning to take that opportunity to
beef up Perl's slicing facilities and provide for arbitrary slicing and
dicing of multidimensional arrays. But that's for a future Apocalypse.

For the time being, it's enough to know that, if you put a single
scalar in the square brackets, you get a single element look-up; if you
put a list in the brackets, you get a slice.

=head1 Haven't we met before? (part 2)

The last assignment to a C<%node> entry has one other little twist. The
(copy of the) value being assigned is also ascribed a C<Found>
property, initialized to the value zero:

                %node{VALUE}  = $val is Found(0);

Once again, that works because, when a property is set using C<is>, the
result of the operation is the left operand (in this case C<$val>),
I<not> the new value of the property.

Indeed, although we glossed over it at the time, that's the only reason
the:

        while (<$ARGS prompts("Search? ")>) {

syntax actually worked. The expression C<$ARGS prompts("Search? ")> set
the handle's prompt, and then returned C<$ARGS>, which became the
operand of the diamond operator, resulting in a prompt-and-read
operation through that handle.

=head1 We don't need no stinking backslashes

Once the new C<%node> is initialized, a reference to it needs to be
assigned to the variable that was passed as the first argument (if it's
not clear why, see section 12.3.2 of I<Object Oriented Perl> for a
detailed explanation of this tree-manipulation technique).

In Perl 5, modifying an original argument would require an assignment
to C<$_[0]> (i.e. C<@_[0]> in Perl 6), but because we declared C<$tree>
to be C<rw>, we can assign directly to it and have the original
argument change appropriately:

                $tree = %node;

I<Oops,> (you're probably thinking), I<he just fell victim to one of
the Classic Blunders: In a scalar context, a hash evaluates to the
ratio of used buckets to allocated buckets!>

In Perl 5 maybe, but in Perl 6 that near-useless behaviour has gone the
way of the powdered wigs, buggy whips, and DSL providers. Instead, when
evaluated in a scalar context, a hash (or an array) returns a reference
to itself. So the above line of code works correctly.

I<Okay,> (you're now wondering), I<if arrays do that too, how do I get
the length of an array???> The answer is that in a numeric context an
array reference now evaluates to the length of the array. So the
translation of the Perl 5 code:

        while (@queue > 0) {    # scalar eval of @queue yields length

is:

        while (@queue > 0) {    # scalar eval of @queue yields ref to array
                                # ref to array in numeric context yields length

Similarly, in a boolean context, an array evaluates true if it contains
any elements, so the translation of the Perl 5 code:

        while (@queue) {    # scalar eval of @queue yields length

is:

        while (@queue) {    # boolean eval of @queue yields true if not empty

Cunning, huh?

=head1 You say C<%node{VALUE}>, but I say C<$tree{VALUE}>

When we were loading up the new node, we wrote C<%node{VALUE}> to
access its C<'VALUE'> entry. Now that C<$tree> holds a reference to
C<%node>, we need some way of accessing the same entry.

In Perl 5 that would be:

        $tree->{VALUE}        # Perl 5 entry access through hash ref in $tree

And since C<< -> >> is spelled C<.> in Perl 6, that becomes:

        $tree.{VALUE}         # Perl 6 entry access through hash ref in $tree

However, since the direct hash access syntax now uses a completely
different sigil -- C<%node{VALUE}> -- the C<.> isn't needed for
disambiguation there and hence can be made optional:

        $tree{VALUE}          # Perl 6 entry access through hash ref in $tree

And that's the usual way accesses to hash references will be written:

            if    ($tree{VALUE} > $val) { insert($tree{LEFT},  $val) }
            elsif ($tree{VALUE} < $val) { insert($tree{RIGHT}, $val) }
            else                        { warn "dup insert of $val\n" }
        }

This is actually far I<less> confusing than it might at first seem. For
example, back in Haven't we met before? (part 1), did you notice that:

        if (my $node = search($root, $_)) {
            print "Found $_ at $node: $node{VALUE}\n"

already used this new syntax?

In Perl 5 that would have been a (very common) error -- the second line
would print an entry of C<%node>, when we actually wanted an entry of
C<%{$node}>. But in Perl 6, it just Does What We Mean.

And, of course, access through other kinds of references will also
allow the C<.> to be omitted: C<$arr_ref[$index]> and
C<$sub_ref(@args)>.

Here's a handy conversion table:

        Access through...       Perl 5          Perl 6
        =================       ======          ======
        Scalar variable         $foo            $foo
        Array variable          $foo[$n]        @foo[$n]
        Hash variable           $foo{$k}        %foo{$k}
        Array reference         $foo->[$n]      $foo[$n] (or $foo.[$n])
        Hash reference          $foo->{$k}      $foo{$k} (or $foo.{$k})
        Code reference          $foo->(@a)      $foo(@a) (or $foo.(@a))
        Array slice             @foo[@ns]       @foo[@ns]
        Hash slice              @foo{@ks}       %foo{@ks}

=head1 A good, old-fashioned show

The C<show> subroutine illustrates the optional nature of parameter
lists. Here we omit the parameter specifications entirely, and get the
good old familiar
"take-any-number-of-arguments-and-stick-them-all-in-C<@_>" semantics.

Indeed, apart from its DWIM-ier array access syntax, the C<show>
subroutine is vanilla Perl 5:

        sub show {
            return unless @_[0];
            show(@_[0]{LEFT}, @_[1]) unless @_[1] == $post;
            show(@_[0]{RIGHT},@_[1])     if @_[1] == $pre;
            print @_[0]{VALUE};
            show(@_[0]{LEFT}, @_[1])     if @_[1] == $post;
            show(@_[0]{RIGHT},@_[1]) unless @_[1] == $pre;
        }

And that, we believe, will be the normal experience when moving from 5
to 6: Perl will still be Perl...only slightly more so.

Of course, the C<show> subroutine is moderately funky Perl anyway, so
if symmetrically guarded repetitions of the left- and right- subtree
traversals aren't your maintenance dream, this would also be the ideal
place to use Perl's new I<case> statement.

But that won't be unveiled until Apocalypse 4, so if you could just
look at this little red light....<FLASH>...Thank-you.

=head1 Search me

The parameter list of the C<search> subroutine is interesting because
it's a hybrid of the old and new Perl semantics:

        sub search (HASH $tree is rw, *@_) {

Both parameter's are explicitly declared, but the second declaration
(C<*@_>) causes the remaining parameters to be collected in C<@_>.
There's nothing I<magical> about C<@_> there: if the second declaration
had been C<*@others>, the rest of the arguments would have turned up in
C<@others>.

The asterisk in the second parameter tells Perl 6 that the
corresponding argument position is a plain ol' list context, so that
any arguments there (or thereafter) should be treated as a single list
and assigned to the corresponding parameter variable. It's the
equivalent of the Perl 5 C<@> prototype.

In contrast, a parameter declaration of C<@param>, is the equivalent of
Perl 5's C<\@> prototype -- and explicitly requires an array variable
as the corresponding argument.

Notice that, because we started collecting arguments in C<@_> from the
I<second> parameter, the value we're looking for (i.e. the second
argument) is referred to as C<@_[0]>, not C<@_[1]>:

            return search($tree{@_[0]<$tree{VALUE} && "LEFT" || "RIGHT"}, @_[0])
                unless $tree{VALUE} == @_[0];

=head1 Haven't we met before? (part 3)

The second last line of C<search> is where all the Perl 6 action is.
Having worked out that we're already at the desired node, we're going
to return it. But we also need to increment its C<Found> property,
which we do like so:

            $tree{VALUE} is Found($tree{VALUE}.Found+1);

This highlights two of the three ways of accessing a property: the
read-write C<.> syntax, and the write-only C<is> operator.

If a property is accessed as if it were a method, its value can be set
by passing the new value as an argument. Whether such a value is passed
or not, the result of the operation is an alias (i.e. an lvalue) for
the property itself. So we could also increment the values's C<Found>
property like this:

        $tree{VALUE}.Found($tree{VALUE}.Found+1);

or, like this:

        $tree{VALUE}.Found++;

The C<is> syntax, on the other hand, can only set a property, because
the C<is> operation returns its left operand (the referent that owns
the property), not the value of property itself. This is often highly
useful, however, for last-minute property setting in a C<return>
statement:

        return $result is Verified;

Another very common usage is expected to be in returning zero-but-true
and non-zero-but-false values:

        sub my_system ($shell_command) {
                ...
                return $error is false if $error;
                return 0 is true;
        }

The I<third> way of accessing a property is via the C<prop>
meta-property, which returns a reference to a hash containing all the
properties of a referent:

        $tree{VALUE}.prop{Found}++;

You can also use this feature to list I<all> the properties that a
referent has been ascribed:

        for (keys %{$tree.prop}) {
            print "$_: $tree{VALUE}.prop{$key}\n";
        }

By the way, in Apocalypse 2, Larry waggishly referred to the C<prop>
meta-property as C<btw>, but with the help of modern therapeutic
techniques, he's now gotten over the idea.

=head1 Coda on an earlier theme

This article has illustrated several important new features that Perl 6
will provide. But don't let all that newness scare you. Perl has always
offered the ability to code at your own level and in the style that
suits you best. That's not going to change, even if the style that
suits you best is Perl 5.

Almost every new feature covered here will be I<optional>, and if you
choose not to use them, you can still write the same program in a
manner that is I<very> close to Perl 5. Like so:

        use strict;
        use warnings;
        my ($root, $n);
        while ($n++ < 20) { insert($root, int rand 1000) }
        my ($pre, $in, $post) = (0..2);
        print "Pre order:  "; show($root,$pre);  print " \n";
        print "In order:   "; show($root,$in);   print " \n";
        print "Post order: "; show($root,$post); print " \n";
        for (print "Search? "; <$ARGS>; print "Search? ") {
            chomp;
            if (my $node = search($root, $_)) {
                print "Found $_ at $node: $node{VALUE}\n";
                print "(again!)\n" if $node{FOUND} > 1;
            }
            else {
                print "No $_ in tree\n";
            }
        }
        exit;
        #########################################
        sub insert {
            unless (@_[0]) {
                @_[0] = { LEFT  => undef, RIGHT => undef,
                          VALUE => @_[1], FOUND => 0,
                        };
                return;
            }
            if    (@_[0]{VALUE} > @_[1]) { insert(@_[0]{LEFT},  @_[1]) }
            elsif (@_[0]{VALUE} < @_[1]) { insert(@_[0]{RIGHT}, @_[1]) }
            else                         { warn "dup insert of @_[1]\n"  }
        }
        sub show  {
            return unless @_[0];
            show(@_[0]{LEFT}, @_[1]) unless @_[1] == $post;
            show(@_[0]{RIGHT},@_[1])     if @_[1] == $pre;
            print @_[0]{VALUE};
            show(@_[0]{LEFT}, @_[1])     if @_[1] == $post;
            show(@_[0]{RIGHT},@_[1]) unless @_[1] == $pre;
        }
        sub search {
            return unless @_[0];
            return search(@_[0]{@_[1]<@_[0]{VALUE} && "LEFT" || "RIGHT"}, @_[1])
                unless @_[0]{VALUE} == @_[1];
            @_[0]{FOUND}++;
            return @_[0];
        }

In fact, that's only 40 characters (out of 1779) from being pure Perl
5. And almost all of those differences are C<@>'s instead of C<$>'s at
the start of array element look-ups.

98% backwards compatibility even without an automatic p52p6
translator...pretty slick!
