This and other RFCs are available on the web at
http://dev.perl.org/rfc/
=head1 TITLE
True Polymorphic Objects
=head1 VERSION
Maintainer: Nathan Wiger <[EMAIL PROTECTED]>
Date: 25 Aug 2000
Mailing List: [EMAIL PROTECTED]
Version: 1
Number: 159
Status: Developing
=head1 ABSTRACT
Currently, using objects in numeric and string contexts is not very
useful or easy:
$r = new CGI;
$z = $r + $x; # oops
print "$r\n"; # double-oops
You can use facilities such as C<tie> to help fix this issue, but C<tie>
is limited and slow. You can also overload operators, but this is not
flexible enough for many applications since it applies to a package (and
not individual objects).
This RFC proposes the concept of B<true polymorphic objects>, which are
objects that can morph into numbers, strings, booleans, and much more
on-demand. As such, objects can be freely passed around and manipulated
without having to care what they contain (or even that they're objects).
=head1 DESCRIPTION
=head1 Overview
The top-level syntax remains the same. As such, transition to Perl 6 is
very smooth for most people, and in fact most users don't have to care
about any of the following details. To them, this script will "just
work":
$y = Math->data(7);
$x = 3;
$name = getname("Nate");
if ( $x < 5 ) {
$y += $x;
if ( ! $name ) {
$name = "The math whiz";
}
}
print "$name got $y"; # "Nate got 10"
However, under the hood things might work drastically differently. In
fact, C<$y> and C<$name> might well be polymorphic objects:
$y = Math->data(7); # $y->CREATE, $y->STORE(7)
$x = 3; # $x = 3
$name = getname("Nate"); # $name->CREATE, $name->STORE("Nate")
if ( $x < 5 ) { # $x < 5
$y += $x; # $y->STORE($y->NUMBER->PLUS($x))
if ( ! $name ) { # $name || $name->BOOLEAN
$name = "The math whiz";# $name->STORE("...")
}
}
print "$name got $y"; # $name->STRING , $y->STRING
Here, C<$y> and C<$name> are objects, but we don't have to care. These
objects have a key property: I<context sensitivity>. They have numerous
different methods which are each called only in specific instances. So,
being called in a numeric context calls C<NUMBER>, whereas being called
in a string context would call C<STRING>.
Plus, operators are overloadable as well. This means that we might
decide to overload C<+> to become a Java-like concatenation operator on
our objects:
$string = $name + "Wiger"; # $name->STRING->PLUS("Wiger")
Yuck. :-) But it can be done, and that's pretty cool.
=head2 Polymorphic Methods
The following are the proposed methods for Perl 6 objects. Note that
these methods are completely I<optional> for a class to define. If they
are not defined, the object would retain its current behavior. The hooks
are in Perl if you want them, otherwise they don't get in the way.
Note that C<STRING>, C<NUMBER>, and C<BOOLEAN> are specialized forms of
C<FETCH>. If you define them, they are used instead of C<FETCH> in the
given context, otherwise C<FETCH> is used. Also note that the operators,
when overloaded, behave similarly to 'use overload', but on an
I<object-by-object basis>, rather than package-wide.
Data Conversion and Access
-------------------------------------------------
STRING Called in a string context
NUMBER Called in a numeric context
BOOLEAN Called in a boolean context
Operator Overloading
-------------------------------------------------
PLUS Called in + context
MINUS Called in - context
TIMES Called in * context
DIVIDED Called in / context
MODULUS Called in % context
NUMCMP Called in <=> context
NUMEQ Called in == context
NUMNE Called in != context
NUMLT Called in < context
NUMGT Called in > context
NUMLE Called in <= context
NUMGE Called in >= context
STRCMP Called in cmp context
STREQ Called in eq context
STRNE Called in ne context
STRLT Called in lt context
STRGT Called in gt context
STRLE Called in le context
STRGE Called in ge context
BITAND Called in & context
BITOR Called in | context
BITXOR Called in ^ context
BITNOT Called in ~ context
Assignment and Existence
-------------------------------------------------
CREATE Called in object creation
STORE Called in an lvalue = context
FETCH Called in an rvalue = context
READLINE Called in a <> context
PRINT Called in a print context
PRINTF Called in a printf context
DESTROY Called in object destruction
There are undoubtedly other functions that should be added. However, the
purpose of this RFC is to propose an idea and a basic interface. [1]
Others proposed an alternative set of names for these functions, such as
"OP_*" and "OP_-". However, I strongly disagree with these names. First,
they're not English words or phrases, so are bad for humans. Second,
they're not legal \w+ names, which is something we should not circumvent
with special cases. Third, they're not consistent with already-existing
Perl functions like C<FETCH> and C<STORE>. Finally, there is actually a
good amount of ambiguity. For example, does "OP_*" refer to a unary or
binary * context? With the word "TIMES" there is no such ambiguity.
Now, whether the word "TIMES" is better than "MULTIPLY" is open for
debate. I was trying to get the English verb context right:
$x * $y # $x->NUMBER->TIMES($y)
Which I think makes the function names intuitive and easy to remember. I
left out any potential _'s because these are a pain to type, and no
other Perl builtins have them.
Also, note the C<CREATE> method is actually quite useful. This allows
you to have multiple methods for creating objects, and C<CREATE> is
always called first (so you can do your basic blessing in there). This
is just like a C<BEGIN> for objects. Again, you don't have to use it,
but the hooks are there.
=head1 IMPLEMENTATION
Let's not get ahead of ourselves...yet...
=head1 MIGRATION
This introduces new functionality, however p52p6 would have to catch any
subs defined with the names listed above and warn the user that this sub
name is now reserved for Perl.
=head1 NOTES
[1] Abiding by the KISS property (Keep It Simple, Stupid)
=head1 REFERENCES
RFC 49: Objects should have builtin stringifying STRING method
RFC 73: All Perl core functions should return objects
Thanks to brian d foy and Damian Conway for their input
Thanks to Uri Guttman for suggesting CREATE on a different topic