Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Jenda Krynicky
From: Eric Wilhelm <[EMAIL PROTECTED]>
> # The following was supposedly scribed by
> # David Golden
> # on Monday 28 February 2005 07:07 pm:
>
> >Which would you prefer?
> >
> >á á $ perl -le '$x=1/0; print $x+1' á á
> >á á Illegal division by zero at -e line 1.
> >
> >or
> >
> >á á $ perl -le '$x=1/0; print $x+1' á á
> >á á 1
>
> I like the one where you get the mathematically-correct (or at least
> mathematically-useful) infinity.
>
>   $perl -le 'use bigint; $x = 1/0; print $x+1'
>   inf

And is it +inf or -inf?

Let's see

1/1 = 1
1/0.1 = 2
1/0.01 = 4
1/0.001 = 8
...
lim( 1 / (1/10^n)) for n->inf = inf
vs.

1/-1 = -1
1/-0.1 = -10
1/-0.01 = -100
1/-0.001 = -1000
...
lim( 1 / -(1/10^n)) for n->inf = -inf

So, how did we get to the 0? Did we go from positive numbers or
negative numbers? And is the result positive or negative infinity?

>   $perl -le 'use bigint; $x = 1/0; print 1/$x'
>   0

Yep, in this case we know the final result "should" be 0, no matter
whether we define N/0 as plus or minus infinity, but ...

What's (inf - inf)? What's (inf / inf)? What's (inf < inf)?

No you do not want to start counting with infinities, unless you
really know what kind of beasts are you unleashing.

Jenda
= [EMAIL PROTECTED] === http://Jenda.Krynicky.cz =
When it comes to wine, women and song, wizards are allowed
to get drunk and croon as much as they like.
-- Terry Pratchett in Sourcery



Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread A. Pagaltzis
* Eric Wilhelm <[EMAIL PROTECTED]> [2005-03-01 06:45]:
> >Think about 1/(1/0) == 2/(1/0).
> 
> That sounds about right.

So you accept 1 == 2? Go ahead, then. :-)

> A real-world example where you really do want to operate on
> infinities is when you want to compare slopes of lines.  If
> $l[0][1] - $l[1][1] == 0, you might as well just divide and
> throw-around an infinity for your slope comparisons.

You can certainly correctly make assertions about the relationships
of infinities. That's not the same as operating on infinities,
eg. dividing by infinity getting a defined result.

Regards,
-- 
Aristotle
"If you can't laugh at yourself, you don't take life seriously enough."


Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Ofer Nave
Austin Schutz wrote:
	I suppose I could try to create a use divide 0/undef/inf/crap pragma.
Then you could do whatever you want. You'd still get a surprise if you ever
forgot it though..
 

I think that's the best answer.  Not a good idea for most programs, 
wonderful idea for math programs - which can simply say "use infinity;" 
or something along those lines at the top.

BTW-I'm reading Perl 6 Now, and I believe there was mention there about 
Perl 6 having support for infinity and possibly other equally strange 
notions.  I'm at work, though, so I don't have access to the book right now.

-ofer


Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Ken Williams
On Feb 28, 2005, at 7:55 PM, Eric Wilhelm wrote:
# The following was supposedly scribed by
# David Golden
# on Monday 28 February 2005 07:07 pm:
Which would you prefer?
    $ perl -le '$x=1/0; print $x+1'    
    Illegal division by zero at -e line 1.
or
    $ perl -le '$x=1/0; print $x+1'    
    1
I like the one where you get the mathematically-correct (or at least
mathematically-useful) infinity.
  $perl -le 'use bigint; $x = 1/0; print $x+1'
  inf
  $perl -le 'use bigint; $x = 1/0; print 1/$x'
  0
So, is that positive or negative infinity?  Sometimes that makes an 
awful lot of difference.

When you're wishing for 1/0 to be infinity, you're probably thinking of 
the limit as x->0 of 1/x.  And it matters which direction you approach 
0 from - if you approach from the right, the limit is infinity.  If you 
approach from the left, the limit is negative infinity.  If you don't 
specify the approach direction, the limit is undefined, even if you 
allow infinity in your computational system.

See also http://mathforum.org/dr.math/faq/faq.divideby0.html .  The 
explanations get progressively more advanced as you go down the page.

 -Ken


Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Fergal Daly
On Tue, Mar 01, 2005 at 12:50:35AM -0800, Austin Schutz wrote:
>   I don't know, but I do know that having the interpreter crap out
> is not helpful to most of us simpletons who find phrases like "core dumped"
> not especially user friendly.

If you haven't loaded some external module written in C then you should
never see "core dumped" coming from Perl. If you do, it's a bug and you
should report it.

I think most people (simpletons or not) should be able to understand
"Illegal division by zero at..." which is what Perl gives me when I divide
by zero.

If on the other hand this happens to you in C, you're simply experiencing
the downside of putting performance before error checking. Nothing is free,

F


Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Austin Schutz
On Tue, Mar 01, 2005 at 08:13:46AM +, Fergal Daly wrote:
> On Mon, Feb 28, 2005 at 07:55:36PM -0600, Eric Wilhelm wrote:
> > I like the one where you get the mathematically-correct (or at least 
> > mathematically-useful) infinity.
> > 
> >   $perl -le 'use bigint; $x = 1/0; print $x+1'
> >   inf
> > 
> >   $perl -le 'use bigint; $x = 1/0; print 1/$x'
> >   0
> 
> and what should these print?
> 
> $perl -le 'use bigint; $x = 2/0; print $x*0'
> 
> $perl -le 'use bigint; $x = 1/0; print ($x+1)-$x'
> 
> $perl -le 'use bigint; $x = 1/0; print ($x*2)/$x'
> 


I don't know, but I do know that having the interpreter crap out
is not helpful to most of us simpletons who find phrases like "core dumped"
not especially user friendly.

Maybe if there is a divide by zero you could set one of the cussword
variables ([EMAIL PROTECTED]@#$!) in addition to returning undef or inf, 
whatever. Then
if you mathematically correct types don't like the result you can make your
own, or go back to crapping out by kill(SIGBUS,$$).

I suppose I could try to create a use divide 0/undef/inf/crap pragma.
Then you could do whatever you want. You'd still get a surprise if you ever
forgot it though..

Austin



Re: Divide by 0? Was: Re: Introduction Letter

2005-03-01 Thread Fergal Daly
On Mon, Feb 28, 2005 at 07:55:36PM -0600, Eric Wilhelm wrote:
> I like the one where you get the mathematically-correct (or at least 
> mathematically-useful) infinity.
> 
>   $perl -le 'use bigint; $x = 1/0; print $x+1'
>   inf
> 
>   $perl -le 'use bigint; $x = 1/0; print 1/$x'
>   0

and what should these print?

$perl -le 'use bigint; $x = 2/0; print $x*0'

$perl -le 'use bigint; $x = 1/0; print ($x+1)-$x'

$perl -le 'use bigint; $x = 1/0; print ($x*2)/$x'


Allowing inf might make some sense in an interactive calculator but it's a
bad idea in a programming langague.

For example there's no way to evaluate $x/$y when both are inf or even $x *
0 when $x is inf. Perl would have to die with an Inf error. It's bad enough
trying to find the real source of a divide by zero error but for an Inf
error you might have to find 2 occurrences of divide by zero, figure out
which one is wrong and then go fix a divide by zero error. It's also
possible that neither of them is wrong and that both infs are supposed to be
there in which you have a big refactoring job ahead.

There is actually a system of arithmetic which allows infinitely large and
small values (it provides an infinite number of infinitely large/small
numbers) and produces "sensible" results for any expression, no matter if
the values involved are finite or inifintely large/small. In this system (x
* 2) / x is always 2 for any x, except x = 0 - even in this system division
by zero is not allowed.

http://mathforum.org/dr.math/faq/analysis_hyperreals.html

has a good explanation.

F


Re: Divide by 0? Was: Re: Introduction Letter

2005-02-28 Thread Eric Wilhelm
# The following was supposedly scribed by
# A. Pagaltzis
# on Monday 28 February 2005 11:24 pm:

>Are you *really* sure you want to do that?

Yes.  And don't try to take it away from me.  My right to shoot myself 
in the foot is as important as my right to bear arms.

>Think about 1/(1/0) == 2/(1/0).

That sounds about right.

>You really don't want to actually operate on infinities.

If you think about it pragmatically, it really does make a lot of sense.

A real-world example where you really do want to operate on infinities 
is when you want to compare slopes of lines.  If $l[0][1] - $l[1][1] == 
0, you might as well just divide and throw-around an infinity for your 
slope comparisons.  It works great.  One infinity is the same size as 
another, so your sorts work out (with -inf at the bottom, etc.)

Maybe infinity is bad (hah! really bad) if you're writing a banking 
application, but in geometry it works great.  Besides, you can't have 
pi without infinity (bad pun #2 left as exercise for the reader.)

--Eric
-- 
The opinions expressed in this e-mail were randomly generated by the 
computer and do not necessarily reflect the views of its owner. 
   -- Management
-
http://scratchcomputing.com
-


Re: Divide by 0? Was: Re: Introduction Letter

2005-02-28 Thread A. Pagaltzis
* Eric Wilhelm <[EMAIL PROTECTED]> [2005-03-01 04:25]:
>   $perl -le 'use bigint; $x = 1/0; print 1/$x'
>   0

Oh la la.

Are you *really* sure you want to do that?

Think about 1/(1/0) == 2/(1/0).

You really don't want to actually operate on infinities.

Regards,
-- 
Aristotle
"If you can't laugh at yourself, you don't take life seriously enough."


Re: Divide by 0? Was: Re: Introduction Letter

2005-02-28 Thread Eric Wilhelm
# The following was supposedly scribed by
# David Golden
# on Monday 28 February 2005 07:07 pm:

>Which would you prefer?
>
>    $ perl -le '$x=1/0; print $x+1'    
>    Illegal division by zero at -e line 1.
>
>or
>
>    $ perl -le '$x=1/0; print $x+1'    
>    1

I like the one where you get the mathematically-correct (or at least 
mathematically-useful) infinity.

  $perl -le 'use bigint; $x = 1/0; print $x+1'
  inf

  $perl -le 'use bigint; $x = 1/0; print 1/$x'
  0

--Eric
-- 
"Everything should be made as simple as possible, but no simpler." 
  -- Albert Einstein
-
http://scratchcomputing.com
-


Re: Introduction Letter

2005-02-28 Thread Buddy Burden
Aristotle,
Try
perlfunc system
just for a start.

Surely you mean
perldoc -f system
? :)
Sorry; yes, that's what I meant.  I aliased that so long ago I forgot it 
wasn't built in. 

		-- Buddy


Re: Divide by 0? Was: Re: Introduction Letter

2005-02-28 Thread David Golden
Austin Schutz wrote:
This is not related to the original topic, but I've always
wondered this: In math a number divided by 0 is "undefined". Why is it
that in a language which has an undefined value does the interpreter
poop out rather than just having the intuitively obvious behavior of
returning undef? Is that really by design, or just a legacy quirk they're
afraid to fix?
	Austin
 

Which would you prefer?
   $ perl -le '$x=1/0; print $x+1'
   Illegal division by zero at -e line 1.

or
   $ perl -le '$x=1/0; print $x+1'
   1

It only makes sense if "undef" in any arithmetic operation always gives 
"undef", which means that all variables have to be explicitly 
initialized to zero before you can perform any arithmetic on them.  That 
breaks tons of useful idioms and generally adds programming overhead. 

You shouldn't confuse "undefined" meaning "not definable" (math) with 
"not yet defined" (Perl).

David



Re: Introduction Letter

2005-02-28 Thread Ofer Nave
Andrew Savige wrote:
BTW, this slip-up is also a good advertisement for ensuring that your
test suite tests all examples given in your documentation to ensure
that they actually work.
 

Hey, good point.  I'll start with that, then.
I'm familiar with the make-up of the 16-bit return value of the system call.
What I want to learn more about is the possibility that a process could
crash and yet return a 0 exit code.  I had not thought that possible,
and hence, had seen no need to test for $? & 127.
   

I did a simple test on Linux.
This is file crash.c:
---
#include 
int main(int argc, char* argv[])
{
   return 5 / atoi(argv[1]);
}
---
After compiling with:
cc crash.c
running this Perl program:
use strict;
sub div_by_zero { exec("./a.out $_[0]"); die "should not be here" }
defined(my $pid = fork()) or die "fork: $!";
if ($pid == 0) {
   warn "child, my pid $$\n";
   div_by_zero(0);  # sig 8
   # div_by_zero(); # sig 11
   exit;
}
warn "parent, my pid $$\n";
waitpid($pid, 0);
my $rv  = $? >> 8;
my $sig = $? & 127;
warn "$$: rv=$rv sig=$sig\n";
produces:
parent, my pid 12091
child, my pid 12092
12091: rv=0 sig=8
Replacing div_by_zero() above with:
sub div_by_zero { 5 / shift }
produced:
parent, my pid 12133
child, my pid 12134
Illegal division by zero at g2.pl line 2.
12133: rv=255 sig=0
Perl is catching this one it seems. However, using this one:
sub div_by_zero { warn "sleeping"; sleep(60) }
then manually killing the child process (with SIGTERM), produces:
parent, my pid 12356
child, my pid 12357
sleeping at g2.pl line 3.
12356: rv=0 sig=15
It's pretty rare and no biggie to me, but if I were implementing it
I would check the signal value in addition to the return value.
 

That's why I wanted to get this on CPAN.  I knew others could point out 
things I'd never think of.  ;)

I just checked my code.  Here's what it's doing right now:
   $child_registry{$child}[1] = $? >> 8;
   $successes++ if ( $? == 0 );
I'm only saving the 8-bit exit value for the user to inspect, BUT I'm 
only considering the execution successful if all 16 bits are off, so 
that means your crash example above would be marked as a failure, even 
though the exit value is 0.

It seems like categorizing non-zero $? values as failures is still a 
good idea, but since it is possible that a block could fail and still 
return 0, that will confuse users inspecting the return value trying to 
figure out what went wrong.  The obvious solution is give the user all 
16 bits, instead of $? >> 8 for them.

Which sucks, cause no one likes doing the $? >> 8 part.  It's ugly.  I 
was hoping to Keep It Simple by doing it for them.

-ofer


Divide by 0? Was: Re: Introduction Letter

2005-02-28 Thread Austin Schutz
On Tue, Mar 01, 2005 at 11:43:31AM +1100, Andrew Savige wrote:
> running this Perl program:
> 
> use strict;
> sub div_by_zero { exec("./a.out $_[0]"); die "should not be here" }
> defined(my $pid = fork()) or die "fork: $!";
> if ($pid == 0) {
> warn "child, my pid $$\n";
> div_by_zero(0);  # sig 8
> # div_by_zero(); # sig 11
> exit;
> }
> warn "parent, my pid $$\n";
> waitpid($pid, 0);
> my $rv  = $? >> 8;
> my $sig = $? & 127;
> warn "$$: rv=$rv sig=$sig\n";
> 
> produces:
> 
> parent, my pid 12091
> child, my pid 12092
> 12091: rv=0 sig=8
> 
> Replacing div_by_zero() above with:
> 
> sub div_by_zero { 5 / shift }
> 
> produced:
> 
> parent, my pid 12133
> child, my pid 12134
> Illegal division by zero at g2.pl line 2.
> 12133: rv=255 sig=0
> 


This is not related to the original topic, but I've always
wondered this: In math a number divided by 0 is "undefined". Why is it
that in a language which has an undefined value does the interpreter
poop out rather than just having the intuitively obvious behavior of
returning undef? Is that really by design, or just a legacy quirk they're
afraid to fix?

Austin


Re: Introduction Letter

2005-02-28 Thread Andrew Savige
Ofer Nave wrote:
>>   die( Parallel::errplus() );
> Incidentaly, the above should have read "die( Parallel::Simple::errplus );".
> I left out the 'Simple::'. Amazing where you find bugs nowadays.  :)

Call me Mr Magoo. I mis-interpreted the 'Bareword "Parallel::errplus"
not allowed while "strict subs" in use' error message when I tried
running your example. In addition to helping people with poor eyesight,
always using () for user-defined function calls means you don't have
to change the code when you switch between "use Parallel::Simple"
and "require Parallel::Simple".

BTW, this slip-up is also a good advertisement for ensuring that your
test suite tests all examples given in your documentation to ensure
that they actually work.

> I'm familiar with the make-up of the 16-bit return value of the system call.
> What I want to learn more about is the possibility that a process could
> crash and yet return a 0 exit code.  I had not thought that possible,
> and hence, had seen no need to test for $? & 127.

I did a simple test on Linux.

This is file crash.c:
---
#include 
int main(int argc, char* argv[])
{
return 5 / atoi(argv[1]);
}
---

After compiling with:

cc crash.c

running this Perl program:

use strict;
sub div_by_zero { exec("./a.out $_[0]"); die "should not be here" }
defined(my $pid = fork()) or die "fork: $!";
if ($pid == 0) {
warn "child, my pid $$\n";
div_by_zero(0);  # sig 8
# div_by_zero(); # sig 11
exit;
}
warn "parent, my pid $$\n";
waitpid($pid, 0);
my $rv  = $? >> 8;
my $sig = $? & 127;
warn "$$: rv=$rv sig=$sig\n";

produces:

parent, my pid 12091
child, my pid 12092
12091: rv=0 sig=8

Replacing div_by_zero() above with:

sub div_by_zero { 5 / shift }

produced:

parent, my pid 12133
child, my pid 12134
Illegal division by zero at g2.pl line 2.
12133: rv=255 sig=0

Perl is catching this one it seems. However, using this one:

sub div_by_zero { warn "sleeping"; sleep(60) }

then manually killing the child process (with SIGTERM), produces:

parent, my pid 12356
child, my pid 12357
sleeping at g2.pl line 3.
12356: rv=0 sig=15

It's pretty rare and no biggie to me, but if I were implementing it
I would check the signal value in addition to the return value.

/-\


Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


Re: Introduction Letter

2005-02-28 Thread A. Pagaltzis
* Buddy Burden <[EMAIL PROTECTED]> [2005-02-28 19:20]:
> >I've also now removed any traces of the run() synonym.  You're
> >right - why complicate things with no benefit.
> 
> I didn't see anything wrong with the concept.  Personally I
> would have done it the other way around (i.e. make prun a
> synonym for Parallel::Simple::run), but that's a minor point.

Personally, I would pick yet another different approach: call the
function "run", but export it as "prun". When qualified with
Parallel::Simple::, even the very short "run" identifier is clear
and unambiguous. When exported, however, a simple "run" is more
likely to clash than "prun" and might be harder to search the
source for too.

> Oh, and I do agree with the comments about using
> 
>   *Parallel::Simple::run = \&prun;

Note that this is how exporting works -- the only difference is
that the left and right hand side of the assignment refer to
symbols in different packages. So there's a sort of natural
precedent for my preference of exporting with a longer name...

> Try
> 
>   perlfunc system
> 
> just for a start.

Surely you mean

perldoc -f system

? :)

Regards,
-- 
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;


Re: better SEE ALSO sections (was: Re: Introduction Letter)

2005-02-28 Thread Andy Lester
On Mon, Feb 28, 2005 at 04:05:09PM -0500, Mark Stosberg ([EMAIL PROTECTED]) 
wrote:
> I was hoping for more of a comparison with Data::Page, which is similar but
> already established.

AND at 100% Devel::Cover coverage, thanks to yours truly! :-)

xoxo,
Andy

-- 
Andy Lester => [EMAIL PROTECTED] => www.petdance.com => AIM:petdance


better SEE ALSO sections (was: Re: Introduction Letter)

2005-02-28 Thread Mark Stosberg
On Mon, Feb 28, 2005 at 08:57:04AM -0500, Christopher Hicks wrote:
> 
> This is a phenomenal initial cut of a POD.  The review of relevant other 
> modules in SEE ALSO and the philisophical differences with each deserves 
> particular note.  Bravo.

I share your appreciation.

I agree that this part of the documentation is frequently sub-optimal
from a users perspective, especially when a new alternative appears 
when they are several standard options. 

For example (and not to pick on a particular module), here's one that was
just released today:

http://search.cpan.org/~jbuhacoff/Data-SimplePaginator-0.1/lib/Data/SimplePaginator.pm

I was hoping for more of a comparison with Data::Page, which is similar but
already established.

Mark


Re: Introduction Letter

2005-02-28 Thread Ofer Nave
Buddy Burden wrote:
Ofer,
With all due respect to Andrew, please remember that his is but one 
opinion.

I've also now removed any traces of the run() synonym.  You're right 
- why complicate things with no benefit.

I didn't see anything wrong with the concept.  Personally I would have 
done it the other way around (i.e. make prun a synonym for 
Parallel::Simple::run), but that's a minor point.  To me, run is a 
perfectly reasonable name for the function when fully qualified, but 
it makes sense not to export (even only when requested) such a simple 
function name into the global namespace.  In fact, I might go even 
further and name it par_run or somesuch.  But that's just me.

True, but my own thoughts were already somewhat in tune with Andrew's 
suggestion.  Having two names was cluttering the docs, with the only 
benefit being the lack of the redundant 'p' on fully-qualified calls.

Oh, and I do agree with the comments about using
*Parallel::Simple::run = \&prun;
instead of the way you've done it.  That's the proper way to create a 
"synonym" IMHO.

What's funny is that I actually like the parentheses, since I strive 
to avoid any ambiguity, but I left them off here because I was trying 
to make my first CPAN module as perl-ish as possible - when in Rome 
and all that.  I'll add parentheses back on.

Using the "without parends" style is perfectly valid.  It won't cause 
a bareword error unless the subroutine is undefined.  Many people 
prefer it.  I personally use both ... I know that would drive many 
people crazy as inconsistent, but I actually feel that sometimes it 
seems more natural with and sometimes without.  Bottom line is go with 
whichever you personally prefer.

Personally, I almost always prefer parens on function calls.  For 
built-ins, my philosophy is more complicated, and I won't go into it 
here.  :)

I've added them for the docs, since the point of docs is to make things 
as clear as possible.  Users can always do their own thing, as usual.  :)

Seriously?  Is there anywhere I can learn more about this?

Try
perlfunc system
just for a start.
No, I'm familiar with the make-up of the 16-bit return value of the 
system call.  What I want to learn more about is the possibility that a 
process could crash and yet return a 0 exit code.  I had not thought 
that possible, and hence, had seen no need to test for $? & 127.

-ofer


Re: Introduction Letter

2005-02-28 Thread Buddy Burden
Ofer,
With all due respect to Andrew, please remember that his is but one opinion.
I've also now removed any traces of the run() synonym.  You're right - 
why complicate things with no benefit.
I didn't see anything wrong with the concept.  Personally I would have done it 
the other way around (i.e. make prun a synonym for Parallel::Simple::run), but 
that's a minor point.  To me, run is a perfectly reasonable name for the 
function when fully qualified, but it makes sense not to export (even only 
when requested) such a simple function name into the global namespace.  In 
fact, I might go even further and name it par_run or somesuch.  But that's 
just me.

Oh, and I do agree with the comments about using
*Parallel::Simple::run = \&prun;
instead of the way you've done it.  That's the proper way to create a 
"synonym" IMHO.

What's funny is that I actually like the parentheses, since I strive to 
avoid any ambiguity, but I left them off here because I was trying to 
make my first CPAN module as perl-ish as possible - when in Rome and all 
that.  I'll add parentheses back on.
Using the "without parends" style is perfectly valid.  It won't cause a 
bareword error unless the subroutine is undefined.  Many people prefer it.  I 
personally use both ... I know that would drive many people crazy as 
inconsistent, but I actually feel that sometimes it seems more natural with 
and sometimes without.  Bottom line is go with whichever you personally prefer.

Seriously?  Is there anywhere I can learn more about this?
Try
perlfunc system
just for a start.
		-- Buddy


Re: Introduction Letter

2005-02-28 Thread Ofer Nave
Andrew Savige wrote:
--- Ofer Nave wrote: 
 

Here's the POD for my new Parallel::Simple module:
   

Interface
-
To me, offering both:
   Parallel::Simple::run()
and:
   Parallel::Simple->run()
just makes the interface bigger -- more for the user to read and
grok -- without any benefit (at least, none I can see). Suggest
you drop the second form (which does not currently work correctly
because the class name is passed as the first parameter and is not
being shifted). Ditto for offering the run() synonym for prun().
 

I realized last night that it's impossible for me to support both 
syntaxes with anything better than a total hack, so I'm throwing it 
out.  In fact, I've replaced all occurances of the word 'method' with 
'function'.  It's no an OO module, it doesn't need method calling 
syntax.  I just tried to put it in initially because 'class methods' 
seem all the rage now, and I thought I'd just follow the example of 
those I respect.

I've also now removed any traces of the run() synonym.  You're right - 
why complicate things with no benefit.

Naming. I wonder if your:
   { use_return => 1 },
is the recommended Perl style for named parameters? I thought not
until I noticed HTML::Parser uses this style. Alternatives are
CamelCase style (a la XML::Parser, for example):
   { UseReturn => 1 },
or dash-option style (a la CGI, for example):
   { -use_return => 1 },
I'm damned if I can find a reference clearly stating which one of
these three styles is preferred. Can anyone point me to a reference
on this?
 

I've seen all three.  They're all good, so I'm up for using any one of 
them.  I chose all-lowercase initially to match the identifer naming 
conventions.

Your example:
  die( Parallel::errplus );
should be written:
  die( Parallel::errplus() );
to avoid bareword error under use strict.
 

Again, I copied that convention from the greats - in this case, 
DBI::errstr.  In the examples, Tim never includes the parentheses.

What's funny is that I actually like the parentheses, since I strive to 
avoid any ambiguity, but I left them off here because I was trying to 
make my first CPAN module as perl-ish as possible - when in Rome and all 
that.  I'll add parentheses back on.

Incidentaly, the above should have read "die( Parallel::Simple::errplus 
);".  I left out the 'Simple::'.  Amazing where you find bugs nowadays.  :)

Implementation
--
Just a couple of micro-optimizations I noticed.
This function synonym:
sub run { prun( @_ ) }
is better implemented as:
sub run { &prun }
This special form of sub call makes current @_ visible to called
subroutine. I suppose the primitive-obsessed might prefer:
*Parallel::Simple::run = \&prun;
 

After sending my email out, I discovered that realpath() is an alias in 
the Cwd module and hit the source to see how it's being done.  They're 
using the function aliasing style, which I believe is the fastest ( 
*alias  = \&function ), so I changed my code to that style.  Of course, 
five minutes ago I got rid of the alias entirely (per your suggestion), 
so this is no longer relevant.

In a couple of places, I noticed:
   /HASH/o
The /o modifier is meaningless here and should be removed.
 

Ok.
You get the return code here:
   $child_registry{$child}[1] = $? >> 8;
yet miss getting if it died hard from a signal via:
   $? & 127;
Further getting whether it dumped core via:
   $? & 128;
is probably overkill. Not sure how this would affect your interface,
but I've seen cases where a process crashes yet returns a $? >> 8
of zero while $? & 127 is 11 (SIGSEGV).
 

Seriously?  Is there anywhere I can learn more about this?
-ofer


Re: Introduction Letter

2005-02-28 Thread Dave Rolsky
On Mon, 28 Feb 2005, Andrew Savige wrote:
Naming. I wonder if your:
   { use_return => 1 },
is the recommended Perl style for named parameters? I thought not
This is pretty common.  Pretty much every module I've written uses it ;)
-dave
/*===
VegGuide.Orgwww.BookIRead.com
Your guide to all that's veg.   My book blog
===*/


Re: Introduction Letter

2005-02-28 Thread 'A. Pagaltzis'
* Orton, Yves <[EMAIL PROTECTED]> [2005-02-28 14:45]:
> > messy. Four thumbs down to this idea.
> 
> You have four thumbs Aristotle? Must make for a crowded space
> bar eh?

Heh, got me. I was referring to thumbs + big toes, wrongly
assuming the toes are called thumbs in English. I actually had to
rummage around in my memory when it occured to me that they're
not called the same as thumbs in German either. It is becuase
there are no separate words for toes or thumbs in Greek. The
thumb is just the "big finger", and the toes are "fingers of the
foot", and the big toe is referred to as big finger of the foot.

So basically, four big fingers down to the idea.

Okay, that was very offtopic.

Regards,
-- 
Aristotle
"If you can't laugh at yourself, you don't take life seriously enough."


Re: Introduction Letter

2005-02-28 Thread Christopher Hicks
On Sun, 27 Feb 2005, Ofer Nave wrote:
Here's the POD for my new Parallel::Simple module:
NAME
 Parallel::Simple - the simplest way to run code blocks in parallel
SEE ALSO
 Parallel::ForkControl, Parallel::ForkManager, and Parallel::Jobs are
 all similarly themed, and offer different interfaces and advanced fea-
 tures.  I suggest you skim the docs on all three (in addition to mine)
 before choosing the right one for you.  Or you can foolishly trust the
 executive summaries below:
 Parallel::ForkControl
 Only takes one subroutine reference to run, but provides wonderful
 ways to control how many children are forked and keeping activity
 below certain thresholds.  Arguments to the run() method will be
 passed on to the subroutine you specified during construction, so
 there's some run-time flexibility.  It is not yet possible to learn
 anything about what happened to the forked children, such as
 inspecting return or exit values.
 Conclusion: Best for repetitive, looped tasks, such as fetching web
 pages or running a command across a cluster of machines in paral-
 lel.
 Incidentally, Parallel::ForkControl would be far more useful with
 the following two changes:
 o   Support some kind of feedback - return/exit values at a mini-
 mum, or even a single value summary, like the return value of
 my prun method.
 o   Allow the user to specify the Code value in the run method
 instead of during construction.  Then Parallel::ForkControl
 could do everything this module does and more, albeit with a
 more sophisticated interface.
 Parallel::ForkManager
 Unique in the Parallel::* world in that it keeps the user somewhat
 involved in the forking process.  Rather than taking a code refer-
 ence, you call the start() method to fork and test the return value
 to determine whether you are now the parent or child... almost like
 just calling fork yourself.  :)
 Provides control over how many child processes to allow, and blocks
 new forks until some previous children have exited.  Let's child
 determine the process exit value.  Provides a trigger mechanism to
 run callbacks when certain events happen (child start, child exit,
 and start blocking).  You must supply a callback for the child exit
 event to inspect the exit value of the child.
 Conclusion: While also designed for repetitive, looped tasks, it is
 far more flexible, being a thin wrapper around fork rather than
 taking over child creation and management entirely.  Useful mostly
 if you want to limit child processes to a certain number at a time
 and/or if the native system calls scare you.
 Parallel::Jobs
 Different in that it executes shell commands as opposed to subrou-
 tines or code blocks.  Provides all the features of the open3 func-
 tion, including explicit control over STDIN, STDOUT, and STDERR on
 all 'jobs'.  Lets you monitor jobs for output and exit events (with
 associated details for each event).
 Conclusion: Great for shell commands!  Not great for not shell com-
 mands.
This is a phenomenal initial cut of a POD.  The review of relevant other 
modules in SEE ALSO and the philisophical differences with each deserves 
particular note.  Bravo.

--

"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)


Re: Introduction Letter

2005-02-28 Thread Christopher Hicks
On Mon, 28 Feb 2005, Torsten Schoenfeld wrote:
 http://lists.netthink.co.uk/listinfo/code-review-ladder
That box was having hardware problems last week.  The maypole lists were 
on the box (now they're on SrcFrg), so maybe this has moved somewhere else 
too.

--

"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)


RE: Introduction Letter

2005-02-28 Thread Orton, Yves
Title: RE: Introduction Letter





> messy. Four thumbs down to this idea.


You have four thumbs Aristotle? Must make for a crowded space bar eh?


;-)


Yves





Re: Introduction Letter

2005-02-28 Thread A. Pagaltzis
* Andrew Savige <[EMAIL PROTECTED]> [2005-02-28 10:25]:
> Naming. I wonder if your:
> 
> { use_return => 1 },
> 
> is the recommended Perl style for named parameters? I thought
> not until I noticed HTML::Parser uses this style.

File::Find also uses this. So do a large number of OO modules
which use named parameters. This style follows accepted naming
practice for variables and subs/methods.

> Alternatives are CamelCase style (a la XML::Parser, for
> example):

Yuck. We look down on that in variable and sub/method names; why
would we prefer it for hash keys?

> or dash-option style (a la CGI, for example):

Ech! This meme should be killed with great prejudice. It makes
code noisy for no good reason. Try reading the source of a
complex Tk GUI and tell me if you don't think it looks ugly and
messy. Four thumbs down to this idea.

Regards,
-- 
#Aristotle
*AUTOLOAD=*_=sub{s/(.*)::(.*)/print$2,(",$\/"," ")[defined wantarray]/e;$1};
&Just->another->Perl->hacker;


Re: Introduction Letter

2005-02-28 Thread Ricardo SIGNES
* Andrew Savige <[EMAIL PROTECTED]> [2005-02-28T04:22:04]
> This function synonym:
> 
> sub run { prun( @_ ) }
> 
> is better implemented as:
> 
> sub run { &prun }

...which, in turn, is better implemented as 

sub run { goto &prun }

because it will never have to return to &run.  The return value of &prun
will be returned directly.

Or, finally:

*run = \&prun

which will just make calls to &run invoke &prun directly.

-- 
rjbs


pgp66ooVqWZSK.pgp
Description: PGP signature


Re: Introduction Letter

2005-02-28 Thread David Landgren
Andrew Savige wrote:
[...]
Naming. I wonder if your:
   { use_return => 1 },
is the recommended Perl style for named parameters? I thought not
until I noticed HTML::Parser uses this style. Alternatives are
 

I like this style.
CamelCase style (a la XML::Parser, for example):
   { UseReturn => 1 },
 

I think this is yucky. Its use is eschewed for variable names (perlstyle 
says that it's harder for non-native English speakers) so I don't see 
that it has any legitimate use for hash keys (which are nothing more 
than second-class variable names).

or dash-option style (a la CGI, for example):
   { -use_return => 1 },
 

I'm not too fond of this either. I've always felt that it's trying to 
emulate command line switches, poorly. It fails on "multi word" names. A 
longword switch should be written as --use-return, at least according to 
long-standing tradition. It grates on my nerves when I see switches that 
mix dashes and underscores like --use_return. That just feels wrong, as 
if the author isn't aware of prior art.

And so if you accept my hypotheses that --use-return is the Right Thing, 
then you can't specify that as a hash key bareword. Hence I judge it to 
be a failure.

So I would tend to consider that { use_return => 1 } is the preferred 
way. I certainly find it to be the most appealing from a visual point of 
view.

I'm damned if I can find a reference clearly stating which one of
these three styles is preferred. Can anyone point me to a reference
on this?
 

Nor can I, but my gut feeling is that most of the modules I use on a 
regular basis use the first form.

David


Re: Introduction Letter

2005-02-28 Thread Torsten Schoenfeld
On Sun, 2005-02-27 at 16:28 -0800, Ofer Nave wrote:

> 2) requesting feedback on design/implementation

For reviews there's also the code-review-ladder:

  http://lists.netthink.co.uk/listinfo/code-review-ladder

-- 
Bye,
-Torsten



Re: Introduction Letter

2005-02-28 Thread Andrew Savige
--- Ofer Nave wrote: 
> Here's the POD for my new Parallel::Simple module:

Interface
-

To me, offering both:

Parallel::Simple::run()

and:

Parallel::Simple->run()

just makes the interface bigger -- more for the user to read and
grok -- without any benefit (at least, none I can see). Suggest
you drop the second form (which does not currently work correctly
because the class name is passed as the first parameter and is not
being shifted). Ditto for offering the run() synonym for prun().

Naming. I wonder if your:

{ use_return => 1 },

is the recommended Perl style for named parameters? I thought not
until I noticed HTML::Parser uses this style. Alternatives are
CamelCase style (a la XML::Parser, for example):

{ UseReturn => 1 },

or dash-option style (a la CGI, for example):

{ -use_return => 1 },

I'm damned if I can find a reference clearly stating which one of
these three styles is preferred. Can anyone point me to a reference
on this?

Your example:

   die( Parallel::errplus );

should be written:

   die( Parallel::errplus() );

to avoid bareword error under use strict.

Implementation
--

Just a couple of micro-optimizations I noticed.

This function synonym:

sub run { prun( @_ ) }

is better implemented as:

sub run { &prun }

This special form of sub call makes current @_ visible to called
subroutine. I suppose the primitive-obsessed might prefer:

*Parallel::Simple::run = \&prun;

In a couple of places, I noticed:

/HASH/o

The /o modifier is meaningless here and should be removed.

You get the return code here:

$child_registry{$child}[1] = $? >> 8;

yet miss getting if it died hard from a signal via:

$? & 127;

Further getting whether it dumped core via:

$? & 128;

is probably overkill. Not sure how this would affect your interface,
but I've seen cases where a process crashes yet returns a $? >> 8
of zero while $? & 127 is 11 (SIGSEGV).

HTH,
/-\


Find local movie times and trailers on Yahoo! Movies.
http://au.movies.yahoo.com


Re: Introduction Letter

2005-02-27 Thread Ofer Nave
No problem.
BTW-It has nothing to do with the IO:: modules - I was just using that 
as an example illustrating the degrees of seriousness when considering 
namespace requests.  As in, if I *were* creating an IO:: module, 
namespace usage would be more closely scrutinized that my 
Parallel::Simple module likely will be.  That is, I don't expect to have 
to defend my module's name this time, but while we're on the topic of 
best practices, I thought I'd ask for future reference.  This is 
actually very relevant to me, since I'm also working on another module 
right now for which I would like a new top level namespace, but I won't 
get in to that now.

Here's the POD for my new Parallel::Simple module:
NAME
  Parallel::Simple - the simplest way to run code blocks in parallel
SYNOPSIS
   use Parallel::Simple qw( prun );
   # Style 1 - Simple List of Code Blocks
   prun(
   sub { print "$$ foo\n" },
   sub { print "$$ bar\n" },
   ) or die( Parallel::errplus );
   # Style 1 with options
   prun(
   { use_return => 1 },
   sub { print "$$ foo\n" },
   sub { print "$$ bar\n" },
   ) or die( Parallel::errplus );
   # Style 2 - Named Code Blocks (like the Benchmark module)
   prun(
   foo => sub { print "$$ foo\n" },
   bar => sub { print "$$ bar\n" },
   ) or die( Parallel::errplus );
DESCRIPTION
  I generally write my scripts in a linear fashion.  Do A, then B, then
  C.  However, I often have parts that don't depend on each other, and
  therefore don't have to run in any particular order, or even 
linearly.
  I could save time by running them in parallel - but I'm too lazy to
  deal with forking, and reaping zombie processes, and other nastiness.

  The goal of this module is to make it so mind-numbingly simple to run
  blocks of code in parallel that there is no longer any excuse not 
to do
  it, and in the process, drastically cut down the runtimes of many of
  our applications, especially when running on multi-processor servers
  (which are pretty darn common these days).

  Parallel code execution is now as simple as calling prun and 
passing it
  a list of code blocks to run, followed by testing the return 
value for
  truth using the common "or die" perl idiom.

EXPORTS
  By default, Parallel::Simple does not export any symbols.  You gener-
  ally want to export the prun method to save time:
  use Parallel::Simple qw(prun);
  prun( ... );
  But you don't have to:
  use Parallel::Simple;
  Parallel::Simple::run( ... );
  The run method is a synonym for prun, and exists for people who don't
  want to export any symbols, because Parallel::Simple::run() looks 
nicer
  than Parallel::Simple::prun().

METHODS
  All of the following may be called as class methods:
  Parallel::Simple->run()
  Or as normal subroutines:
  Parallel::Simple::run()
  run Synonym for prun.
  prun
  Runs multiple code blocks in parallel by forking a process 
for each
  one and returns when all processes have exited.

  Style 1 - Simple List of Code Blocks
  In its simplest form (which is what we're all about 
here), prun
  takes a list of code blocks and then forks a process to run
  each block.  It returns true if all processes exited with 
exit
  value 0, false otherwise.  Example:

  prun(
  sub { print "$$ foo\n" },
  sub { print "$$ bar\n" },
  ) or die( Parallel::errplus );
  By default, the exit value will be 255 if the code block dies
  or throws any exceptions, or 0 if it doesn't.  You can 
exercise
  more control over this by using the use_return option (docu-
  mented below) and returning values from your code block.

  If prun returns false and you want to see what went 
wrong, try
  the err, errplus, and rv methods documented below - 
especially
  rv which will tell you the exit values of the processes that
  ran the code blocks.

  Style 2 - Named Code Blocks
  Alternatively, you can specify names for all of your code
  blocks by using the common "named params" perl idiom.  
The only
  benefit you get from this currently is an improved lookup
  method for code block return values (see rv for more 
details).
  Example:

  prun(
  foo => sub { print "$$ foo\n" },
  bar => sub { print "$$ bar\n" },
  ) or die( Parallel::errplus );
  Other than looking nicer, this behaves identically to the 
Style
  1 example.

  Options
  You can optionally pass a reference to a hash containi

Re: Introduction Letter

2005-02-27 Thread Lincoln A. Baxter
Hello Ofer,

Motivate us!

Tell the list why we should look at it.  What does it do? How does it
solve a problem that is not already solved, or solves it better?

I get the sense from the brief comment you made about IO:: that it has
to do with some mechanism for implementing parallel IO?  

Pasting the POD is often a good way to do this.

Lincoln




On Sun, 2005-02-27 at 16:28 -0800, Ofer Nave wrote:
> Hello everyone.
> 
> I just subscribed to this list, I just recently received my PAUSE 
> account, and I just finished writing/documenting/testing the first perl 
> module that I've written for CPAN.  I'd like to know what is considered 
> a good set of practices for new modules with regards to:
> 
> 1) naming
> 2) requesting feedback on design/implementation
> 3) announcing the module
> 4) informing authors of similar modules
> 
> In this case, the I've already named the module Parallel::Simple, but I 
> imagine things would be trickier if I want to call it IO:: something or 
> create a new top-level namespace.
> 
> Here's the module, if anyone is interested:
> 
> http://ofernave.com/pm/
> 
> I've already sent copies to my local perl mongers group and posted it on 
> comp.lang.perl.modules, and I've gotten a little bit of feedback on it.  
> I'm comfortable with the design as it stands right now, and only need 
> write some formal tests before it will be ready for its first upload.
> 
> -ofer
>