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

=head1 TITLE

Improved parsing and flexibility of indirect object syntax

=head1 VERSION

   Maintainer: Nathan Wiger <[EMAIL PROTECTED]>
   Date: 29 Aug 2000
   Last Modified: 20 Sep 2000
   Mailing List: [EMAIL PROTECTED]
   Number: 174
   Version: 2
   Status: Developing

=head1 CHANGES

   1. Removed the ability to include an optional comma after the
      first argument, since a way to force function calls is needed.

   2. Clarified much verbage and expanded the parsing rules.

   3. Changed the title

=head1 ABSTRACT

Currently, Perl 5 makes a distinction between routines called in the
indirect object vs. function form:

   $r = new CGI;          # CGI->new
   $r = new CGI (@args);  # CGI->new(@args)
   $r = new(CGI  @args);  # mail::new(main::CGI(@args))

This causes many problems, such as having to have special prototypes
that translate the optional first argument object into the indirect
object syntax. Special cases like this, and the inability to prototype

   print(HANDLE @list);

Have led some to suggest indirect objects be expunged altogether.

However, inflexbility is not the solution to this problem, since there
are many benefits to indirect object syntax. In Perl 6, the distinction
between function and indirect object syntax should be dropped. Instead,
the second form should be automatically translated to the first when
possible. This increased flexibility allows prototyping of key functions
while still being able to take advantage of indirect objects.

=head1 DESCRIPTION

=head2 Indirect objects should be any valid single value

Currently, indirect objects can only be a scalar, block, or bareword.
This RFC proposes that this concept be extended to any valid singular
thingy. So in Perl 6 these:

   print $handles{'mainout'} "Hello, world!";
   print $output[0] "Hi there!";

Should work as indirect objects. Code should still have to be enclosed
in blocks, since this is needed to reduce ambiguity between indirect
objects and chained functions.

=head2 Indirect objects should be enclosable in parens

Let's get into a more common example:

   print @data;
   print(@data); 
   print STDERR @data;
   print(STDERR @data);

Currently, the fact that all of these can coexist contributes to the
fact that CORE::print is not prototypeable/overrideable, which is a bad
thing, obviously. That last one is particularly sticky, since it would
intrinsically be parsed as something like:

   CORE::print(main::STDERR(@data));

But now we have to have special rules to deal with this. I'm going to
digress for a moment and skip barewords, coming back to them later.

Assuming that the above became scalar filehandles:

   print $STDERR @data;
   print($STDERR @data);

We can add a simple parsing rule to convert the second form into the
first:

   If the first argument to a function is a scalar value which
   is not followed by a comma, then that value is the indirect
   object for that function.

So, under this rule, the above two would both become:

   $STDERR->print(@data);

Assuming that print really did work as a true indirect object. This rule
generalizes to any function:

   clone($obj @args);        # $obj->clone(@args)
   mogrify($data[0] @stuff); # $data[0]->mogrify(@stuff);

So, this allows us to use the current C<print(HANDLE @data)> form
without special parsing rules. Notice that this rule does I<not> allow
you to do this:

   do_stuff(@data);

and expect Perl to magically figure out that C<$data[0]> is an object
reference. That's just I<too weird>. The first argument I<must> be a
scalar without a trailing comma.

=head2 Why this is a needed

At first, this may seem like syntactic sugar. It's not, it's much more
than that.

In fact, this makes Perl 6 much more flexible and reduces the number of
core methods, without confusing the end user with inconsistent syntax.
In fact, methods such as C<close> and C<open> could leave core
altogether, instead being called on the objects:

   $FILE = open(http "http://www.yahoo.com/");  # http->open
   close($FILE);                                # $FILE->close

It should be obvious what the benefits of being able to do this are.

It makes the core syntax much more flexible, and reduces the need
to include simple translator prototypes. This makes B<RFC 168:
Built-in functions should be functions>, much more realistic since
these prototypes no longer have to handle the special case of an
"optional first argument object". For example:

   print($STDOUT @data)   becomes   $STDOUT->print(@data);

automatically via parsing, meaning that CORE::print can be a
prototypeable function.

=head3 Ambiguity: Bareword indirect object

The following ambiguity exists in Perl 5 which is neither solved not
made worse by this RFC. However, it is worth addressing since we're
talking about indirect objects.

When the indirect object is a bareword, considerable ambiguity exists
which can actually be quite difficult to resolve cleanly:

   $p = new Person name => $name, age => $age;

The above example is valid in Perl 5. However, it can be difficult to
read and maintain, and many people would promote disambiguating it in
one of the following ways:

   $p = new Person (name => $name, age => $age);
   $p = new {Person} name => $name, age => $age;
   $p = Person->new(name => $name, age => $age);

Under this RFC, you would be able to write this as well:

   $p = new(Person name => $name, age => $age);

However, note that like the first disambiguating case above, you are
still stricken with the problem that if the person defines
C<main::Person>, that will be called, and not your indirect object,
resulting in parsing as such:

   $p = main::new(main::Person(name => $name, age => $age));

B<RFC 244> suggests that the bareword indirect object be dropped
altogether to resolve this ambiguity. While I do find this disturbing in
a way, it is hardly the only syntactic ambiguity in Perl and bareword
indirect objects are, in most cases, is quite useful.

Because this RFC neither helps nor hurts this specific ambiguity, it
defers to whatever is decided with barewords and simply states: The
precedence rules for bareword indirect objects inside parens should be
the same as for those outside parens.

=head1 IMPLEMENTATION

Add the singular rule:

   If the first argument to a function is a scalar value which
   is not followed by a comma, then that value is the indirect
   object for that function.

To Perl's parsing. Changes to C<toke.c> (or the equivalent in Perl 6)
would be required.

=head1 MIGRATION

This introduces new functionality that does not break any existing code.
No translation should be required.

=head1 REFERENCES

RFC 14: Modify open() to support FileObjects and Extensibility 

RFC 168: Built-in functions should be functions 

RFC 244: Method calls should not suffer from the action on a distance

http://www.mail-archive.com/perl6-language%40perl.org/msg03186.html

http://www.mail-archive.com/perl6-language-objects%40perl.org/msg00097.html

Reply via email to