A subroutine or a function
is an section of codes that can be used repeatly in any other section of the codes (not including the subroutine itself). So in this way it saves you a lot of times writting the same section of the codes when there are many placese that will use it.
Like many languages, Perl provides for user-defined subroutines. These may be located anywhere in the main program, loaded in from other files via the do, require, or use keywords, or generated on the fly using eval or anonymous subroutines. You can even call a function indirectly using a variable containing its name or a CODE reference.

The Perl model for function call and return values is simple: all functions are passed as parameters one single flat list of scalars, and all functions likewise return to their caller one single flat list of scalars. Any arrays or hashes in these call and return lists will collapse, losing their identities--but you may always use pass-by-reference instead to avoid this. Both call and return lists may contain as many or as few scalar elements as you'd like. (Often a function without an explicit return statement is called a subroutine, but there's really no difference from Perl's perspective.)

Any arguments passed in show up in the array @_. Therefore, if you called a function with two arguments, those would be stored in $_[0] and $_[1]. The array @_ is a local array, but its elements are aliases for the actual scalar parameters. In particular, if an element $_[0] is updated, the corresponding argument is updated (or an error occurs if it is not updatable). If an argument is an array or hash element which did not exist when the function was called, that element is created only when (and if) it is modified or a reference to it is taken. (Some earlier versions of Perl created the element whether or not the element was assigned to.) Assigning to the whole array @_ removes that aliasing, and does not update any arguments.

The return value of a subroutine is the value of the last expression evaluated. More explicitly, a return statement may be used to exit the subroutine, optionally specifying the returned value, which will be evaluated in the appropriate context (list, scalar, or void) depending on the context of the subroutine call. If you specify no return value, the subroutine returns an empty list in list context, the undefined value in scalar context, or nothing in void context. If you return one or more aggregates (arrays and hashes), these will be flattened together into one large indistinguishable list.

Real world Example:
This is a section of my main program:

#!/usr/local/bin/perl -w
       use Tk;
       use Cwd;
       use File::Copy;
       use IO::File;
       use IO::Handle;
       use Tk::Balloon;
       use Noah_2D;
       use Diamod1;
       use Noah_flx;
       use Noah_par;
       use Noah_par_adv;
       use Diamod_par;
       use CYS_par;
       use Stereo_par;
       use subs qw/proitems/;
       use IPC_nodia;
       use Aco_default;
       use Aco_user1;
       use Import_pks;
       use Import_vls;
       use Noah_fmt1;
       use Openfile;
       use Help;
       use End;
       use Reset;

{......
     $noahbutton -> separator;
     $noahbutton -> AddItems
             (
               ['command' => "Read DIAMOD ovw",
                -command => sub{open_noah_inp(6)}],
               ['command' => "Read DIAMOD str name",
                -command => sub{open_noah_inp(7)}],
               ['command' => "Read NOAH ass file",
                -command => sub{open_noah_inp(8)}]
             );

return;
}
To see it all please click My_main.pl
#
sub open_noah_inp {
# Use getOpenFile to popup a window for selecting file to open
# First define type of files to select
#    print "Here: $_[0], $file_types[$_[0]]\n";
    if ($file_types[$_[0]] eq "seq")
      {
        $id = ".seq";
        $txt = "Open sequence file:";
          $chk_seq++;
#         print STDOUT "Yuan $chk_seq\n";
# close Import_vls and Import_pks windows if opend
     $import_vls = $Import_vls::import_vls;
     $format_pks = $Import_pks::format_pks;
     $import_pks = $Import_pks::import_pks;
     if ($import_vls ne "")
      {
            End::close_widget($import_vls,$status,2); #important: use madule's name End
            $Import_vls::project -> entryconfigure(7,-state => "normal",-foreground => "red");
          }
          if ($format_pks ne "")
       {
            End::close_widget($format_pks,$status,2)
           }; #important: use madule's name End
          if ($import_pks ne "")
       {
            End::close_widget($import_pks,$status,2)
           };
      }
.....
}
#
#
and to see the End subroutine please click End subroutine