develooper Front page | perl.perl6.language | Postings from February 2005

Re: Slurpy nullary vs nonslurpy nullary

Thread Previous | Thread Next
From:
Autrijus Tang
Date:
February 18, 2005 08:46
Subject:
Re: Slurpy nullary vs nonslurpy nullary
Message ID:
20050218164449.GB5674@aut.dyndns.org
On Fri, Feb 18, 2005 at 08:26:26AM -0800, Larry Wall wrote:
> Just as a BTW, that syntax is illegal currently, since those
> curlies would be interpreted as hash subscripts.

Noted.  Which reminds me I need to implement hashes... :)

> : It sort of makes sense to me.  Please correct me if it's wrong. :)
> 
> As long as the first is always called as single dispatch, and the
> second as multiple dispatch, there should be no confusion.

Cool.  I'll see if I can adverbify other builtins, then.

> Right, it's the anchoring problem--but it's really only a problem for
> compile time typing, and documenting your intent.  At run time we know
> perfectly well that there are 0 arguments.

Uhm, yes and no.  Currently, at runtime, I have an "arityMatch"
function that compares all potential multisub matches with the
invocant and arguments; however, different candidate may impose
different contexts on the arguments (slurping == List, nonslurping
== usually Scalar).

A difficulty arises because the expressions used as arguments
is not evaluated when arityMatch is done, and for good reason --
they may do wildly different things depending on its context.

When Pugs was only implementing FP6, I could affort to force
evaluation for each multisub candidate, and see if they yield
values that can match the signature.  However, because now the
expressions may contain "say" statements, I can no longer do that.

As a concrete (not neccessarily correct) example:

    multi sub foo ($x, Int $y) returns Num { ... }
    multi sub foo ($x, *$a, *$b) returns Str { ... }

    sub baz { given want { if (rand > .5) { ... } else { ... } } }

    foo( bar(), baz() );

I fail to find a way to statically find out how many values (and what
type of values) baz() will return under "Int" and "List" contexts,
short of actually evaluating it twice.  Hence, the return type of
foo() can't be analyzed in advance because I don't know which foo()
will be invoked.

Currently it is an outstanding problem in Pugs implementation, and
that was the reason why I had to use destructive "=" instead of 
the binding ":=" for @pre and @post.  I'd be delighted to learn of a 
solution to that.

> So I think your initial solution is actually the right one from the
> viewpoint of the Perl programmer.  If we need to tweak something,
> it's perhaps to document the fact that *$x is required to match an argument,
> while *@x isn't required to match any arguments at all.  So if you
> had
> 
>     multi sub quicksort ( ) { () }
>     multi sub quicksort ( *@x ) {
> 
> then when dispatching 0 arguments you actually have an ambiguity that
> either has to be illegal or solved by ordered matching.

In pugs, currently it's ordered by local vs global, then by subtyping
distance of invocants, then finally by then finally by the order of
creation of CODE objects.  That's just a working heuristics, though.

Thanks,
/Autrijus/


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About