On Tue, Jul 06, 2004 at 07:41:22PM -0600, Luke Palmer wrote: : Considering that: : : $obj.meth "foo"; : : No longer needs parentheses, and that argument processing is done on the : callee rather than the caller side (well, most of the time), do I still : have to predeclare C<foo> if I want to say: : : foo "bar", "baz"; : : ?
It would be really nice if method calls and function calls worked the same, especially since your function call could in fact be a multimethod call. And since we've outlawed barewords, it would be possible to force any unrecognized word to be treated as a list operator. However, if you want to change the signature of C<foo> to impose some kind of context, or only take one argument, then you could be in trouble, retroactively speaking. Some things can be patched up when the signature is noticed. Some can't. The trick will be to blow up informatively when we can't. : Also, how does: : : method evil($x is rw) : : Work if argument processing is done on the callee side and we want to : avoid constructing lvalues out of everything? This is just one more aspect of the run-time context problem above. In general, I don't think it's a problem as long as you're passing in an object consistent with the run-time semantics. So when you call evil($foo) you're already passing a valid lvalue. If you say evil(laughter()) then you don't know whether laughter is being called in an lvalue context when you call it (presuming it gets called before evil() is dispatched, and not as a side effect of that dispatch.) However, since laughter() must be declared as an "rw" sub anyway if you're going to use it as an lvalue, it has presumably returned something that can function as an lvalue. Where the context problem gets trickier is when you don't know whether laughter() should be called in a scalar or list context. We already had this problem in Perl 5 for method calls. In Perl 5 we just punted and said that function arguments know their context and method arguments don't, so arguments to methods are always called in list context. I think that for Perl 6 we take the same approach for function/multimethod calls--but that's not as much of a burden as a Perl 5 programmer might expect. First, we've made it easy to specify numeric or string scalar context with a single unary op. Second, even if laughter() is called in list context and returns a list, if evil() expects only a scalar, that list is only ever passed as the first argument to evil() unless they've explicitly used a splat. So it doesn't matter to the parsing--the only damage is if the list object returned doesn't have the same semantics that any scalar value returned would have. All that being said, I do think that we still have to require predeclaration of any ordinary function that wants to force scalar context at compile time or wants to change the default parse rules from list operator parsing. Most everything else can be faked at run-time except, as noted above, the context of a function called to supply an argument to another function. Even that *could* conceivably be faked, if we could delay the actual call of laughter() to inside the argument processing of whichever evil() is dispatched. Unfortunately, that makes a chicken-and-egg problem with multiple dispatch, which has to know the inner value's *actual* type before it can dispatch. Here is a place where a language strongly typed at compile time could get away with more than we can get away with. So I think we just live with the default context of list in those cases. I guess another approach would be to return both a list value and a scalar value when you're not sure. Perhaps the scalar value of such a list object could be set by a special property instead of defaulting to the number of elements. (I almost said "the length". :-) But this seems like it could be a lot of overhead. On the other hand, it's analogous to what we're already doing with lvalues and iterators and such. Larry