develooper Front page | perl.perl5.porters | Postings from February 2013

Re: Salvaging lexical $_ from deprecation

Thread Previous | Thread Next
From:
Rafael Garcia-Suarez
Date:
February 20, 2013 06:42
Subject:
Re: Salvaging lexical $_ from deprecation
Message ID:
CAMoYMM8dh1855iUbCQSMsMbmYKxqieYw2_nUJT-=oyHgK8ZGSg@mail.gmail.com
On 20 February 2013 00:23, Ricardo Signes <perl.p5p@rjbs.manxome.org> wrote:
> * Rafael Garcia-Suarez <rgs@consttype.org> [2013-02-19T16:07:08]
>> I notice that the lexical topicalizer "my $_" is deprecated in blead.
>> At this point I assume that the reasons for the deprecation given in
>> perl5177delta are exhaustive. All those reasons are pointing to
>> implementation problems, notably at the XS interface level, which can
>> be solved; there are no reasons given that pertain to language design
>> issues.
>
> The reasons I find more compelling are those that Jesse L. mentioned.  How do
> you suppose that the language is supposed to work, there?
>
>> In conclusion: think first about language design; think about having a
>> vision for the future. Don't throw away language features just because
>> they introduce difficult bugs you'd rather sweep under the rug.
>> Deprecating $_ is laziness and impatience of the worst kind; do not
>> forget to also display hubris, because only hubris makes the future
>> promises shine.
>
> I *am* thinking about language design.  The bugs that interest me are the ones
> that will be written by users, in Perl, because of the language design.  I
> don't see how it can be made to make sense or become valuable.
>
> What *should* this program print?
>
>   use 5.12.0;
>   my ($A, $B, $C, $D, $E);
>
>   {
>     my $_ = "foo";
>
>     $A = sub { say "A" if       /foo/ };
>     $B = sub { say "B" if $_ =~ /foo/ };
>     $C = sub { say "C" if grep { /foo/ } qw(bar) };
>     $D = sub { say "D" if grep { (sub { $_ =~ /foo/})->() } qw(bar) };
>     $E = sub { say "E" if (sub { $_ =~ /foo/ })->() };
>   }
>
>   local $_ = "bar";
>   $A->();
>   $B->();
>   $C->();
>   $D->();
>   $E->();

This program should print A, B, and E, given that grep in C and D is
using $_ as an iteration variable. And actually it does. This is also
what it will do if you replace $_ by a more mundane "my $x" in A, B
and E.

>> In my opinion, the more important problem here is the impression that
>> P5P is throwing away without much thought of a perfectly nice and
>> modern language feature (for some value of modern that means
>> "post-FORTRAN"). This could give the impression of a the lack of
>> vision for Perl 5 (and reinforce the "perl is dead" death spiral as
>> perceived by the outside world -- the Perl users).
>
> You may have that impression, but I believe you have it entirely backward.  I
> do not think that lexical $_ is nice or modern.  I think it is half-baked,
> confused, and confusing.  I don't see how it can be made useful or
> straightforward, at the language level.  If ejecting constructs that cannot be
> salvaged makes someone think that the language is dead, I can live with that.
>
> On the other hand, I am absolutely willing to give you the benefit of the
> doubt, here.  Can you tell me how this feature can be made to make sense
> going forward?  (My understanding of the lexicality of the topic in Perl 6 is
> that it makes sense because it is also propagated dynamically by their calling
> conventions.  I am looking into this.)
>
> If you feel certain that it can be salvaged, and can give some idea of how it
> would work sensibly in the future, maybe we'll mark it experimental instead
> to see if the plan can be enacted.

I do not feel certain. However I'm not certain either it cannot be
made useful, and the current problems corrected or mitigated. What I'm
certain of, is that having a global $_ introduces action-at-distance
bugs -- some of which requiring being worked around by such ugly
constructs as "local *_" or just avoiding $_ entirely. I would have
attempted to do so if 5.18 wasn't so near, but now the only course of
action is to buy time.

>> So, to be clear: $_ is still global by default due to the need for
>> backwards compatibility. If something should be deprecated, it should
>> be plain $_, not "my $_".
>
> How would we get there from here without breaking "everything"?  Right now, a
> subroutine can rely on the $_ from its caller being available without that
> subroutine having to do anything.
>
>   lather, rinse, reap, eat for @data;
>
> If we can't get there, how will $::_ and my $_ interoperate without causing
> great confusion?

I think backwards compatibility is preventing us from using the full
Perl 6 rules for $_ scoping, but certainly we could improve on the (_)
prototype. $OUTER::_ ?

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