FUNCTIONS AND PROCEDURES IN PASCAL by Ed Nelson III The main difference between a function and a procedure is that a function must return a value, whereas a procedure does not. Procedures can, however, return a value. This article discusses the use of functions and procedures in Pascal programs. A function will return the value in its name. For example, if a function is declared as "Function Paint: char;", then the word Paint will contain the character that has been returned by the function. This is limited in its usefulness; to retain the value returned by a function you must assign its value to a variable. However, functions are ideal for testing looping conditions since they provide the necessary information with a minimum of Pascal commands. There are two types of procedures -- call by value and call by reference. The call by value procedure is declared like Demo3 in the demonstration program listed below. Although these procedures do not return values, they can affect global variables. Call by value procedures can be used to do anything that does not require the return of information. For example, a call by value procedure can display information on the screen. The other kind of procedure is the call by reference. The call by reference procedure is declared like Demo4 in the demonstration program. This kind of procedure returns its values in variables declared as VAR in the procedure heading. Once the procedure has completed execution, the variables contain their new values, where the information is retained until it is changed. Note: ISO Pascal does not allow certain data structures to be returned by a Function (this is the 'Error 47' described elsewhere in this newsletter). A way around this is to use a procedure with variables passed by reference. Functions and procedures have similar abilities. As a general rule of thumb, anything a function can do, a procedure can do, and vice versa. The largest difference between functions and procedures does not lie in their respective abilities and limitations, but in how they are used. Functions are generally used to find and return a value. Procedures are used to do other things, such as displaying data, or opening and closing files. The main difference is stylistic, not something enforced by the language. In the demonstration program below, functions and procedures are used for different aspects of pattern matching in strings. S2 will be the pattern that is looked for, and S1 will be the string that is searched. S3 is not used until it is passed into Demo4. Note: There was a misprint in some early editions of the manual regarding the Index function. The correct description of this function is: the first string passed (S1) is the string to be searched. The second string passed (S2) is the pattern looked for in the first string. The two functions, Demo1 and Demo2, are used to find a value and return it. Demo1 returns a TRUE if S2 is in S1 and returns a FALSE if S2 is not in S1. It is worth noting that a boolean function can be used wherever a boolean expression is used, such as in IF-THEN, UNTIL, and WHILE statements. For an example, look at the IF-THEN statement in the main program. The second function, Demo2, counts the number of occurrences of S2 in S1. The main program prints out the information received. Procedure Demo3 is a call by value procedure. It does not pass any information back to the main program. Instead, it displays its information on the screen. Procedure Demo4 is a call by reference procedure. This procedure breaks up S1 and return parts of it in S1, S2, and S3. After this procedure is called, S1 contains the part of the string before the pattern, S2 contains the pattern, and S3 contains everything after the pattern. If you are going to pass large data types in a program, you may want to use a call by reference procedure rather than a function. The reason is that in a call by reference procedure, a point (that points to the data structure) is passed rather than the whole data structure (which is what happens with a function). Thus this technique saves time and stack space. Following is the Demonstration program: PROGRAM Demo (input, output); Const maxstring = 20; (* maximum string length is 20 *) empty = ' '; (* 20 spaces *) Type string = array [1..maxstring] of char; Var S1, S2, S3 : string; i : integer; {The following function is an include file on the Kyan Pascal disk. String A1 is searched to see if it contains string A2. If it is, the location of the first character the string A2 is returned. If it isn't, a zero is returned. For example, if A1 is 'that theory is not viable at this time' and A2 is 'viable', the function INDEX (A1, A2) will return the value 20 which is the position of the first letter of A2 in A1.} FUNCTION Index (VAR A1, A2: string): integer; VAR I, J, K, L: integer; BEGIN I := Maxstring; WHILE ((A2[I] = ' ') AND (I <> 1)) DO I := I - 1; K := 0; REPEAT J := 1; L := 1; WHILE (J <= I) DO BEGIN IF (A1[J+K] <> A2[J]) THEN L := 0; J := J+1; END; K := K+1; UNTIL ((L = 1) OR ((I+K) > Maxstring)); IF (L = 1) THEN Index := K ELSE Index := 0; END; {The next function is an include file on the Kyan Pascal disk. It returns the length of the string passed to it.} FUNCTION Length (VAR A1: String): Integer; VAR I: Integer; BEGIN I := Maxstring; WHILE ((A1[I] = ' ') and (I <> 1)) DO I := I-1; LENGTH := I; END; {The next procedure is also an include file on the Kyan Pascal disk. It copies part of A1 into A2, as specified by I (the position in A1 of the first character copied) and J (the number of characters copies to A2).} PROCEDURE Substring (VAR A1, A2: String; I,J: Integer); VAR K : Integer; BEGIN FOR K := 1 TO Maxstring DO A2[K] := ' '; I := I - 1; FOR K := 1 TO J DO A2[K] := A1[I+K] END; {This next function return a value TRUE if S2 is in S1, otherwise it returns a FALSE.} FUNCTION Demo1 (S1, S2: String) : Boolean; VAR Result : integer; BEGIN Result := Index (S1, S2); IF Result = 0 THEN {If result = 0, then S2 is not in S1} Demo1 := FALSE ELSE Demo1 := TRUE {If result <> 0, then S2 is in S1} END; {The next function returns an integer equal to the number of times S2 appears in S1. It will not work if the first character in S2 is a space.} FUNCTION Demo2 (S1, S2: string): Integer; VAR Result : integer; Dem : integer; BEGIN Result := Index (S1, S2); Dem := 0; WHILE Result <> 0 DO BEGIN Dem := Dem +1; S1 [Result] := ' '; Result := Index (S1, S2); END; Demo2 := Dem; END; {This procedure prints out the position and length of S2 in S1} PROCEDURE Demo3 (S1, S2: String); VAR Result : integer; BEGIN Result := Index (S1, S2); Writeln (S1: length (S1)); Writeln ('position: ', result : 2); Writeln ('length: ', length (S2) : 2); END; {If S2 is in S1, this procedure will return everything before the first occurrence of S2 in S1 (in S1), everything after the first occurrence of S2 in S1 (in S3), and S2 itself (in S2). If S2 is not in S1, then S1, S2, and S3 are unchanged. For example, if S1 is 'Gumby and Pokey live' and S2 is 'and' (plus 17 spaces), then Procedure Demo4 will change S1, S2, and S3 into the following: S1 will be 'Gumby', S2 will be 'and', and S3 will be 'Pokey live'. All three will be padded with spaces after the last letter.} PROCEDURE Demo4 (Var S1, S2, S3: string); VAR Position, len, p, l : integer; temp : string; BEGIN Position := Index (S1, S2); IF Position <> 0 THEN BEGIN len := length (S2); p := 1; l := Position -1; Substring (S1, temp, p, l); p := position + len; l := maxstring - p +1; Substring (S1, S3, p, l); Substring (S1, S2, position, len); S1 := temp END; END; BEGIN {Main program] S1 := empty; S2 := empty; S3 := empty; S1 := 'Gumby and Pokey live'; S2 := 'and '; IF Demo1 (S1, S2) THEN (* Boolean function instead of Boolean expression *) Writeln ('Demo1: It's there!'); Writeln;