Re: Run time dispatch on ~~

2006-07-14 Thread Aaron Sherman
On Fri, 2006-07-14 at 00:08 +0300, Yuval Kogman wrote:

 Also, sometimes i am matching on behalf of my caller, this is very
 common in dispatch algorithms, or things like tree visitors:
 
   my @list = $tree.filter_children( $match ); # very generic and useful

It's really the fact that that's a method that hoses everything. There's
essentially no way to compile-time dispatch that, so even macros won't
help you grr.

No, you've got me. There needs to be a way to do that, but oh dear it's
going to be confusing, and as ever, I worry about those who will use
this sort of thing poorly or mistakenly, and then rant on about how Perl
is write-only.

Perhaps the solution is not code, but documentation. Perhaps if we make
a clean break between comparison and matching in the docs, and push
people away from non-regex/string-~~ until they understand its
implications, we can head off much of the lossage.

For example (modified S03 Smart matching section without the table):

=head1 Smart matching

Smart matching is the process of asking, does thing Ia conform to the
specification of Ib? The most common reason to want to do this is to
match a string against a regex:

 if $s ~~ /^\d+$/ { ... }

But smart matching is also performed by given/when for switch-like behavior:

 given $s {
   when 'Apple' { ... }
   when 'Pear'  { ... }
   default  { die No fruit! }
 }

Notice that the specification can also be a string, as above, but because
Ceqv and C~~ mean the same thing in this context, it is clearer, when
writing a single expression to explicitly use Ceqv:

 if $a eqv $b { ... }

The right-hand side of C~~ (the specification) always controls the
nature of the matching, so care must be taken when matching. Do not
think of this as simple comparison where the arguments are considered
peers.

Here is the current table of smart matches with respect to $_ and $x
as they would be used here:

 given $_ {
   when $x {...}
 }

or

 $_ ~~ $x

The list is intended to reflect forms that can be recognized at
compile time.  If none of these forms is recognized at compile time, it
falls through to do MMD to C infix:~~() , which presumably
reflects similar semantics, but can finesse things that aren't exact
type matches.  Note that all types are scalarized here.  Both C~~
and Cgiven/Cwhen provide scalar contexts to their arguments.
(You can always hyperize C~~ explicitly, though.)

Both C$_ (the value) and C$x (the match specification) here are
potentially references to container objects.
And since lists promote to arrays in scalar context, there need be no
separate entries for lists.

(table goes here)

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: Run time dispatch on ~~

2006-07-14 Thread Dr.Ruud
Aaron Sherman schreef:

  given $_ {
when $x {...}
  }

 or

  $_ ~~ $x

Can that be written as .~~ $x?

-- 
Affijn, Ruud

Gewoon is een tijger.




Re: Run time dispatch on ~~

2006-07-14 Thread Larry Wall
On Fri, Jul 14, 2006 at 04:34:26PM +0200, Dr.Ruud wrote:
: Aaron Sherman schreef:
: 
:   given $_ {
: when $x {...}
:   }
: 
:  or
: 
:   $_ ~~ $x
: 
: Can that be written as .~~ $x?

No, but you might just possibly get away with writing:

.infix:~~($x)

assuming that the $_.foo($x) SMD eventually fails over to foo($_,$x) MMD.
But that doesn't seem to be much of an improvement over when $x.

Larry


Re: Run time dispatch on ~~

2006-07-14 Thread Dr.Ruud
Larry Wall schreef:
 Dr.Ruud:
 Aaron Sherman:

  $_ ~~ $x

 Can that be written as .~~ $x?

 No, but you might just possibly get away with writing:

 .infix:~~($x)

 assuming that the $_.foo($x) SMD eventually fails over to foo($_,$x)
 MMD. But that doesn't seem to be much of an improvement over when
 $x.

OK, thanks. Is it ever useful for an SMD to fail over to MMD?

-- 
Affijn, Ruud

Gewoon is een tijger.




Run time dispatch on ~~

2006-07-13 Thread Aaron Sherman
I'm told that I did a terrible job of making my point in the === thread,
and nothingmuch asked me on IRC to re-state my concerns. I'll do so
briefly, and then give examples. Please do have a look at the examples,
just in case I'm not clear.

Overview:

~~ is great. It matches on all kinds of useful right-hand-sides like
regexes, strings, methods, your neighbor's kids, you-name-it.

The only problem that I have is ~~ matching against an unknown type
(Any~~Any). In this case, the programmer cannot know what it is that
they're getting themselves into, and for the life of me, I can't see why
Perl would do anything other than an only slightly smart comparison
there, since that's obviously what the programmer had in mind.

However, S03 specs that ~~ will do a run-time dispatch based on the type
of that value at the time. Matching Arrays (@~~@) is just a
hyperoperated case of the same problem, except for the case where the
array on the right-hand-side can be typed at compile-time or is a list
that can be coerced painlessly into such a typed array. Then there's no
dispatch at run-time.

Solution:

Ok, so first let me re-propose my solution: Any~~Any and @~~@ are
compile-time dispatched to =~= and =~= respectively (no, I'm not
married to the name, and perhaps eqv is better for this, I don't know),
which has some smarts about comparing values in meaningful ways, and
which programmers know to override if they really need special matching
semantics, but basically is just a very slightly smarter ===. Regexes
are compared, not executed. Code is compared, not executed.

Examples:

Now, let's look at some of the good that ~~ does for us:

$a ~~ Some string # sameness
$a ~~ 5 # sameness
$a ~~ -{...}   # test
$a ~~ /.../ # regex matching

That's great, and we don't want to mess with any of it.

But, then we have:

$a ~~ $b# uh... something

We can't even say what it does, much less why it's useful. It does
match whatever that is. Sure, it's great for implementing your own ~~,
but that's about it.

The even worse:

@a ~~ @b# uh... lots of something

looks like array comparison to the casually misinformed user, but is
actually a run-time, hyperized vector dispatch...

Now, I do think people will want to:

@a ~~ ( /^\d+$/, /^\w+$/, /^\s+$/ )

but we can coerce that into a typed array at compile time, so there's no
problem.

Going with my suggestion would mean that ~~ is still very powerful, just
not opaque. You would have to ask for it to activate a particular
superpower by giving it a right-hand-side that has a type, or expect a
fairly mundane comparison to be performed.

The _security_ implications will likely get sorted out, but I still
forsee some major end-user bogglage when $a~~$b is true, even though
they have no relationship to each other that was obvious to the
programmer who wrote the statement.

Keep in mind that if you have an Any and you want to match against it
smartly, you can always request your poison:

$a ~~ ($b as Regex)

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
We had some good machines, but they don't work no more. -Shriekback




Re: Run time dispatch on ~~

2006-07-13 Thread Yuval Kogman
On Thu, Jul 13, 2006 at 15:44:33 -0400, Aaron Sherman wrote:

 Now, let's look at some of the good that ~~ does for us:
 
   $a ~~ Some string # sameness
   $a ~~ 5 # sameness
 $a ~~ -{...}   # test
 $a ~~ /.../ # regex matching
 
 That's great, and we don't want to mess with any of it.
 
 But, then we have:
 
   $a ~~ $b# uh... something


One compelling reason to have them behave exactly the same is to
allow refactoring.

If i'm using the same pattern on several inputs i'd like to maybe
delegate this to a helper sub that will actually run the ~~ for me,
in some way, and i'd like 100% compatibility.

Also, sometimes i am matching on behalf of my caller, this is very
common in dispatch algorithms, or things like tree visitors:

my @list = $tree.filter_children( $match ); # very generic and useful


-- 
  Yuval Kogman [EMAIL PROTECTED]
http://nothingmuch.woobling.org  0xEBD27418



pgp8KEQiTHBTj.pgp
Description: PGP signature