On Mon, Feb 18, 2008 at 04:22:57PM -0600, brian d foy wrote: : This is actually a bug from Perl 5, but Perl 5's given is supposed to : act like Perl 6's given.
Unfortunately, "supposed to" is pretty far off the mark in this case... Perl 5's switch differs from Perl 6's in several significant ways. First, it copied an old design when smartmatching was symmetrical, which it hasn't been for some time in Perl 6. The design of how arrays match has changed as well. (They match as a whole in Perl 6, and you must use any(@array) to match against the individual array elements. Finally, there are just quite a few things that cannot be done the same way in Perl 5 because of the fundamentally different way it parses and treats various object references in scalar context. : The long post is in use.perl: : : http://use.perl.org/~brian_d_foy/journal/35682 : : I was playing with a when condition that used a logical operator to see : if the topic was both an element of an array and a key of a hash: : : given( $foo ) { : when( @array && %hash ) { ... } : } : : I thought that should acting like two smart matches: : : given( $foo ) { : when( (@array ~~ $_) && (%hash ~~ $_) ) { ... } : } : : In Perl 5.10.0, it's acting like one smart match, which I'm pretty sure : is a bug: : : given( $foo ) { : when( ( scalar @array and scalar %hash ) ~~ $_) ) { ... } : } which is exactly what I would expect from Perl 5, unless when is really a very intelligent macro of some sort. As far as I know Perl 5's when has no clue how to distribute a smartmatch. : Perl 5's perlsyn talks about smart matching with logical operators, but : I don't see that in S04 (or anywhere else). Knowing what is supposed to : happen in Perl 6 would help me fix the Perl 5.10 version. : : So what would Perl 6 do (WWP6D) ? :) Certainly nothing like you'd expect from the P5 implementation. :) To see the exact semantics of smartmatching in P6, I highly recommend the section on "Smart Matching" in S03. To write what you want there, you'd need something like: when any(@array) & any(%hash.keys) {...} Actually, you might just get away with: when %hash & any(@array) {...} There can be no corresponding operation in Perl 5 because %hash in scalar context would not return the hash, but only its bucket count. And, of course, there's no "&" infix for "and" junctional logic. At best you could use when (all(\%hash, any(@array))) {...} assuming you've used something that pulls in Quantum::Superpositions or Perl6::Junctions. But even in Perl 6, "&&" or "and" is not going to autothread the junction for you, which is why you need "&" or all() to distribute the "~~" if you don't do it the explicit way by distributing $_ yourself: when %hash.:exists{$_} and @array.any ~~ $_ {...} Larry