Mark A. Biggar skribis 2005-04-23 10:55 (-0700):
> After some further thought (and a phone talk with Larry), I now think
> that all of these counted-level solutions (even my proposal of _2.foo(),
> etc.) are a bad idea.

In that case, why even have OUTER::?

I agree, though, and have always found this, that using the full name
(binding one if it doesn't have one already) is the better solution.

    given returns_object() -> $foo {
        when SomeClass { ... }
    }

I think we all agree that smart match (implied by when) should work on
$_. The following is consistent with the above:

    method ($foo: @bar) {
        when SomeClass { ... }
    }

Only the first line changes, and everything still works as expected.

The same would work very well for method calls:

    method ($foo: @bar) {
        .method;
    }

I would expect that if we change the first line back (less academically,
copied and pasted the code elsewhere), it would still work on the same
thing.

    given returns_object -> $foo {
        .method;
    }

The block passed to given aliases the first argument to $_. Methods
should do the same. And I really beleave that using a : to separate
instead of , does not make the invocant any less the first argument.

> They have a similar problems to constructs like "next 5;" meaning jump
> to the next iteration of the loop 5 level out.

Yes, that's ugly.

> Any time you refactor you code and change levels, they break in a
> subtle and very hard to debug way, causing mysterious errors.

Same thing for having one thing default to $_ and another to $self, in a
way. If everything defaults to $_, which may or may not be the same
thing as $self, things become more predictable, and you can when
refactoring just copy the body of a loop to a new method without
breaking it.

> Just like the current Perl construct of "labeled loops" so that you
> can talk about the target loop explicitly, the proper solution for
> up-level access to $OUTER::OUTER::...::OUTER::_ is to create a named
> binding like "$uplevel_topic := $_;" at that upper level and then use
> that to refer to it at lower levels.

Indeed. Fortunately, many built in constructs involving blocks that get
arguments already set up that binding for you.

> Beside is ".......foo();" seven of eight levels up?

A rather irrelevant question, IMHO. It is as irrelevant as the similar
"Is 5521243 approximately .5 million or 5.5 million?", because just as
you can write 5_521_243 to make the number more clear, you could write

    ... ... .foo();

to show it's 7 dots.

> Any other way than explicit naming is madness; leading to unreadable
> and unmaintainable code.

Not if implict naming (completely implicit, that is, so without any
indication of level even) is consistent in what it means. Currently,
things default to $_ in almost every place where a value is needed but
left out. I'd hate to see that change to some other variable for only a
portion of the operations now defaulting to $_.

Automatic binding of the invocant as $_ and the possibility to provide
your own name for the thing (either by specifying it in the signature or
by explicitly using the := operator) makes that .method defaulting to
working on $_ is not a problem.

A method's block shouldn't be too different from a given's block, or any
other closure for that matter. They should both topicalize using the
same semantics, IMO.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html

Reply via email to