46 - 01: Coding in Pascal
Large libraries often use include files for that purpose, an example would be the
FireDAC library, a database library which is now part of the system libraries.
Another example, showcased by the system RTL units, is the use of individual
includes for each platform, with an $IFDEF used for conditionally including only one
of them.
Marco Cantù, Object Pascal Handbook
02: Variables and Data Types - 47
02: variables and
data types
Object Pascal is what is known as a strongly-typed language. Variables in Object
Pascal are declared to be of a data type (or user defined data type). The type of a
variable determines the values a variable can hold, and the operations that can be
performed on it. This allows the compiler both to identify errors in your code and
generate faster programs for you.
This is why the concept of type is stronger in Pascal than in languages like C or C++.
Later languages based on the same syntax but that break compatibility with C, like
C# and Java, divert from C and embrace Pascal's strong notion of data type. In C, for
example, arithmetic data types are almost interchangeable. By contrast the original
versions of BASIC, had no similar concept, and in many of today's scripting lan-
guages (JavaScript being an obvious example) the notion of data type is very
different.
note In fact, there are some tricks to bypass type safety, like using variant record types. The use of
these tricks is strongly discouraged and are little used today.
Marco Cantù, Object Pascal Handbook
48 - 02: Variables and Data Types
As I mentioned, all of the dynamic languages, from JavaScript onwards, don't have
the same notion of data type, or (at least) have a very loose idea of types. In some of
these languages the type is inferred by the value you assign to a variable, and the
variable type can change over time. What is important to point out is that data types
are a key element for enforcing correctness of a large application at compile-time,
rather than relying on run-time checks. Data types require more order and struc-
ture, and some planning of the code you are going to write... which clearly has
advantages and disadvantages.
note Needless to say I prefer strongly typed languages, but in any case my goal in this book is to explain
how the language works, more than to advocate why I think it is such a great programming lan-
guage. Though I'm sure you'll get that impression while you read the text.
Variables and Assignments
Like other strongly-typed languages, Object Pascal requires all variables to be
declared before they are used. Every time you declare a variable, you must specify a
data type. Here are some variable declarations:
var
Value: Integer;
IsCorrect: Boolean;
A, B: Char;
The var keyword can be used in several places in a program, such as at the begin-
ning of a function or procedure, to declare variables local to that portion of the code,
or inside a unit to declare global variables.
note Differently from C and other curly-brace languages, in Object Pascal you cannot mix variable dec-
larations with programming statements, but you need to group them in specific sections (like at
the beginning of a method). Since this is not always handy, the IDE code editor let's you actually
type the var keyword followed by the actual declaration within your method or function code, but
it will immediately move it up to the correct position. This is one of the predefined Live Tem-
plates, a very nice coding helper in the IDE that you can customize and extend.
After the var keyword comes a list of variable names, followed by a colon and the
name of the data type. You can write more than one variable name on a single line,
as A and B in the last statement of the previous code snippet (a coding style that is
less common today, compared to splitting the declaration on two separate lines).
Marco Cantù, Object Pascal Handbook
02: Variables and Data Types - 49
Once you have defined a variable of a given type, you can only perform the opera-
tions supported by its data type on it. For example, you can use the Boolean value in
a test and the integer value in a numerical expression. You cannot mix Booleans and
Integers, for example, or any incompatible data type (even if the internal representa-
tion might is physically compatible, as it is the case for Booleans and Integers).
The simplest assignment is that of an actual value, let's say you want the Value vari-
able to hold the value 10. But how do you express literal values? While this concept
might be obvious, it is worth looking into it with some detail.
Literal Values
A literal value is a value you type directly in the program source code. If you need a
number with the value of twenty, you can simply write:
20
There is also an alternative representation of the same numeric value, based on the
hexadecimal value, like:
$14
These will be literal values for an integer number (or one of the various integer num-
ber types that are available). If you want the same numeric value, but for a floating
point literal value, you generally add an empty decimal after it:
2.0
Literal values are not limited to numbers. You can also have characters and strings.
Both use single quotes (were many other programming languages will use double
quotes for both, or single quotes for characters and double quotes for strings):
// literal characters
'K'
#55
// literal string
'Marco'
As you can see above, you can also indicate characters by their corresponding
numeric value (originally the ASCII number, now the Unicode code point value),
prefixing the number with the # symbol, as in #32 (for a space). This is useful
mostly for control characters without a textual representation in the source code,
like a backspace or a tab.
In case you need to have a quote within a string, you'll have to double it. So if I want
to have my first and last name (spelled with a final quote rather than an accent) I
can write:
Marco Cantù, Object Pascal Handbook
50 - 02: Variables and Data Types
'Marco Cantu'''
The two quotes stand for a quote within the string, while the third consecutive quote
marks the end of the string. Also note that a string literal must be written on a single
line, but you can concatenate multiple string literals using the + sign. If you want to
have the new line or line break within the string, don't write it on two lines, but con-
catenate the two elements with the sLineBreak system constant (which is platform
specific), as in:
'Marco' + sLineBreak + 'Cantu'''
Assignment Statements
Assignments in Object Pascal use the colon-equal operator (:=), an odd notation for
programmers who are used to other languages. The = operator, which is used for
assignments in many other languages, in Object Pascal is used to test for equality.
note The := operator comes from a Pascal predecessor, Algol, a language few of todays developers have
heard of (let even used). Most of today's languages avoid the := notation and favor the = assign-
ment notation.
By using different symbols for an assignment and an equality test, the Pascal com-
piler (like the C compiler) can translate source code faster, because it doesn't need to
examine the context in which the operator is used to determine its meaning. The use
of different operators also makes the code easier for people to read. Truly Pascal
picked two different operators than C (and syntactic derivatives like Java, C#,
JavaScript), which uses = for assignment and == for equality testing.
note For the sake of completeness I should mention JavaScript has also a === operator, but that's
something that even most JavaScript programmers get confused about.
The two elements of an assignment are often called lvalue and rvalue, for left value
(the variable or memory location you are assigning to) and right value, the value of
the expressions being assigned. While the rvalue can be an expression, the lvalue
must refer (directly or indirectly) to a memory location you can modify. There are
some data types that have specific assignment behaviors which I'll cover in due time.
The other rule is that the type of the lvalue and of the rvalue must match, or there
must be an automatic conversion between the two, as explained in the next section.
Marco Cantù, Object Pascal Handbook
02: Variables and Data Types - 51
Assignments and Conversion
Using simple assignments, we can write the following code (that you can find among
many other snippets in this section in the VariablesTest project):
Value := 10;
Value := Value + 10;
IsCorrect := True;
Given the previous variable declarations, these three assignments are correct. The
next statement, instead, is not correct, as the two variables have different data types:
Value := IsCorrect; // error
If you try to compile this code, the compiler issues an error with a description like
this:
[dcc32 Error]: E2010 Incompatible types: 'Integer' and 'Boolean'
The compiler informs you that there is something wrong in your code, namely two
incompatible data types. Of course, it is often possible to convert the value of a vari-
able from one type to another type. In some cases, the conversion is automatic, for
example if you assign an integer value to a floating point variable (but not the oppo-
site, of course). Usually you need to call a specific system function that changes the
internal representation of the data.
Initializing Global Variable
For global variables, you can assign an initial value as you declare the variable, using
the constant assignment notation covered below (=) instead of the assignment oper-
ator (:=). For example, you can write:
var
Value: Integer = 10;
Correct: Boolean = True;
This initialization technique works only for global variables, which are initialized to
their default values anyway (like 0 for a number).
Variables declared at the beginning of a procedure or function, instead, are not ini-
tialized to a default value and don't have an assignment syntax. For those variables,
it is often worth adding explicit initialization code at the beginning of the code:
var
Value: Integer;
begin
Value := 0; // initialize
Marco Cantù, Object Pascal Handbook
52 - 02: Variables and Data Types
Again, if don't initialize a local variable but use it as it is, the variable will have a
totally random value (depending on the bytes that were present at that memory
location). In several scenarios, the compiler will warn you of the potential error, but
not always.
In other words, if you write:
var
Value: Integer;
begin
ShowMessage (Value.ToString); // X is indefined
The output will be a totally random value, whatever bytes happened to be at the
memory location of the Value variable considered as an Integer.
Constants
Object Pascal also allows the declaration of constants. This let's you to give meaning-
ful names to values that do not change during program execution (and possibly
reducing the size by not duplicating constant values in your compiled code).
To declare a constant you don't need to specify a data type, but only assign an initial
value. The compiler will look at the value and automatically infer the proper data
type. Here are some sample declarations (also from the VariablesTest application
project):
const
Thousand = 1000;
Pi = 3.14;
AuthorName = 'Marco Cantu';
The compiler determines the constant data type based on its value. In the example
above, the Thousand constant is assumed to be of type SmallInt, the smallest inte-
gral type that can hold it. If you want to tell the compiler to use a specific type you
can simply add the type name to the declaration, as in:
const
Thousand: Integer = 1000;
When you declare a constant, the compiler can choose whether to assign a memory
location to the constant and save its value there, or to duplicate the actual value each
time the constant is used. This second approach makes sense particularly for simple
constants.
Once you have declared a constant you can use it almost like any other variable, but
you cannot assign a new value to it. If you try, you'll get a compiler error.
Marco Cantù, Object Pascal Handbook