develooper Front page | perl.perl5.porters | Postings from June 2013

Re: key/value hash and index/valuse array slices syntax

Thread Previous | Thread Next
Aristotle Pagaltzis
June 11, 2013 17:22
Re: key/value hash and index/valuse array slices syntax
Message ID:
* Ruslan Zakirov <> [2013-06-11 14:05]:
> On Mon, Jun 10, 2013 at 2:27 PM, demerphq <> wrote:
> > Also what happens if I do:
> >
> > my $sub_hash= %hash{thing};
> >
> > does $sub_hash end up with the value 2 if "thing" existed, and with
> > the value 0 if it didn't?
> It end ups with value, not 2 or 0 and produce a warning
> (%hash{'thing'} is better written as $hash{'thing'}). As aslice and
> hslice, kvhslice returns list, so last element is assigned to
> $sub_hash which is value. I hate this "list" thing, but I'm for
> consistency.

Then immediately the question becomes, what does the following do?

    my %h = ( foo => 1 );
    my $e = %h{ "foo", "bar" };

Does it assign undef, or 1? (I surmise from later mails of yours that it
will assign undef – correct?)

* Leon Timmermans <> [2013-06-11 12:55]:
> One question I do have: what should it do with nonexistent keys? E.g.
> my %first = (a => 1, b => 2);
> my %second = %first{qw/a c/};
> Should %second now contain «c => undef», not no c at all? I think I'm
> currently leaning towards the latter, it seems like the more useful
> behavior to me.

Reluctant though I am, I feel that the right thing to do would be to
return `c => undef` from the slice. For one thing, it makes the
behaviour more regular and predictable. For another, it aligns with

    my @second = @first{qw/a c/};

and also

    my @first = (1) x 3;
    my @second = @first[0,9];

As well, it is not terribly difficult to get what you want by doing

    my %second = %first{ grep { exists $first{$_} } qw/a c/ };

which is easy to tuck away in a utility function in such as Hash::Util
as well. (The downside is that if your list of keys to copy is gigantic
then doing it this way instead of natively will cost measurably in terms
of both cycles and memory.)

More importantly, given hash slices that *omit* non-existent keys, it is
much harder to get the opposite behaviour. I cannot even think of any
sensible way to do it as an expression within the same statement, only
if I accept multiple statements, by doing such as

    my %second = %first{qw/a c/};
    @first{qw/a c/} = @first{qw/a c/};

* Ruslan Zakirov <> [2013-06-11 14:15]:
> If only we had op modifiers for such ops like we have for s/// and
> m///.

I think there are in Perl 6…

> Interesting thought is to make the following work like you want:
> my %second = exists %first{qw/a c/};

My first gut reaction is that I don’t like this at all. Overloading
existing things with new semantics without any systematic model, just
hacking together ad-hoc syntactic sugar, rarely makes a solid design. It
has a tendency to create strange corner cases not discovered for years,
that then turn out to have no clear resolution.

The approach of a keyword that modifies the slice operation does make
sense though. It’s how `exists` works too – which OT1H feels like an
integral part of the language’s character, though OTOH it is the lone
and sole bit of precedent we have on this count.

I would just rather mint a new keyword for this, or even a Hash::Util
function. (And I think that the parser hooks we have now even allow
writing such a function entirely outside core – no?)

But when I then go to think about what to call this keyword/function,
reusing `exists` seems like not necessarily a bad idea.

So my feelings on this are unclear.

Aristotle Pagaltzis // <>

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About