> Date: Thu, 12 Dec 2002 02:19:18 -0500
> From: Dan Sugalski <[EMAIL PROTECTED]>
>
> Since that may be either:
> 
>    $foo = bar($x, $y), foo()
> 
> in which case it's in scalar context, or
> 
>    $foo = bar($x, $y, foo())
>
> in which case it's in list context (sort of)
>
> The fun thing is that, potentially, you need to actually *call* foo() 
> to figure out what context to call foo in. (Since, depending on what 
> it returns, you may dispatch to different bar subs, which may or may 
> not actually need what foo returns, thus changing its context)

A similar thing arises with multimethods:

    class Foo;  class Bar;
    
    sub baz(*@args);
    sub foo(Foo $thing) { ... }
    sub foo(Bar $thing, $arg) { ... }
    

    sub bar($blah) {
      if $blah {
        return new Foo:;    # is that : required?
      } 
      else {
        return new Bar:;
      }
    }

    baz foo bar $x, $y; 

If $x is true, that's:

    baz(foo(bar($x)), $y)

Otherwise, it's:

    baz(foo(bar($x), $y));

It's not as paradoxical as Dan's example, but it's also not fixable
with an "actually, context ..." argument.

As a solution (not just to this, just as a general sanity mechanism),
I propose that we

  a) Only differentiate between unary and list ops, as in Perl 5.  
  b) Consider a sub unary only if _all_ of it's versions are unary.

Thus, in this case, it would parse as:

    baz(foo(bar($x), $y));

And if $x happened to be true, a run-time error would occur.

This way, people would not have to remember how many arguments things
take, just whether they're unary or not.  This allows for easier
parsing on the human side, and encourages parentheses when they would
be beneficial to readers.

Luke
 

Reply via email to