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

Reply via email to