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

Reply via email to