[33120] in Perl-Users-Digest
Perl-Users Digest, Issue: 4396 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Sun Mar 22 18:09:21 2015
Date: Sun, 22 Mar 2015 15:09:06 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Sun, 22 Mar 2015 Volume: 11 Number: 4396
Today's topics:
Re: An error on page 142 of The Camel Book. (Seymour J.)
Re: An error on page 142 of The Camel Book. (Seymour J.)
Re: An error on page 142 of The Camel Book. (Seymour J.)
Re: An error on page 142 of The Camel Book. <kaz@kylheku.com>
Re: An error on page 142 of The Camel Book. (Seymour J.)
Re: An error on page 142 of The Camel Book. <rweikusat@mobileactivedefense.com>
Re: An error on page 142 of The Camel Book. <kaz@kylheku.com>
Re: An error on page 142 of The Camel Book. <kaz@kylheku.com>
Re: An error on page 142 of The Camel Book. <rweikusat@mobileactivedefense.com>
Re: An error on page 142 of The Camel Book. <rweikusat@mobileactivedefense.com>
Re: Error Messages <sbryce@scottbryce.com>
Re: Error Messages <edgrsprj@ix.netcom.com>
Re: Error Messages <jurgenex@hotmail.com>
Re: Error Messages <news@lawshouse.org>
Re: Error Messages (Seymour J.)
Re: Wait, lexical variables in loops do NOT always real <rweikusat@mobileactivedefense.com>
Re: Wait, lexical variables in loops do NOT always real <kaz@kylheku.com>
Re: Wait, lexical variables in loops do NOT always real <hjp-usenet3@hjp.at>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Sat, 21 Mar 2015 22:09:23 -0400
From: Shmuel (Seymour J.) Metz <spamtrap@library.lspace.org.invalid>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <550e2453$3$fuzhry+tra$mr2ice@news.patriot.net>
In <20150320072802.260@kylheku.com>, on 03/20/2015
at 02:50 PM, Kaz Kylheku <kaz@kylheku.com> said:
>*All* loops, no matter how messy, can be expressed as
>initialization, the conditional execution of a body with an
>increment phase:x.
But not cleanly.
>So, program in assembler! Every instruction is clearly on a line
>by itself.
Sorry, but no; it depends on which assembler.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
------------------------------
Date: Sat, 21 Mar 2015 22:10:04 -0400
From: Shmuel (Seymour J.) Metz <spamtrap@library.lspace.org.invalid>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <550e247c$5$fuzhry+tra$mr2ice@news.patriot.net>
In <20150320121814.890@kylheku.com>, on 03/20/2015
at 07:35 PM, Kaz Kylheku <kaz@kylheku.com> said:
>So what? All control structures reduce to a graph of labels, ifs
>and gotos.
No; some involve, e.g., popping the stack.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
------------------------------
Date: Sat, 21 Mar 2015 22:14:15 -0400
From: Shmuel (Seymour J.) Metz <spamtrap@library.lspace.org.invalid>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <550e2577$6$fuzhry+tra$mr2ice@news.patriot.net>
In <87oann1dpa.fsf@doppelsaurus.mobileactivedefense.com>, on
03/20/2015
at 10:55 PM, Rainer Weikusat <rweikusat@mobileactivedefense.com>
said:
>Since C doesn't have a construct which supports
>looping over a range of integers,
Or since some understand the concept of the empty set.
>they tend to emulate this as for (i = 0; i < 1024; ++i);
Quite properly.
>despite this doesn't make much sense
The fact that you don't understand the utility doesn't mean that it
doesn't make much sense.
>it ends up as
>i = 0;
>while (i < 1024) {
> .
> .
> ++i;
>}
As it should.
>while the counting loop should really be
>i = 0;
>do {
> .
> .
> .
>} while (++i < 1024);
Not if that yields different results, which it does in general.
>ie, it should have the test at the end because the initial value of
>i is known to be less than 1024.
Only because of the fortuitous use of constants. Consider for (i =
first; i < last; ++i);
>That's actually a nice of example of habits asserting themselves
>despite they don't make any sense:
No; it's an example of habits that keep you from recognizing when
something makes sense.
If you want to change your claim to "for(foo;bar;baz) isn't always the
correct tool", I'll agree, but there are cases for which it is
appropriate.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
------------------------------
Date: Sun, 22 Mar 2015 04:37:38 +0000 (UTC)
From: Kaz Kylheku <kaz@kylheku.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <20150321205211.627@kylheku.com>
On 2015-03-20, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
> while the counting loop should really be
>
> i = 0;
> do {
> .
> .
> .
> } while (++i < 1024);
No, the loop should not be this.
If 1024 is replaced by an n which could be zero. The correct loop guard for
each execution of the body is (i < n). The generalization dictates the form
for the hard-coded specializations, unless there is a great reason to deviate.
I think you, or anyone with similar ideas, really should critically re-examine
your infactuation with "bottom test" loops, and maybe think about laying it to
rest.
Bottom test loops are not really "bottom test". They are top-test loops,
which skip the top test for the first iteration. I.e.
goto into; /* I happen to know i < n now! */
while (i < n)
{
into:
i++;
}
There is usually no good reason to skip the first test, and that explains
the relative disuse of the do/while loop in C.
The fact that n is actually the constant 1024 which is greater than zero
is not a sufficient justification for skipping the first test.
You need a much better reason, such as a situation in which the first test
would misbehave in some way that is mitigated by the execution of the body at
least once.
For example, this is illustrates a nice use for do/while:
/* atomically do *mem_location = func(*mem_location) */
do {
old = *mem_location;
new = func(old);
} while (!compare_and_swap(mem_location, old, new);
Other than this sort of rare, special thing, there is the C use of do/while(0)
in macros, which is neither here nor there, since it revolves around
a semicolon triviality. I mention this because if you want to run some
statistics on C project about how often they use do/while, you should probably
discount this:
#define macro(x, y) do { ... \
... \
} while (0)
Here is another nice use of do, from a project of mine:
static val lazy_flatten_scan(val list, val *escape)
{
for (;;) {
if (list) {
val a = car(list);
if (nilp(a)) {
list = cdr(list);
} else if (atom(a)) {
return list;
} else do {
push(cdr(list), escape); /* safe mutation: *escape is a local var */
list = a;
a = car(list);
} while (consp(a));
return list;
} else if (*escape) {
list = pop(escape);
} else {
return nil;
}
}
}
That "else do" could be:
} else while (consp(a)) {
...
}
Why did I make it do? Because this is an else case of "if (atom(a))". If a is
not an atom, it is necessarily a cons! So in other words, we have already
implicitly tested for consp, and so skipping this test on the first iteration
is logically justified.
------------------------------
Date: Sat, 21 Mar 2015 22:03:27 -0400
From: Shmuel (Seymour J.) Metz <spamtrap@library.lspace.org.invalid>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <550e22ef$1$fuzhry+tra$mr2ice@news.patriot.net>
In <PqadncSDKZAqCpbInZ2dnUVZ572dnZ2d@giganews.com>, on 03/19/2015
at 08:44 PM, Robbie Hatley <see.my.sig@for.my.address> said:
>But then, not everyone is going to be able to program in C anyway.
>It's a dangerous language for those not familiar with the way
>computers work "under the hood"
TMTOWTDI applies to more than just Perl. Not every computer works like
a PDP-7.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
------------------------------
Date: Sun, 22 Mar 2015 16:46:07 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <87pp81nfow.fsf@doppelsaurus.mobileactivedefense.com>
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2015-03-20, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
>> while the counting loop should really be
>>
>> i = 0;
>> do {
>> .
>> .
>> .
>> } while (++i < 1024);
>
> No, the loop should not be this.
>
> If 1024 is replaced by an n which could be zero.
> The correct loop guard for each execution of the body is (i < n).
Even this isn't necessarily true when 'generalizing' as the loop body
may well need to be executed once in any case. This depends on the
circumstances. For the counting loop example I gave, the test belongs at
the end of the loop because the state changes after the loop body was
executed. That's how it will very likely be implemented if 'the human
error' is just allowed to request a counting loop, as opposed being
allowed to implement his idea of a counting loop. Even in the latter
case, it's not uncommon for compilers to recognize tests which should
occur after the loop body and generate appropriate machine code. Which
amounts to a tacit admission of the logic error in the code --- the
computer wouldn't need to correct it automatically had the human been
willing to do it right to begin with .... but there 'we' again collide
with habits: I have always done it this way! Everyone (I care for) has
always done it this way! Therefore, this is Right and anything else is
Just Wrong (allusion to an irrational argument about 'coding morality'
entirely intentional).
> I think you, or anyone with similar ideas, really should critically re-examine
> your infactuation with "bottom test" loops, and maybe think about laying it to
> rest.
>
> Bottom test loops are not really "bottom test". They are top-test loops,
> which skip the top test for the first iteration. I.e.
>
> goto into; /* I happen to know i < n now! */
>
> while (i < n)
> {
> into:
>
> i++;
> }
Well, top-test loops are not really top-test loops, they're bottom-test
loops skipping the loop body on the first iteration:
goto test; /* in line with the for-convention, first things come
last in the text */
do {
.
.
.
++i;
test:
} while (i != n);
Other implementation variants are possible and such an 'argument', while
being an opportunity to post some pseudo-code people usually wouldn't
write for good reasons (sort of a guilty-by-association) doesn't really
get anyone anywhere.
> There is usually no good reason to skip the first test, and that explains
> the relative disuse of the do/while loop in C.
>
> The fact that n is actually the constant 1024 which is greater than zero
> is not a sufficient justification for skipping the first test.
That's a perfect reason for executing the loop body followed by testing
the condition instead of the other way round: I don't really know
English terms but in German, there are 'abweisende Schleife' (loop
which rejects) and 'nicht-abweisende Schleife' (loop with the opposite
behaviour), the first one refering to a loop which executes 0 or more
times, the second to one which executes 1 or more times. Both are useful
in practice. Since the second case is obviously a subset of the first,
people who prefer not being bothered with such details usually restrict
their usage of the/ a language to the first case.
------------------------------
Date: Sun, 22 Mar 2015 17:03:40 +0000 (UTC)
From: Kaz Kylheku <kaz@kylheku.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <20150322095528.687@kylheku.com>
On 2015-03-20, Robbie Hatley <see.my.sig@for.my.address> wrote:
> But then, not everyone is going to be able to program in C anyway.
> It's a dangerous language for those not familiar with the way
> computers work "under the hood" (CPUs, memory, addresses,
> instruction codes, etc). Very easy to shoot yourself in the foot
> in C if you're not familiar with computers at a detailed level.
Some of those who know how machines work are *much* more dangerous in C,
because they take a misleading shortcut: they pretend that the operators of C
correspond to some assembly language instructions. Since those instructions
are well-defined, everything is cool.
"I know how the machine works, and C is just ahigh level assembler.
All I need is page 53 of K&R2 for operator precedence and I'm good."
They are dangerous also because sometimes they get quite far in development,
and ship code to large numbers of users.
> Perhaps Perl would be a better choice for folks with little or no
> computer-science background who need to do some programming.
Of course; those who do have a CS background usually cannot stomach it.
------------------------------
Date: Sun, 22 Mar 2015 20:43:21 +0000 (UTC)
From: Kaz Kylheku <kaz@kylheku.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <20150322105225.523@kylheku.com>
On 2015-03-22, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
> Kaz Kylheku <kaz@kylheku.com> writes:
>> On 2015-03-20, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
>>> while the counting loop should really be
>>>
>>> i = 0;
>>> do {
>>> .
>>> .
>>> .
>>> } while (++i < 1024);
>>
>> No, the loop should not be this.
>>
>> If 1024 is replaced by an n which could be zero.
>> The correct loop guard for each execution of the body is (i < n).
>
> Even this isn't necessarily true when 'generalizing' as the loop body
> may well need to be executed once in any case.
> circumstances. For the counting loop example I gave, the test belongs at
> the end of the loop because the state changes after the loop body was
> executed.
Nope. Since the i < 1024 test is in fact valid before the first iteration, it
shows that the precondition for the execution of the loop body is the same for
that iteration as it is for the others.
You just choose not to test it, because you think the C compiler isn't
smart enough to figure this out, and shave off the couple of cycles for you.
>> I think you, or anyone with similar ideas, really should critically re-examine
>> your infactuation with "bottom test" loops, and maybe think about laying it to
>> rest.
>>
>> Bottom test loops are not really "bottom test". They are top-test loops,
>> which skip the top test for the first iteration. I.e.
>>
>> goto into; /* I happen to know i < n now! */
>>
>> while (i < n)
>> {
>> into:
>>
>> i++;
>> }
>
> Well, top-test loops are not really top-test loops, they're bottom-test
> loops skipping the loop body on the first iteration:
>
> goto test; /* in line with the for-convention, first things come
> last in the text */
> do {
> .
> .
> .
> ++i;
> test:
> } while (i != n);
Sure, and if all we had was the do/while loop in a C dialect, we would be using
this pattern quite a lot. Why? Due to the need to test a precondition
before the execution of a loop body.
Note that the while loop can unconitionally execute the first iteration,
if necessary, *without* the use of an unconditional goto to a label.
i = 0;
while (i == 0 || i < n) {
/* ... */
i++;
}
If other words, we can attack the problem with logic: identify the additional
condition which controls the first iteration, and add it via logical
disjunction to the loop guard.
The reverse isn't the case; you can't simply alter/extend the condition in the
do/while loop so that the first iteration isn't skipped.
This is very clear: we see clearly that the loop body is executed when i == 0,
even if n == 0. We can also have a good deal of confidence that it's
intentional.
The following does not convince me that the unconditional execution of
the loop at least once is intentional.
i = 0;
do {
/* ... */
i++;
} while (i < n)
Maybe this was originally written with a hard coded 1024 instead of n,
and a maintainer didn't bother changing it to a while loop when n was
introduced.
> Other implementation variants are possible and such an 'argument', while
> being an opportunity to post some pseudo-code people usually wouldn't
> write for good reasons (sort of a guilty-by-association) doesn't really
> get anyone anywhere.
In fact, I posted some examples of do/while loops, one of them directly
pasted from a project of mine.
>> There is usually no good reason to skip the first test, and that explains
>> the relative disuse of the do/while loop in C.
>>
>> The fact that n is actually the constant 1024 which is greater than zero
>> is not a sufficient justification for skipping the first test.
>
> That's a perfect reason for executing the loop body followed by testing
> the condition instead of the other way round: I don't really know
No, it's not a "perfect reason", because the "i < 1024" precondition is
the correct one even for the first iteration.
The only reason for not testing it would be that you think you can shave
a few nanoseconds off the execution time by avoiding one test, and that the
compiler won't be smart enough to do it.
GCC is smart enough:
extern void bar(int);
void foo(void)
{
int i = 0;
while (i < 1024) {
bar(i);
i++;
}
}
.globl foo
foo:
.LFB0:
pushl %ebx
xorl %ebx, %ebx
subl $24, %esp
.L2:
movl %ebx, (%esp)
addl $1, %ebx
call bar
cmpl $1024, %ebx
jne .L2
addl $24, %esp
popl %ebx
ret
See? bar is called, then there is a test with a backward branch.
You're completely silly to be doing this microoptimization by hand
at the source level.
> English terms but in German, there are 'abweisende Schleife' (loop
> which rejects) and 'nicht-abweisende Schleife' (loop with the opposite
> behaviour), the first one refering to a loop which executes 0 or more
> times, the second to one which executes 1 or more times. Both are useful
> in practice. Since the second case is obviously a subset of the first,
> people who prefer not being bothered with such details usually restrict
> their usage of the/ a language to the first case.
In the analysis of imperative programs, the language of computer science
gives us the terms "(weakest strict) precondition", "postcondition" and
"invariant". The test condition of a while loop closely corresponds with the
concept of the weakest strict precondition for executing the loop body.
If a precondition that is correct for iterations 1 through n-1 is also correct
for iteration 0, it usually behooves us to clearly write the code that way.
In my example, I was justified to do this by hand:
if (atom(a)) {
..
} else do {
} while (consp(a));
rather than:
if (atom(a)) {
..
} else while (consp(a)) {
}
because GCC does not know about the equivalence !atom(a) == consp(a).
------------------------------
Date: Sun, 22 Mar 2015 21:10:28 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <87h9tcd9h7.fsf@doppelsaurus.mobileactivedefense.com>
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2015-03-22, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
>> Kaz Kylheku <kaz@kylheku.com> writes:
>>> On 2015-03-20, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
>>>> while the counting loop should really be
>>>>
>>>> i = 0;
>>>> do {
>>>> .
>>>> .
>>>> .
>>>> } while (++i < 1024);
>>>
>>> No, the loop should not be this.
>>>
>>> If 1024 is replaced by an n which could be zero.
>>> The correct loop guard for each execution of the body is (i < n).
>>
>> Even this isn't necessarily true when 'generalizing' as the loop body
>> may well need to be executed once in any case.
>> circumstances. For the counting loop example I gave, the test belongs at
>> the end of the loop because the state changes after the loop body was
>> executed.
>
> Nope. Since the i < 1024 test is in fact valid before the first iteration, it
> shows that the precondition for the execution of the loop body is the same for
> that iteration as it is for the others.
>
> You just choose not to test it, because you think the C compiler isn't
> smart enough to figure this out, and shave off the couple of cycles
> for you.
As I wrote in the original postings, loops come in two kinds, 'execute 0
or more times' and 'execute 1 or more times' and I advocate picking the
one which makes the most sense in any given situation, regardless of
what a compiler might or might not be capable of.
------------------------------
Date: Sun, 22 Mar 2015 21:24:11 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: An error on page 142 of The Camel Book.
Message-Id: <87bnjkd8uc.fsf@doppelsaurus.mobileactivedefense.com>
Kaz Kylheku <kaz@kylheku.com> writes:
> On 2015-03-22, Rainer Weikusat <rweikusat@mobileactivedefense.com> wrote:
[...]
> The only reason for not testing it would be that you think you can shave
> a few nanoseconds off the execution time by avoiding one test, and that the
> compiler won't be smart enough to do it.
>
> GCC is smart enough:
>
> extern void bar(int);
>
> void foo(void)
> {
> int i = 0;
>
> while (i < 1024) {
> bar(i);
> i++;
> }
> }
>
> .globl foo
> foo:
> .LFB0:
> pushl %ebx
> xorl %ebx, %ebx
> subl $24, %esp
> .L2:
> movl %ebx, (%esp)
> addl $1, %ebx
> call bar
> cmpl $1024, %ebx
> jne .L2
> addl $24, %esp
> popl %ebx
> ret
>
> See? bar is called, then there is a test with a backward branch.
I specifically mentioned this in the other posting:
Even in the latter case, it's not uncommon for compilers to
recognize tests which should occur after the loop body and
generate appropriate machine code. Which amounts to a tacit
admission of the logic error in the code --- the computer
wouldn't need to correct it automatically had the human been
willing to do it right to begin with ....
Even in cases where the condition wasn't obviously misplaced, gcc will
usually move the test to the end, see
-------------
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int i = 0;
while (i < atoi(argv[1])) printf("%d\n", i++);
return 0;
}
--------------
which is translated to (quoting just the loop)
--------------
jmp .L2
.p2align 4,,10
.p2align 3
.L3:
leal 1(%rbx), %ebp
movl %ebx, %esi
movl $.LC0, %edi
xorl %eax, %eax
movl %ebp, %ebx
call printf
.L2:
movq 8(%r12), %rdi
xorl %esi, %esi
movl $10, %edx
call strtol
cmpl %eax, %ebx
jl .L3
---------------
because that's the only way to implement the loop with just a single
jump statement. But that's obviously completely irrelevant for a
discussion of Perl code at the 'source code' level.
------------------------------
Date: Sat, 21 Mar 2015 08:32:42 -0600
From: Scott Bryce <sbryce@scottbryce.com>
Subject: Re: Error Messages
Message-Id: <mejvct$c71$1@dont-email.me>
On 3/20/2015 2:18 AM, E.D.G. wrote:
> When the Perl language programs are run from a Windows computer
> screen any error messages disappear so quickly they cannot be seen.
If my Perl scripts are generating that many errors, odds are they are
still under development. My text editor of choice under Windows is
UltraEdit. It has a feature that allows me to run the script from the
editor. The editor opens a command window, runs the script, captures the
output and writes the output to a new window in the editor.
I thought all of the better text editors had this feature. Would this be
a solution to the problem?
I use UltraEdit to run any Perl script I might otherwise run in a
command window precisely because of this feature.
------------------------------
Date: Sat, 21 Mar 2015 15:48:36 -0500
From: "E.D.G." <edgrsprj@ix.netcom.com>
Subject: Re: Error Messages
Message-Id: <1cCdnaR7JM29RJDInZ2dnUU7-RGdnZ2d@earthlink.com>
"E.D.G." <edgrsprj@ix.netcom.com> wrote in message
news:2cWdnRIT6qgqFZHInZ2dnUU7-RudnZ2d@earthlink.com...
Thanks for all the comments. This is the outcome of this effort for
the moment.
For programming and debugging purposes I have a simple Perl program
that uses a DO command to start a second very large and complex Perl
program.
The first one never changes and always compiles. If changes were
made to the the second one and it fails to compile, control returns to the
first one that remains running.
What I am now planning to do is put an error message redirect command
into the first program. It will execute when that one compiles. And I am
assuming that the redirect will remain active for the second program. So if
the second one fails to compile I will have a permanent record of any
compilation error messages.
These are not numerous or complex compilation errors. The longer
program contains quite a few complex math statements. And when someone
keeps adding lengthy math statements to any computer program, sooner or
later he or she will probably type something in wrong. So, all the error
messages need to do is identify the line number where a math or FOR loop
error was made and also what type of error it was. Then the error can be
easily identified and corrected.
Two of my important Perl programs are not usually started from the
DOS screen or with a run command or by double clicking on the program name
in a Windows screen. They are both used numerous times every day on
multiple computers and are started with Windows "Hot Keys."
The programs also have a form that they can run from any flash drive.
So, I can go to other locations and they will still run if Perl is active on
that computer. If it is not I use .exe versions of the programs or install
Perl.
To install Perl on other computers I use the original ActiveState 5.10
version. Then I erase all of the files in the Perl directory and copy over
my files from my regular Perl 5.10 directory. That way all of the necessary
modules are included. They don't have to be downloaded again. It works
quite well and saves a lot of time.
E.D.G.
------------------------------
Date: Sat, 21 Mar 2015 15:05:29 -0700
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: Error Messages
Message-Id: <2aqrgatb5v5i4bhbu18rhrauio2lljit2l@4ax.com>
"E.D.G." <edgrsprj@ix.netcom.com> wrote:
> These are not numerous or complex compilation errors. The longer
>program contains quite a few complex math statements. And when someone
>keeps adding lengthy math statements to any computer program, sooner or
>later he or she will probably type something in wrong.
Certainly correct. But then why on earth doesn't he test the new code he
has just written before publishing it? At the very least for compiler
errors?
Anyone who writes code and throws it at the user without this most basic
test should be banned from using a computer for life.
>So, all the error
>messages need to do is identify the line number where a math or FOR loop
>error was made and also what type of error it was. Then the error can be
>easily identified and corrected.
Well, yeah, that is what perl does.
> Two of my important Perl programs are not usually started from the
>DOS screen or with a run command or by double clicking on the program name
>in a Windows screen. They are both used numerous times every day on
>multiple computers and are started with Windows "Hot Keys."
Well, fine. There is just a tiny little difference between developing a
program and using a program in production.
Anyone using a program in production that hasn't been checked if at the
very least it passes the compiler should be banned from using a computer
for life.
> The programs also have a form that they can run from any flash drive.
>So, I can go to other locations and they will still run if Perl is active on
>that computer. If it is not I use .exe versions of the programs or install
>Perl.
Again, are you talking about program developement or about running a
program in production?
jue
------------------------------
Date: Sun, 22 Mar 2015 19:25:25 +0000
From: Henry Law <news@lawshouse.org>
Subject: Re: Error Messages
Message-Id: <1bWdnfI1C5e7ipLInZ2dnUVZ8s6dnZ2d@giganews.com>
On 20/03/15 21:34, jurgenex@hotmail.com wrote:
> I would assume that competent programmers know how to start a Perl
> program
Indeed so you would. So turn your logic round the other way: since
_this_ programmer doesn't know how to start a Perl program that way ...
what?
Actually, I'm surprised you don't recognise the poster's name and recall
the (long) history.
--
Henry Law Manchester, England
------------------------------
Date: Sun, 22 Mar 2015 17:31:20 -0400
From: Shmuel (Seymour J.) Metz <spamtrap@library.lspace.org.invalid>
Subject: Re: Error Messages
Message-Id: <550f34a8$1$fuzhry+tra$mr2ice@news.patriot.net>
In <b4coga5mjlgvnoo14v7e54ehctipmparhu@4ax.com>, on 03/20/2015
at 07:49 AM, J³rgen Exner <jurgenex@hotmail.com> said:
>That has nothing to do with Perl but is a standard feature of any
>command line shell,
No; there are shells that do not have redirection.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spamtrap@library.lspace.org
------------------------------
Date: Sun, 22 Mar 2015 20:11:34 +0000
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Subject: Re: Wait, lexical variables in loops do NOT always reallocate per-iteration.
Message-Id: <87lhiodc7d.fsf@doppelsaurus.mobileactivedefense.com>
Robbie Hatley <see.my.sig@for.my.address> writes:
> I'd quoted page 373 of The Camel Book, 4th ed, pdf version, as saying...
>
>> .... Finally, the following dangerous-looking code actually works fine:
>>
>> for $i (1..10) {
>> my @array = somefunc($i);
>> $AoA[$i] = \@array;
>> }
>>
>> That’s because the lexically scoped my @array variable is created
>> afresh on each pass through the loop...
>
> But on further experimentation, I see that it's NOT always true that
> lexical variables in loops re-allocate each iteration. They only do it
> if they have non-zero ref count.
>
> In the example above, a reference to @array is being stored in an
> array-of-array-refs on each iteration, so Perl retains a copy of
> @array each iteration.
>
> HOWEVER, if the ref count of a lexical variable declared in a loop is
> zero when loop bottom is reached, Perl re-uses the same memory address
> like C does.
This is not quite true: my $something actually creates a $something at
compile time and the same object will continue to be used for as long as
possible, as demonstrated by this program:
-------------
use Devel::Peek;
sub mydemo
{
for ($_[0] .. $_[1]) {
my $v = 'x' x 2**(11 - $_);
Dump($v);
BEGIN {
Dump($v);
print STDERR ("\t** what the compiler saw\n");
}
}
}
mydemo(1, 5);
print STDERR ("\t** now for the 2nd time\n");
mydemo(5, 10);
-------------
The address of $v itself never changes and it sticks to using the same
string buffer for as long as the new value will still fit in. That's
something to keep in my when storing large amount of data in lexical
variables.
------------------------------
Date: Sat, 21 Mar 2015 14:41:44 +0000 (UTC)
From: Kaz Kylheku <kaz@kylheku.com>
Subject: Re: Wait, lexical variables in loops do NOT always reallocate per-iteration.
Message-Id: <20150321074024.357@kylheku.com>
On 2015-03-21, Peter J. Holzer <hjp-usenet3@hjp.at> wrote:
> However, in many cases destroying a variable just to recreate it
> immediately again is wasteful. So if perl detects that it can safely
> reuse the same variable, it will do so.
In a language which has lexical closures, this kind of waffling about
behavior has somewhat deeper implications about the semantics.
If I capture lexical closures in the separate invocations of a loop,
do those closures share the variable? Or do they have their own?
------------------------------
Date: Sat, 21 Mar 2015 17:39:29 +0100
From: "Peter J. Holzer" <hjp-usenet3@hjp.at>
Subject: Re: Wait, lexical variables in loops do NOT always reallocate per-iteration.
Message-Id: <slrnmgr7m1.9en.hjp-usenet3@hrunkner.hjp.at>
On 2015-03-21 14:41, Kaz Kylheku <kaz@kylheku.com> wrote:
> On 2015-03-21, Peter J. Holzer <hjp-usenet3@hjp.at> wrote:
>> However, in many cases destroying a variable just to recreate it
>> immediately again is wasteful. So if perl detects that it can safely
>> reuse the same variable, it will do so.
>
> In a language which has lexical closures, this kind of waffling about
> behavior has somewhat deeper implications about the semantics.
>
> If I capture lexical closures in the separate invocations of a loop,
> do those closures share the variable? Or do they have their own?
They have their own of course. As I wrote, conceptionally, you always
get a fresh variable. The compiler is just free to reuse the space if
there is no possibility that the original variable may still be used. If
it is captured by a closure, this can of course not be guaranteed, so
the optimzation is not possible.
#!/usr/bin/perl
use v5.20;
use warnings;
sub f {
my @f;
for my $i (1..9) {
push @f, sub { $i *= 10; return $i };
}
return @f;
}
my @f = f();
for (@f) {
say $_->();
}
say "again";
for (@f) {
say $_->();
}
__END__
10
20
30
40
50
60
70
80
90
again
100
200
300
400
500
600
700
800
900
--
_ | Peter J. Holzer | Fluch der elektronischen Textverarbeitung:
|_|_) | | Man feilt solange an seinen Text um, bis
| | | hjp@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/ | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 4396
***************************************