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 variable... 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. Thoughts? Stuart