Here's a suggestion:

Outside of argument lists, both a=>'b' and :a('b') (and friends) are
equivalent, and denote an ordinary pair value.

Within argument lists, both of them are special syntactic forms for
named arguments:

  foo(a => 'b', :c<d>);  # both named args

If you want to pass pair values into a sub, either use an intermediate

  my $pair = :a<b>;
  foo($pair);  # not a named-arg call

...or else find new syntax to disambiguate:

  foo( (a => 'b') );  # ok, so maybe parens aren't such a good idea

Or just use existing language constructs:

  foo( do{a=>'b'}, {:c<d>;}() );  # both positional args

And if you explicitly want to use individual pair values as named
args, just exploit the fact that a pair can act like a one-element
hash, and splat it:

  my $arg = :echo<foxtrot>;
  foo( *%$arg );  # yes, I know it's three symbols

Then the only magic rule most people need to remember is:

  "Pair syntax denotes named-arg passing, but only in an arg list."

Magic can never be hidden (or happen accidentally), people can
explicitly circumvent the default behaviour, and the whole system has
very little inconsistency.



Reply via email to