Well, it seemed like a good idea when I started. However, I've run into an odd issue. Here's my simplified which doesn't work:
# bintree - binary tree demo program
# adapted from "Perl Cookbook", Recipe 11.15
# converted to modern Perl 6 by SF
use v6;
my (%root, $n);
for (1..1000).pick(2) {
say "Inserting $_";
insert(%root, $_);
say %root.perl;
}
say %root.keys;
say "Doom";
#########################################
sub insert(Hash $tree is rw, Int $val) {
unless $tree {
my %node;
%node<LEFT> = Hash;
%node<RIGHT> = Hash;
%node<VALUE> = $val ; # but Found(0);
say %node.perl;
$tree = %node;
say $tree.perl;
return;
}
if ($tree<VALUE> > $val) { insert($tree<LEFT>, $val) }
elsif ($tree<VALUE> < $val) { insert($tree<RIGHT>, $val) }
else { warn "dup insert of $val\n" }
}
And here's sample output:
Inserting 640
{"VALUE" => 640, "RIGHT" => Hash, "LEFT" => Hash}
{"VALUE" => 640, "RIGHT" => Hash, "LEFT" => Hash}
{}
Inserting 461
{"VALUE" => 461, "RIGHT" => Hash, "LEFT" => Hash}
{"VALUE" => 461, "RIGHT" => Hash, "LEFT" => Hash}
{}
If you match that back up with the says in the code, you'll see that a value is assigned to
$tree in insert, but that value does not make it back to the point where insert is called, despite $tree is rw. I've no idea why this should be the case, the same sort of code seems to work quite well in the REPL. Does anyone have an idea? Am I doing something stupid here, or did I just find a bug in a very-soon-to-be-obsolete version of Rakudo?Update: Not sure if this is just something I don't understand or a rakudobug. It turns out that the problem is the line
$tree = %node. If I use equals to assign something to $tree, that doesn't get passed back out. On the other hand, if I add hash keys directly to $tree, they are passed out just like I would expect.

I believe it's because $tree starts as a reference to %root, but then becomes a reference to %node. That assignment won't alter %root at all.
ReplyDeleteThis comment has been removed by the author.
ReplyDeletetry 'sub insert( %tree is ref ' - note changed sigil and trait, as well as lack of type qualifier. The % sigil adds an automatic 'where { * ~~ Associative }'
ReplyDelete