perl subroutine

W

worlman385

what are the difference of below 2 factorial function?

the 1st return 0;
the 2nd return factorial result;

what 's the problem of 1st one?

sub factorial
{
$number = $_[0];

if ( $number == 0 ) {
1;
}
else {
$number * factorial( $number - 1 );
}
}

sub factorial
{
if ($_[0] == 0) {
1;
}
else {
$_[0] * factorial($_[0]-1);
}
}
 
M

Mirco Wahab

what are the difference of below 2 factorial function?

the 1st return 0;
the 2nd return factorial result;

what 's the problem of 1st one?

sub factorial
{
$number = $_[0];

if ( $number == 0 ) {
1;
}
else {
$number * factorial( $number - 1 );
}
}

The problem is the 'global' variable $number,
which has no definition within the actual stack
frame, so all accesses to $number refer to the
same variable (which gets overwritten by 0
in the deepest recursion).

Just use

my $number = $_[0];

and thats it.

BTW, next time use the usual prolog
and don't do 'cool' implicicte returns
if more then one return point.

use strict;
use warnings;

sub factorial {
my $number = $_[0];
return 1 if $number == 0;
return $number * factorial( $number - 1 );
}


Regards

M.
 
S

Sherm Pendley

what are the difference of below 2 factorial function?

the 1st return 0;
the 2nd return factorial result;

what 's the problem of 1st one?

The problem is the same with both - you're relying on an implicit return
of the last expression evaluated. That *happens* to work in the second,
but that's fragile and not recommended; even adding something completely
unrelated to the value you want to return (setting the value of a package
variable, for instance) could affect the value your sub returns.

Another problem is that you're not using 'strict', or properly declaring
your lexical variable $number.

You should use an explicit return() instead:
sub factorial
{
$number = $_[0];

my $number = $_[0];

# Or, more commonly, to allow you to easily add arguments:
# my ($number) = @_;
if ( $number == 0 ) { return 1;
}
else {
$number * factorial( $number - 1 );
} return $number;
}

sub factorial
{
if ($_[0] == 0) { return 1;
}
else {
return $_[0] * factorial($_[0]-1);

sherm--
 
J

John Bokma

Sherm Pendley said:
(e-mail address removed) writes:
# Or, more commonly, to allow you to easily add arguments:
# my ($number) = @_;

Or if you're sure it's 1 (or for other reasons):

my $number = shift;


No need for IMO else, because the if returns. I probably would have
written:

$number or return 1;

return $number;

Doesn't work. :-D

else {

return $number * factorial( $number - 1 );
}

or just (without the else):

return $number * factorial( $number - 1 );
 
J

John Bokma

Mirco Wahab said:
sub factorial {
my $number = $_[0];
return 1 if $number == 0;
return $number * factorial( $number - 1 );
}


or:

sub factorial {

my $number = $_[0];
return $number == 0
? 1
: $number * factorial( $number - 1 )
;
}
 
U

Uri Guttman

JB> No need for IMO else, because the if returns. I probably would have
JB> written:

JB> $number or return 1;

JB> else {

JB> return $number * factorial( $number - 1 );
JB> }

JB> or just (without the else):

JB> return $number * factorial( $number - 1 );

you are pushing a concept i have used for years and are now calling,
eschew else! :)

i hate seeing flow control in if blocks and then useles else blocks
which should be main level code. and if you use statement modifiers (or
or as you show) it makes things even cleaner. 10k lines of stem have
about 25 elses.

uri
 
J

John Bokma

Uri Guttman said:
you are pushing a concept i have used for years and are now calling,
eschew else! :)

:-D. I rarely use else, I prefer to exit early. I doubt I even have 25
elses in code that consist of 10k lines.
 
U

Uri Guttman

BTW, next time use the usual prolog
and don't do 'cool' implicicte returns
if more then one return point.

use strict;
use warnings;

sub factorial {
my $number = $_[0];
return 1 if $number == 0;
return $number * factorial( $number - 1 );
}

MD> Yeah, I like and use the implicit return all the time, but never ever
MD> with an if...else structure like that. Actually I wouldn't have even
MD> thought it to work. Appearently the return value is the last
MD> expression evaluated. Come to think of it: that's the documented way
MD> for things to happen. Whatever, it's just *too* implicit.

well we disagree on that one too. :) i strongly support using return
calls in almost all cases. there are some places (like a dispatch table
of short subs and or some very short regular subs) where i might do an
implicit return. but never as the result of an if/else. might as well
use ?: there which is what it is for.

i have more reasons to use return statements but i am not in the mood to
write them up. i am sure i have flamed about it before so google for it
if you want. :)

uri
 
A

anno4000

Michele Dondi said:
BTW, next time use the usual prolog
and don't do 'cool' implicicte returns
if more then one return point.

use strict;
use warnings;

sub factorial {
my $number = $_[0];
return 1 if $number == 0;
return $number * factorial( $number - 1 );
}

Yeah, I like and use the implicit return all the time, but never ever
with an if...else structure like that. Actually I wouldn't have even
thought it to work. Appearently the return value is the last
expression evaluated. Come to think of it: that's the documented way
for things to happen. Whatever, it's just *too* implicit.

I don't even think it *should* work. An if statement doesn't have
a value and nowhere else is it treated as if it had one.

my $y = if ( $x ) { 1 } else { 2 };

and

func( if ( $x ) { 1 ) else { 2 });

are syntax errors. So is an explicit return of an if-statement.
Only the implicit return coaxes a value out of an if-statement
that it otherwise doesn't have.

As sub whose last statement is a loop (while or for) returns empty,
not the value of the last statement executed in the loop. "if" should
behave likewise.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top