moonscript icon indicating copy to clipboard operation
moonscript copied to clipboard

Named slices

Open bpj opened this issue 3 years ago • 2 comments

One thing I really like in Perl is hash slices, i.e. in Perl you can do this:

my %map = (a => 'A', b => 'B', c => 'C', d => 'D');

my @slice = @map{'a', 'c', 'b'};

say "@slice"; # --> "A C B"

Which can be done like this in current MoonScript:

map = {a: 'A', b: 'B', c: 'C', d: 'D'}
slice = [map[k] for k in *{'a','c','b'}]

In more recent versions of perl you can even do this:

my %map_slice = %map{'a','b','c'};
say join(" ", %map_slice)
# Will print something like this:
# c C a A b B

which in current MoonScript can be done with

map_slice = {k,map[k] for k in *{'a','c','b'}}

The "problem" is that I keep wanting to use these syntaxes:

slice = map[:a, :c, :b]
map_slice = map{:a, :c, :b}

The distinction between foo[...] and foo{...} is admittedly a bit un-Lua-ish, but in exactly the same way as MoonScript's list vs. table comprehensions!

It may be just me, but I think that those syntaxes would be nice to have!

Meanwhile I have written functions based on the traditional way of doing the map slice in Perl:

sub mslice (\%@) {
    my $map = shift;
    my @keys = grep { exists $map->{$_} } @_;
    my %slice;
    @slice{@keys} = @{$map}{@keys};
    return \%slice;
}
$map_slice_ref = mslice %map, qw(a b c);

Thus

aslice = (t, ...) ->
  [t[k] for k in *{...}]
  
mslice = (t, ...) ->
  {k,t[k] for k in *{...}}
  
slice = aslice map, 'a', 'c', 'b'
map_slice = mslice map, 'a', 'b', 'c'

These are not much more to type than the suggested syntaxes but are far less self-explanatory, I think.

bpj avatar Jul 26 '20 16:07 bpj

Any reason for that Perl mslice function except dor non-existent keys?

vendethiel avatar Jul 26 '20 17:07 vendethiel

Before perl 5.20 key—value slices weren't supported, so you had to use a function. That's still true for modules which want to support earlier versions.

bpj avatar Jul 28 '20 17:07 bpj