Is there a convenient way to replicate R's concept of 'named vectors' in Raku, possibly using Mixins?
Recent questions on StackOverflow pertaining to Mixins in Raku have piqued my interest as to whether Mixins can be applied to replicate features present in other programming languages.
For example, in the R-programming language, elements of a vector can be given a name (i.e. an attribute), which is very convenient for data analysis. For an excellent example see: "How to Name the Values in Your Vectors in R" by Andrie de Vries and Joris Meys, who illustrate this feature using R
's built-in islands
dataset. Below is a more prosaic example (code run in the R-REPL):
> #R-code
> x <- 1:4
> names(x) <- LETTERS[1:4]
> str(x)
Named int [1:4] 1 2 3 4
- attr(*, "names")= chr [1:4] "A" "B" "C" "D"
> x
A B C D
1 2 3 4
> x[1]
A
1
> sum(x)
[1] 10
Below I try to replicate R
's 'named-vectors' using the same islands
dataset used by de Vries and Meys. While the script below runs and (generally, see #3 below) produces the desired/expected output, I'm left with three main questions, at bottom:
#Raku-script below;
put "Read in data.";
my $islands_A = <11506,5500,16988,2968,16,184,23,280,84,73,25,43,21,82,3745,840,13,30,30,89,40,33,49,14,42,227,16,36,29,15,306,44,58,43,9390,32,13,29,6795,16,15,183,14,26,19,13,12,82>.split(","); #Area
my $islands_N = <<"Africa" "Antarctica" "Asia" "Australia" "Axel Heiberg" "Baffin" "Banks" "Borneo" "Britain" "Celebes" "Celon" "Cuba" "Devon" "Ellesmere" "Europe" "Greenland" "Hainan" "Hispaniola" "Hokkaido" "Honshu" "Iceland" "Ireland" "Java" "Kyushu" "Luzon" "Madagascar" "Melville" "Mindanao" "Moluccas" "New Britain" "New Guinea" "New Zealand (N)" "New Zealand (S)" "Newfoundland" "North America" "Novaya Zemlya" "Prince of Wales" "Sakhalin" "South America" "Southampton" "Spitsbergen" "Sumatra" "Taiwan" "Tasmania" "Tierra del Fuego" "Timor" "Vancouver" "Victoria">>; #Name
"----".say;
put "Count elements (Area): ", $islands_A.elems; #OUTPUT 48
put "Count elements (Name): ", $islands_N.elems; #OUTPUT 48
"----".say;
put "Create 'named vector' array (and output):\n";
my @islands;
my $i=0;
for (1..$islands_A.elems) {
@islands[$i] := $islands_A[$i] but $islands_N[$i].Str;
$i++;
};
say "All islands (returns Area): ", @islands; #OUTPUT: returns 48 areas (above)
say "All islands (returns Name): ", @islands>>.Str; #OUTPUT: returns 48 names (above)
say "Islands--slice (returns Area): ", @islands[0..3]; #OUTPUT: (11506 5500 16988 2968)
say "Islands--slice (returns Name): ", @islands[0..3]>>.Str; #OUTPUT: (Africa Antarctica Asia Australia)
say "Islands--first (returns Area): ", @islands[0]; #OUTPUT: 11506
say "Islands--first (returns Name): ", @islands[0]>>.Str; #OUTPUT: (Africa)
put "Islands--first (returns Name): ", @islands[0]; #OUTPUT: Africa
put "Islands--first (returns Name): ", @islands[0]>>.Str; #OUTPUT: Africa
Is there a simpler way to write the Mixin loop
...$islands_A[$i] but $islands_N[$i].Str;
? Can the loop be obviated entirely?Can a
named-vector
ornvec
wrapper be written aroundput
that will return(name)\n(value)
in the same manner that R does, even for single elements? Might Raku'sPair
method be useful here?Related to #2 above, calling
put
on the single-element@islands[0]
returns the nameAfrica
not the Area value11506
. [Note this doesn't happen with the call tosay
]. Is there any simple code that can be implemented to ensure thatput
always returns (numeric)value
or always returns (Mixin)name
for all-lengthed slices of an array?
-
Recent related Raku 'Mixin' questions on SO: 1. Is there a straightforwad way to check if something is a mixin? and 2. Is there a way to access mixed-in components when the original variable has a default coercion? – jubilatious1 Apr 4 at 1:16