From: mjtg@cus.cam.ac.uk (M.J.T. Guy)
Newsgroups: comp.lang.perl.misc
Subject: Re: Lexical scope and embedded subroutines.
Date: 6 Jan 1998 18:22:39 GMT
Organization: University of Cambridge, England
Lines: 95
Message-ID: <68tspf$9f0$1@lyra.csx.cam.ac.uk>
References: <34B11E43.167E@gcg.com> <Pine.GSO.3.96.980105145051.3896K-100000@user1.teleport.com> <68sc4k$3p2$1@brokaw.wa.com>
NNTP-Posting-Host: taurus.cus.cam.ac.uk

In article <68sc4k$3p2$1@brokaw.wa.com>, Aaron Harsh <ajh@rtk.com> wrote:
>
>Before I read this thread (and perlsub to get the details) I would have
>assumed the original code was fine.
>
>This behavior brings up the following questions:
>  o Is Perl's behavior some sort of speed optimization?

No, but see below.

>  o Did the Perl gods just decide that scheme-like behavior was less
>important than the pseduo-static variables described in perlsub?

This subject has been kicked about at some length on perl5-porters.
The current behaviour was chosen as the best of a bad job.
In the context of Perl, it's not obvious what "scheme-like behavior"
means.    So it isn't an option.    See below for details.

>  o Does anyone else find Perl's behavior counter-intuitive?

*Everyone* finds it counterintuitive.    The fact that it only generates
a warning rather than a hard error is part of the Perl Gods policy
of hurling thunderbolts at those so irreverent as not to use -w.

>  o Did programming in scheme destroy my ability to judge a decent language
>feature?

You're still interested in Perl, so it can't have rotted your brain
completely.

>  o Have I misremembered how scheme handles these situations?

Probably not.

>  o Do Perl programmers really care how much Perl acts like scheme?

Some do.

>  o Should I have stopped this message two or three questions ago?

Yes.



The problem to be solved can be stated as

"When a subroutine refers to a variable which is instantiated more than
 once (i.e. the variable is declared in a for loop, or in a subroutine),
 which instance of that variable should be used?"

The basic problem is that Perl isn't Scheme (or Pascal or any of the
other comparators that have been used).

In almost all lexically scoped languages (i.e. those in the Algol60
tradition), named subroutines are also lexically scoped.   So the scope
of the subroutine is necessarily contained in the scope of any external
variable referred to inside the subroutine.   So there's an obvious
answer to the "which instance?" problem.

But in Perl, named subroutines are globally scoped.  (But in some
future Perl, you'll be able to write

       my sub lex { ... }

to get lexical scoping.)    So the solution adopted by other languages
can't be used.

The next suggestion most people come up with is "Why not use the most
recently instantiated variable?".   This Does The Right Thing in many
cases, but fails when recursion or other complications are involved.

Consider

sub outer {

    inner();
    outer();
    my $trouble;
    inner();
    sub inner { $trouble };
    outer();
    inner();
}

Which instance of $trouble is to be used for each call of inner()?
And why?

The consensus was that an incomplete solution was unacceptable, so
the simple rule "Use the first instance" was adopted instead.

And it is more efficient than possible alternative rules.   But that's not
why it was done.


Mike Guy

