Author: larry
Date: Fri Dec 22 20:29:46 2006
New Revision: 13498
Modified:
doc/trunk/design/syn/S03.pod
doc/trunk/design/syn/S12.pod
Log:
Attempts to simplify and rationalize smartmatch semantics. Run-time semantics
of ~~ are now severely limited; no recursion to ~~ is used, and final fallback
is a single multi dispatch that is normally expected to failover to ===.
Modified: doc/trunk/design/syn/S03.pod
==============================================================================
--- doc/trunk/design/syn/S03.pod (original)
+++ doc/trunk/design/syn/S03.pod Fri Dec 22 20:29:46 2006
@@ -12,9 +12,9 @@
Maintainer: Larry Wall <[EMAIL PROTECTED]>
Date: 8 Mar 2004
- Last Modified: 20 Dec 2006
+ Last Modified: 22 Dec 2006
Number: 3
- Version: 78
+ Version: 79
=head1 Changes to Perl 5 operators
@@ -596,56 +596,63 @@
=head1 Smart matching
-Here is the current table of smart matches.
-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 C<given>/C<when> provide scalar contexts to their arguments.
-(You can always hyperize C<~~> explicitly, though.) So both C<$_>
-and C<$x> here are potentially references to container objects.
-And since lists promote to arrays in scalar context, there need be no
-separate entries for lists.
+Below is the current table of smart matches. The list is intended
+to reflect forms that can be recognized at compile time. To avoid
+explosion of options, the following types are remapped for the
+compile-time lookup only:
+
+ Actual type Use entries for
+ =========== ===============
+ List Seq Array
+ KeySet KeyBag KeyHash Hash
+ .{Any} .<string> .[number] .method
+ Class Subset Enum Role Type
+ Subst Regex
+ Buf Char Str
+ Int UInt etc. Num
+
+Note that all types are scalarized. Both C<~~> and C<given>/C<when>
+provide scalar contexts to their arguments. (You can always
+hyperize C<~~> explicitly, though.) So both C<$_> and C<$x> here
+are potentially container objects. The first possible match in this
+table is used. By definition all normal arguments can be matched to
+at least one of these entries.
$_ $x Type of Match Implied Matching Code
====== ===== ===================== =============
Any Code:($) scalar sub truth match if $x($_)
+ Any .method method truth* match if $_.method
+
Hash Hash hash keys identical sets match if $_.keys === $x.keys
- Hash any(Hash) hash key intersection match if exists $_{any($x.keys)}
Hash Array hash value slice truth match if $_{any(@$x)}
- Hash any(list) hash key slice existence match if exists $_{any(list)}
- Hash all(list) hash key slice existence match if exists $_{all(list)}
- Hash Regex hash key grep match if any($_.keys) ~~ /$x/
- Hash Any hash entry existence match if exists $_{$x}
- Hash .{Any} hash element truth* match if $_{Any}
- Hash .<string> hash element truth* match if $_<string>
- Array Array arrays are comparable match if $_ »~~« $x
- Array any(list) list intersection match if any(@$_) ~~ any(list)
- Array Regex array grep match if any(@$_) ~~ /$x/
+ Hash Junction hash key slice existence match if $_.exists($x)
+ Hash Regex hash key grep match if any($_.keys) === /$x/
+
+ Array Array arrays are comparable match if $_ »===« $x
+ Array Junction list intersection match if any(@$_) === $x
+ Array Regex array grep match if any(@$_) === /$x/
Array Num array contains number match if any($_) == $x
- Array Str array contains string match if any($_) eq $x
+ Array Str array contains string match if any($_) eqv $x
Array Buf array equivalent to buf match if $_ eqv Array($x)
Array Set array equivalent to set match if Set($_) === $x
- Array Any array contains item* match if any($_) === $x
- Array .[number] array element truth* match if $_[number]
+
Num NumRange in numeric range match if $min <= $_ <= $max
- Str StrRange in string range match if $min le $_ le $max
- Any Range in range match if $min !after $_ !after
$max
- Capture Signature parameter binding match if $cap can bind to $sig
+
Code Signature signature compatibility* match if $_ is a subset of $x
Signature Signature signature compatibility match if $_ is a subset of $x
- Any Code:() simple closure truth* match if $x() (ignoring $_)
- Any Class class membership match if $_.does($x)
- Any Role role playing match if $_.does($x)
- Any Num numeric equality match if $_ == $x
- Any Str string equality match if $_ eq $x
- Any .method method truth* match if $_.method
+
+ Hash Any hash entry existence match if exists $_{$x}
+ Array Any array contains item* match if any($_) === $x
+ Any Signature parameter binding match if $_ can bind to $x
+ Any Range in range match if [!after]
$x.min,$_,$x.max
+ Any Type type membership match if $_.does($x)
Any Regex pattern match match if $_ ~~ /$x/
- Any subst substitution match* match if $_ ~~ subst
+ Any Num numeric equality match if $_ == $x
+ Any Str string equality match if $_ eqv $x
+ Any Code:() simple closure truth* match if $x() (ignoring $_)
Any boolean simple expression truth* match if $x.true given $_
Any undef undefined match unless defined $_
- Any Whatever default match anything
+ Any * default match anything
Any Any run-time dispatch match if infix:<~~>($_, $x)
Matches marked with * are non-reversible, typically because C<~~> takes
@@ -693,11 +700,22 @@
can return a list of matched substrings, as in Perl 5. The complete
list of such operands is TBD.
-It has not yet been determined if run-time dispatch of C<~~> will
-attempt to emulate the compile-time precedence table before reverting
-to MMD, or just go directly to MMD. There are good arguments for
-both sides, and we can decide when we see more examples of how
-it'll work out.
+The C<~~> operator is intended primarily for compile-time resolution,
+and if the types of the operands resolve at compile time according
+to the table above, any existing C<< infix:<~~> >> routines are
+completely ignored. If the types cannot be matched at compile time,
+one attempt is made to multiply dispatch to all C<< infix:<~~> >>
+infix definitions. If this fails, the most generic multi definition
+of C<< infix:<~~> >> calls C<===> to match the two variables exactly
+according to their type. In general you should just rely on this
+and not attempt to define your own C<< infix:<~~> >> operators,
+because complexifying the run-time semantics of C<~~> is not doing
+anyone a favor. This is one of those mechanisms we provide knowing
+that people I<will> shoot themselves in the foot with it. However,
+we also recognize that we probably aren't aware of all useful forms of
+pattern matching, especially the ones that haven't been invented yet.
+We choose to make it possible to add such forms using C<~~>. Please
+construe this as future proofing, not idiot proofing.
For the purpose of smartmatching, all C<Set> and C<Bag> values are
considered to be of type C<KeyHash>, that is, C<Hash> containers
Modified: doc/trunk/design/syn/S12.pod
==============================================================================
--- doc/trunk/design/syn/S12.pod (original)
+++ doc/trunk/design/syn/S12.pod Fri Dec 22 20:29:46 2006
@@ -1731,7 +1731,8 @@
$obj.HOW.does(Dog)
which is true if C<$obj> either "does" or "isa" C<Dog> (or "isa"
-something that "does" C<Dog>).
+something that "does" C<Dog>). If C<Dog> is a subset, any additional
+C<where> constraints must also evaluate true.
Unlike in Perl 5 where C<.can> returns a single C<Code> object,
Perl 6's version of C<.HOW.can> returns a "WALK" iterator for a