Tom (>):
> In creating some new Perl 6 programs I've run across several instances
> I'm confused about, to wit:
>
> Example 1
> ---------------
>
>> my %h; say 'false' if !%h<a>:exists;
> Unexpected named parameter 'exists' passed

I can explain this one. But it's the kind of explanation that makes a
person sadder, not happier.

Adverbs like `:exists` latch onto a preceding operator according to a
rule described below. The operator you want it to latch onto is the
postcircumfix `<a>` indexing of `%h`. The operator it *does* latch on
to is the prefix `!`. That's not what a sane human reader expects, but
that's what happens.

How does it happen? Here's the rule for what an adverb latches onto:
it looks back at the preceding expression, views it as a tree, and
picks the "top" node, that is, whatever operator is holding the rest
of the expression.

Without the `!`, the top node is `<a>`. With the `!`, the top node is `!`.

This is slightly easier to see if we convert the expression the adverb
is considering to Lisp form:

(prefix:<!> (postcircumfix:<< <> >> %h "a"))

The fact that the "prefix:<!>" ends up being first in Lisp form means
that it's the top node in the expression tree.

This also means that one way to make this problem go away is to add
extra parentheses, because that again puts `<a>` at the top by
shutting out `!` from consideration:

    $ perl6 -e 'my %h; say "false" if !(%h<a> :exists)'
    false

Personally, I find that while the "top node" rule always perfectly
explains the behavior of adverbs in retrospect, it's not a natural
rule to use, and it's downright refactoring-hostile. It sows distrust
in one's ability to just add a `!` somewhere and being able to predict
the result.

I think I would much prefer adverbs to latch onto the textually last
operator. (But in saying this, I realize that I might be unaware of
some terribly important use case for adverbs that this would
preclude.)

Of course, all this is moot if you just take lizmat++'s advice and do
:!exists. :)

// Carl

Reply via email to