R
Rainer Weikusat
Ben Morrow said:It explicitly does not keep the variable alive: it sets the PADSTALE
bit, which indicates that this variable is 'dead', and prevents string
evals and such from picking the variable up by mistake. It doesn't
deallocate the storage used for the variable, but that's just the same
level of optimisation as malloc uses when it doesn't reduce the brk just
because something has been freed.
It's not: Malloc usually retains whatever 'memory' (adress space, actually) it
already requested from the kernel in order to satisfy future
allocation requests. This means that code like this
-------------------
use Devel:eek;
sub yow
{
for (0 .. 100) {
{
my $a = "$_ + 1";
print(\$a, "\n");
Dump($a);
}
{
my $b = "$_ + 1";
print(\$b, "\n");
Dump($b);
}
}
}
&yow;
-------------------
would reuse the same space both for the $a and $b 'control blocks' and
their string bodies and that all meta-information associated with any
of these four 'logical' memory areas would be lost after each
block: There wouldn't be a way to 'set the PADSTALE bit' for any of
the scalars because whatever memory happened to be allocated to them
would turn into a completely generic 'free memory area' of a certain
size. That's not happening in this case (for perl 5.10.1 at least).
[...]
The computer has been programmed to work around this obsession with
the 'micro-optimized lifecycle management' (And this is a
euphemism. I'd wager a bet this this is practically just 'create a
new variable whenever you need one because remembering what
variables were created two lines ago would be SO cumbersome' [and
'plan in advance variables will be needed' an imposition beyond any
physically tolerable by man]).
We are not writing assembler, where you have a limited number of
registers and their use needs to be planned carefully.
Programming means 'construction of algorithms', these algorithms are
usually stateful, that is, they employ variables to keep track of
'past events' and constructing such an algorithm requires a certain
amount of planning/ forethought, especially if it is supposed to be a
sensibly implemented algorithm, that is, one which both solves a
certain problem efficiently and does so without unneeded complications
putting a burden on the mind of someone trying to understand the code.
You're free to believe that you're - thankfully - absolved form the
burden of thinking about what you're going to write before you write
it because "you are not writing assembler" but so far, I haven't
encountered a more ludicrous statement about 'software development'
(and I'm fairly certain that you didn't mean to express that).
A variable is just a way of giving a value a name;
This is true for so-called 'functional programming languages' but Perl
isn't one: There, a 'variable' is something like a deposit box
(term?): A container which can be used to store 'stuff' of a certain
kind (depending on the type of box) until it is again needed which can
be 'addressed' in a convenient way (usually, by using an abstract name
referring to the 'function' of this variable).
[...]
The whole point of lexical variables is to avoid the problems that
occur when uncontrolled and implicit data leakage occurs between
different parts of the program; having Perl ensure that values we no
longer need are properly disposed of as soon as possible is just
common sense.
(And, again, this is not about efficiency, either of CPU or memory. It's
about making the code comprehensible.)
IMO, it is about making the code incomprehensible for the sake of
'efficiency', namely, to avoid the dreaded, mythological function call
overhead, by cramming as many different algorithms into a single run
of sequential code as seems remotely feasible instead of giving
'different things different names' and invoke them using these in
higher-level control routines. If 'possible information leakage'
becomes a problem, the constituent parts of 'the code' are way too
large and do way too many different things.
Um, it's the one in the 'my' statement just above your cursor. That's
the whole point of tight scoping: except for the various kinds of
globals, which should not be created lightly and do require planning,
the scope of a single variable should not exceed one screenful of
code.
Except if 'screenful' is supposed to refer to 80x25, it should
usually be less: Some random 'screenful of code' I just looked at (148
lines of text) contained five different complete subroutines whose
bodies where (from top to bottome), 5 lines of text, 12 lines of text,
17 lines of text, 4 lines of text and 1 line of text.
[...]
If you are having to deal with code which has multiple variables with
the same name in nested scopes, some extending over hundreds of lines of
code, you have my sympathies. That is not a code style I am
advocating.
It's rather "multiple variables of the same type with the names spelled
somewhat differently, eg mdmCommand, MdmCommand and MDMCommand, all
supposed to contain the same thing, namely, the current MDM command,
which occur (or in this case, occurred) in the same 'hundreds of lines
of code' subroutine (Java method), with the number of different
spellings presumably equal to the number of different people who added
code to this particular method" (this is slight 'abstraction' of the
actual situation, but IMO an honest one). And without the possiblity
to 'declare variables on the spot' whenever one is needed, something
like this couldn't occur.