0% found this document useful (0 votes)
28 views5 pages

Ex 01

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views5 pages

Ex 01

Uploaded by

skamelrech2020
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 5

94 - 04: Procedures and Functions

syntax provides for a single mechanism, functions, and in C a procedure is a func-


tion with a void (or null) result.
Both types of routines can have multiple parameters of specified data types. As we'll
see later, procedures and functions are also the basis of the methods of a class, and
also in this case the distinction between the two forms remains. In fact, differently
from C, C++, Java, C#, or JavaScript, you need to one of these two keywords when
declaring a function or a method.
In practice, even if there are two separate keywords, the difference between func-
tions and procedures is very limited: you can call a function to perform some work
and then ignore the result (which might be an optional error code or something like
that) or you can call a procedure which passes back a result in one of the parameters
(more on reference parameters later in this chapter).
Here is the definition of a procedure using the Object Pascal language syntax, which
uses the specific procedure keyword and is part of the FunctionTest project:
procedure Hello;
begin
Show ('Hello world!');
end;
As a comparison, this would be the same function written with the C language syn-
tax, which has no keyword, requires the parenthesis even in case there are no
parameters, and has a void or empty return value to indicate no result:
void Hello ()
{
Show ("Hello world!");
};
In fact, in the C language syntax there is no difference between procedure and func-
tion. In the Pascal language syntax, instead, a function has a specific keyword and
must have a return value (or return type).

note There is another very specific syntactical difference between Object Pascal and other languages,
that is presence of a semicolon at the end of the function or procedure signature in the definition,
before the begin keyword.

There are two ways to indicate the result of the function call, assign the value to
function name or use the Result keyword:
// classic style
function DoubleOld (Value: Integer) : Integer;
begin
DoubleOld := Value * 2;
end;

// modern alternative

Marco Cantù, Object Pascal Handbook


04: Procedures and Functions - 95

function Double (Value: Integer) : Integer;


begin
Result := Value * 2;
end;

note Differently from the classic Pascal language syntax, Object Pascal has actually three ways to indi-
cate the result of a function, including the Exit mechanism discussed in this chapter in the section
“Exit with a Result”.

The use of Result instead of the function name to assign the return value of a func-
tion is the most common syntax and tends to make the code more readable. The use
of the function name is a classic Pascal notation, now rarely used.
Again, by comparison the same function could be written with the C language syntax
as the following:
int Double (int Value)
{
return Value * 2;
};
If this is how these routines can be defined, the calling syntax is relatively straight-
forward, as you type in the identifier followed by the parameters within parenthesis.
In cases where there are no parameters, the empty parenthesis can be omitted
(again, unlike languages based on the C syntax). This code snippet and several fol-
lowing ones are part of the FunctionsTest project of this chapter:
// call the procedure
Hello;

// call the function


X := Double (100);
Y := Double (X);
Show (Y.ToString);
This is the encapsulation of code concept that I've introduced. When you call the
Double function, you don't need to know the algorithm used to implement it. If you
later find out a better way to double numbers, you can easily change the code of the
function, but the calling code will remain unchanged (although executing it might
become faster).
The same principle can be applied to the Hello procedure: We can modify the pro-
gram output by changing the code of this procedure, and the main program code will
automatically change its effect. Here is how we can change the procedure implemen-
tation code:
procedure Hello;
begin
Show ('Hello world, again!');
end;

Marco Cantù, Object Pascal Handbook


96 - 04: Procedures and Functions

Forward Declarations
When you need to use an identifier (of any kind), the compiler must have already
seen it, to know to what the identifier refers. For this reason, you usually provide a
full definition before using any routine. However, there are cases in which this is not
possible. If procedure A calls procedure B, and procedure B calls procedure A, when
you start writing the code, you will need to call a routine for which the compiler still
hasn't seen a definition.
In this cases (and in many others) you can declare the existence of a procedure or
function with a certain name and given parameters, without providing its actual
code. One way to declare a procedure or functions without defining it is to write its
name and parameters (referred to as the function signature) followed by the forward
keyword:
procedure NewHello; forward;
Later on, the code should provide a full definition of the procedure (which must be
in the same unit), but the procedure can now be called before it is fully defined. Here
is an example, just to give you the idea:
procedure DoubleHello; forward;

procedure NewHello;
begin
if MessageDlg ('Do you want a double message?',
TMsgDlgType.mtConfirmation,
[TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo],
0) = mrYes then
DoubleHello
else
ShowMessage ('Hello');
end;

procedure DoubleHello;
begin
NewHello;
NewHello;
end;

note The MessageDlg function called in the previous snippet is a relatively simple way to ask a confir-
mation of the user in the FireMonkey framework (a similar functions exists in the VCL framework
as well). The parameters are the message, the type of dialog box, and buttons you want to display.
The result is the identifier of the button that was selected.

This approach (which is also part of the FunctionTest application project) allows
you to write mutual recursion: DoubleHello calls Hello, but Hello might call Dou-
bleHello too. In other words, if you keep selecting the Yes button the program will

Marco Cantù, Object Pascal Handbook


04: Procedures and Functions - 97

continue showing the message, and show each twice for every Yes. In recursive code,
there must be a condition to terminate the recursion, to avoid a condition known as
stack overflow.

note Function calls use a stack for the parameters, the return value, local variables and more. If a func-
tions keeps calling itself in an endless loop, the memory area for the stack (which is generally of a
fixed and predefined size, determined by the linker) will terminate through an error known as a
stack overflow. Needless to say that the popular developers support site (www.stackoverflow.-
com) took its name from this programming error.

Although a forward procedure declaration is not very common in Object Pascal,


there is a similar case that is much more frequent. When you declare a procedure or
function in the interface section of a unit, it is automatically considered as a forward
declaration, even if the forward keyword is not present. Actually you cannot write
the body of a routine in the interface section of a unit. At the same time, you must
provide in the same unit the actual implementation of each routine you have
declared.

A Recursive Function
Given I mentioned recursion and gave a rather peculiar example of it (with two pro-
cedures calling each other), let me also show you a classic example of a recursive
function calling itself. Using recursion is often an alternative way to code a loop.
To stick with a classic demo, suppose you want to compute the power of a number,
and you lack the proper function (which is available in the run-time library, of
course). You might remember from math, that 2 at the power of 3 corresponds to
multiplying 2 by itself 3 times, that is 2*2*2.
One way to express this in code would be to write a for loop that is executed 3 times
(or the value of the exponent) and multiplies 2 (or the value of the base) by the cur-
rent total, starting with 1:
function PowerL (Base, Exp: Integer): Integer;
var
I: Integer;
begin
Result := 1;
for I := 1 to Exp do
Result := Result * Base;
end;
An alternative approach is to repeatedly multiply the base by the power of the same
number, with a decreasing exponent, until the exponent is 0, in which case the result

Marco Cantù, Object Pascal Handbook


98 - 04: Procedures and Functions

is invariably 1. This can be expressed by calling the same function over and over, in a
recursive way:
function PowerR (Base, Exp: Integer): Integer;
var
I: Integer;
begin
if Exp = 0 then
Result := 1
else
Result := Base * PowerR (Base, Exp - 1);
end;
The recursive version of the program is likely not faster than the version based on
the for loop, nor more readable. However there are scenarios such as parsing code
structures (a tree structure for example) in which there isn't a fixed number of ele-
ments to process, and hence writing a loop is close to impossible, while a recursive
functions adapts itself to the role.
In general, though, recursive code is powerful but tends to be more complex. After
many years in which recursion was almost forgotten, compared to the early days of
programming, new functional languages such Haskell, Erlang and Elixir make heavy
use of recursion and are driving this idea back to popularity.
In any case, you can find the two power functions in the code in the FunctionTest
application project.

note The two power functions of the demo don't handle the use of a negative exponent. The recursive
version in such a case will loop forever (an until the program hits a physical constraint). Also, by
using integers it is relatively fast to reach the maximum data type size and overflow it. I wrote
these functions with these inherent limitations to try to keep their code simple.

What Is a Method?
We have seen how you can write a forward declaration in the interface section of a
unit of by using the forward keyword. The declaration of a method inside a class
type is also considered a forward declaration.
But what exactly is a method? A method is a special kind of function or procedure
that is related to one of two data types, a record or a class. In Object Pascal, every
time we handle an event for a visual component, we need to define a method, gener-
ally a procedure, but the term method is used to indicate both functions and
procedures tied to a class or record.
Here is an empty method automatically added to the source code of a form (which is
indeed a class, as we'll explore much later in the book):

Marco Cantù, Object Pascal Handbook

You might also like