Keep It Simple, Stupid PerlMonks

### factorial through recursion

by hnd (Scribe)
 on Jul 23, 2009 at 19:38 UTC Need Help??

hnd has asked for the wisdom of the Perl Monks concerning the following question:

why is this piece of code not working?
it shows a syntax error at line 10 and 13

```#factorial through recursion
use strict;
use warnings;
print "enter number\n";
my \$num=<>;
&fact(\$num,1);
print "factorial: \n";
##################
sub fact
{
my(\$num1,\$flag)=shift;
if(\$num1==0)
print "\$flag" and die "brrrrrrrreeeeeee :D\n";
else
{fact(\$num1-1,\$num1*\$flag);}
}
=====================================================
i'am worst at what do best and for this gift i fell blessed...
i found it hard it's hard to find well whatever
NEVERMIND

Replies are listed 'Best First'.
Re: factorial through recursion
by blokhead (Monsignor) on Jul 23, 2009 at 19:48 UTC
In addition to missing braces in the if-statement, you have a problem with this line:
```my(\$num1,\$flag)=shift;
shift only returns one element from @_. You probably mean:
```my(\$num1,\$flag)=@_;

Re: factorial through recursion
by ikegami (Patriarch) on Jul 23, 2009 at 19:55 UTC

In addition to the previously mentioned missing curlies,

• my(\$num1,\$flag)=shift; takes one value from @_ and assigns to the first of two. \$flag never gets a value. You want

```my \$num1 = shift;
my \$flag = shift;

or

```my (\$num1, \$flag) = @_;
• Then there's the issue that your program always dies. Return the value you find instead of dying. This will also allow you to remove the print from fact, which is appropriate since finding the factorial of a number has nothing to do with I/O.

• Finally, it's very weird that your factorial function takes two inputs. That's inconsistent with the mathematical function.

Solution:

Finally, it's very weird that your factorial function takes two inputs. That's inconsistent with the mathematical function.
Yes, but I note that his function looks similar to what a helper function would look like in a language with tail recursion optimization. It should still return a value instead of printing it though.
I have no problem with a helper function having more arguments.
```sub fact {
my (\$n) = @_;

local *_fact = sub {
my (\$n, \$prod) = @_;
return \$prod if \$n == 0;
return _fact(\$n-1, \$n*\$prod);
};

return _fact(\$n, 1);
}

fact(\$n);

In this case, you could even fake it as follows:

```sub fact {
my (\$n, \$prod) = @_;
\$prod ||= 1;
return \$prod if \$n == 0;
return _fact(\$n-1, \$n*\$prod);
}

fact(\$n);

But since Perl doesn't do tail recursion optimisation, and since sub calls are relatively slow, you're better off with:

```sub fact {
my (\$n) = @_;
my \$prod = 1;
\$prod *= \$n-- while \$n > 0;
return \$prod;
}

fact(\$n);
Re: factorial through recursion
by SuicideJunkie (Vicar) on Jul 23, 2009 at 19:45 UTC
Specifically, it says near the ") \n\t print"
You seem to be lacking a curly bracket right there between the ) and the print.
Re: factorial through recursion (diagnostics)
by toolic (Bishop) on Jul 23, 2009 at 20:13 UTC
You can also use diagnostics; to help debug errors (emphasis is mine).
```    (F) Probably means you had a syntax error.  Common reasons include
+:

A keyword is misspelled.
A semicolon is missing.
A comma is missing.
An opening or closing parenthesis is missing.
An opening or closing brace is missing.
```        A closing quote is missing.

Often there will be another error message associated with the synt
+ax
+)
The error message itself often tells you where it was in the line
+when
it decided to give up.  Sometimes the actual error is several toke
+ns
before this, because Perl is good at understanding random input.
Occasionally the line number may be misleading, and once in a blue
+ moon
the only way to figure out what's triggering the error is to call
perl -c repeatedly, chopping away half the program each time to se
+e
if the error went away.  Sort of the cybernetic version of S<20
questions>.
Re: factorial through recursion
by imrags (Monk) on Jul 24, 2009 at 06:56 UTC
Here's something that might work:
```#factorial through recursion
use strict;
use warnings;
print "enter number\n";
my \$num=<>;
my \$fac = &fact(\$num,1);
print "factorial: \$fac\n";
##################
sub fact
{
my(\$num1,\$flag)=@_;
if(\$num1==0) {
return \$flag;
#     print "\$flag" and die "brrrrrrrreeeeeee :D\n";
}
else
{fact(\$num1-1,\$num1*\$flag);}
}
It's good (better/best) to use return statement in recursive code!
Also, instead of shift, use @_
Raghu
Re: factorial through recursion
by Anonymous Monk on Jul 23, 2009 at 19:53 UTC
brrrrrrrreeeeeee :D

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://782769]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2022-01-23 10:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In 2022, my preferred method to securely store passwords is:

Results (63 votes). Check out past polls.

Notices?