Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[svn:perl6-synopsis] r10215 - doc/trunk/design/syn

7 views
Skip to first unread message

la...@cvs.perl.org

unread,
Jul 14, 2006, 8:00:13 PM7/14/06
to perl6-l...@perl.org
Author: larry
Date: Fri Jul 14 17:00:12 2006
New Revision: 10215

Modified:
doc/trunk/design/syn/S03.pod

Log:
Differentiate === from eqv and clarify semantics.
Redefine cmp and add leg operator for old semantics.
Add ! metaoperator.
Fix random typos.


Modified: doc/trunk/design/syn/S03.pod
==============================================================================
--- doc/trunk/design/syn/S03.pod (original)
+++ doc/trunk/design/syn/S03.pod Fri Jul 14 17:00:12 2006
@@ -12,9 +12,9 @@

Maintainer: Larry Wall <la...@wall.org>
Date: 8 Mar 2004
- Last Modified: 12 Jul 2006
+ Last Modified: 14 Jul 2006
Number: 3
- Version: 46
+ Version: 47

=head1 Changes to existing operators

@@ -158,7 +158,7 @@

Operators that imply list operations are excluded: prefix C<@>,
prefix C<%> and infix C<xx>, for instance. Hyper operators are
-also excluded, but post-assigment forms such as C<SIMPLE += SIMPLE>
+also excluded, but post-assignment forms such as C<SIMPLE += SIMPLE>
are allowed.

All other forms imply parsing as a list assignment, which may or may not
@@ -317,22 +317,24 @@
side for definedness instead of truth. There is a low-precedence form,
too: C<err>.

-=item * Binary C<===> tests type and value correspondence: for two value types,
-tests whether they are the same value (eg. C<1 === 1>); for two reference
-types, checks whether they have the same identity value. For reference
-types that do not define an identity, the reference itself is used (eg. it
-is not true that C<[1,2] === [1,2]>, but it is true that C<@a === @a>).
-
-Any reference type may pretend to be a value type by defining a C<.id> method
-which returns a built-in value, i.e. an immutable object or a native value,
-as specified in S06.
-
-Because Perl 6 uses a false C<.id> to signify a non-instantiated prototype,
-all instances should arrange to return a C<.id> that boolifies to true.
-
-A class may also overload C<< infix:<===> >> for more efficient comparison of
-any two objects of that type, but it must return the same result as if
-the two identity values had been generated and compared.
+=item * Binary C<===> tests immutable type and value correspondence:
+for two value types (that is, immutable types), tests whether
+they are the same value (eg. C<1 === 1>); for two mutable types
+(object types), checks whether they have the same identity value.
+(For most such types the identity is simply the reference itself.)
+It is not true that C<[1,2] === [1,2]> because those are different
+Array objects, but it is true that C<@a === @a> because those are
+the same Array object).
+
+Any object type may pretend to be a value type by defining a C<.id>
+method which returns a value type that can be recursively compared
+using C<===>, or in cases where that is impractical, by overloading
+C<===> such that the comparison treats values consistently with their
+"eternal" identity. (Strings are defined as values this way despite
+also being objects.)
+
+(Because Perl 6 uses a false C<.id> to signify a non-instantiated prototype,
+all instances should arrange to return a C<.id> that boolifies to true.)

Two values are never equivalent unless they are of exactly the same type. By
contrast, C<eq> always coerces to string, while C<==> always coerces to
@@ -342,7 +344,44 @@
Note also that, while string hashes use C<eq> semantics by default,
object hashes use C<===> semantics.

-=item * Binary C<< => >> is no longer just a "fancy comma." It now
+=item * Binary C<eqv> tests equality much like C<===> does, but does
+so with "snapshot" semantics rather than "eternal" semantics. For
+top-level components of your value that are of immutable types, C<eqv>
+is identical in behavior to C<===>. For components of your value
+that are mutable, however, rather than comparing object identity using
+C<===>, the C<eqv> operator tests whether the canonical representation
+of both subvalues would be identical if we took a snapshot of them
+right now and compared those (now-immutable) snapshots using C<===>.
+
+If that's not enough flexibility, there is also an C<eqv()> function
+that can be passed additional information specifying how you want
+canonical values to be generated before comparison. This gives
+C<eqv()> the same kind of expressive power as a sort signature.
+(And indeed, the C<cmp> operator from Perl 5 also has a functional
+analog, C<cmp()>, that takes additional instructions on how to
+do 3-way comparisons of the kind that a sorting algorithm wants.)
+In particular, a signature passed to C<eqv()> will be bound to the
+two operands in question, and then the comparison will proceed
+on the formal parameters according to the information contained
+in the signature, so you can force numeric, string, natural, or
+other comparisons with proper declarations of the parameter's type
+and traits. If the signature doesn't match the operands, C<eqv()>
+reverts to standard C<eqv> comparison. (Likewise for C<cmp()>.)
+
+=item * Binary C<cmp> is no longer the comparison operator that
+forces stringification. Use the C<leg> operator for the old Perl 5
+C<cmp> semantics. The C<cmp> is just like the C<eqv> above except that
+instead of returning C<Bool::False> or C<Bool::True> values it always
+returns C<Order::Increase>, C<Order::Same>, or C<Order::Decrease>
+(which numerify to -1, 0, or +1).
+
+=item * the C<leg> operator (less than, equal, or greater) is defined
+in terms of C<cmp>, so C<$a leg $b> is now defined as C<~$a cmp ~$b>.
+The sort operator still defaults to C<cmp> rather than C<leg>. The
+C<< <=> >> operator's semantics are unchanged except that it returns
+and Order value as described above.
+
+=item * Binary C<< => >> is no longer just a "fancy comma". It now
constructs a C<Pair> object that can, among other things, be used to
pass named arguments to functions. It provides scalar context to both sides.
Its precedence is now equivalent to assignment, and it is right associative.
@@ -430,7 +469,7 @@

=item * Unary C<=> reads lines from a filehandle or filename, or
iterates an iterator, or in general causes a scalar to explode its guts
-when it would otherwise not. How it does that is context senstive.
+when it would otherwise not. How it does that is context sensitive.
For instance, C<=$iterator> is scalar/list sensitive and will
produce one value in scalar context but many values in list context.
(Use C<@$iterator> to force a fetch of all the values even in scalar
@@ -540,6 +579,53 @@
both sides, and we can decide when we see more examples of how
it'll work out.

+=head1 Meta operators
+
+Perl 6's operators have been greatly regularized, for instance, by
+consistently prefixing bitwise, stringwise, and boolean operators
+with C<+>, C<~> and C<?> respectively to indicate operator type.
+But that's just naming conventions. In addition to those naming
+conventions, Perl 6 has four standard metaoperators for turning a
+given standard operator into a related but more powerful operator.
+
+Note: spaces are never allowed between any metaoperator and the
+operator it's modifying, because all operators including modified
+ones have to recognized by the Longest-Token Rule, which disallows
+spaces within a token.
+
+=head1 Assignment operators
+
+These are already familiar to C and Perl programmers. The C<.=> operator
+now means to call a mutating method on object on the left, and C<~=> is
+string concatenation. Most non-relational infix operators may be turned
+into their corresponding assignment operator by suffixing with C<=>.
+
+=head1 Negated relational operators.
+
+Any infix relational operator may be transformed into its negative
+by prefixing with C<!>. A few of these have traditional shortcuts:
+
+ Full form Shortcut
+ --------- --------
+ !== !=
+ !eq ne
+ !~~ !~
+
+but most of them do not:
+
+ !<
+ !>=
+ !ge
+ !===
+ !eqv
+ !=:=
+
+To avoid visual confusion with the C<!!> operator, you may not modify
+any operator already beginning with C<!>.
+
+[Conjecture: we could probably do away with C<!~>, but probably not
+C<!=> or C<ne>.]
+
=head1 Hyper operators

The Unicode characters C<»> (C<\x[BB]>) and C<«> (C<\x[AB]>) and
@@ -637,12 +723,12 @@
such optimizations to be applied to C<Int>, C<Num>, and such. In the
absence of that, run-time analysis of partial MMD dispatch may save
some MMD searching overhead. Or particular object arrays might even
-keep track of their own run-time type purity and cache partical MMD
+keep track of their own run-time type purity and cache partial MMD
dispatch tables when they know they're likely to be used in hyperops.

=head1 Reduction operators

-The other metaoperator in Perl 6 is the reduction operator. Any
+The final metaoperator in Perl 6 is the reduction operator. Any
infix operator (except for non-associating operators and assignment
operators) can be surrounded by square brackets in term position to
create a list operator that reduces using that operation:

Darren Duncan

unread,
Jul 15, 2006, 12:49:08 AM7/15/06
to perl6-l...@perl.org
At 5:00 PM -0700 7/14/06, la...@cvs.develooper.com wrote:
>Author: larry
>Date: Fri Jul 14 17:00:12 2006
>New Revision: 10215
>
>Modified:
> doc/trunk/design/syn/S03.pod
>
>Log:
>Differentiate === from eqv and clarify semantics.
>Redefine cmp and add leg operator for old semantics.
>Add ! metaoperator.
>Fix random typos.

Larry, this new version looks great.

A few small omissions or clarifications though ...

>+=item * Binary C<cmp> is no longer the comparison operator that
>+forces stringification. Use the C<leg> operator for the old Perl 5
>+C<cmp> semantics. The C<cmp> is just like the C<eqv> above except that
>+instead of returning C<Bool::False> or C<Bool::True> values it always
>+returns C<Order::Increase>, C<Order::Same>, or C<Order::Decrease>
>+(which numerify to -1, 0, or +1).
>+
>+=item * the C<leg> operator (less than, equal, or greater) is defined
>+in terms of C<cmp>, so C<$a leg $b> is now defined as C<~$a cmp ~$b>.
>+The sort operator still defaults to C<cmp> rather than C<leg>. The
>+C<< <=> >> operator's semantics are unchanged except that it returns
>+and Order value as described above.

1. I suggest for parity (vs leg as exists eq vs ==) and clarity that
you explicitly state the <=> semantics like you did for leg, rather
than just saying "it was unchanged". Eg, amend the last sentence
there to say specifically that C<$a <=> $b> is now defined as C<+$a
cmp +$b>, especially since you don't explicitly say this anywhere
else in Synopsis 3.

>+[Conjecture: we could probably do away with C<!~>, but probably not
>+C<!=> or C<ne>.]

2. I support eliminating !~ in favor of just !~~.

Unlike != or 'ne', which are each part of a set of 6 operators that
remained unchanged as a whole from Perl 5 (so backwards compatability
could be useful), the binding/smartmatch operator set that !~ belongs
to was greatly changed, so there is no benefit to keeping !~ just
because that syntax was in Perl 5.

3. The "Precedence" table at the end of Synopsis 3 currently does not
reflect your latest changes. Most importantly, it is missing 'eqv'
and 'leg'.

Also importantly, it is missing the ?| operator and friends, which in
my case leads to confusion as to whether it belongs with the tight-or
set or the bitwise operator set.

Less importantly, I would consider the main versions of the negated
eqality operators !==, !eq, !~~ to be more important than the
alternate != or ne forms; as it is, that table already just lists the
more canonical versions of things like the zip operator rather than
both or the alternate versions.

4. I'm confused regarding the ?| operator, which is only mentioned in
this paragraph near the top of Synopsis 3:

=item * Bitwise operators get a data type prefix: C<+>, C<~>, or C<?>.
For example, C<|> becomes either C<+|> or C<~|> or C<?|>, depending on
whether the operands are to be treated as numbers, strings, or boolean
values. Left shift C< << > becomes C< +< >, and correspondingly with
right shift. Unary C<~> becomes either C<+^> or C<~^> or C<?^>, since a
bitwise NOT is like an exclusive-or against solid ones. Note that C<?^>
is functionally identical to C<!>. C<?|> differs from C<||> in that
C<?|> always returns a standard boolean value (either 1 or 0), whereas
C<||> return the actual value of the first of its arguments that is
true.

First of all, this paragraph seems to confuse in my mind as to
whether or not ?| is a bitwise operator. On one hand, it says that
it takes 2 boolean values as input and or's them. On the other hand,
it says that it is just like ||, which takes any kind of values as
input, but that the latter returns the first actual value of the
first 2 arguments, while the former doesn't. The || comparison
suggests that maybe ?| belongs with the tight-or operator set rather
than bitwise. It might help if some of this was clarified. Part of
the confusion though is that ?| isn't in the operator precedence
table.

-- Darren Duncan

Andy Bach

unread,
Jul 15, 2006, 10:55:16 PM7/15/06
to Darren Duncan, perl6-l...@perl.org
+=item * the C<leg> operator (less than, equal, or greater) ... The

+C<< <=> >> operator's semantics are unchanged except that it returns
+and Order value as described above.

typo alert: "an Order value" ... right?

a

--
Andy Bach, Sys. Mangler
Internet: andy...@wiwb.uscourts.gov
VOICE: (608) 261-5738 FAX 264-5932

"Capital is only the fruit of labor. Labor is the superior of capital and
deserves much the higher consideration."
Abraham Lincoln, first annual address to Congress 1861

0 new messages