Augustana University College

COMPUTING SCIENCE 370
Programming Languages


Pascal



History and Motivation

Design Goals

  1. Suitable for teaching programming.

  2. Implementation should be reliable and efficient, at compile-time and run-time, on available computers.

Although Pascal was designed as a teaching language, it has been used successfully as a production language, due both to its strong typing and to its support for both commercial and scientific programming through its rich collection of data structuring constructs.

Structural Organization

Data Structures

Pascal adds character (char) and a secure (typed) pointer type to Algol's real, integer, and Boolean types.

Enumeration Types

A new type can be declared by listing (enumerating) all its possible values.
E.g.,

   type
      DayOfWeek = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);

Subrange Types

Pascal permits the programmer to define subranges of any discrete (scalar) type.
E.g.,

   type WeekDay = Mon .. Fri;
   var dayOfMonth: 1 .. 31;

Set Types

Pascal introduced support for small finite sets.
E.g.,

   var S, T, U: set of 1 .. 10;
   :
   S := [1, 2, 3, 5, 7];
   T := [1 .. 6];
   U := S + T;   { set union }
   if 6 in S * T   { set intersection }
      then . . .


ELEGANCE PRINCIPLE
Confine your attention to designs that look good because they are good.

RESPONSIBLE DESIGN PRINCIPLE
Don't ask users what they want; find out what they need.

Array Types

Pascal's arrays are both more general and more restrictive than Algol's.
E.g.,

   var hoursWorked : array [Mon .. Fri] of 0 .. 24;

Record Types

Pascal provides a heterogeneous data constructor (as in COBOL, Algol-W), with the "dot" operator as a field selector.
E.g.,

   type Date =
      record
         mon : month;
         day : 1 .. 31;
         year : 1900 .. 2100;
      end;
   :
   var today : Date;
   :
      today.mon := Jan;

A record defines a scope: field names are only visible with the dot selector, unless a with statement is used to "open up" the record.
E.g.,

   with today do
      begin
         mon := Oct;
         day := 18;
         year := 2001;
      end;

Variant records allow different fields to be used for subtypes (variants) of a basic heterogeneous type. A tag field indicates which variant is currently in use.
E.g.,

   type Employee = record
      name : NameType;
      position : (executive, manager, sales, clerical);
      birthDate : Date;
      hireDate : Date;
      case payType : ( salary, commission, wage ) of
         salary: ( perMonth : real );   { paid monthly }
         commission: (
            base : real;
            rate : real );
         wage: (
            regularHours: 0 .. 40;    { paid weekly }
            overtimeHours: 0 .. 20; { time-and-a-half }
            perHour: real );
   end {Employee}

Pointer Types

Instead of using PL/I's primitive pointer type, Wirth introduced typed pointers in Pascal.
E.g.,

   var 
      p : ^real;
      x : real;
      c : char;
   begin
      new( p );
      p^ := 3.14159;
      x := p^;   { OK }
      c := p^;   { Illegal }
   end.

Type Equivalence

A compiler often has to determine if two types are equivalent. For example,

There are two general ways (and many variants of these approaches) to determine if two types are equivalent:

Structural equivalence
Two types are considered equivalent if they have the same structure.
Name equivalence
Two objects have the same type if the names of their types are the same.

E.g.,

   type Example1 = record
      x : real;
      y : integer;
   end;

   type Example2 = record
      y : integer;
      x : real;
   end;

   type Example3 = record
      a : real;
      b : integer;
   end;

The first and second examples are the same if we ignore the order of the fields; the first and third are the same if we ignore the names of the fields. The variant of structural equivalence which requires field names to be the same is called structural equivalence under naming.

Two basic problems with structural equivalence:

Furthermore, it is not clear that two types which are structurally equivalent should be considered equivalent. Consider these two types:

   type 
      Person = record
         id : integer;
         age : integer;
         weight : real
      end;

      Auto = record
         id : integer;
         age : integer;
         weight : real
      end;

   var
      mother : Person;
      car    : Auto;

   begin
      :
      mother := car;

This example suggests that name equivalence is more secure, on the assumption that if a programmer declares two types with different names, they probably represent different things which would not be considered equivalent in the "real world".

There are problems with name equivalence too:

Pascal uses a variant of name equivalence which might be called declaration equivalence, with some exceptions:

Name Structures

Control Structures

Pascal has more control constructs than Algol-60, but they are simpler and more structured.


LABELING PRINCIPLE
Avoid arbitrary sequences more than a few items long; do not require the user to know the absolute position of an item in a list. Instead, associate a meaningful label with each item and allow the items to occur in any order.

Parameter-Passing Modes

Pascal supports only pass by value and pass by reference.

Originally, Pascal provided another in-mode parameter passing method -- pass as constant -- which allowed the compiler to pass a parameter as either a value (e.g., for a simple variable) or an address (e.g., for an array), but disallowed assignment to the parameter in the body of the procedure or function.

The restriction to only pass by value and pass by reference causes programmers to pass large data structures such as arrays and large records as variable (var) parameters, even if they are actually being passed as in-mode parameters only (i.e., they will not be altered by the procedure). This undermines security and readability by confusing two orthogonal issues:

Procedural Parameters

Pascal allows procedures and functions to be passed as parameters to other procedures and functions. This allows procedures to be more general; for example, a compare function could be passed to a sort procedure to allow it to sort an array according to a variety of sort orders.

According to the Revised Report, the syntax for passing a function which accepted a real parameter and returned a real result was:

   function name (function f : real; x : real) : real;

However, this created a type loophole, since the parameters of f are not specified. The ISO Pascal Standard requires:

   function name (function f( y : real) : real; x : real) : real;

Note the correction relative to the textbook, pp. 302-302.

Function Return Types

As in Algol, the value to be returned by a function is specified by an assignment to the name of the function within the body of the function. This syntax causes programmers to think of the name of the function as a local variable, which it is not; it is illegal to use the name of the function on the right-hand side of an assignment statement, for example. C's function return syntax -- return expr -- is preferable.

Although arrays, procedures, and functions may be passed to a procedure or function as parameters, a Pascal function can only return values of type real, ordinal types (integer, char, boolean or subranges of these types), and pointers. Thus, arrays, procedures, and functions are not first-class citizens in Pascal.

Copyright © 2001 Jonathan Mohr