Pascal Programming/Routines

In the opening chapter routines were already mentioned. Routines are, as it was described before, reusable pieces of code that can be used over and over again. Examples of routines are &#8239;/&#8239;  and  &#8239;/&#8239;. You can invoke, call, these routines as many times as you want. In this chapter you will learn
 * how to define your own routines,
 * the difference between a definition and declaration, and
 * the difference between functions and procedures.

Different routines for different occasions
Routines come in two flavors. In Pascal, routines can either replace statements, or they replace a (sub‑)expression. A routine that can be used where statements are allowed is called a. A routine that is called as part of an expression is a.

Functions
A  is a routine that returns a value. Pascal defines, among others, a function. The function  takes one  -expression as a parameter and returns   or , depending on the parity of the supplied parameter (in layman terms that means whether it is divisible by 2). Let’s see the function  in action: is pronounced “odd of x”. First, the expression in parentheses is evaluated. Here it is simply, the variable’s value to be precise, but a more complex expression is allowed too, as long as it eventually evaluates to an  -expression. The value of this expression, the actual parameter, is then handed to a (in this case invisible) block of code that processes the input, performs some calculations on it, and returns  or   according to the calculation’s findings. The function’s returned value is ultimately filled in in place of the function call. You can, in your mind, read &#8239;/&#8239;  in place of , although this is dynamic depending on the given input.

Procedures
Procedures on the other hand cannot be used as part of an expression. You can only call procedures where statements are allowed.

Effects
A  may use functions, and the other way around. Do not understand a  as a mere substitute for an expression. In the following section we will learn why.

Rationale
The dichotomy of routines, distinguishing between a  and a , is meant to gently push the programmer to write “clean” programs. Doing so, a routine does not conceal whether it is just a replacement for a sequence of statements or shorthand for a complex, difficult to write out expression. This kind of notation works without introducing nasty pseudo types like, for example,  in the C programming language where every routine is a function, but the “invalid” data type   will allow you to make it (in part) behave like a.

Definition
Defining routines follows a pattern you are already familiar with since your very first. A  is, in some regards, like a special routine: You can run it as many times as you want through OS-defined means. A ’s definition looks almost just like a routine’s.

A routine is defined by, in that order. The routine header shows a couple differences depending on whether it is a  or. We will first take a look at blocks, since these are the same for both types of routines.
 * 1) a header, and
 * 2) a block

Block
A block is the synthesis of a productive part (statements) and (optional) declarations and definitions. In Standard Pascal (as laid out by the ISO standard 7185) a block has a fixed order: All items but the last one, the productive part, are optional.
 * 1) constant definitions (the  -section)
 * 2) type definitions (the  -section)
 * 3) variable declarations (the  -section)
 * 4) routine declarations and definitions
 * 5) sequence (, possibly empty)

In EP, the fixed order restriction has been lifted. There, sections and routine declarations and definitions may occur as many times as needed and do not necessarily have to adhere to a particular order. The consequences are detailed in the chapter “Scopes”. For the remainder of this book we will refer to EP’s definition of block, because all major compilers support this. Nevertheless, the order defined by Standard Pascal is a good guideline: It makes sense to define types, before there is a section that may use those types (i.&#8239;e. -section).

Header
A routine header consists of
 * 1) the word   or  ,
 * 2) an identifier identifying this routine,
 * 3) possibly a parameter list, and,
 * 4) lastly, in the case of functions, the data type of an expression a call to this function results in, the result data type.

The parameter list for routines also defines the data type of every single parameter. Thus, the header of the function  could look like this: Take notice of the colon after the parameter list separating the function’s result data type. You can view functions as sort of special variable declaration which also separates an identifier with a colon, except in the case of a function the “variable’s” value is computed dynamically.

Formal parameters, i.&#8239;e. parameters in the context of a routine header, are separated by a semicolon. Consider the following procedure header: Note that every routine header is terminated with a semicolon.

Body
While the routine header tells the processor (usually a compiler), “Hey, there’s a routine with the following properties: […]”, it is not enough. You have to “flesh out”, give the routine a body. This is done in the subsequent block.

Inside the block all parameters can be read as if they were variables.

Function result
In the sequence of the block defining a function there is automatically a variable of the function’s name. You have to assign a value exactly one time, so the function, mathematically speaking, becomes defined. Confer this example: Note that the block did not contain a -section declaring the variable , but it is already implicitly declared by the function’s header: Both the name and the data type are part of the function header.

Declaration
A routine declaration happens most of the time implicitly. Declaring a routine, or in general any identifier, refers to the process of giving the processor (i.&#8239;e. usually a compiler) information in order to correctly interpret your program source code. This information is not directly encoded in your executable program, but it is implicitly there. Examples are: Declarations make an identifier known to denote a certain object (“object” mathematically speaking). Definitions on the other hand will, hence their name, define what this object exactly is. Whether it is a value of a constant, the value of a variable, or the steps taken in a routine (the statement sequence), data defined through definitions will result in specific code in your executable file, which may vary according to the information given in related declarations; writing a variable possessing the data type  is fundamentally different than writing a value of the type. The code for properly storing, calculating and retrieving  and   values differs, but the computer is not aware of that. It just performs the given instructions, the circumstance that a certain set of instructions resemble operations on Pascal’s data type  for instance is, so to speak, a “coincidence”.
 * A variable declaration tells the processor to install proper provisions in order to reserve some memory space. This chunk of memory will be interpreted according to its associated data type. However, neither the variable’s name, nor the data type are in any way stored in your program. Only the processor knows about this information as it is reading your source code file.
 * A routine header constitutes a routine declaration (which is usually directly followed by its definition ). Here again, the information given in a routine header are not stored directly in the executable file, but they ensure the processor (the compiler) will correctly transform your source code.
 * Likewise,  declarations merely serve the purpose of clean and abstract programming, but those declarations do not end up in the executable program file.

Routing
Routines are selected based on their signature. A routine signature consists of Thus the signature of the function  reads. The function named  accepts one   value as the first (and only) argument.
 * 1) the routine’s name,
 * 2) the data type’s of all arguments, and
 * 3) (implicitly) their correct order.

Overloading
Pascal allows you to declare and define routines of the same name, but differing formal parameters. This is usually called overloading. When calling a routine there must be exactly one routine of that name that accepts parameters with their corresponding data types.

Persistent variables
Some compilers, such as the FPC, allow you to use constants as if they were variables, but different lifetime. In the following example the “constant”  exists for the entire duration of program execution, but is only accessible in the scope it was declared in. The program will print,  ,   for every call. Lines 2, 4, and 5 contain specially crafted comments that instruct the compiler to support persistent variables. These comments are non-standard, yet some are explained in the appendix, chapter “Preprocessor Functionality”.

Note, the concept of typed “constants” is not standardized. Some object-oriented programming extensions will give nicer tools to implement such behavior as demonstrated above. We primarily explained the concept of persistent variables to you, so you can read and understand source code by other people.

Benefit
Routines can be used as many times as you want. They are no tools of mere “text substitution”: The definition of a routine is not “copied” to the place where it is called, the call site. The size of the executable program file remains about the same.

Utilizing routines can also be and usually is beneficial to the development progress of a program. By splitting up a programming project into smaller understandable problems you can focus on solving isolated issues as part of the big task. This approach is known as divide and conquer. We now ask you to slowly shift toward thinking more about your programming tasks before you start typing anything. You may need to spend more time on thinking about, for example, how to structure a routine’s parameter list. What information, what parameters, does this routine require? Where and how can a recurring pattern be generalized through a routine definition? Identifying such questions needs time and expertise, so do not be discouraged if you are not seeing everything the task’s sample answers show. You will learn through your mistakes.

Keep in mind, though, routines are no panacea. There are situations, very specific situations, where you do not want to use routines. Recognizing those, however, is out this book’s scope. For the sake of this textbook, and in 99% of all your programming projects you want to use routines if possible. Modern compilers can even recognize some situations where a routine was “unnecessary”, yet the only gain is that your source code becomes more structured and thus readable, albeit at the expense of being more abstract and therefore complex.

Tasks
Notes: