Re: Run time dispatch on ~~
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 ~~
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 ~~
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 ~~
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 ~~
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 ~~
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