Turbo Pascal 2.0 course cover
← Back to Courses
module
15

Your Own Commands

Introduction

Programs grow. The guessing game in S14 was fifteen lines; Warehouse will be hundreds. The way to keep a big program readable is to break it into pieces, give each piece a name that says what it does, and then write the program in terms of the names. Pascal calls those pieces procedures, and you have been using Turbo's own - Writeln, Readln, Delete - since S4. Now you write your own.

A Procedure

program Lines;

procedure Line;
begin
  Writeln('----------');
end;

begin
  Line;
  Writeln('Hello');
  Line;
end.

The procedure is declared after the program line (and after any var), before the program's own begin. It looks like a small program: the word procedure, a name, a semicolon, and a begin ... end - with a semicolon after its end, not a full stop. Then the name on its own is a new statement: Line; does whatever the procedure says.

A procedure must be declared before anything uses it. Turbo reads the program from the top, and a name it has not yet met is Error 41: Unknown identifier - the same as a misspelling.

Giving It Values

A procedure becomes far more useful when it can be told things:

procedure Row(N: Integer; C: Char);
var
  I: Integer;
begin
  for I := 1 to N do Write(C);
end;

N and C are parameters. Row(10, '#') runs the procedure with N as 10 and C as '#', and prints ten #s. The values given in the call - the arguments - are matched to the parameters in order, and must be the right kinds: Row('#', 10) is Error 44: Type mismatch, and Row(10) with one missing is Error 3: ',' expected. An argument can be any expression: Row(W - 2, ' ').

Its Own Variables

Row declares its own I, under its own var. That I belongs to Row alone: it exists while Row runs, and the rest of the program cannot see it (Error 41 if it tries). If the program has a variable called I too, they are two different variables that happen to share a name; inside Row, I means Row's own.

A procedure can use the program's variables - those declared at the top - but a procedure that works only through its parameters and its own variables is one you can move to another program and trust. That is the habit to form.

Changing The Caller's Variables

Normally a parameter is a copy of the argument. A procedure can change its copy as much as it likes and the caller's variable is untouched. To let a procedure change the caller's variable itself, put var in front of the parameter:

procedure Swap(var P, Q: Integer);
var
  T: Integer;
begin
  T := P;
  P := Q;
  Q := T;
end;

Swap(A, B) really swaps A and B. Without the var, it would swap two copies and leave A and B as they were. A var parameter must be given a variable - Swap(A, 5) makes no sense, and Turbo says Error 41.

Strings As Parameters

A parameter's type must be a name. procedure Greet(Who: string[20]) is refused (Error 36: Type identifier expected). Give the string type a name first, in a type section before var:

type
  Str20 = string[20];

and then use it: procedure Greet(Who: Str20). A Str20 variable, or text in quotes, can then be passed to Who. A var parameter is stricter: it must be given a variable of exactly that type - a string[10] passed to a var parameter of type Str20 is Error 44. Declaring all your strings with the same named type avoids the problem.

The Code

program Boxes;

procedure Row(N: Integer; C: Char);
var
  I: Integer;
begin
  for I := 1 to N do Write(C);
end;

procedure Box(W, H: Integer);
var
  I: Integer;
begin
  Row(W, '#');
  Writeln;
  for I := 1 to H - 2 do
  begin
    Write('#');
    Row(W - 2, ' ');
    Writeln('#');
  end;
  Row(W, '#');
  Writeln;
end;

begin
  Box(10, 4);
  Box(4, 3);
end.

Box uses Row, so Row comes first. The program itself is two lines, and they say exactly what they do.

Starting from

Turbo freshly started, Y, a new work file called BOXES.

What you should see

##########
#        #
#        #
##########
####
#  #
####

Change One Thing

  • Change Box(10, 4) to Box(20, 2). Why is there nothing between the top and the bottom?
  • Move the whole of procedure Row to below procedure Box. What does Turbo say, and where?
  • In Box, change the first Row(W, '#') to Row('#', W). What does Turbo say?

Exercises

15.1 Write a procedure Greet that takes a name and prints Hello, and the name. Call it three times with different names.

15.2 Write a procedure Order(var A, B: Integer) that swaps A and B if A is larger, so that afterwards they are in order. Try it with 9 and 4, and with 2 and 5.

15.3 Using Row, write a procedure Triangle(H) that draws a triangle of #s H rows high.

Worked solutions are in Appendix II.

When It Goes Wrong

SymptomCause
Error 41 at a call of your procedureIt is declared further down, or its name is misspelt. Declare it above the code that calls it.
Error 36: Type identifier expected in a headingA type written out, such as string[20], in a parameter list. Name it under type and use the name.
Error 44: Type mismatch at a callThe arguments are in the wrong order or of the wrong kind - or a string of another length given to a var string parameter.
Error 3: ',' expected at a callToo few arguments.
Error 41 on a var argumentA value, not a variable, given to a var parameter.
A procedure's changes vanishIts parameter is not var, so it changed a copy.

Summary

procedure Name(parameters); followed by its own var and begin ... end; makes a new statement, Name(arguments). Declare procedures before their use. Parameters are copies unless marked var, which lets the procedure change the caller's variables. A procedure's own variables are its alone. Parameter types must be names - declare them under type.

Next

S16, Functions, And One That Calls Itself - procedures that hand back a value, and a procedure that uses itself.

Get the Newsletter

New guides, disk images and community finds, roughly once a quarter. No spam, we promise, this isn't Tatung's marketing department.
Your subscription could not be saved. Please try again.
Your subscription has been successful.

Newsletter

Subscribe to our newsletter and stay updated.