develooper Front page | perl.perl5.porters | Postings from August 2012

Re: fixing smartmatch just hard enough (and when, too)

Thread Previous | Thread Next
Eirik Berg Hanssen
August 17, 2012 05:07
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
On Fri, Aug 17, 2012 at 12:39 PM, Ed Avis <> wrote:

> Hmm, I understand the enthusiasm for magic junction types like 'any', since
> Perl 6 has them, and Perl 6 is somehow related to Perl 5 in some way, but I
> still feel that a simple 'in' operator would be far more straightforward.
>     if ($x in @a)
> Reading that you immediately see what it is going to do: the Perl
> interpreter
> will loop over each element in @a, do an equality comparison against $x
> (and
> I do entirely agree that string equality is the way to go) and stop when
> one
> is found.

  Ah, but if you have junctions, you are not restricted to one type of
equality, or even to equality tests.

  if ($x eq any(@a)

  if ($x < any(@a))

  if ($x =~ any(@a)) # assuming more Perl 6-like semantics, not the
Perl6::Junction implementation

  if (any(@a) =~ $x) # likewise

  if (any(@a)->accepts($x)) # likewise

  if ($x->accepts(any(@a))) # um ...

  ... and that's not even counting the other kinds of junctions ...

  But, as noted in my comments above, the Perl6::Junction implementation
does not do all that Perl 6 leads me to expect.

  I mean, hey, they currently don't even allow C<< any(2,3,4) * 2 == 8 >>,
do they?  See

  I don't think Perl6::Junction is ready for core.  I don't know how much
it would take to make junctions ready for core.

  I'm not even sure what semantics they should have.  As you say:

> The semantics of 'any' are much less straightforward, especially if you
> want
> to reason about memory usage.  Does creating the junction object involve
> taking
> a copy of the array?  More importantly, the 'any' junction cannot be used
> to
> implement a list membership test that works in all cases.
>     my $j1 = any(qw(a b));
>     my $j2 = any(qw(c d));
>     my $j = any($j1, $j2);
>     if ('a' eq any($j)) { say 'yes a' }
>     if ($j1 eq any($j)) { say 'yes j1' }
> Clearly, it cannot be the case that both 'a' and $j1 are members of the
> list
> ($j1, $j2).

  Clearly you don't mean to be testing with C<eq> here.  Both 'a' and $j1
are C<eq> to some member of the list C<< $j1, $j2 >>.  Since that's not
what you want, you'll have to write a test that DWYW.

  Conceptually – what is "list membership"?  C<< first { eqv($item, $_) }
@list >>, perhaps?  If so, how would you define that C<< eqv >>?
(Conceptually.  Worry about implementation later.)

  (Too terse?  Let me try to expand it:  If your C<eqv> is merely C<eq>,
you'll have to accept that stuff that overloads C<eq>, like junctions, have
their own idea of list membership.  If one item in your list is the $j1
junction above, this definition will grant both 'a' and $j1 membership in
your list.)


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About