HyperWhatever in subscripts
With v6.e we will get SemiLists, both in assiciative and positinal subscribts.
my @a = <1 2 3>;
my %h; %h{||@a} = 42;
say %h;
# OUTOUT: {1 => {2 => {3 => 42}}}
One could say, that the key of a Hash of Hashs or Array of Arrays is a list of keys. This opens the path to implement @array[**], which is NYI right now and %hash{**} which is undefined (and wrongly defaults to %hash{*}.
As it happens, a new beginner was struggling with `%hash.deepmap({ say 'only .value available here'; }). This is not the first and likely no the last time.
A prove of concept implementation in pure Raku (read: sloooow) as follows. https://gist.github.com/gfldex/f2be82aaf19ccaac4245ad35284ac102
use v6.e.PREVIEW;
my %hash := {
A => {
B => 1,
C => 2,
D => {
E => 3,
F => 4,
},
G => 5,
H => 6,
},
J => 7,
K => 8,
};
multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$kv!, *%other ) is raw {
gather for SELF.kv -> $key, $value {
$value ~~ Associative
?? $value.kv.map(&?BLOCK)
!! take slip $key, $value;
}
}
multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$k!, *%other ) is raw {
gather for SELF.kv -> $key, $value {
$value ~~ Associative
?? $value.kv.map(&?BLOCK)
!! take $key;
}
}
multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$v!, *%other ) is raw {
gather for SELF.kv -> $key, $value {
$value ~~ Associative
?? $value.kv.map(&?BLOCK)
!! take $value;
}
}
multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$tree!, *%other ) is raw {
gather for SELF.kv -> $key, $value {
$value ~~ Associative
?? (take slip $key, $value; $value.kv.map(&?BLOCK))
!! take slip $key, $value;
}
}
# This requires v6.e .
multi sub postcircumfix:<{ }>( \SELF, HyperWhatever, :$semi!, *%other ) is raw {
multi sub recurse(%hash) {
for %hash.kv -> $key, $value {
recurse $key, $value;
}
}
multi sub recurse($key is copy, Associative $value) {
for $value.kv -> $child-key, $child-value {
recurse slip($key, $child-key), $child-value
}
}
multi sub recurse($key, $value) {
take $key, $value
}
gather recurse(SELF);
}
say %hash{**}:kv; # (C 2 H 6 G 5 B 1 E 3 F 4 J 7 K 8)
say %hash{**}:k; # (C H G B E F J K)
say %hash{**}:v; # (2 6 5 1 3 4 7 8)
say %hash{**}:tree; # (A {B => 1, C => 2, D => {E => 3, F => 4}, G => 5, H => 6} C 2 H 6 G 5 B 1 D {E => 3, F => 4} E 3 F 4 J 7 K 8)
say %hash{**}:semi; # (((A C) 2) ((A H) 6) ((A G) 5) ((A B) 1) ((A D E) 3) ((A D F) 4) (J 7) (K 8))
for %hash{**}:semi -> ($deepkey, $value) {
say [$deepkey.join, %hash{||$deepkey}]; # [J 7]¶[K 8]¶[AG 5]¶[AH 6]¶[AC 2]¶[AB 1]¶[ADF 4]¶[ADE 3]¶
}
# mark is needed to disabiguate from the multi candidate in CORE
multi sub postcircumfix:<[ ]>( \SELF, HyperWhatever:D, :$mark! ) is raw {
gather SELF.deepmap(*.take)
}
multi sub postcircumfix:<[ ]>( \SELF, HyperWhatever:D, :$semi! ) is raw {
multi sub recurse(@array) {
for @array.kv -> $key, $value {
recurse $key, $value;
}
}
multi sub recurse($key is copy, Positional $value) {
for $value.kv -> $child-key, $child-value {
recurse slip($key, $child-key), $child-value
}
}
multi sub recurse($key, $value) {
take $key, $value
}
gather recurse(SELF);
}
my @array := [1, [2, [3]], 4, [5, 6]];
say @array[**]:mark; # (1 2 3 4 5 6)
for @array[**]:semi -> ($deepkey, $value) {
say $deepkey, ' -> ', @array[||$deepkey]; # 0 -> 1¶(1 0) -> 2¶(1 1 0) -> 3¶2 -> 4¶(3 0) -> 5¶(3 1) -> 6¶
}
Adding this as a module is hindered by the NYI candidate of @array[**] in CORE.
This proposal would remove a long standing NYI and allows iteration over LoL and HoH with ease.
It may be wise to think about a .deepmap({ say .key, .value;}, :kv) candidate to allow functional iteration.