Luke wrote:
> If the alternatives are: > > * declare $self, use $self.method, and .method for calling on $_ > * use .method, and use $_.method for calling on $_ > > I'd say the former has no case.
I, for one, am not nearly so certain of that.
Our original rationale for that choice was not capricious (and, by the way, it's getting a little tedious to have to continually remind people that we don't just pull these decisions out of a hat; that we actually do weight the case for and against them before we decide).
In this instance, the decision (at least, as far as I was concerned) was based on a simple observation. How often do you have an object on which you need to call many other methods? In my experience, relatively often. For example:
for @clients { my $value = .volume * .rate; my $cost = .management_ratio * .volume; .add_profit($value - $cost); .gen_report() }
Remember too that hash and array look-ups are method calls, which greatly increases the utility of method calls on a topic:
given %options { .{width} //= 80; .{height} //= 24; .{gutter} //= 4; .{justification} //= 'left';
.{available} = .{width} - .{gutter}
.{size} = .{width} * .{height}; }
*But* all my experience of OO programming suggests that the one place where these kinds of code constructs are comparative rare is...inside methods (because they're supposed to be short and highly focused). Calling lots of methods from within another method just isn't a frequent requirement...and if it is, it's usually isolated to one or two high level methods within a class. Especially when your language gives you dot-variables to access your attributes, and class-scoped subroutines to implement your internal utilities. Widespread nesting of method calls is usually an indication that the design is off.
Furthermore, all my experience of *general* programming suggests that OO programming is only one choice of code structure, and not even the most widely applicable or appropriate one, especially when your language offers good support for procedural and functional programming approaches.
So abandoning a very general facility (unary-method-call-on-topic) for a very specific one (unary-method-call-on-invocant) could be construed to be very un-Huffman at the semantic level: there are many more contexts in which something is topicalized than there are contexts in which something is an invocant. So it makes sense to have the short-cut on the more commonly created default.
Now, personally, I would like to see a short-cut for *both* types of method call, but if we can't have that (if only for the lack of spare punctuation) then I really think we have to go with the more general form.
If I have .foo() as $_.foo(), then I can get unary method call on invocant very easily, even if methods don't topicalize their invocant.
method bar ($_:) { .foo(); }
But if .foo() means $?SELF.foo(), how do I then get unary method call on topic???
As a final observation, designing a language isn't just about minimizing keystrokes on common operations. That admittedly desirable goal has to be balanced against other aspects of the language. One important one is internal consistency.
The whole point of having a topic in the first place is so it can be the thing you don't have to explicitly name all the time: the standard default. $_ is the default target of a C<readline>, the default chompee of a C<chomp>, the default data source of a C<print>, the default string against which patterns are matched, the default filename that C<stat> stats, the default source code that C<eval> executes, the default text that C<split> divides, the default argument upon which most of the mathematical functions operate. Almost every place you can leave something out in Perl, that something is $_. Now we're proposing unary dot as a method call in which you can leave something out. If you were an average Perl programmer and had to guess what that something was, what would you guess?
Damian