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: 29 Sep 2000 Mailing List: [EMAIL PROTECTED] Number: 174 Version: 3 Status: Frozen =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 references 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($trans[0] @stuff); # $trans[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 nor 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