We have already used different functions but in this section we are going to make our own functions.

## Why do we need functions?

**Function** or **subroutine** or **method** is a set of codes written together in our program and given a name. We can call that set of program at any place of our code by just calling its name and without writing the whole set of codes again.

Let's take an example.

```
sub print_poem{
print "I am a programmer
You have a hammer
I like code
and I hate load\n";
}
print_poem();
```

You have a hammer

I like code

and I hate load

**sub** is a keyword used for making functions. We first write **sub** and then the name of the function to make a function.

**print_poem** is the name of the function. It means that we can use all the codes written inside it by just using this name.

**print_poem();** - Here we have called the print_poem function and then the codes inside it got executed.

**{ }**to represent the body of a function.

## Passing arguments to function

We can also pass arguments to a function while calling it. It means that we can pass a value to a function while calling it. Passed arguments are stored inside a function in an array **@_**. It means that whatever you have passed, it will be stored in this array (**@_**) and to access them, we need to access the elements of this array. We can access the 1^{st} passed argument as **$_[0]**, 2^{nd} passed argument as **$_[1]** and so on.

Suppose you have written a function to check if a number is even or not, then you can pass different numbers while calling the function to check. It will be clear by the example given below:

```
sub is_even{
$x = $_[0];
if ($x%2 == 0){
print "even\n";
}
else{
print "odd\n";
}
}
is_even(2);
is_even(3);
```

odd

**is_even** is the name of the function.**$x = $_[0]** - Our first passed parameter will be **$_[0]** in function.

2 is passed in the first function call. In the function, $_[0] is 2 (as we have passed 2).

In the same way, during second time, 3 is passed. So, $_[0] is 3 there.

Once a function is called, codes inside the function are executed. So, when is_even(2) was called, then the codes inside the function 'is_even' were executed with '$_[0]=2'.

As we saw here, we have not passed any parameter. Whenever we want to print the whole poem, we just have to call that function.

Let's see one more example for calculating the sum of the numbers passed to the function:

```
sub sum{
$s = 0;
foreach $i (@_){
$s = $s + $i;
}
print "$s\n";
}
sum(2,5);
sum(5,2,3);
```

10

In the above example, we are accessing every element of our function **sum** using array **@_**. So, when we called 'sum(2,5)', **@_** became (2,5) and when we called 'sum(5,2,3)', **@_** became (5,2,3).

**shift**function to extract the first element of the array @_. shift(@array_name) extracts the first element of an array 'array_name' but using only

**shift**will extract the first element of the array @_.

```
sub is_even{
$x = shift;
if ($x%2 == 0){
print "even\n";
}
else{
print "odd\n";
}
}
is_even(2);
is_even(3);
```

odd

## Returning from a function

Functions can do one more thing, they can return you something. This means that these can give you something back. This will be clearer from the following examples. Let's see how:

```
sub is_even{
$x = $_[0];
if ($x%2 == 0){
return 1;
}
else{
return 0;
}
}
print is_even(1),"\n";
print is_even(2),"\n";
```

1

Here, our function is returning us a number (0 or 1). So, after 1 is returned from 'is_even(2)', the statement **print is_even(2),"\n";** became equivalent to **print 1,"\n";**. Let's see one more example.

```
sub rev{
@c = ();
$i = scalar@_-1;
while ($i>=0){
push(@c,$_[$i]);
$i = $i-1;
}
return @c;
}
@z = rev(2,4,6,3,5,2,6,43);
print "@z\n";
```

Here, our function is returning an array.

## Calling a function inside another function

Yes, we can call a function inside another function.

Let's take an example of checking a number's divisibility with 6. For a number to be divisible by 6, it must be divisible by both 2 and 3. In the example given below, we have a function **is_even** to check its divisibility with 2. **div6** function calls the **is_even** inside itself to check the number's divisibility with both 2 and 3. Let's see how:

```
sub is_even{
$x = $_[0];
if ($x%2 == 0){
return 1;
}
else{
return 0;
}
}
# div6 function to check divisiblity by 6
sub div6{
$y = $_[0];
if (is_even($y) && $y%3 == 0){
return 1;
}
else{
return 0;
}
}
```

We have called **is_even** function inside **div6** function.

Here, **is_even** will return 1 if the given number is even or divisible by 2. And **if (is_even($y) and $y%3 == 0)** will be true only if **is_even** and **$y%3==0** both are true, which means that the number is divisible by both 2 and 3 or divisible by 6.

## Recursion

Recursion is calling a function inside the same function. Before going into this, let's learn some mathematics.

We will calculate the factorial of a number. Factorial of any number n is (n)*(n-1)*(n-2)*....*1 and written as (n!) and read as 'n factorial'.

e.g.:

4! = 4*3*2*1 = 24

3! = 3*2*1 = 6

2! = 2*1 = 2

1! = 1

Also, **0! = 0**

Let's code to calculate the factorial of a number:

```
sub fac{
my($x) = $_[0];
if ($x == 0 || $x == 1){
return 1;
}
else{
return $x*fac($x-1);
}
}
print fac(0),"\n";
print fac(1),"\n";
print fac(4),"\n";
print fac(5),"\n";
print fac(10),"\n";
```

1

24

120

3628800

Let's go through this code.

If we give 0 or 1, our function will return 1 because the vaue of both 0! and 1! are 1. It is very simple till here. Now see what happens if we pass 2 to our function 'fac'**else{ return x*fac(x-1)}**

Going for fac(x-1) i.e. fac(1) which is 1. ( This is called recursion, the fac function is called inside itself ). So, it is 2*factorial(1) = 2*1 i.e. 2.

So, it will return 2.

Now see for 3:

x*factorial(x-1)

3*factorial(2) Now fac(2) will be called and then it will be

**2*fac(1)**:

3*2*fac(2) Since, fac(2) will be 2*fac(2-1)

3*2*1

So, it will return 6.

For 4

4*fac(3)

4*3*fac(2)

4*3*2*fac(1)

4*3*2*1

You have just done something which most beginners have a tough time doing. Go and get yourself a cookie.

## use warnings and use strict

**use strict** is used to make sure that all the variables are declared with **my**. It minimizes the number of errors. We write **use strict;** at the beginning of our program to use this.

**use warnings** is used to emit warnings if we are doing wrong things. We declare it also at the top of our program by writing **use warnings;**.

Let's write the above code using these two and without my and see what happens.

```
use strict;
use warnings;
sub fac{
$x = $_[0];
if ($x == 0 || $x == 1){
return 1;
}
else{
return $x*fac($x-1);
}
}
print fac(0),"\n";
print fac(1),"\n";
print fac(4),"\n";
print fac(5),"\n";
print fac(10),"\n";
```

Global symbol "$x" requires explicit package name at a.pl line 5.

Global symbol "$x" requires explicit package name at a.pl line 5.

Global symbol "$x" requires explicit package name at a.pl line 9.

Global symbol "$x" requires explicit package name at a.pl line 9.

Execution of a.pl aborted due to compilation errors.

## Do you know Fibonacci series?

It is a series having its 0^{th} and 1^{st} terms 0 and 1 respectively.

2,4,6,8,10,... is a series. Its n

^{th}term is n*2. Eg- 1

^{st}term is 2*1 = 2, 2

^{nd}term is 2*2 = 4.

One more example can be 11,15,19,23,... . Its 1

^{st}term is 11 and any other n

^{th}term is (n-1)

^{th}term + 4. Eg- 2

^{nd}term is 1

^{st}term + 4 = 11+4 = 15. 3

^{rd}term is 2

^{nd}term + 4 = 15+4 = 19.

^{th}term of fibonacci series is 0. 1

^{st}term of fibonacci series is 1. And its n

^{th}term f(n) = f(n-1)+f(n-2)

It means that

f(2) = f(1)+f(0)

= 1+0 = 1

f(3) = f(2)+f(1)

= 1 + 1 = 2

Now, let's program it

```
use strict;
use warnings;
my %prev = (0=>0,1=>1);
sub fib{
my($n) = $_[0];
if (exists($prev{$n})){
return $prev{$n};
}
else{
my($fi);
$fi = fib($n-1) + fib($n-2);
$prev{$n} = $fi;
return $fi;
}
}
print fib(0),"\n";
print fib(1),"\n";
print fib(2),"\n";
print fib(3),"\n";
print fib(4),"\n";
```

1

1

2

3

**%prev = (0=>0,1=>1)** - We are using a hash to store the Fibonacci series corresponding to the n^{th} term. Initially there are only two numbers f(0) = 0 and f(1) = 1.

Coming to the next line:**if (exists($prev{$n}))** If the required term is in the hash, then it will simply return that, else it will calculate and also store the corresponding calculated value in the hash.

For f(2):**$fi = fib(n-1) + fib(n-2)** => $fi = f(1)+f(0) = 1.**$prev($n) = $fi** It will update our hash and return 1 in the last line.

For f(3)

$fi = f(1)+f(2)

For f(1), simply 1 will be returned and f(2) will be calculated as shown above and thus 1+0 i.e., 1 will be returned.

Similarly we will do for f(4).