RFC 161 (v2) OO Integration/Migration Path

2000-08-27 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

OO Integration/Migration Path

=head1 VERSION

  Maintainer: Matt Youell [EMAIL PROTECTED]
  Date: 25 Aug 2000
  Last Updated: 27 Aug 2000
  Mailing List: [EMAIL PROTECTED]
  Version: 2
  Number: 161


=head1 ABSTRACT

Allow Perl 6 to benefit more directly from object orientation and object
syntax while leaving a bridge to Perl 5.


=head1 DESCRIPTION

=head2 Overview

Everything in Perl becomes an object, using existing object-syntax. Out of
plain sight, there would be essentially three base classes: Scalar, List,
and Hash. Stricter typing would be imposed (as needed) at the object level
without the need for new keywords. The Scalar base class would know about a
fixed number of types, perhaps: ref, int, long, bool, and string. Other
types could be added by subclassing Scalar.

=head2 Examples

For example, rather than:

 my int $intVal = 0;

you would say:

 my $intVal = 0;

 $intVal-asInt;

Or possibly even:

 my $invVal-asInt = 0;

for simplicity.

Unary operations could also be made the Scalar object's responsibility in
the same style:

 $record-chop;

Or even possibly controversial things like:

 $value-undef;

Finally, some of the more domain-specific features being requested of the
language could be added in a subclass of Scalar. For example,
transaction-friendly variables might be subclassed:

 use Transactions;

 my $firstName = "Bob";

 # ... (transaction happens) ...

 $firstName-commit; # or -rollback


(Of course, transaction vars might be in their own, independent, class ala
TMTOWTDI.)


=head2 Wrap-up

What this gives us is a means for adding functionality while leaving the
basic language structure alone. This way we don't interfere with
improvements happening elsewhere in the language, and we leave a clean
migration path for Perl 5.

Also, by allowing lower-level extensibility, many language-feature requests
may become moot.


=head1 IMPLEMENTATION

Most of the tools required to implement this system are already there.

- Scalar values already have Perl Doing The Right Thing for type conversion.
Providing the user with methods to activate type conversion explicitly
shouldn't be a major chore. In fact it could lighten Perl's load in many
cases by eliminating guess work about when to convert.

- The existing bless-based object system provides most (if not all) of the
tools needed to implement this system. For example, if I create my own
scalar class in Perl 5, I can say:

 $myScalar-chop;

or

 chop $myScalar;

and Perl automagically knows what I mean, barring namespace considerations.

It could work the same way in Perl 6. That would mean that older code could
very easily get along with newer code, because all of the same operators
would still be there and they would still work as expected.


=head1 MISC

This approach may also allow for better organization of Perl's internals,
specifically if the plan is to move toward a Topaz-style (C++)
implementation. Also, by organizing responsibilities into explicit classes,
the "mind-reading" load might lighten for the Perl interpreter. At least it
looks that way from outside.


=head1 REFERENCES

RFC 4:   "Type Inference"

RFC 35: "A proposed internal base format for perl variables"

RFC 49:  "Objects should have builtin stringifying STRING method"

RFC 89:  "Controllable Data Typing"

RFC 137: "Overview: Perl OO should Inot be fundamentally changed."
(specifically the EXECUTIVE SUMMARY)

http://www.perl.com/pub/1999/09/topaz.html : "Topaz: Perl for the 22nd
Century" - Chip Salzenberg

http://www.youell.com/matt/perlstring/ - A C++ string class that emulates
Perl's scalar manipulation tools. Bears some similarity to the Scalar object
described here.




RFC 163 (v1) Automatic accessors for hash-based objects

2000-08-27 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Automatic accessors for hash-based objects

=head1 VERSION

 Maintainer: James Mastros [EMAIL PROTECTED]
 Date: 25 Aug 2000
 Version: 1
 Mailing List: [EMAIL PROTECTED]
 Number: 163

=head1 ABSTRACT

This RFC proposes an attribute, C:accessible L[1] that may be applied
to hash keys to make them accessible to the outside as C$obj-Egtfoo,
this being (largely) equivalent to C$obj-Egt{foo}.

=head1 DESCRIPTION

The C:accessible attribute on a hash key L[2] would make it such
that, given a blessed hashref C$obj, C$obj-Egtfoo can refer to the
same variable as C$obj-Egt{foo}.  Note that I say "can", because
whether or not it Iwill depends on the parameters to the accessible
attribute.

The phrase $obj-Egtfoo will be referred to as an accessor for the
rest of this document, and an autoaccessor if it is not a real method,
but emulated via the :accessible mechanism.  The value part of the
hash element that defines the autoaccessor is called the
autoaccessor's value.

If the call to an autoaccessor is in list context, it returns the
single-element list containing the value of the key, just as
C$obj-Egt{foo} would.  This means that it is impossible for an
autoaccessor to ever return a list (it can return an arrayref,
though).

This hopefully isn't a problem.

If the attribute has parameters, each can be a context-permission
specifier, or a meta-attribute.

A context-permission parameter consists of an optional permission,
followed by an access type, a sequence which can repeat zero or more
times.

The permissions are:

The defined permissions are:

'!', which forces the method call to fail, without further ado L[5], and
'+', which makes the autoaccessor handle the call
'~', which makes the autoaccessor fail, but allow traditional ways
 of handling the method call..

The default is '+', if no permission is specified for a context.

A context with a '~' permission is the same as not specifying the
context letter at all L[7], and is included only for completeness.

The context can be:

'r' for rvalue (or 'r' for read)
'l' for lvalue (or 'w' for write)
'm' for mutator (which has no synonym) L[6]

If a letter is not present, use of the autoaccessor does not occur in
this context, but normal subs, AUTOLOAD, and inheritance are all
tried.  The letters attempt to be mnemonic with both the computer
science terms and the analogous file permissions.

The exception to this is that if the attribute is present, but has no
arguments, the default is '+r', that is the autoaccessor is used for
read access only, but mutate and write access must be through a
written lvalue sub L[7] L[8].

In addition, there is one defined meta-attributes, which change the
way in which the autoaccessor determines the value to return.

(Note that these cannot be concatenated to the permission specs or to
each-other.)

The first is "list", which tells the autoaccessor that in list
context, it should deref its value, and then return it.  Without this,
the autoaccessor will return the ref itself, even in list context.

L[9]

=head1 IMPLEMENTATION

Here is one possible method, which does require changes to core (or
possibly transparent ties).

Whenever this attribute is set on a hash key, an attribute
(C:has_accessible_keys) is set on the hash.

Whenever method lookup fails on an object that is a hashref, the hash
would be checked for the C:has_accessible_keys attribute and, if
found, a lookup for the key in the thingy would occur.  If it is
found, and the :accessible attribute is found, the parameter of the
attribute would be checked, and it is processed as in DESCRIPTION
above.

The attribute on the hash is there on the assumption that it's much
faster then a key lookup.  This might not be the case.

=head1 DIAGNOSTICS

=begin perldiag

=item call to method "%s" in class %s denied by autoaccessor permissions

(F) You attempted to call an autoaccessor in a context it didn't like.
This probably means that it's impossible to do this (or the
permissions are wrong).  Check the documentation of the class mentioned.

=end perldiag

The first %s should be the method name, and the second should be ref($obj).

=begin perldiag

=item Autoaccessor '%s' attempted to deref nonref '%s'.

(F) The autoaccessor is set up to autoderef it's value, but it's value
isn't a ref.  This is probably the fault of the module writer.

=end perldiag

The first %s is the name of the autoaccessor, the second is it's value.

=head1 EXAMPLES

This example shows how much easier it would have been to write the
example on line 170 of perltoot.pod:

package Person;
use strict;

##
## the object constructor (simplistic version)  ##
##
sub new {
my $self  = {};
$self-{name} :accessible('rw') = undef;
$self-{age}  :accessible('rw') 

RFC 193 (v1) Objects : Core support for method delegation

2000-09-04 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Core support for method delegation

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 4 September 2000
  Mailing List: [EMAIL PROTECTED]
  Version: 1
  Number: 193
  Status: Developing

=head1 ABSTRACT

This RFC proposes that Perl 6 offer built-in support (via a pragma) for
delegating method calls to attributes of an object.


=head1 DESCRIPTION

Delegation of method calls to attributes is a powerful OO technique that
is not well supported in most OO-capable languages, including Perl 5.

Delegation offers most of the advantages of inheritance (and, more
particularly, multiple inheritance) without most of the headaches. It
also offers some extra features that inheritance cannot provide.

The proposed delegation mechanism would work via a pragma:

use delegation
attr1 = [qw( method1 method2 method3 )],
attr2 = [qw( method4 method5 )],
attr3 = [],
attr4 = [],
# etc.
;

This would cause method calls whose names match an element in the first
list to be delegated to the "attr1" attribute of an object. Likewise,
calls to a method whose name appears in the second list would be
forwarded to the "attr2" attribute of the object.

That is, calls like:

$obj-method3(@args);
$obj-method5(@other_args);

would act as if they were:

$obj-{attr1}-method3(@args);
$obj-{attr2}-method5(@other_args);

(and, if these attribute objects also delegated, the process might repeat
recursively until some deeply nested attribute actually provided a method
to call).

Attributes which appear in with an Iempty method list become
"catch-alls". Unresolvable method calls are delegated to the first of
these that is able to handle it.

So, for example, a call like:

$obj-method6(@more_args);

would become equivalent to:

$obj-{attr3}-method6(@more_args);

if $obj-{attr3} had a Cmethod6 method (or an CAUTOLOAD), or else:

$obj-{attr4}-method6(@more_args);

if $obj-{attr4} had a suitable method.

Unlike explicitly delegated methods, which are delegated on the first
method look-up pass, delegation to catch-alls occurs on the second pass,
just before the dispatch mechanism tries the package's CAUTOLOAD method.

Note that the presence of one or more catch-all's does not prevent an
CAUTOLOAD being called, if none of the catch-alls can handle the
requested method.

If the explicit methods, the catch-alls (and any CAUTOLOAD) all fail to
provide a suitable method, the normal dispatch would then continue into the
object's ancestral classes (if any).

An attribute can appear several times in a Cuse delegation statement, with
all its delegation method lists being consolidated.

An attribute may also
appear with an explicit delegation list and as a catch-all. For example:

use delegation
attr1 = [qw(method1 method2)],
attr2 = [qw(method3 method4)],
attr1 = [],
;

This example specifies that calls to the methods Cmethod1 and
Cmethod2 should be delegated to the "attr1" attribute, calls to the
methods Cmethod3 and Cmethod4 should be delegated to the "attr2"
attribute, and any remaining calls that are not handled before the
CAUTOLOAD pass should be delegated to the "attr1" attribute (if
it can handle them).




=head2 New dispatch sequence

With delegation available, the method dispatch sequence becomes
(Ichanges from Perl 5 mechanism in italics):

=over 4

=item 1.

Look for the named method in current class, Ichecking for explicitly
delegated methods as well.

=item 2.

Recursively repeat steps 1 and 2 in ancestral class(es) and in UNIVERSAL.

=item 3.

ICheck for implicitly delegated methods through catch-all attributes.
These may be explicit or CAUTOLOADed in the attribute object's class.

=item 4.

Check for CAUTOLOAD in current class

=item 5.

Recursively repeat steps 3 to 5 in ancestral class(es) and in UNIVERSAL.

=back


=head2 Using delegation instead of inheritance

One powerful application of delegation is as a replacement for inheritance
where the internals of a prospective base class are inaccessible or
inconvenient, or the base class was not designed to be inherited and yet 
it must be.

For example, consider the task of creating an IO::File-like class that 
reads and writes to separate handles:

use IO::Bi;

my $handle = IO::Bi-new('infile', 'outfile');

if (defined($_ = $handle-getline)) {
$handle-print($_);
}

foreach ($handle-getlines) {
$handle-print($_);
}

IO::Bi can't inherit from IO::File, because it needs two file handles,
with input methods going to one and output methods going to the other.
That's impossible with inheritance (even using the dreaded "diamond
inheritance pattern") because a class can inherit 

RFC 161 (v3) Everything in Perl becomes an object.

2000-09-07 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Everything in Perl becomes an object. 


=head1 VERSION

Maintainer: Matt Youell [EMAIL PROTECTED]
Date: 25 Aug 2000
Last Updated: 7 Sep 2000
Mailing List: [EMAIL PROTECTED]
Number: 161
Version: 3
Status: Developing


=head1 ABSTRACT

Everything in Perl becomes an object, out of sight, but within easy reach.

Perl stays Perlish. Syntax remains fundamentally the same; Perl 5 code
migrates well.

Previous versions of this RFC were entitled "OO Integration/Migration Path".


=head1 DESCRIPTION

=head2 Goals

1. Provide a more complete mechanism for extending the language.
2. Organize responsibilities closer to the corresponding data structures.
3. Maintain a compatibility bridge to Perl 5.


=head2 Proposal

Everything in Perl becomes an object, using (mostly) existing object-syntax.
The built-in types $scalar, @list, and %hash become the extensible base
classes Scalar, List, and Hash. New built-in data types (such as int, bool,
string, etc.) are derived from Scalar. Regular "vanilla" $scalars don't go
away, they are simply considered to be instances of Scalar. And like any
$scalar, they still Do The Right Thing.


=head2 Syntax

"my Dog $spot" works under this model.

Where a class is not provided, a default is deduced from context ($, @, %).

For example:

 my $foo = "foo";

is equivalent to:

 my Scalar $foo = new Scalar("foo"); # (Or similar. This syntax is currently
in discussion.)


Methods would be called as they are for any object:

 $noun-verb();

or, indirectly:

 verb $noun;


=head2 Extensibility

By allowing Perl's built-in types to be extended, programmers can retain
Perl's simple syntax while better fitting their particular problem domain.
All without polluting the core language.

For example, there has been discussion of adding transaction support to
Perl. Rather than adding such support into the language directly, it could
be added as a subclass of Scalar. This might work like so:

 use Transactions::Scalar; # This replaces the default scalar with a derived
class. A detail needing exploration.

 my $firstName = "Bob"; # AKA: my Transactions::Scalar $firstName = new
Transactions::Scalar("Bob");

 # ... (transaction happens) ...

 commit $firstName; # or rollback $firstName

Or, say that you wanted to override built-in behavior. Perhaps you want
'ord' to return numeric EBCDIC values. You can create your own 'ord' routine
in your derived class and have it do that very thing.


=head2 Conclusion

This approach provides a means for adding functionality while leaving the
basic language structure alone. It doesn't interfere with improvements
happening elsewhere in the language, and it leaves a clean migration path
for Perl 5 code.


=head1 IMPLEMENTATION

This RFC tries to present a user-interface view of how this feature would
work. Other RFCs cover the specific nuts  bolts approaches that are
possible.


=head1 REFERENCES

RFC 137: Overview: Perl OO should Inot be fundamentally changed.
(specifically the EXECUTIVE SUMMARY)

RFC 159: True Polymorphic Objects

http://www.youell.com/matt/perlstring/ - A C++ string class that emulates
Perl's scalar manipulation tools. Bears some similarity to the Scalar object
described here.





RFC 200 (v1) Objects: Revamp tie to support extensibility (Massive tie changes)

2000-09-07 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects: Revamp tie to support extensibility (Massive tie changes)

=head1 VERSION

   Maintainer: Nathan Wiger [EMAIL PROTECTED]
   Date: 07 Sep 2000
   Mailing List: [EMAIL PROTECTED]
   Version: 1
   Number: 200
   Status: Developing
   Requires: RFC 159, RFC 174

=head1 ABSTRACT

Ctie is really cool. Mostly. It has an amazing amount of power in
concept, but suffers from several limitations which this RFC attempts to
address.

=head1 DESCRIPTION

=head2 Overview

Many people have expressed problems with tie, including Larry [1].
Ctie suffers from several limitations:

   1. It is non-extensible; you are limited to
  using functions that have been implemented
  with tie hooks in them already.

   2. Any additional functions require mixed calls
  to tied and OO interfaces, defeating a chief
  goal: transparency.

   3. It is slow (at least slower than other objects)

   4. You can't easily integrate tie and operator
  overloading.

   5. If defining tied and OO interfaces, you must
  define duplicate functions or use typeglobs.

   6. Some parts of the syntax are, well, kludgey

This RFC attempts to address all of these points with some changes to
syntax and implementation concepts. It interacts with the concept of
Bpolymorphic objects, described in LRFC 159, to provide a simple and
extensible framework.

=head2 New Concepts

This RFC proposes two key principles that will provide a more
general-purpose Ctie framework:

   1. Operator, data, and syntax overloading will be
  done via the ALLCAPS methods described in RFC 159.

   2. All other functions are directly translated via the
  indirect object syntax.

In addition, the declaration of a tie statement is suggested to be
changed into a standard indirect object function:

   $object = tie Tie::Class @array_to_tie;

The default Ctieing would be performed by CUNIVERSAL::tie, which
would be a new method that properly "blessed" the tied variable and then
simply turned around and called the class's CTIE method, similar to
how the builtin Ctie works currently.

There are many changes, so let's go through them one at a time and then
revisit how they will all tie (ha-ha) together at the end.

=head2 Syntax Changes

=head3 Drop Ctie builtin and replace with CUNIVERSAL::tie

As mentioned above, this allows us to call Ctie in a simple indirect
object form. This eliminates one more special-case function which
currently requires that quotes be placed around the class name. This
syntax should simply be modified to be called on the object it will be
tied to, since Ctie is after all an object constructor.

=head3 Merge CTIESCALAR, CTIEHASH, and CTIEARRAY into CTIE

In practice, people rarely make a class that Cties multiple data types
through the same interface. The reason is that CSTORE, CFETCH,
CDESTROY, and other methods overlap. As such, it is more feasible to
create several different modules; witness CTie::Array, CTie::Scalar,
CApache::Session, and other modules.

=head3 Drop CTIEHANDLE

Thanks to the below syntax, differentiating between filehandles and
other scalars is no longer important. It would also be very difficult to
make this distinction, since in Perl 6 filehandles are intended to be
C$scalars.

=head3 Continue to do data handling through ALLCAPS methods

This will not change. CSTORE and CFETCH, along with other functions
described in RFC 159 and below, will continue to do data handling. In
addition, these methods will be used for operator overloading as well.

=head3 Perform functions through the indirect object syntax

Currently, Ctie incurs a fairly substantial overhead (depending on
your application) because function calls such as this:

   push @tied_array, $value;

Must be internally transformed into this:

   $self-PUSH($value);

In addition, you are bound by the methods that the designers have
implemented. While Perl 5.6 finally has a fairly substantial collection,
nonetheless it is easy to imagine that future functions will arise which
you want to Ctie, but which support has not been added for yet.

Plus, if you want to support extra methods of your own, you must mix
object and tied calls:

   $obj = tie %trans, 'Transaction';
   $trans{$var} = $value;
   $obj-lock($var);

Unfortunately, this defeats one of the key purposes of tie, which is OO
transparency. And, creating a class that supports both OO and tied
interfaces is difficult, requiring typeglobs or duplicate handler
functions.

Instead, this RFC proposes that Ctie's operation become much more
fundamental, simply translating functions via the existing indirect
object syntax:

   tie Transaction %trans;# indirect object constructor
   $trans{$var} = $value ;# $obj-STORE($var, $value);
   lock $trans{$var}; # $obj-lock($var);
   delete $trans{$var};   # $obj-delete($stuff);
   foo %trans;# $obj-foo;
   %trans = ();   # 

RFC 49 (v3) Objects should have builtin stringifying STRING method

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE 

Objects should have builtin stringifying STRING method

=head1 VERSION

   Maintainer: Nathan Wiger [EMAIL PROTECTED]
   Date: 06 Aug 2000
   Last Modified: 14 Sep 2000
   Mailing List: [EMAIL PROTECTED]
   Number: 49
   Version: 3
   Status: Frozen

=head1 ABSTRACT

Currently, $ single-whatzitz types in Perl can hold several different
things. One of the things that these are commonly used to hold are
objects, such as:

   $q = new CGI;
   $r = Apache-request;

Unfortunately, there is no easy way to tell these are actually objects
without lots of annoying ref checks throughout your code. So if you say:

   print "$q";

This prints out something like this:

   CGI=HASH(0x80ba4e8)

Which isn't very useful. This RFC attempts to fix this by providing
builtin special method CSTRING which is automatically called when an
object is "stringified".

While this can be accomplished through the use of 'use overload', a more
automatic, object-specific method has certain advantages. For more
details on this, please see RFC 159.

=head1 NOTES ON FREEZE

This RFC goes into details on the uses of CSTRING, but what you really
want to read is LRFC 159: True Polymorphic Objects, which extends
these concepts to other Perl operators and contexts.

=head1 DESCRIPTION

Currently, there is no way to easily distinguish between these two
syntaxes:

   $scalar  =  date; # scalar ctime date, same as localtime()
   $object  =  date; # date object with accessor functions

As such, there is no easy way to have the Cdate() function return both
- it must decide what to return within the general scalar context.
Damian's excellent RFC 21 on Cwant() addresses several specific cases,
several have suggested alternate syntaxes, such as:

   my Date $object = date;   # return object of class 'Date'
   my tm $object = date; # return object of struct 'tm'

However, this doesn't solve the problem, since printing out either of
these in a scalar context still results in "garbage".

I suggest that objects provide a default method called CSTRING that
determines what they produce in a string context. When stringified, an
object would automatically call its CSTRING function and return the
correct value. For example, RFC 48 describes a new Cdate() interface.
In a scalar context, it could produce a date object always:

   $date = date;

However, when you went to do anything with it in a string context, it
would call the appropriate method:

   print "$date"; # calls $date-STRING, which in this case would
  # print out a ctime formatted date string

The call to C$object-STRING would be a decision made by Perl, similar
to the way that Ctie() works. The object simply has to provide the
method; Perl does the rest.

This gives us several other really neat side effects. First, we can now
return a list of objects and have them act the same as a "regular old
list":

   (@objects) = Class-new;

Since, in a stringifying context, each of these objects would call their
CSTRING methods:

   print "@objects";   # calls $objects[0]-STRING, $objects[1]-STRING,
   # and so on for the whole array, thus making it
   # look like a plain old list

As such, we no longer have to distinguish between objects and "true"
scalars. Objects are automatically converted when appropriate. 

=head1 IMPLEMENTATION

All core objects should be modified to include a CSTRING function.
This function may just be a typeglob pointing to another function, or it
may be an actual separate function.

Hooks will have to be put in Perl's string context so that if something
is an object, then that object's CSTRING method is called
automatically if it exists.

=head1 MIGRATION

None. This introduces new functionality.

=head1 REFERENCES

RFC 159: True Polymorphic Objects

RFC 21: Replace wantarray with a generic want function 

RFC 48: Replace localtime() and gmtime() with date() and utcdate()

Lots of people on perl6-language for great input, thanks!




RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Interpolation of method calls

=head1 VERSION

  Maintainer: Michael G Schwern [EMAIL PROTECTED]
  Date: 14 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 222
  Version: 1
  Status: Developing


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather-temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO  Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C$obj-foo() is usually better than C$obj-{foo}.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather-temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C$weather-temp as a method
call, it comes out as C$weather.'-temp' and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)-temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather-temp;

my $temp = $weather-temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather-temp]} degrees and sunny.";

print "Today's weather will be ".$weather-temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather-{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather-temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a single scalar
is treated normally.  If a list is returned, it should be treated same as
array interpolation.  The list seperator will be applied.  In effect, the
deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather-temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
Bany method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather-temp("F") degrees and sunny.";

This should deparse to:

print 'Today\'s weather will be '.$weather-temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj-foo(this = $yar, that = 2 + 2) in my head.";

deparses as:

print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head.";


=head1 CAVEATS

Indirect object syntax, being already ambiguous, cannot be easily be
distinguished in a string from normal text and should not be interpolated. 
This is ok, since accessors are rarely called with indirect object syntax.


Are there any contexts besides double quotes ("", qq{}, "EOF") where this
need be applied?  What about inside regexes?  And if so, left and/or right
hand side?


Normally, whitespace is allowed between tokens of a method call.

$obj - bar ("this");

and

$obj-bar("this");

are equivalent.  Whitespace between the object, '-', method name and opening
paren should be disallowed when interpolated.  This will avoid many ambiguous
cases.


Should the method not exist, Perl will throw an exception/die as usual.


C"$var-{this}[2]{is}-{complex}-method" should also be interpolated.  Also
C"$obj-method-{key}" for the case where a method returns a reference.


=head1 IMPLEMENTATION

The behavor of the parser to check for embedded variables would have to be
altered, namely the case where an embedded variable is being dereferenced.  A
case would be added to allow method calls as well as hash and array index
dereferences.  Otherwise, parsing should remain as normal.

=head1 

RFC 189 (v2) Objects : Hierarchical calls to initializers and destructors

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Hierarchical calls to initializers and destructors

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 1 September 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 189
  Version: 2
  Status: Developing

=head1 ABSTRACT

This RFC proposes a new special method called CBUILD that is 
invoked automagically whenever an object is created. Furthermore,
it proposes that both CBUILD and CDESTROY methods should
be invoked hierarchically in all base classes.

=head1 DESCRIPTION

One of the major limitations of object-oriented Perl is that, unlike
most other OO languages, it does not automatically invoke the 
initializers and destructors of base classes, when initializing
or destructing an object of a derived class.

This leads to tediously complex code in constructors and destructors 
in order to manually achieve the same effect. More often, it leads to bugs.

It is proposed that Perl 6 introduce an automatic object initialization
mechanism, analogous to the automatic object clean-up mechanism 
provided by CDESTROY methods. 

It is further proposed that both the initialization and destruction
mechanisms automatically call their corresponding base class versions
to ensure that complete initialization and destruction of derived
objects occurs correctly.

=head2 The CBUILD method

It is proposed that, if a class has a method named CBUILD, that method
will be invoked automatically during any call to Cbless. It
is further proposed that Cbless be extended to take an optional argument
list after its second argument, and that this list would be passed to
any CBUILD method invoked by the Cbless.

The typical constructor would then be reduced to:

package MyClass;

sub new { bless {}, @_ }

with initialization handled in a separate CBUILD routine:

sub BUILD {
my ($self, @ctor_data) = @_;
# initialization of object referred to by $self occurs here
}


=head2 Hierarchical CBUILD calls

It is proposed that when an object is blessed, Iall of the CBUILD methods
in any of its base classes are also called, and passed the argument list
appended to the invocation of Cbless. CBUILD methods would be called
in depth-first, left-most order (i.e. ancestral CBUILD methods would be
called before derived ones). Any given CBUILD method would only be called 
once for the same object, no matter how many separate paths its class might be 
inherited through.

For example, given the following class hierarchy:

package Base1;

sub new { bless {}, @_ }
sub BUILD { print "Base1::BUILD : @_\n" }


package Base2; 

sub BUILD { print "Base2::BUILD : @_\n" }


package Base3; 

sub BUILD { print "Base3::BUILD : @_\n" }


package Derived1; 
use base qw(Base1 Base2);

sub BUILD { print "Derived1::BUILD : @_\n" }


package Derived2; 
use base qw(Base2 Base3);

sub BUILD { print "Derived2::BUILD : @_\n" }


package Rederived1; 
use base qw(Derived1 Derived2);

sub BUILD { print "Rederived1::BUILD : @_\n" }


then the call to:

$obj = Rederived-new(1..3)

would print:

Base1::BUILD : 1 2 3
Base2::BUILD : 1 2 3
Derived1::BUILD : 1 2 3
Base3::BUILD : 1 2 3
Derived2::BUILD : 1 2 3
Rederived1::BUILD : 1 2 3

Note in particular that CBase2::BUILD is only called once (as early as
possible), even though class Rederived inherits it through two distinct paths.


=head2 Hierarchical CDESTROY calls

It is further proposed that when an object's destructor is invoked, all
inherited destructors would also be invoked, in depth-Ilast, right-most
order. Again, each CDESTROY for an object would be called exactly once, 
regardless of how many different paths it is inherited through.

For example, given the following class hierarchy (with the same topology
as the example for CBUILD above):

package Base1;

sub new { bless {}, @_ }
sub DESTROY { print "Base1::DESTROY\n" }


package Base2; 

sub DESTROY { print "Base2::DESTROY\n" }


package Base3; 

sub DESTROY { print "Base3::DESTROY\n" }


package Derived1; 
use base qw(Base1 Base2);

sub DESTROY { print "Derived1::DESTROY\n" }


package Derived2; 
use base qw(Base2 Base3);

sub DESTROY { print "Derived2::DESTROY\n" }


package Rederived1; 
use base qw(Derived1 Derived2);

sub DESTROY { print "Rederived1::DESTROY\n" }


then the destruction of an object:

$obj = "something else";

would print:

Rederived1::DESTROY
Derived2::DESTROY
Base3::DESTROY
Derived1::DESTROY
Base2::DESTROY
Base1::DESTROY

Note that CBase2::DESTROY is only called once (as late as 

RFC 224 (v1) Objects : Rationalizing Cref, Cattribute::reftype, and Cbuiltin::blessed

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Rationalizing Cref, Cattribute::reftype, and Cbuiltin::blessed

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 14 September 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 224
  Version: 1
  Status: Developing

=head1 ABSTRACT

This RFC proposes that rather than three separate mechanisms (in three
separate namespaces) to determine object typing information, Perl 6
simply extend the Cref function to return all the necessary
information in a list context.

=head1 DESCRIPTION

In Perl 5, the class into which an object is blessed is returned by
calling Cref on a reference to that object. To determine the
underlying implementation type of the object, Cattribute::reftype is
used. To determine whether or not a reference refers to a blessed
object, builtin::blessed is used.

It is proposed that the behaviour of Cref be altered in Perl 6 so that
in a list context it returns up to two values: the underlying
implementation type of the object (always returned), and the class into
which the object is blessed (only if the object Iis blessed).

Thus:

if (builtin::blessed $ref) {
$type  = attribute::reftype $ref;
$class = ref $ref;
}
else {
$type  = ref $ref;
$class = "no class";
}

print "Object of type $type, blessed into $class\n";


Would become:

($type, $class) = ref($ref);
$class ||= "no class";

print "Object of type $type, blessed into $class\n";


=head1 MIGRATION ISSUES

All existing calls to Cref in a list context would have to be
translated to Cscalar ref.


=head1 IMPLEMENTATION

Trivial.

=head1 REFERENCES

None.




RFC 222 (v1) Interpolation of method calls

2000-09-14 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Interpolation of method calls

=head1 VERSION

  Maintainer: Michael G Schwern [EMAIL PROTECTED]
  Date: 14 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 222
  Version: 1
  Status: Developing


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather-temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO  Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C$obj-foo() is usually better than C$obj-{foo}.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather-temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C$weather-temp as a method
call, it comes out as C$weather.'-temp' and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)-temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather-temp;

my $temp = $weather-temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather-temp]} degrees and sunny.";

print "Today's weather will be ".$weather-temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather-{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather-temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a single scalar
is treated normally.  If a list is returned, it should be treated same as
array interpolation.  The list seperator will be applied.  In effect, the
deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather-temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
Bany method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather-temp("F") degrees and sunny.";

This should deparse to:

print 'Today\'s weather will be '.$weather-temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj-foo(this = $yar, that = 2 + 2) in my head.";

deparses as:

print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head.";


=head1 CAVEATS

Indirect object syntax, being already ambiguous, cannot be easily be
distinguished in a string from normal text and should not be interpolated. 
This is ok, since accessors are rarely called with indirect object syntax.


Are there any contexts besides double quotes ("", qq{}, "EOF") where this
need be applied?  What about inside regexes?  And if so, left and/or right
hand side?


Normally, whitespace is allowed between tokens of a method call.

$obj - bar ("this");

and

$obj-bar("this");

are equivalent.  Whitespace between the object, '-', method name and opening
paren should be disallowed when interpolated.  This will avoid many ambiguous
cases.


Should the method not exist, Perl will throw an exception/die as usual.


C"$var-{this}[2]{is}-{complex}-method" should also be interpolated.  Also
C"$obj-method-{key}" for the case where a method returns a reference.


=head1 IMPLEMENTATION

The behavor of the parser to check for embedded variables would have to be
altered, namely the case where an embedded variable is being dereferenced.  A
case would be added to allow method calls as well as hash and array index
dereferences.  Otherwise, parsing should remain as normal.

=head1 

RFC 137 (v2) Overview: Perl OO should Inot be fundamentally changed.

2000-09-18 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Overview: Perl OO should Inot be fundamentally changed.

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 21 Aug 2000
  Last Modified: 18 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 137
  Version: 2
  Status: Frozen

=head1 ABSTRACT

This RFC proposes that the OO model and mechanisms present in 
Perl 5 Inot be changed significantly in Perl 6. It provides
an overview of a suite of forthcoming RFC proposals that will
provide the features, convenience, and safety that are missing
from Perl 5, without compromising the essential flexibility of
the existing Perl OO model.


=head1 EXECUTIVE SUMMARY

It ain't broken. Don't fix it.


=head1 DESCRIPTION

Perl's current OO model has a number of well-known deficiencies:
lack of (easy) encapsulation, poor support for hierarchical method
calls (especially constructors and destructors), limited (single)
dispatch mechanism, poor compile-time checking. More fundamentally,
many people find that setting up reliable OO class hierarchies requires
too much low-level coding.

But these very deficiencies are also Perl's great strength, compared
to other, more restrictive, OO languages. The non-prescriptive,
non-proscriptive nature of Perl's OO model makes it possible to 
construct am enormous range of OO systems within the one language:
from archetype-based classless OO (Class::Classless), to formal
Design-By-Contract models (Class::Contract). Effectively, Perl's
OO mechanism spans the range of metaphors from Self to Eiffel --
an astonishing achievement.

It is proposed that modules like Class::Classless, Class::Struct,
and Class::Contract continue to be the preferred method of constraining
and simplifying the creation of Perl classes, and that a better 
range of such modules (at very least, Class::Contract) be included in
the standard distribution.

To deal with the existing deficiencies without losing the remarkable
power, I intend to propose the following extensions to OO Perl:

=over 4

=item *

A Cprivate keyword that lexically scopes hash keys to the current
package, and allows hashes to contain two or more identically named (but
differently scoped) entries. This would solve the problem of
encapsulation in OO Perl for the vast majority of (predominantly
hash-based) class structures.

=item *

A new special subroutine name -- CSETUP -- to separate construction
from initialization. CSETUP methods would be automatically -- and
hierarchically -- called whenever an object is created.

=item *

Changes to the semantics of Cbless so that, after associating an
object with a class, the class's CSETUP methods are automatically
called on the object. An additional trailing C@ parameter for
Cbless, to allow arguments to be passed to CSETUP methods.

=item *

Changes to the semantics of DESTROY, so that all inherited destructors
are, by default, automatically called when an object is destroyed.

=item *

Pre- and post-condition specifiers, which associate code blocks with
particular subroutine/method names. These blocks would be automatically
called before and after the subroutine/method of the same name, and
trigger an exception on failure. For methods, pre- and post-conditions
would be inherited and called hierarchically (with disjunctive
short-circuiting, in the case of post-conditions).

=item *

Class invariant specifiers, which associate code blocks with a particular
package/class. These blocks would be called automatically after the the
execution of subroutine/method of the same name, and trigger an
exception on failure. For methods, invariants would be inherited and
called hierarchically.

=item *

Optional, configurable, multiple dispatch of methods, based upon typed
parameters.

=item *

A CNEXT pseudo-class, enabling resumption of the dispatch search
from within an invoked method, as well as the "rejection" of invocation
(e.g. by an CAUTOLOAD).

=item *

Constraints on lexical variables such that Cmy Dog $spot can only
be assigned a value $v if C$v-isa('Dog').

=item *

An optional constraint (Cuse strict 'objvars'?), making it a fatal
error to store a object reference in a non-typed lexical.

=item *

A new pragma -- Cdelegation -- that would modify the dispatch
mechanism to automatically delegate specific method calls to specified
attributes of an object.

=back

Collectively these extensions would significantly reduce the amount
of code required to construct safe OO classes, whilst leaving 
available the existing "unconstrained" OO model where it might
be needed.


There will also be one additional -- and far more radical -- proposal
that does not form part of the above suite. It would greatly enhance the
reusability of OO Perl software, but at the cost of existing
flexibility and greater migration effort.

The proposal is:

=over 4

=item *

That in Perl 6, only hashes (and perhaps pseudohashes) may be blessed.

=back

This would result in no loss of 

RFC 190 (v2) Objects : NEXT pseudoclass for method redispatch

2000-09-18 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : NEXT pseudoclass for method redispatch

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 1 Sep 2000
  Last Modified: 18 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 190
  Version: 2
  Status: Frozen

=head1 ABSTRACT

This RFC proposes a new pseudoclass named CNEXT.
This pseudoclass would provide a way of correctly redispatching a method
or an autoloaded method.


=head1 DESCRIPTION

Perl 5 provides a pseudoclass named CSUPER that allows a method to
redispatch a call to the next available method in one of its parent
classes. This redispatch mechanism works by searching for an inherited
method in any of the ancestors of the Icurrent package (but not
necessarily the invocant's package). This works well in many cases, but
not when the next most appropriate method is actually in a sibling class
of the current package, rather than in an ancestor.

For example, consider invoking a debugging method named Cdump_info
on a derived class object:

$obj-dump_info();

In order to ensure that all the object's ancestral information
was also dumped, its Cdump_info method might be structured like so:

package Derived;
use base qw(Base1 Base2);

sub dump_info {
my ($self) = @_;
$self-SUPER::dump_info();
print $self-{derived_info};
}

The various ancestral classes would then be structured similarly:

package Base1;
use base qw(GrandBase1);

sub dump_info {
my ($self) = @_;
$self-SUPER::dump_info();
print $self-{base1_info};
}


package Base2;
use base qw(GrandBase2 GrandBase3);

sub dump_info {
my ($self) = @_;
$self-SUPER::dump_info();
print $self-{base2_info};
}

# etc.


Unfortunately, this does not result in the derived object's complete
information being dumped, since each call to CSUPER::dump_info
will only call a single (left-most) ancestral Cdump_info. Thus only the
Cdump_info methods in the left-most inheritance branch will ever
be called.

What is required here is a mechanism to resume the Ioriginal dispatch
process, rather than initiate a new one from the current point.

It is proposed that Perl 6 provide a new pseudoclass -- CNEXT -- 
to facilitate exactly that.

A method invocation in which the method name is explicitly qualified
with CNEXT:: (e.g. C$self-NEXT::method(@args)) would cause the
original dispatch that invoked the current method to be restarted and
the next suitable method called.

Another way of thinking of the effect of such a redispatch would be that 
it repeats the original dispatch of C$self-method(@args), but ignores
all dispatch candidates until it has reached (and by-passed) the current
method. Of course, the mechanism wouldn't actually be implemented in
this inefficient manner.

Note that, after the redispatch, control returns to the original method.


=head2 Redispatch of CAUTOLOAD methods

The CNEXT pseudoclass also solves the problem of how to allow
CAUTOLOAD methods to "decline" to handle particular invocations. 

For example, with CNEXT it is possible to implement an CAUTOLOAD
method that only handles method calls of the form Cget_... and
Cset_... and is effectively invisible to any other method requests
(which might then trigger other CAUTOLOADs elsewhere in the
object's inheritance tree).

The implementation would look like this:

sub AUTOLOAD {
$AUTOLOAD =~ s/.*:://;
if ($AUTOLOAD =~ /^get_\w+$/) {
# Handle getting...
}
elsif ($AUTOLOAD =~ /^set_\w+$/) {
# Handle setting...
}
else {
# Decline to handle,
# passing the request on to someone else...
shift-${\"NEXT::$AUTOLOAD"}(@_);
}
}

Note that the same trick could be applied by any method, to selectively
refuse certain invocations, handing them on to some other inherited
method instead. For example:

package IO::URL;
use base 'IO::File';

sub open {
my ($self, $filename, @args) = @_;
if ($filename !~ /^(http|ftp):/) {
$self-NEXT::open($filename, @args);
}
else {
# Open URL...
}
}



=head1 MIGRATION ISSUES

None.

=head1 IMPLEMENTATION

Presumably it would be necessary to cache the dispatch stack until
the dispatched method finishes executing.

Alternatively, implementing the method dispatcher as a coroutine
would make this very easy.


=head1 REFERENCES

Conway, IObject Oriented Perl, pp. 183-184.

RFC 8: The AUTOLOAD subroutine should be able to decline 

RFC 224 (v2) Objects : Rationalizing Cref, Cattribute::reftype, and Cbuiltin:blessed

2000-09-18 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Rationalizing Cref, Cattribute::reftype, and Cbuiltin:blessed

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 14 Sep 2000
  Last Modified: 18 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 224
  Version: 2
  Status: Frozen

=head1 ABSTRACT

This RFC proposes that rather than three separate mechanisms (in three
separate namespaces) to determine object typing information, Perl 6
simply extend the Cref function to return all the necessary
information in a list context.

=head1 DESCRIPTION

In Perl 5, the class into which an object is blessed is returned by
calling Cref on a reference to that object. To determine the
underlying implementation type of the object, Cattribute::reftype is
used. To determine whether or not a reference refers to a blessed
object, builtin::blessed is used.

It is proposed that the behaviour of Cref be altered in Perl 6 so that
in a list context it returns up to two values: the underlying
implementation type of the object (always returned), and the class into
which the object is blessed (only if the object Iis blessed).

Thus:

if (builtin::blessed $ref) {
$type  = attribute::reftype $ref;
$class = ref $ref;
}
else {
$type  = ref $ref;
$class = "no class";
}

print "Object of type $type, blessed into $class\n";


Would become:

($type, $class) = ref($ref);
$class ||= "no class";

print "Object of type $type, blessed into $class\n";


=head1 MIGRATION ISSUES

All existing calls to Cref in a list context would have to be
translated to Cscalar ref.


=head1 IMPLEMENTATION

Trivial.

=head1 REFERENCES

None.




RFC 256 (v1) Objects : Native support for multimethods

2000-09-18 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects : Native support for multimethods

=head1 VERSION

  Maintainer: Damian Conway [EMAIL PROTECTED]
  Date: 18 September 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 256
  Version: 1
  Status: Developing

=head1 ABSTRACT

This RFC proposes that Perl natively support multiply dispatched
subroutines (multimethods).


=head1 DESCRIPTION

Multimethods solve a class of problems in which objects of two or more
hierarchies must interact polymorphically, but where the nature of the
interaction is determined by the run-time type of Iboth (Iall) the
objects.

=head2 Theoretical model

It is proposed that calls to certain (explicitly marked) subroutines be
dispatched using a different mechanism from that used for regular Perl 5
subroutines, or that used for Perl 5 methods.

These explicitly marked subroutines would share the same name, but
provide unique parameter lists. Collectively all marked subroutines 
with the same name but different parameters lists would be known
as a Imultimethod, with each individual subroutine known as a 
Ivariant of the multimethod.

The new dispatch mechanism would look at the classes or types of each
argument to the subroutine (by calling Cref on each) and determine
the "closest" matching variant of the multimethod, according to the
parameter types specified in the variants' parameter list.

The result would subsume the behaviour of function overloading (e.g. in
C++) but in a more sophisticated manner, since multimethods take the
run-time inheritance relationships of each argument into account.
Another way of thinking of the mechanism is that it would perform
polymorphic dispatch on every argument of a multimethod, not just on
the first.

=head2 Defining multimethods

A single variant of a multimethod would be defined by specifying a 
subroutine with a full parameter list (as per RFC 128), and
appending the attribute C:multi. Two or more such subroutines
could be defined with the same name, in the same package namespace, provide
they were both defined with the C:multi attribute, and their parameter
lists were not identical.

For example:

package LargeNum;
package LargeInt;use base 'LargeNum';
package LargeFloat;  use base 'LargeNum';

package LargeMath;

sub divide(LargeInt $a, LargeInt $b) : multi {
...
}

sub divide(LargeInt $a, LargeFloat $b) : multi {
...
}

This creates a (single) multimethod called CLargeMath::divide with two
variants. If the multimethod is called with two references to LargeInt
objects as arguments:

$x = LargeInt-new(1234567890);
$y = LargeInt-new(9876543210);
$quotient = divide($x, $y);

then the first variant is invoked. If the multimethod
is called with a LargeInt reference and a LargeFloat reference:

$x = LargeInt-new(1234567890);
$y = LargeFloat-new(9876543210.12345);
$quotient = divide($x, $y);

then the second variant is called.

Calling the multimethod with any other combination of LargeNum-derived
reference arguments (e.g. a reference to a LargeFloat and a reference
to a LargeInt, or two LargeFloat references) results in an exception
being thrown, with the message: 

No viable candidate for call to multimethod divide

To avoid this, a "catch-all" variant could be specified:

sub divide(LargeNum $b, LargeNum $b) : multi {
...
}

Now, calling Cdivide with (for example) a LargeFloat
reference and a LargeInt reference causes this third variant to be
invoked. That's because a LargeFloat Iis-a LargeNum (so the first
argument is compatible with the first parameter), and a LargeInt Iis-a
LargeNum too (so the second argument is compatible with the second
parameter). Note that adding this third variant doesn't affect calls
to the other two, since multiple dispatch always selects the nearest
match.


=head2 Finding the "nearest" multimethod

The usefulness of multiple dispatch depends on how intelligently the
dispatcher decides which variant of a multimethod is "nearest" to a
given set of arguments. That decision process is called Idispatch
resolution, and it is proposed that it be done (or Iappear to be done,
modulo optimization) like this:

=over 4

=item 1.

If the types of the arguments given (as determined by applying Cref
to each in turn) exactly match the set of parameter types
specified in any variant of the multimethod, that variant is
immediately called.

=item 2.

Otherwise, the dispatch mechanism compiles a list of viable targets.
A viable target is a variant of the multimethod with the same
number of parameters as there were arguments passed. In addition,
for each parameter the specified parameter type must be a base
class of the actual type of the corresponding argument in the
actual call (i.e. each argument must belong to a subclass of the
corresponding parameter 

RFC 200 (v2) Objects: Revamp tie to support extensibility (Massive tie changes)

2000-09-20 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Objects: Revamp tie to support extensibility (Massive tie changes)

=head1 VERSION

  Maintainer: Nathan Wiger [EMAIL PROTECTED]
  Date: 7 Sep 2000
  Last Modified: 20 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 200
  Version: 2
  Status: Developing
  Requires: RFC 159

=head1 CHANGES

   1. Dropped all references to "indirect object" syntax,
  since it was misleading, inaccurate, and unimplementable.
  Instead, added a Cuse tie pragma to arbitrarily override
  functions.

   2. Dropped suggestion to merge TIE* methods

   3. Added an UNTIE method and dropped the idea that untie
  should take all references out of scope.

=head1 ABSTRACT

Ctie is really cool. Mostly. It has an amazing amount of power in
concept, but suffers from several limitations which this RFC attempts to
address.

=head1 DESCRIPTION

=head2 Overview

Many people have expressed problems with tie, including Larry [1].
Ctie suffers from several limitations:

   1. It is non-extensible; you are limited to using
  functions that have been implemented with tie hooks
  in them already.

   2. Any additional functions require mixed calls to tied
  and OO interfaces, defeating a chief goal: transparency.

   3. It is slow. Very slow, in fact.

   4. You can't easily integrate tie and operator overloading.

   5. If defining tied and OO interfaces, you must define
  duplicate functions or use typeglobs.

   6. Some parts of the syntax are, well, kludgey

This RFC attempts to address all of these points with some changes to
syntax and implementation concepts. It interacts with the concept of
Bpolymorphic objects, described in BRFC 159, to provide a simple and
extensible framework.

=head2 New Concepts

This RFC proposes two key principles that will provide a more
general-purpose Ctie framework:

   1. Operator, data, and syntax overloading will be
  done via the ALLCAPS methods described in BRFC 159.

   2. All functions can be overloaded via the Cuse
  tie pragma.

In addition, the declaration of a tie statement is suggested to be
changed into a standard indirect object function:

   $object = tie Tie::Class @array_to_tie;

The default Ctieing would be performed by CUNIVERSAL::tie, which
would be a new method that properly "blessed" the tied variable and then
simply turned around and called the class's CTIE* method, similar to
how the builtin Ctie works currently.

There are many changes, so let's go through them one at a time and then
revisit how they will all tie (ha-ha) together at the end.

=head2 Syntax Changes

=head3 Drop Ctie builtin and replace with CUNIVERSAL::tie

As mentioned above, this allows us to call Ctie in a simple indirect
object form. This eliminates one more special-case function which
currently requires that quotes be placed around the class name. This
syntax should simply be modified to be called on the object it will be
tied to, since Ctie is after all an object constructor.

=head3 Drop CTIEHANDLE

Thanks to the below syntax, differentiating between filehandles and
other scalars is no longer important. It would also be very difficult to
make this distinction, since in Perl 6 filehandles are intended to be
C$scalars.

=head3 Continue to do data handling through ALLCAPS methods

This will not change. CSTORE and CFETCH, along with other functions
described in BRFC 159 and below, will continue to do data handling.
In addition, these methods will be used for operator overloading as
well, providing a unified Ctie and Cuse overload environment.

=head3 Add CUNTIE method called by Cuntie

When called, Cuntie currently suffers the somewhat nasty problem of
not being able to automatically destroy inner references. This means if
you've mixed OO and Ctied calls, you may not be able to destroy your
tied object as easily as you like. [2]

An CUNTIE method should be added which is called when a tied variable
is untied. This solves the problem of CDESTROY not being called when
you think it's going to be.

=head3 Ability to Ctie arbitrary functions

Currently, Ctie suffers from being non-extensible:

   push @tied_array, $value;
   sort { $a = $b } @tied_array;

The first one can be implemented as CPUSH by your tied array class,
but there is no way that you can transparently offer a custom Csort
routine. While Perl 5.6 finally has a fairly substantial collection of
Ctie methods, it is easy to imagine that future functions will arise
which you want to Ctie, but which support has not been added for yet.

Plus, if you want to support extra methods of your own, you must mix
object and tied calls:

   # Perl 5
   $obj = tie %trans, 'Transaction';
   $trans{$var} = $value;
   $obj-lock($var);

Unfortunately, this defeats one of the key purposes of Ctie, which is
BOO transparency. And, creating a class that supports both OO and tied
interfaces is difficult, requiring typeglobs or duplicate handler

RFC 222 (v2) Interpolation of object method calls

2000-09-16 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Interpolation of object method calls

=head1 VERSION

  Maintainer: Michael G Schwern [EMAIL PROTECTED]
  Date: 14 Sep 2000
  Last Modified: 17 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 222
  Version: 2
  Status: Developing

=head1 CHANGES

=head2 v2.  

Mistakenly said that C"$obj-meth("Foo")" should interpolate.  It
should, of course, be C"$obj-meth(\"Foo\")".

Added a section about variable method calls C"$obj-$meth()".
MIGRATION updated accordingly.

Clarified the title, restricting this RFC to object methods only.
Class methods will be delt with in a seperate RFC.

The caveat about whitespace now has its own section.


=head1 ABSTRACT

Method calls should interpolate in double-quoted strings, and similar
locations.

print "Today's weather will be $weather-temp degrees and sunny.";

Would deparse to:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';


=head1 DESCRIPTION

=head2 The Current Problem With OO  Interpolation

Object-oriented programming encourages data-hiding, and one of the most basic
tool for this is the accessor method.  For reasons which should be obvious,
C$obj-foo() is usually better than C$obj-{foo}.  However, there are
several barriers to using an accessor method as simply as one does a hash
lookup.  Other RFCs deal with most of the current issues, but a basic one
still remains.

print "Today's weather will be $weather-temp degrees and sunny.";

This does not DWIM.  Instead of interpolating C$weather-temp as a method
call, it comes out as C$weather.'-temp' and is usually followed immediately
by the question "What does 'Weather=HASH(0x80d4174)-temp' mean??"  Most
programmers learning OO Perl expect this to work and are surprised to find
that it does not.

Work arounds abound:

# If I wanted printf(), I'd have written it in C.
printf "Today's weather will be %d degrees and sunny.", $weather-temp;

my $temp = $weather-temp;
print "Today's weather will be $temp degrees and sunny.";

print "Today's weather will be @{[$weather-temp]} degrees and sunny.";

print "Today's weather will be ".$weather-temp." degrees and sunny.";

None are as simple and as obvious as:

print "Today's weather will be $weather-{temp} degrees and sunny.";

and because of this users groan at having to use accessor methods and are
often tempted to violate encapsulation for ease of use.

=head2 Proposed Solution - Interpolate Methods

Therefore, it is proposed that direct object method calls be interpolated
inside double quoted strings and similar constructs.

print "Today's weather will be $weather-temp degrees and sunny.";

should parse out as:

print 'Today\'s weather will be '.$weather-temp().' degrees and sunny.';

thus returning DWIMness to methods and strings and removing one barrier to
accessor method's acceptance over hash lookups for objects.

Methods will be run in scalar context.  A method which returns a
single scalar is treated normally.  If a list is returned, it should
be treated same as array interpolation.  The list seperator will be
applied.  In effect, the deparsing will really work out as follows:

print 'Today\'s weather will be '.join($", $weather-temp()).
  ' degrees and sunny.';

However if temp() calls wantarray(), the result will be FALSE (scalar).

(For the remainder of the RFC, the join() will be assumed when discussing
deparsing for brevity.)

Should it be decided that a formal distinction be made between accessor
methods and other types (RFC 95), method interpolation should interpolate
Bany method.


=head2 Argument passing

Interpolation should also handle passing arguments to methods in a string:

print "Today's weather will be $weather-temp(\"F\") degrees and sunny.";

BNOTE escaping the quotes is analagous to how C"$hash{\"foo\"}"
currently interpolates.

This should deparse to:

print 'Today\'s weather will be '.$weather-temp("F").
  ' degrees and sunny.';

The arguments to the method are considered as normal expressions, thus:

print "There is $obj-foo(this = $yar, that = 2 + 2) in my head.";

deparses as:

print 'There is '.$obj-foo(this = $yar, that = 2 + 2). ' in my head.";


=head2 Variable method calls

The accessor method is not always known when the program is written,
thus variable method calls should also be interpolated:

my $what = 'temperature';
print "The $what will be $weather-$what() with a 50% chance of kittens.";

interpolates to

my $what = 'temperature';
print 'The '.$what.' will be '.$weather-$what().' with a 50% chance of kittens.';

As with normal usage, the parenthesis are mandatory.  This:

my $what = 'color';
print "I like traffic lights, but only when they're $light-$what";

interpolates to:

my $what = 'color';
print 'I like traffic lights, but only when they're '.$light.'-'.$what;


=head2 Whitespace


RFC 73 (v2) All Perl core functions should return objects

2000-09-16 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

All Perl core functions should return objects

=head1 VERSION

   Maintainer: Nathan Wiger [EMAIL PROTECTED]
   Date: 8 Aug 2000
   Last-Modified: 15 Sep 2000
   Mailing List: [EMAIL PROTECTED]
   Number: 73
   Version: 2
   Status: Frozen
   Requires: RFC 159

=head1 ABSTRACT

In the past, Perl has only provided two return options for its builtin
functions: scalars or lists. In a scalar context, only one select value
was returned, greatly impacting the functionality of the function
(unless you like pulling apart long lists, or pain, or both).

The reason this was done was to allow easy access to string/numeric
data, and because polymorphic objects were not a reality. However,
objects can use the mechanisms described in BRFC 159: True Polymorphic
Objects to become strings, numbers, and other data types on-demand in
Perl 6. As such, we should make all Perl functions return objects in a
scalar context in Perl 6.

=head1 NOTES ON FREEZE

This is mainly a philosophical document designed to show how the methods
described in BRFC 159: True Polymorphic Objects can be used to give us
a greater amount of core power in Perl 6. One actual proposed
implementation of these ideas can be found in BRFC 48, which suggests
a new Cdate function which produces a polymorphic object in scalar
context.

The only fear was performance-related; however, as Dan Sugalski himself
pointed out, the -internals group will probably wind up putting vtable
stuff in core. In this case, performance should not be a concern because
OO will be tightly integrated from ground up.

=head1 DESCRIPTION

When several of the mechanisms proposed in other RFC's combine,
especially BRFC 159, we have the power in Perl 6 to pass many more
things around as objects, converting them to strings/numbers/etc as
they're needed. This gives us much power, since we present both objects
and "true" scalars to beginners and advanced Perl users alike with one
common set of functions. As such, objects are embedded in Perl from the
ground up.

Others have proposed typing objects, and extracting them that way:

   my $uid   = getpwnam $user;# "true" scalar uid
   my pw $pw = getpwnam $user;# object of type "pw"

However, this has a couple problems:

   1. You have to have the correct object class and, at
  the very least, alter your script's syntax.

   2. You can't make $pw look like $uid transparently.

Instead, having objects that walk and talk like scalars on demand is a
more powerful approach. Note that this RFC does not necessarily preclude
being able to type objects and pull out specific classes. The two
approaches could be combined, giving multi-class objects that can be
transparently accessed as "true" scalars.

We'll start out with complex examples, where it's obvious how this is a
benefit, and go down to simpler functions, where it might be less
obvious.

=head2 Complex Functions

Let's choose Cstat, since it's an easy target. Currently, it only
returns one of two things:

   1. A massive 13-element list (LIST context)
   2. A boolean success/failure (SCALAR context)

Neither of these is particularly useful, unless you like pain. To get a
decent interface, you have to use CFile::stat or some other module.
Instead, let's put an object-oriented interface in the core:

   $stat = stat $file;# returns an object
   @stat = stat $file;# legacy list (like current)
   %stat = stat $file;# hash (see RFC 21)

   print "$stat"; # calls $stat-STRING, which 
  # could print the filename or
  # some other useful piece of info

Note that our legacy calling methods are unaffected, but we now have an
object too. The boolean truth value is simplistic to determine still,
you simply have to say:

   $stat = stat $file or die "Can't stat $file: $!";

The object methods of the C$stat object are powerful enough that
special cases like C_ no longer have to exist. You can stat multiple
files out of order and still get the benefits of cached Cstat calls by
using the object interface:

   $f1 = stat $file1 or die;
   $f2 = stat $file2 or die;
   
   if ( $f1-size  0 and $f2-owner == 0 ) {
  print "root-owned $file1 is mode ", $f1-mode  0;
  if ( $f1-mtime  time ) {
  # here, "$f1" is $f1-STRING == $f1-filename
  warn "Warning: bad mojo, $f1 has an mtime in the future!\n";
  }
   }

Now, we have a full object-oriented Cstat implementation, wrapped in a
tidy function that can work just like Perl 5's if you want it to.

As a second example, let's examine Cgetpwnam, whose return options
are:

   1. A pretty dang big 9-element list
   2. The numeric user id

Cgetpwnam differs from Cstat in that you have to actually use what
you get in a CSCALAR context in many situations. However, this can be
easily addressed thanks to BRFC 159:

   $pw = getpwnam $username; # get 

RFC 159 (v2) True Polymorphic Objects

2000-09-16 Thread Perl6 RFC Librarian

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
  Last-Modified: 16 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 159
  Version: 2
  Status: Frozen

=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 Ctie to help fix this issue, but Ctie
is limited and slow. You can also Cuse overload, 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 Btrue 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 NOTES ON FREEZE

The only comments received were function additions. No real oppositions
were recorded. As such, the functions have been added and the RFC
frozen. 

=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 = Math-data; $y-STORE(7)
   $x = 3;  # $x = 3
   $name = getname("Nate"); # $name = getname; $name-STORE("Nate")
   if ( $x  5 ) {  # $x  5
  $y += $x; # $y-STORE($y-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: Icontext sensitivity. They have numerous
different methods which are each called only in specific instances. So,
being called in a numeric context calls CNUMBER, whereas being called
in a string context would call CSTRING.

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-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 Ioptional 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 CSTRING, CNUMBER, and CBOOLEAN are specialized forms of
CFETCH. If you define them, they are used instead of CFETCH in the
given context, otherwise CFETCH is used. Also note that the operators,
when overloaded, behave similarly to 'use overload', but on an
Iobject by object basis, rather than package-wide.

Alternative names are listed in parens.

   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 (ADD)   Called in + context
   MINUS(SUB)   Called in - context
   TIMES(MUL)   Called in * context
   DIVIDE   (DIV)   Called in / context
   MODULUS  (MOD)   Called in % context
   CONCAT   Called in . context

   NUMCMP   Called in = context 
   NUMEQCalled in == context
   NUMNECalled in != context
   NUMLTCalled in   context
   NUMGTCalled in   context
   NUMLECalled in = context
   NUMGECalled in = context

   STRCMP   Called in cmp context
   STREQCalled in eq context
   STRNECalled in ne context
   STRLTCalled in lt context
   STRGTCalled in gt context
   STRLECalled in le context
   STRGECalled in ge context

   BITAND   Called in  context
   BITORCalled in | context
   BITXOR   Called in ^ context
   BITNOT   Called in ~ context

   LOGNOT   Called in ! context
   LOGHIGHAND   Called in  context
   LOGHIGHORCalled in || context
   LOGLOWANDCalled in and context
   LOGLOWOR Called in or context
   LOGIFELSECalled in ?: context

RFC 101 (v3) Apache-like Event and Dispatch Handlers

2000-09-25 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Apache-like Event and Dispatch Handlers

=head1 VERSION

  Maintainer: Nathan Wiger [EMAIL PROTECTED]
  Date: 14 Aug 2000
  Last Modified: 25 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 101
  Version: 3
  Status: Frozen

=head1 ABSTRACT

A complete Perl 5 implementation of this can be found as Class::Handler
http://www.perl.com/CPAN/authors/id/N/NW/NWIGER/Class-Handler-1.03.tar.gz

Currently, there is no way to have multiple methods or modules for
dealing with events without significant contortions:

   $data = $r1-get_data || $r2-stuff || $r3-func;
   $r1-do_stuff(@vals) or $r1-do_this(@vals);

These simple cases can actually be tolerated. However, there are many
more complex cases which cannot be handled at all in Perl. These include
opening files only in certain directories, having methods decline or
partially handle requests, and so on.

This RFC proposes the idea of a Chandler, which is a special type of
class that is actually composed of one or more classes. Their operation
is very similar to Apache handlers: requests can be handled, declined,
or partially handled, without the top-level program having to know about
it.

=head1 NOTES ON FREEZE

The only concern ever raised was on why this should be core-worthy. One
word: speed. Currently, it can be implemented via CAUTOLOAD, but this
is slow. Also, other RFCs such as BRFC 14 rely on the notion of
handlers to gain important functionality (such as the ability to
transparently open URLs and different file types).

Damian has a separate RFC on pre and post sub handlers. It may be
possible to integrate the two into a common handler
framework/methodology. Unfortunately, I don't think either of us has the
time to do this at this point because of the upcoming RFC deadline.
However, this is something that should definitely be looked into in the
future.

=head1 DESCRIPTION

=head2 Overview

The concept of a Chandler is actually not that complex. In the
simplest case, it can be thought of as a type of abstraction:

   sub open_it {
   my $file = shift;
   return open $file ||
   HTTP::open $file ||
   FTP::open $file;
   }

Then, in your script, you would simply say:

   $fileobject = open_it " $filename";

This gives you several benefits:

   1. The internal handling of open_it can be changed
  without having to update all your programs

   2. Each operation can actually partially process
  the request, if appropriate

   2. Your program is easier to read and understand

From a Perl standpoint, these handlers work just like normal functions
and classes: they have methods, properties, inheritance, and so forth.
The only difference is that these handlers do not live in an external
file, but rather are assembled internally by Perl.

=head2 Adding and Using Handlers

First, the examples assume that the reader is somewhat familiar with RFC
14. If not, it is recommended that you give it a quick read at
http://dev.perl.org/rfc/14.pod

There are several competing syntaxes that I have for this proposal. I've
provided the one that I think is the best, but this is open to
discussion.

The proposed syntax is to use a pragmatic style:

   use handler 'http' = 'MyHTTP';
   use handler 'http' = 'LWP::UserAgent';

This would assemble a Chandler called 'http' which could then be used
in functions in your program. This handler would be a pseudo-class that
inherits methods from CMyHTTP and CLWP::UserAgent, in that order.
So:

   $fo = open http "http://www.yahoo.com" or die;

would call Chttp-open, consistent with the current Perl
implementation. The only difference would be that Chttp now tries to
call the Copen() method from CMyHTTP and CLWP::UserAgent. As such,
the above call would result in the following flow chart:

 $fo http-openundef
  ^  |   ^
  |  |   |
  |  Does MyHTTP::open exist?|
  |YES/ \NO  |
  |  /   \   |
  |  Try it Does LWP::UserAgent::open exist? |
  |   / \^  YES/ \NO |
  |OK/   \UNDEF / /   
  --- --   Try it|
  | /  \ |
  |  OK/\UNDEF   |
  -  -

Some highlights:

   1. Each class's open() method is tried in turn.

   2. If undef is returned, the next one in sequence
  is tried.

   3. If 'OK' (simply meaning 1 or some other true
  value, like $fo) is returned, that is propagated
  out and returned by the top-level handler.

   4. All classes are tried until 'OK' is returned
  or the last one is reached.
  
This allows you to easily chain classes 

RFC 152 (v2) Replace invocant in @_ with self() builtin

2000-09-24 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Replace invocant in @_ with self() builtin

=head1 VERSION

  Maintainer: Nathan Wiger [EMAIL PROTECTED]
  Date: 24 Aug 2000
  Last Modified: 24 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 152
  Version: 2
  Status: Frozen

=head1 ABSTRACT

Currently, the invocant is passed into a sub as the first element of @_,
leading to the familiar construct:

   my $self = shift;

However, this is a big PITA. In particular, if you support several
different calling forms (like CGI.pm), you have to check whether $_[0]
is a ref or class name, etc.

This RFC, therefore, proposes a new builtin called Cself() which will
return the correct invocant information. This has the added advantage
that it is consistent with Ccaller(), Cwant(), ref(), and other
context functions.

=head1 DESCRIPTION

=head2 Syntax

The new function Cself() would be called in the following way:

   sub fullname {
   my $self = self;
   @_ ? $self-{STATE}-{fullname} = $_[0]
  : $self-{STATE}-{fullname};
   }

   sub my_junk {
   my $this = self;
   $this-fork_o_matic(@_);
   }

   # Or even...

   sub error {
   carp @_ if self-config('VerboseErrors');
   }

   sub uid {
   @_ ? self-{uid} = $_[0]
  : self-{uid};
   }

The return value of Cself() would be similar to the current invocant
in $_[0], with increased flexibility. In particular, it can be called
anywhere and everywhere, not just within a method.

Depending on the context it's called in, the return value of Cself()
will be:

   1. A reference to the object, within an object method

   2. The name of the package, within a package

   3. Undef, if a sub is not called as a method

These different return values give us the ability to call Cself()
anywhere within Perl 6 code:

   package MyPackage;
   # ... many other functions ...
   sub do_stuff {
   print "Hello, @_" if self-config('Yep');
   }
   self-do_stuff;   # MyPackage-do_stuff

   package main;
   my $mp = new MyPackage;
   $mp-config('Yep') = 1;
   $mp-do_stuff('Nate');# prints "Hello, Nate"

In addition, having a routine called Cself() has the major advantage
that it hides the internal magic and scoping from the user. Just like
using Cwant() instead of a special variable called C$WANT, Cself()
makes using and comprehending contexts easy, simply changing the Perl
5 rule:

   "The invocant is passed into subs as $_[0] in OO contexts"

To the simpler still:

   "The invocant is always gotten by calling self()"

This provides a consistent interface, since Cself() can be called
anywhere, just like Ccaller(), Cwant(), and other context functions.

=head2 Arguments against Cuse invocant

This RFC was released prior to, and remains in opposition to, RFC 233,
which proposes a Cuse invocant pragma that provides the flexibility to
name the invocant anything you want.

As many have noted, Perl is already hard enough. Cuse invocant only
gives us multiple ways to do something without adding value, only
confusion, by promoting an inconsistent interface. Like providing a
means to rename C@ARGV and CSTDIN because a person prefers C@args
and Coutput, Cuse invocant further complicates an issue which should
only be made easier.

The author of this RFC Bloves Perl and loves its flexibility. However,
just like choosing a name for Ccaller, Cwant, Cprint, C@ARGV,
and so forth, we need to choose a name for Cself as well to ease the
burden on the programmer. "Choosing an interface" does not amount to
"being un-Perlish" as some might purport to suggest. In fact, just the
opposite: We're decreasing the amount of time a user has to spend
decoding somebody else's invocant naming scheme by providing a very
Perlishly-named function. BThis makes things easier.

If it is vital that the invocant must be named something specific, then
a person can always use a sub wrapper, tie, or a typeglob to rename it
appropriately. Actually, they don't even have to go to these extremes
since they can still do this:

   sub getdata {
   my $this = self;
   return $this-{DATA}-{$_[0]};
   }

(that is, assign to a custom variable) anywhere they want to.

Finally, the author would be more than happy to settle for the selection
of something different than Cself, such as Cthis(), C$SELF, or
even C$ME. The main point is that we need to choose something, because
doing so makes the language more consistent and easier (combatting two
widespread criticisms of Perl).

=head1 IMPLEMENTATION

Replace the invocant usually included in $_[0] with Cself(). Stop
passing the invocant in @_.

=head1 MIGRATION

Backwards compatibility is simple. Subs can simply have the expression:

   unshift @_, self if self;

Added as the first line of the sub, since Cself() will return undef if
not in an OO context.

=head1 REFERENCES

Critique of the Cuse invocant pragma:
http://www.mail-archive.com/perl6-language@perl.org/msg03952.html

Outline of the 

RFC 279 (v1) my() syntax extensions and attribute declarations

2000-09-24 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

my() syntax extensions and attribute declarations

=head1 VERSION

  Maintainer: Nathan Wiger [EMAIL PROTECTED]
  Date: 24 Sep 2000
  Mailing List: [EMAIL PROTECTED]
  Number: 279
  Version: 1
  Status: Developing

=head1 ABSTRACT

This RFC fleshes out variable declarations with Cmy, and also proposes
a way to assign attributes without the need for a Cmy anywhere.

=head1 DESCRIPTION

Camel-3 shows some interesting hints of what's been proposed for Cmy
declarations:

   my type $var :attribute = $value;

And we all know that you can use Cmy to declare a group of variables:

   my($x, $y, $z);

Here's the issues:

   1. How do the two jive together?
  
   2. Should it be possible to assign attributes to individiual elements
  of hashes/arrays? (yes)

=head2 Cohesive Cmy syntax

This RFC proposes that you be able to group multiple variables of the
same type within parens:

   my int ($x, $y, $z);
   my int ($x :64bit, $y :32bit, $z);

It seems most logical that:

   1. The type will be the same across variables; this is common
  usage in other languages because it makes sense.

   2. The attributes will be different for different variables.

As such, multiple attributes can be assigned and grouped flexibly:

   my int ($x, $y, $z) :64bit;   # all are 64-bit
   my int ($x, $y, $z :unsigned) :64bit; # plus $z is unsigned

Note that multiple types cannot be specified on the same line. To
declare variables of multiple types, you must use separate statements:

   my int ($x, $y, $z) :64bit;
   my string ($firstname, $lastname :long);

This is consistent with other languages and also makes parsing
realistic.

=head2 Assigning attributes to individual elements of hashes/arrays

This is potentially very useful. ":laccess", ":raccess", ":public",
":private", and others spring to mind as potential candidates for this.
This RFC proposes that in addition to attributes being assignable to a
whole entity:

   my int @a :64bit;   # makes each element a 64-bit int
   my string %h :long; # each key/val is long string

They can also be declared on individual elements, without the need for
Cmy:

   $a[0] :32bit = get_val;   # 32-bit
   $r-{name} :private = "Nate"; # privatize single value
   $s-{VAL} :laccess('data') = "";  # lvalue autoaccessor

However, a problem arises in how to assign types to singular elements,
since this requires a Cmy:

   my int $a[0] :64bit; # just makes that single element
# a lexically-scoped 64-bit int?

   my string $h{name} = ""; # cast $h{name} to string, rescope %h?

Currently, lexical scope has no meaning for individual elements of
hashes and arrays. However, assigning attributes and even types to
individual elements seems useful. There's two ways around this that I
see:

   1. On my'ing of an individual hash/array element, the
  entire hash/array is rescoped to the nearest block.

   2. Only the individual element is rescoped, similar
  to what happens when you do this:

  my $x = 5;
  {
 my $x = 10;
  }

Either of these solutions is acceptable, and they both have their pluses
and minuses. The second one seems more consistent, but is potentially
extremely difficult to implement.

=head1 IMPLEMENTATION

Hold on.

=head1 MIGRATION

None. This introduces a more flexible syntax but does not break old
ones.

=head1 REFERENCES

Camel for the Cmy syntax.