CHAPTER 5 - The Pascal procedures and functions In order to define the procedures and functions we will need to lay some groundwork in the form of a few definitions. These are important concepts, so pay close attention. Program Heading - This is the easiest part since it is only one line, at least it has been in all of our programs up to this point. It is simply the PROGRAM line, and it never needs to be any more involved than it has been up to this point in TURBO Pascal. Declaration Part - This is the part of the Pascal source code in which all constants, variables, and user defined auxiliary operations are defined. In some of the programs we have examined, there have been one or more VAR declarations. These are the only components of the declaration part we have used to this point. There are actually five components in the declaration part, and the procedures and functions are the fifth part. We will cover the others in the next chapter. Statement Part - This is the last part of any Pascal program, and it is what we have been calling the main program. It is one compound statement bracketed with the reserved words BEGIN and END. It is very important that you grasp the above definitions because we will be referring to them constantly during this chapter, and throughout the remainder of this tutorial. With that introduction, lets go on to our first Pascal program with a procedure in it, in fact, it will have three procedures. THE FIRST PROCEDURES Load PROCED1 as your first working file and edit it. You will notice that it doesn't look like anything you have seen up to this point because it has PROCEDUREs in it. Lets go back to our definitions from above. The first line is the Program Heading which should pose no difficulty. The Declaration Part begins with the VAR statement and continues down through and including all three procedures. The last five lines constitute the Statement Part. It may seem strange that what appears to be executable Pascal statements, and indeed they are executable, are contained in the Declaration Part rather than the Statement Part. This is because of the Pascal definition and it will make sense when we have completed our study of the procedures and functions. Page 20 CHAPTER 5 - The Pascal procedures and functions Continuing to examine PROCED1, we will make note of the program itself, which is the Statement Part. The program, due to the nature of Pascal, clearly tells us what it will do, namely write a header, eight messages, and an ending. The only problem we are faced with is, how will it write these messages? This is where the Declaration Part is called upon to define these operations in detail. The Declaration Part contains three procedures which will completely define what is to be done in the main program, or the Statement Part. Hopefully you can begin to see why the procedures are included in the Declaration Part of the Pascal program. Now to examine one procedure in detail, namely the first. The first statement we come to in the main program is the one that says simply, "write_a_header" followed with the usual end of statement, the semicolon. This is a simple procedure call. When the compiler finds this it goes looking for a predefined procedure which it can execute at this point. If it finds one in the Declaration Part of the program, it will execute that procedure. If it doesn't find a user defined procedure, it will search the Pascal library for a system defined procedure and execute it. The WRITE and WRITELN statements are actually system defined procedures, and you have already been using them quite a bit, so procedures are not completely new to you. If it doesn't find the procedure defined in either place, it will generate an error message. HOW TO CALL A PROCEDURE To call a procedure, we simply need to state its name. To define a simple procedure, we use the reserved word PROCEDURE followed by its calling name, with a semicolon as a terminator. Following the Procedure Heading, there is the Declaration Part of the procedure followed by a body which is nothing more than a compound statement bracketed by the reserved words BEGIN and END. This is identical to the Statement Part of the main program except that the procedure ends with a semicolon instead of a period. Any valid Pascal statements can be put between the BEGIN and END, and in fact, there is no difference in what can be put in a procedure and what can be put in the main program. The program we are examining would be no different if we would eliminate the first procedure completely and move the WRITELN contained in it down to the Statement Part in place of "write_a_header". If that is not clear, go back and reread these last two paragraphs until it is. Page 21 CHAPTER 5 - The Pascal procedures and functions The next line will cause the procedure named "write_a_message" to be called 8 times, each time writing a line of output. Suffice it to say at this time that the value of "count", as defined here, is available "globally", meaning anywhere in the entire Pascal program. We will define the variable availability shortly. Finally, the last procedure call is made, causing the ending message to be displayed, and the program execution is complete. Having examined your first Pascal procedures, there is a fine point that is obvious but could be easily overlooked. We mentioned the unbroken rule of Pascal in an earlier chapter and it must be followed here too. "Nothing can be used in Pascal until it has been defined". The procedures must all be defined ahead of any calls to them, once again emphasizing the fact that they are part of the Declaration Part of the program, not the Statement Part. MORE PROCEDURE CALLS Assuming you have run PROCED1 successfully and understand its output, lets go on to PROCED2 and examine it. To begin with, notice that there are three procedure calls in the Statement Part of the program and each has an additional term not contained in the calls in the last program, namely the word "index" within brackets. This is Pascals way of taking a variable parameter to the procedure when it is called. You will notice that the variable "index" is defined as an integer variable in the very top of the Declaration Part. Therefore the procedure "print_data_out" had better be expecting an integer variable or we will have a type mismatch. In fact, observing the procedure itself, indicates that it is indeed expecting an integer variable but it prefers to call the variable "puppy". Calling it something different poses no problem as long as the main program doesn't try to call its variable "puppy", and the procedure doesn't try to use the name "index". Both are actually referring to the same piece of data but they simply wish to refer to it by different names. Notice that the next procedure is called with index as a parameter and it prefers to call it by the name "cat". Notice that in both cases, the procedures simply print out the parameter passed to it, and each then try to modify the value passed to it before passing it back. We will see that one will be successful and the other will not. We are in a loop in which "count" is incremented from 1 to 3 and we are not allowed to modify the loop variable so we make a copy of the value and call it "index". We can then modify "index" if we desire. The first procedure does not contain a VAR in front of the passed parameter and therefore the parameter passing is only one way. The system Page 22 CHAPTER 5 - The Pascal procedures and functions makes a copy of "index", and passes the copy to the procedure which can do anything with it, of course using its new name, "puppy", but when control returns to the main program, the original value of "index" is still there. So think of the passed parameter without the VAR as one way parameter passing. This is a "call by value" because only the value of the variable is passed to the procedure. The second procedure has the reserved word VAR in front of its desired name for the variable, namely "cat", so it can not only receive the variable, it can modify it, and return the modified value to the main program. A copy is not made. The original variable named "index" is actually passed to this procedure and it can modify it, therefore communicating to the main program. A passed parameter with a VAR in front of it is therefore a two way situation. This is a "call by reference" since the reference to the original variable is passed to the procedure. When you run this program, you will find that the first procedure is unable to get the value of 12 back to the main program, but the second procedure does in fact succeed in returning its value of 35 to the main program. Spend as much time as you like studying this program until you fully understand it. It should be noted that as many parameters as desired can be passed to and from a procedure by simply making a list separated by commas in the calls, and separated by semicolons in the procedure. For your own enlightenment, examine PROCED3 for an example of a procedure call with more than one variable in the call. Normally, you would group the three input values together, but for purposes of illustration, they are separated. Observe that the variable "fruit" is a two way variable. When you are satisfied with the present illustration, we will go on to study the scope of variables using PROCED4. A MULTIPLY DEFINED VARIABLE If you will examine PROCED4, you will notice that the variable "count" is defined twice, once in the main program VAR block and once in the VAR block contained within the procedure named "print_some_data". This is perfectly legal and is within the Pascal definition. The variable "index" is defined in the main program VAR block and is valid anywhere within the entire Pascal program, including the procedures. The variable "count" is also defined in the main program VAR block and is also valid anywhere within the entire Pascal program, except within the Page 23 CHAPTER 5 - The Pascal procedures and functions procedure where another variable is defined with the same name "count". The two variables with the same name are in fact, two completely different variables. If a third variable was defined within the procedure, it would be invisible to the main program, since it was defined at a lower level than that of the main program. Any variable defined in the main program or in any procedure is available in any procedure that is within the scope of the defining procedure. That last sentence seems confusing, but thinking about it will clear it up. This is a difficult concept to grasp but is very important. PROCEDURES CALLING OTHER PROCEDURES Load and examine PROCED5 to see an example of procedures that call other procedures. Keep in mind that, "Nothing can be used in Pascal until it has been previously defined", and the order of procedures will be clear in this example. Now that you have a good grasp of procedures, we need to make another important point. Remember that any Pascal program is made up of three parts, the Program Heading, the Declaration Part, and the Statement Part. The Declaration Part is composed of five unique components, four of which we will discuss in detail in the next chapter, and the last component, which is composed of some number of procedures and functions. We will cover functions in the next example, so for now simply accept the fact that it is like a procedure. A procedure is also composed of three parts, a Program Heading (which says "PROCEDURE"), a Declaration Part, and a Statement Part. A procedure, by definition, is therefore nothing more or less than another complete Pascal program embedded within the main program, and any number of procedures can be located in the Declaration Part of the main program. These procedures are all in a line, one right after another. Since a procedure is defined like the main program, it would seem to be possible to embed another procedure within the declaration part of any procedure. This is perfectly valid and is often done, but remember that the embedded procedure can only be called by the procedure in which it is embedded, not by the main program. That is probably a bit difficult to grasp. Don't worry about it too much now, as you become proficient as a Pascal programmer, you will very clearly see how that is used. Page 24 CHAPTER 5 - The Pascal procedures and functions NOW LET'S LOOK AT A FUNCTION Now to keep a promise, lets examine FUNCTION to see what a function is and how to use it. In this very simple program, we have a function that simply multiplies the sum of two variables by 4 and returns the result. The major difference between a function and a procedure is that the function returns a single value and is called from within a mathematical expression, a WRITELN command, or anywhere that it is valid to put any variable, since it is really a variable itself. Observing the Program Heading of the function reveals the two input variables inside the parenthesis pair being defined as INTEGER variables, and following the parenthesis is a colon and another INTEGER. The last INTEGER is used to define the type of the variable being returned to the main program. Since any call to this function is actually replaced by an integer upon completion of the call, it can be used anywhere in a program where an integer variable can be used. NOW FOR THE MYSTERY OF RECURSION One of the great mysteries of Pascal to many people, is the recursion of procedure calls. Simply defined, recursion is the ability of a procedure to call itself. Examine the Pascal example file RECURSON for an example of recursion. The main program is very simple, it sets the variable "count" to the value 7 and calls the procedure "print_and_decrement". The procedure prefers to refer to the variable by the name "index" but that poses no problem. The procedure writes a line to the video display with the value of "index" written within the line, and decrements the variable. The IF statement introduces the interesting part of this program. If the variable is greater than zero, and it is now 6, then the procedure "print_and_decrement" is called once again. This might seem to create a problem except for the fact that this is perfectly legal in Pascal. Upon entering the procedure the second time, the value of "index" is printed as 6, and it is once again decremented. Since it is now 5, the same procedure will be called again, and it will continue until the value of "index" is reduced to zero when each procedure call will be completed one at a time and control will return to the main program. ABOUT RECURSIVE PROCEDURES This is really a stupid way to implement this particular program, but it is the simplest recursive program that can be written and therefore the easiest to understand. You Page 25 CHAPTER 5 - The Pascal procedures and functions will have occasional use for recursive procedures, so don't be afraid to try them. Remember that the recursive procedure must have some variable converging to something, or you will have an infinite loop. THE FORWARD REFERENCE Occasionally you will have a need to refer to a procedure before you can define it. In that case you will need a FORWARD reference. The program FORWARD has an example of a forward reference in it. In this program, each one of the procedures calls the other, a form of recursion. This program, like the last, is a very stupid way to count from 7 to 0, but it is the simplest program possible with the forward reference. The first procedure, "write_a_line", has its header defined in exactly the same manner as any other procedure but instead of the normal procedure body, only the reserved word FORWARD is given. This tells the compiler that the procedure will be defined later. The next procedure is defined as usual, then the body of "write_a_line" is given with only the reserved word PROCEDURE and the procedure name. The variable reference has been defined earlier. In this way, each of the procedure names are defined before they are called. It would be possible, by using the FORWARD reference in great numbers, to move the main program ahead of all procedure definitions and have the program structured like some other languages. This style of programming would be perfectly legal as far as the compiler is concerned, but the resulting program would be very nonstandard and confusing. You would do well to stick with conventional Pascal formatting techniques and use the FORWARD reference sparingly. PROGRAMMING EXERCISES 1. Write a program to write your name, address, and phone number with each WRITELN in a different procedure. 2. Add a statement to the procedure in RECURSON to display the value of "index" after the call to itself so you can see the value increasing as the recurring calls are returned to the next higher level. 3. Rewrite TEMPCONV putting the centigrade to fahrenheit formulas in a function call. Page 26