Pascal Programming/Units

In original Standard Pascal all functionality of a program other than the standard functions Pascal already defines had to be defined in one file, the  source code file. While in the context of teaching the sources remained rather short, entire applications quickly become cluttered despite various comments structuring the text.

Quite soon different attempts to modularize programs emerged. The most notable implementation that remains in use till today is UCSD Pascal’s concept of units.

UCSD Pascal units
A UCSD Pascal unit is like a  except that it cannot run on its own, but is supposed to be used by  s. A   can define constants, types, variables and routines just like any , but there is no executable portion that can be run independently. Using a unit means that this unit becomes a part of the program; It is like copying the entire source code from the  to the , but not quite the same.

Usually, units are stored in separate files thus incredibly cleaning up the ’s source code file. However, this is not a set requirement, since after an  a module is considered complete and another module may follow.

Defining units
A  definition shows many similarities to a regular , but with many additional features.

Header
The first line of a  looks like this: Unlike a  there is no parameter list. A  is a self-contained unit of certain functionality, thus cannot be parameterized in any way.

This line also declares a new identifier, in this example. becomes the first component of the so-called fully-qualified identifier. More on that later.

Parts
The  concept provides means to encapsulate its definitions, so that the programmer using the   does not need to know how certain functionality is implemented. This is done by splitting the  into two parts: A programmer using another unit only needs to know how to use the unit: This is outlined in the  part. The programmer who is programming the unit on the other hand will need to implement the unit’s functionality in the  part. Thus a bare minimum unit looks like this: The  part has to come before the   part. Also note that s terminate with a   just as a   does.
 * 1) the   part, and
 * 2) the   part.

The  part of   consists of a block, except that it cannot contain any statements. The  is merely declaratory. All identifiers defined in the  part will become “public”, i.&#8239;e. a programmer using the unit will have access to them. All identifiers defined in the  part, on the other hand, are “private”: they are only available within the unit’s own  part. There is no way to circumvent this separation of exported and “private” code.

Import
Now, it is great that we have finally outsourced some code, but the point of all of this is to use the outsourced code. For this, UCSD Pascal defines the  clause. A  clause instructs the compiler to import another unit’s code and familiarize with all identifiers declared in the   part of that unit. Thus, all identifiers from the unit’s  part become available, as if they were part of the module importing them via the   clause. Here is an example: Note, that the    neither defines nor declares the function , but nevertheless uses it. Since ’s signature is listed in the   part of , it is available for other modules using that module.

clauses are allowed in any module. Of course it is possible to use other units inside a. Moreover, you are allowed to have two  clauses in one , one in the   and one in   part each. The units listed in the  part’s   clause propagate, that means they become also to the module that uses such units.

Namespaces
Now, programming with units would have been a hassle if all units that were ever programmed had to explicitly define exclusive identifiers. But this is not the case. With the advent of modules all modules implicitly constitute a namespace. A namespace is a self-contained scope where only within identifiers need to be unique. You are quite welcome to define your own  and still use the   unit.

In order to distinguish between identifiers coming from various namespaces, identifiers can be qualified by prepending the namespace name to the identifier, separated by a dot. Thus,  unambiguously identifies the   function exported by the   unit. This notation is called fully-qualified identifier, or FQI for short.

Unit design
There are several considerations that should be accounted for:
 * Whenever some code might be useful for other programs too, you may want to create a separate unit.
 * One unit should provide all functionality necessary in order to be useful, however,
 * a unit should not provide features that are unrelated to its main purpose.
 * Your unit’s usability largely depends on well-defined interface. Requiring knowledge of the specific implementation is usually an indicator for bad code.

Run-time system
Some compilers use units for providing certain functionality that serves the gray zone between a compiler’s actual task and a  (i.&#8239;e. what you write). Most notably, Delphi, the FPC as well as the GPC provide a run-time system (RTS) that includes all standard routines defined as part of the language (e.&#8239;g.  and  ). In Delphi and the FPC this unit is called, whereas the GPC comes with the   unit. These units are sometimes referred to as run-time library, RTL for short.

Knowing what the RTS’s unit is called could be useful, since this implies that all identifiers of the RTL are part of one namespace. That means, in (for example) Delphi and the FP one may refer to the standard function  by both, its short name as well as the FQI. The latter may be required if you are shadowing the  function in the current scope, but need to use Pascal’s own   function.

Debugging
The FPC comes with a special unit  (heap trace). This unit provides a memory manager. It is used to find out whether the  does not release any memory blocks it earlier reserved for itself. Allocating memory and not handing it back to the OS is called “memory leaking” and is a very bad circumstance. Due to the  unit’s intrusive behavior into Pascal’s memory management, it also needs to be loaded very soon after the   unit has been loaded. Hence, FPC forbids you to explicitly include the  unit in the   clause, but provides the   compiler command-line switch that will ensure inclusion of that unit.

The  unit is only used at the development stage. It can print a memory report after the ’s final.

The  unit is somewhat easy to use, but also limited in its features. We recommend to use dedicated debugging and profiling tools such as  as knowing how to use such tools will serve you well if you ever switch programming languages. If you specify the  switch on  ’s invocation, the FPC will insert debugging information for usage with.

Other modularization implementations
The Extended Pascal standard lays out a specification for s. These provide advanced means of modularization. However, neither FPC nor Delphi support this, only the GPC does.

Tasks
Notes: