0% found this document useful (0 votes)
45 views56 pages

PPL Unit-3

This document discusses the fundamentals of subprograms, including their definitions, advantages, types (functions and procedures), and characteristics. It also covers design issues, local referencing environments, parameter passing methods, and the differences between procedures and functions. Additionally, it explains static and stack dynamic local variables, nested subprograms, and various parameter-passing techniques such as pass-by-value and pass-by-result.

Uploaded by

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

PPL Unit-3

This document discusses the fundamentals of subprograms, including their definitions, advantages, types (functions and procedures), and characteristics. It also covers design issues, local referencing environments, parameter passing methods, and the differences between procedures and functions. Additionally, it explains static and stack dynamic local variables, nested subprograms, and various parameter-passing techniques such as pass-by-value and pass-by-result.

Uploaded by

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

UNIT-3

PART-1
3.1.1 FUNDAMENTALS OF SUBPROGRAMS
Basic definition:
A subprogram is collection of statements which are designed to perform
particular task. Subprogram can be reused to save memory space and
coding time is known as a subprogram.
Advantages of Subprograms:
a. Readability
b. Abstraction
c. Code reusability
 There are two type of subprograms: 1. Function 2. Procedures.
 Subprogram contain two parts. First part contains subprogram header and
subprogram body or subprogram definition.
 Subprogram header which is the first part of the definition, it specifies
the type of the subprogram, name of the subprogram and also specifies if
any parameters.
Consider the following header examples:
def adder (parameters)
The above statement is the header of a Python subprogram named
adder. Ruby subprogram headers also begin with def.
procedure adder (parameters)
The above statement is the header of a Ada subprogram named adder.
subroutine adder (parameters)
The above statement is the header of a Fortran subroutine named
adder.
The header of a JavaScript subprogram begins with function. In C, the
header of a function named adder might be as follows:
void adder (parameters)
The reserved word void in this header indicates that the subprogram does
not return a value.

 Body of subprograms: Body of subprograms defines its actions. In the


C-based languages (and some others—for example, JavaScript) the body
of a subprogram is delimited by braces. In Ruby, an end statement
terminates the body of a subprogram.
 A subprogram call: A subprogram call is the explicit request that a
specific subprogram be executed.
 Active Subprogram: A subprogram is said to be active if, after having
been called, it has begun execution but has not yet completed that
execution. As with compound statements, the statements in the body of
a Python function must be indented and the end of the body is indicated
by the first statement that is not indented.
 Parameter Profile: The parameter profile of a subprogram contains the
number, order, and types of its formal parameters.
 Protocol: The protocol of a subprogram is its parameter profile plus, if it
is a function, its return type.
 Subprogram Declaration: Subprogram declarations provide the
subprogram’s protocol but do not include their bodies. Function
declarations are common in C and C++ programs, where they are
called prototypes. In most other languages (other than C and C++),
subprograms do not need declarations, because there is no requirement
that subprograms be defined before they are called.
 Parameters:
Actual parameters: The parameters present in the calling subprogram
are called Actual parameters. Subprogram call statements must include
the name of the subprogram and a list of parameters to be bound to the
formal parameters of the subprogram. These parameters are
called actual parameters.
Formal parameters: The parameters present in the called subprogram
is called formal parameters. Or the parameters in the subprogram header
are called formal parameters.
Positional parameters: In nearly all programming languages the
correspondence between actual parameters and formal parameter (or)
the binding of actual parameters to formal parameters is done by using
positions. Such parameters are called positional parameters.
The first actual parameters is bound to the first formal parameter and the
Second actual parameter & bound to Second formal parameter etc.
This is an effective and Safe method of relating actual parameters to
their corresponding formal parameters as long as the parameter lists are
relatively short.
Keyword Parameters: When parameter lists are long however it is easy
for a programmer to make mistakes in the order of actual parameters in
the list. One Solution to this problem is to provide Keyword Parameters,
in which the name of the formal parameter to which an actual parameter
is to be bound is specified with the actual parameter in a call.
e.g. Python functions can be called using this technique, as in
sumer(length = my_length, list = my_array, sum =
my_sum)
where the definition of sumer has the formal parameters length, list, and
sum.
Advantage is they can appear in any order in the actual parameters list.
Disadvantage is the use of subprogram must know the name of the
actual parameters.
In Python, Ruby, C++, Fortran 95+ Ada, and PHP, formal parameters can
have default values. A default value is used if no actual parameter is
passed to the formal parameter in the subprogram header. Consider the
following Python function header:
def compute_pay(income, exemptions = 1, tax_rate)
calling the above method is
pay = compute_pay(20000.0, tax_rate = 0.15)
In C++, which does not support keyword parameters, the rules for default
parameters are necessarily different. The default parameters must appear
last, because parameters are positionally associated.
float compute_pay(float income, float tax_rate, int
exemption=1)
calling above function
pay= compute_pay(2000.0, 1000.2)
In most languages that do not have default values for formal parameters, the
number of actual parameters in a call must match the number of formal
parameters in the subprogram calling.
General Subprogram Characteristics:
All subprograms have the following characteristics:
 Each subprogram has a single entry point.
 The calling program unit is suspended during the execution of the
called subprogram, which implies that there is only one subprogram in
execution at any given time.
 Control always returns to the caller when the subprogram execution
terminates.
Procedures and Functions:
Procedures: Procedure does not have a return type. In Fortran procedures
are called as subroutines. Procedures are collections of statements that
define parameterized computations. These statements are executed by
calling procedures. Procedures can produce results in the calling program
unit by two methods:
(1)If there are variables that are not formal parameters but are still visible
in both the procedure and the calling program unit, the procedure can
change them and
(2)if the procedure has formal parameters that allow the transfer of data
to the caller, those parameters can be changed.
Elements of procedures are:
1. Name for declaration of procedure
2. Body consist of local declarations and statements
3. Formal parameters which are placeholders of actuals
4. Optional result type.
Syntax for procedures is

Example of procedure in pascal

Advantages of Procedures:
1. The implementation of certain piece of code can be separated out
from the main implementation. Suitable names used for such
procedure represents its purpose as well. For instance - If we call
swap(a,b) function in the main implementation then it will indicate
interchanging of the values a and b.
2. Writing a separate procedure allows to hide Implementation details.
The main procedure looks abstract with simply the call to the
procedures.
3. Procedures can be used to partition a program into smaller modules.
These modules are useful to maintain a large and complex code.
4. Finding errors from a large complex program becomes simplified when
procedures or functions are written.
5. The modifications can be made in the program without affecting rest
of the programming code.
6. There are some standard procedures which are the part of standard
library. For example - sqrt function in C is used for finding the square
root of the number.
Functions: Functions structurally resemble procedures but are semantically
modeled on mathematical functions. Functions are called by appearances of
their names in expressions, along with the required actual parameters. The
value produced by a function’s execution is returned to the calling function.
function body or function definition contain logic to perform particular task.
Syntax according to C-language

If the function contain return type then that function definition should
contain return keyword.
A single function can return only one value.
return(10); return(a); return(‘a’); return(a, b)
first three statements are correct but forth statement is wrong.
Example of function in Pascal

Differences between Procedure and Function


Procedure Function
Procedure may or may not return a Function returns a value.
value.
Procedure is set of commands Function is set of instructions for
executed in order. used for some computation.

Procedures can’t be called from Function can be called from


function. procedure.
Example-Pascal, ADA are some Example-C, C++, Java are some
programming languages that make programming languages that make
use of procedures. use of functions.

Example program that demonstrate function in C language.


Some programming languages like Fortran, Ada provides both functions and
procedures. C language has only functions, these functions behave like
procedures.
Methods of java and C#, member functions of C++ are similar to functions of
C language.

3.1.2 DESIGN ISSUES FOR SUBPROGRAMS


The following are some of design issues of subprogram.
 Are local variables statically or dynamically allocated?
 Can subprogram definitions appear in other subprogram definitions?
 What parameter-passing method or methods are used?
 Are the types of the actual parameters checked against the types of
the formal parameters?
 If subprograms can be passed as parameters and subprograms can be
nested, what is the referencing environment of a passed subprogram?
 Can subprograms be overloaded?
 Can subprograms be generic?
 If the language allows nested subprograms, are closures supported?

3.1.3 LOCAL REFERENCING ENVIRONMENTS


Subprograms can define their own variables, thereby defining local
referencing environments. Variables that are defined inside subprograms are
called local variables, because their scope is usually the body of the
subprogram in which they are defined. local variables can be either static or
stack dynamic.
Static local variable:
The static local variables are variables whose scope finishes when the
subprogram within which it is defined gets terminated and they retain their
value once they are initialized. For static local variable memory is allocated
at compile time.
Advantage of static local variables
 static local variables are slightly more efficient—they require no run-
time overhead for allocation and deallocation.
 Also, if accessed directly, these accesses are obviously more efficient.
Disadvantage of static local variables
 They do not support recursion.
 The storage cannot be shared with the local variables of other inactive
subprograms.
Stack dynamic variable:
The stack dynamic local variables are kind of local variables which are bound
to storage when the subprogram begins execution and are unbound from
storage when the execution terminates. Stack-dynamic variables are
allocated from the run-time stack. For stack dynamic variable memory is
allocated at run time.
Advantages of stack-dynamic local variables:
 The primary one being the flexibility they provide to the subprogram.
 Stack-dynamic local variables support essential that recursive
subprograms
 This is not as great an advantage as it was when computers had
smaller memories.
 Stack-dynamic locals is that the storage for local variables in an active
subprogram can be shared with the local variables in all inactive
subprograms.
Disadvantages of stack-dynamic local variables:
 The cost of the time required to allocate, initialize (when necessary),
and deallocate such variables for each call to the subprogram.
 Accesses to stack-dynamic local variables must be indirect whereas
accesses to static variables can be direct.
 when all local variables are stack dynamic, subprograms cannot be
history sensitive. That means, they cannot retain data values of local
variables between calls.
In most contemporary languages, local variables in a subprogram are by
default stack dynamic. In C and C++ functions, locals are stack dynamic
unless specifically declared to be static. For example, in the following C (or
C++) function, the variable sum is static and count is stack dynamic.
int adder(int list[], int listlen)
{
static int sum = 0; //static local variable
int count; // stack dynamic local variable
for (count = 0; count < listlen; count ++)
sum += list [count];
return sum;
}
 The ADA subprograms and member function of of C++, methods of
Java, and C# have only stack-dynamic local variables.
 All local variables in python methods are static dynamic local variable.

Nested Subprograms:
 The idea of nesting subprograms originated with Algol 60. The
motivation was to be able to create a hierarchy of both logic and
scopes.
 Writing one subprogram definition in another subprogram definition is
called nested subprogram.
 C, C++, Java does not allow nested sub programs
 JavaScript, python, Ruby support nested subprograms.
Example:
Void add()
{
Void sub() //
{
------
------
}
}
3.1.4 PARAMETER PASSING METHODS
Parameter-passing methods are the ways in which parameters are
transmitted to and/or from called subprograms. First, we focus on the
different semantics models of parameter-passing methods. Then, we discuss
the various implementation models invented by language designers for
these semantics models.
Semantics Models of Parameter Passing:
Formal parameters are characterized by one of three distinct semantics
models:
(1)They can receive data from the corresponding actual parameter
(2)They can transmit data to the actual parameter
(3)they can do both.
These models are called in mode, out mode, and inout mode,
respectively.
There are two conceptual models of how data transfers take place in
parameter transmission: Either an actual value is copied (to the caller, to the
called, or both ways), or an access path is transmitted. Most commonly, the
access path is a simple pointer or reference. The three semantics models of
parameter passing when values are copied is shown in below.

Implementation Models of Parameter Passing:


A variety of models have been developed by language designers to guide the
implementation of the three basic parameter transmission modes.
Pass-by-Value:
 When a parameter is passed-by-value, the value of the actual
parameter is used to initialize the corresponding formal parameter,
which then acts as a local variable in the subprogram, thus
implementing in-mode semantics. Pass-by-value is normally
implemented by copy, because accesses often are more efficient with
this approach.
 The advantage of pass-by-value is that for scalars it is fast, in both
linkage cost and access time.
 The main disadvantage of the pass-by-value method if copies are used
is that additional storage is required for the formal parameter, either in
the called subprogram or in some area outside both the caller and the
called subprogram.
 In addition, the actual parameter must be copied to the storage area
for the corresponding formal parameter. The storage and the copy
operations can be costly if the parameter is large, such as an array
with many elements.
 Example C program for swapping the values of the two variables
#include <stdio.h>
void swap(int , int); //prototype of the function
int main()
{
int a = 10;
int b = 20;
printf("Before swapping the values in main a = %d, b = %d\n",a,b);
swap(a,b);
printf("After swapping values in main a = %d, b = %d\n",a,b);
}
void swap (int a, int b)
{
int temp;
temp = a;
a=b;
b=temp;
printf("After swapping values in function a = %d, b = %d\n",a,b);
}

Output:Before swapping the values in main a = 10, b = 20


After swapping values in function a = 20, b = 10
After swapping values in main a = 10, b = 20
Pass-by-Result:
 Pass-by-Result is an implementation model for out-mode parameters.
When a parameter is passed by result, no value is transmitted to the
subprogram. The corresponding formal parameter acts as a local
variable, but just before control is transferred back to the caller, its
value is transmitted back to the caller’s actual parameter, which
obviously must be a variable.
 The pass-by-result method has the advantages and disadvantages of
pass- by-value, plus some additional disadvantages. If values are
returned by copy (as opposed to access paths), as they typically are,
pass-by-result also requires the extra storage and the copy operations
that are required by pass-by-value.
 It is difficulty of implementing pass-by-result by transmitting an access
path usually results in it being implemented by copy.
 One additional problem with the pass-by-result model is that there can
be an actual parameter collision, such as the one created with the call
sub(p1, p1). In sub, assuming the two formal parameters have
different names, the two can obviously be assigned different values.
 For example, consider the following C# method, which specifies the
pass-by-result method with the out specifier on its formal parameter.

If, at the end of the execution of Fixer, the formal parameter x is assigned to
its corresponding actual parameter first, then the value of the actual
parameter a in the caller will be 35. If y is assigned first, then the value of
the actual parameter a in the caller will be 17.
Pass-by-Value-Result:
 Pass-by-value-result is an implementation model for inout-mode
parameters in which actual values are copied. It is in effect a
combination of pass-by-value and pass-by-result. The value of the
actual parameter is used to initialize the corresponding formal
parameter, which then acts as a local variable. At subprogram
termination, the value of the formal parameter is transmitted back to
the actual parameter.
 Pass-by-value-result is sometimes called pass-by-copy, because the
actual parameter is copied to the formal parameter at subprogram
entry and then copied back at subprogram termination.
 The advantage of pass-by-value-reference is that the passing process
itself is efficient, in terms of both time and space. Duplicate space is
not required, nor is any copying required.
 Pass-by-value-result shares with pass-by-value and pass-by-result the
disadvantages of requiring multiple storage for parameters and time
for copying values. The advantages of pass-by-value-result are relative
to pass-by-reference.
 Consider the following example code
In this pass-by-value-result the variable a
corresponding parameter is x and b corresponding
parameter is y. Here a, b values are copies to x and y
parameters. When x is modified this modification is
not affected immediately to a parameter value. after
subprogram is executed formal parameter values are
affected to actual parameters.

a value is 4
b value is 2

Pass-by-Reference:
 Pass-by-reference is a second implementation model for inout-mode
parameters. Rather than copying data values back and forth, however,
as in pass-by- value-result, the pass-by-reference method transmits an
access path, usually just an address, to the called subprogram.
 Thus, the called subprogram is allowed to access the actual parameter
in the calling program unit. In effect, the actual parameter is shared
with the called subprogram.
 The advantage of pass-by-reference is that the passing process itself is
efficient, in terms of both time and space. Duplicate space is not
required, nor is any copying required.
 There are, however, several disadvantages to the pass-by-reference
method. First, access to the formal parameters will be slower than
pass-by-value parameters, because of the additional level of indirect
addressing that is required. Second, if only one-way communication to
the called subprogram is required, inadvertent and erroneous changes
may be made to the actual parameter. Another problem of pass-by-
reference is that aliases can be created.
 Consider a C++ function that has two parameters that are to be
passed by reference
void fun(int &first, int &second)
If the call to fun happens to pass the same variable twice, as in
fun(total, total) then first and second in fun will be aliases.
 Consider the following example code for understanding pass-by-
reference

In this pass-by-reference the variable a corresponding


parameter is x and b corresponding parameter is y. Here
a, b and x, y parameters take the same memory location.
When x is modified this modification immediately
affected to a parameter value.

a value is 4
b value is 2

 Example C program for swapping the values of the two variables


#include <stdio.h>
void swap(int *, int *); //prototype of the function
int main()
{
int a = 10;
int b = 20;
printf("Before swapping the values in main a = %d, b = %d\n",a,b);
swap(&a,&b);
printf("After swapping values in main a = %d, b = %d\n",a,b);
}
void swap (int *a, int *b)
{
int temp;
temp = *a;
*a=*b;
*b=temp;
printf("After swapping values in function a = %d, b = %d\n",*a,*b);
}
Output: Before swapping the values in main a = 10, b = 20
After swapping values in function a = 20, b = 10
After swapping values in main a = 20, b = 10

Pass-by-Name:
 Pass-by-name is an inout-mode parameter transmission method that
does not correspond to a single implementation model.
 When parameters are passed by name, the actual parameter is, in
effect, textually substituted for the corresponding formal parameter in
all its occurrences in the subprogram. A pass-by- name formal
parameter is bound to an access method at the time of the
subprogram call, but the actual binding to a value or an address is
delayed until the formal parameter is assigned or referenced.
 This procedure is treated like macro. The actual parameters can be
surrounded by parenthesis to preserve their integrity.

The variable names a and b are substitute to the formal parameters x, y.


then x is a and y is b.
 Algol language is supports this Pass-by-Name.

3.1. 5 PARAMETERS THAT ARE SUBPROGRAMS


In programming, a number of situations occur that are most conveniently
handled if subprogram names can be sent as parameters to other
subprograms.

Int sum() Void show(int x) Void main()


{ { {
-------- -------- Show(sum());
-------- ------- }
} }
Passing subprogram names as parameter details of how it works can be
confusing. If only the transmission of the subprogram code was necessary, it
could be done by passing a single pointer. However, two complications arise.
1. First, there is the matter of type checking the parameters of the
activations of the subprogram that was passed as a parameter.
In C and C++, functions cannot be passed as parameters, but pointers
to functions can. The type of a pointer to a function includes the
function’s protocol. Because the protocol includes all parameter types,
such parameters can be completely type checked.
Fortran 95+ has a mechanism for providing types of parameters for
subprograms that are passed as parameters, and they must be
checked.
2. The second complication with parameters that are subprograms
appears only with languages that allow nested subprograms.
The issue is what referencing environment for executing the passed
subprogram should be used.
There are three choices:
 The environment of the call statement that enacts the passed
subprogram (shallow binding)
 The environment of the definition of the passed subprogram (deep
binding)
 The environment of the call statement that passed the subprogram
as an actual parameter (ad hoc binding)

3.1.6 CALLING SUBPROGRAMS INDIRECTLY


The calling of subprograms indirectly occurs in a situation when there several
possible subprograms to be called and the correct one on a particular run of
the program is not known until execution particularly in event handling.
 In C/C++ much calls are made through function pointer.
 In C#, the power and flexibility of method pointers is increased by
making them objects. These are called delegates, because instead of
calling a method, a program delegates that action to a delegate. To use
a delegate, first the delegate class must be defined with a specific
method protocol. An instantiation of a delegate holds the name of a
method with the delegate’s protocol that it is able to call. The syntax of
a declaration of a delegate is the same as that of a method
declaration, except that the reserved word delegate is inserted just
before the return type. For example, we could have the following:
public delegate int display(int x);
 This delegate type, named display, can be instantiated with any
method that takes an int as a parameter and returns an int. For
example, consider the following method declaration: static int
fun(int x)
{
// Function body
}
 We can create an instance of display method by passing the fun as
parameter.
display displayfun = new display(fun);
 The call to the instance displayfun can be made as follows-
displayfun(100);
 A delegate can store more than one address, which is called a
multicast delegate.
 C and C allow a program to define a pointer to function, through which
the function can be called.

3.1.7 OVERLOADED SUBPROGRAMS


Overloading is mechanism in which we can use many methods having the
same function name but can pass different number of parameters or
different type of parameters.
 An overloaded subprogram is a subprogram that has the same
name as another subprogram in the same referencing environment.
 Every version of an overloaded subprogram must have a unique
protocol; that is, it must be different from the others in the number,
order, or types of its parameters, and possibly in its return type if it is a
function.
 The meaning of a call to an overloaded subprogram is determined by
the actual parameter list (and/or possibly the type of the returned
value, in the case of a function).
Ex: int sum(int a, int b)
double sum(double a, double b);
int sum(int a, int b, int c);
 C++, Java, Ada, and C# include predefined overloaded subprograms.
For example, many classes in C++, Java, and C# have overloaded
constructors. Because each version of an overloaded subprogram has a
unique parameter profile, the compiler can disambiguate occurrences
of calls to them by the different type parameters.
 Users are also allowed to write multiple versions of subprograms with
the same name in Ada, Java, C++, C#, and F#.
 Overloaded subprograms that have default parameters can lead to
ambiguous subprogram calls.
Example program in java

3.1.8 GENERIC SUBPROGRAMS


There are situations in which the similar subprograms are written several
times because of some minor differences in parameters. For example, if we
want to perform addition of two integers & addition of two double values
then we write following

int add int(int a, int b)double add_double (double a,


{ double b)
int c; {
c=a+b; double c;
return c; c=a+b;
} return c;
}
 A polymorphic subprogram takes parameters of different types on
different activations. Overloaded subprograms provide a particular
kind of polymorphism called ad hoc polymorphism. Overloaded
subprograms need not behave similarly.
 Languages that support object-oriented programming usually support
subtype polymorphism. Subtype polymorphism means that a
variable of type T can access any object of type T or any type derived
from T.
 Parametric polymorphism is provided by a subprogram that takes
generic parameters that are used in type expressions that describe the
types of the parameters of the subprogram. Parametrically
polymorphic subprograms are often called generic subprograms. Ada,
C++, Java 5.0+, C# 2005+, and F# provide a kind of compile-time
parametric polymorphism.
 Note that the instructions in both the subprograms are very much
similar but due to change in data types we need to write two different
routines. To avoid these efforts, programming languages offer the
concept of generic subprogram.
 Definition: Generic subprogram is a subprogram which implements
the desired algorithm using general data type.
 In C++, the concept of generic routine is achieved by using templates.
 For example - In C the above code can be implemented using generic
routine as follows
T add(T a, T b)
{
T c;
c=a+b;
return c;
}

Generic Functions in C++:


Generic functions in C++ have the descriptive name of template functions.
The definition of a template function has the general form
template <template parameters>
—a function definition that may include the template parameters.
A template parameter (there must be at least one) has one of the forms
class identifier typename identifier
A template can take another template, in practice often a template class that
defines a user-defined generic type, as a parameter, but we do not consider
that option here.
As an example of a template function, consider the following:
template <class Type>
Type max(Type first, Type second) {
return first > second ? first : second;
}

where Type is the parameter that specifies the type of data on which the
function will operate. This template function can be instantiated for any type
for which the operator > is defined.
Generic Methods in Java 5.0:
Support for generic types and methods was added to Java in Java 5.0. The
name of a generic class in Java 5.0 is specified by a name followed by one or
more type variables delimited by pointed brackets. For example,
generic_class<T>
where T is the type variable.
Java’s generic methods differ from the generic subprograms of C++ in
several important ways.
 First, generic parameters must be classes—they cannot be primitive
types. This requirement disallows a generic method that mimics our
example in C++, in which the component types of arrays are generic and
can be primitives. In Java, the components of arrays (as opposed to
containers) cannot be generic.
 Second, although Java generic methods can be instantiated any number
of times, only one copy of the code is built. The internal version of a
generic method, which is called a raw method, operates on Object class
objects. At the point where the generic value of a generic method is
returned, the compiler inserts a cast to the proper type.

3.1.9 DESIGN ISSUES FOR FUNCTIONS


The following design issues are specific to functions:
 Are side effects allowed?
 What types of values can be returned?
 How many values can be returned?
Functional Side Effects:
Parameters to the function should always be in-mode parameters.
 For example, Ada functions can have only in-mode formal parameters.
This requirement effectively prevents a function from causing side
effects through its parameters.
 Pure functional languages, such as Haskell, do not have variables, so
their functions cannot have side effects.
Type of return values are allowed:
 Most imperative languages restrict the return types that can be return
by the functions.
 C allows any type except arrays and functions
 C++ is like C but also allows user-defined types
 Ada subprograms can return any type
 Java and C# methods can return any type.
Number of Returned Values:
 In most languages, only a single value can be returned from a function.
However, that is not always the case. Ruby allows the return of more
than one value from a method.
 If a return statement in a Ruby method is not followed by an
expression, nil is returned.
 Lua also allows functions to return multiple values. Such values follow
the return statement as a comma-separated list, as in the following:
return 3, sum, index;
In F#, multiple values can be returned by placing them in a tuple and having
the tuple be the last expression in the function.

3.1.10 USER-DEFINED OVERLOADED OPERATORS


 Operator Overloading means providing additional meaning for the
existing operator without Effecting its basic meaning.
 There are predefined operators such as +, -, *, / and so on which
operate on the fundamental data types such as integer, double, char
and so on.
 In order to make the user defined data type as natural as fundamental
data type, the user defined data types can be associated with the set
of predefined operators the concept called operator overloading is
used.
 For instance - If we want to perform the operations on two complex
numbers then with the help of operator overloading the operations
such as addition, multiplication and so on can be carried out. In this
case the class for Complex number is created.
 Definition of Operator Overloading: Operator overloading is a
mechanism in which the existing operator is used to give user defined
meaning to it without changing the basic operation.
 Languages like C++, ADA, Python, Ruby use the concept of operator
overloading.
 Syntax of overloading an operator is

The above syntax for inside of


The above syntax for outside of the
the class.
class.
C++ program to demonstrate operator overloading is given below.

Output:
The addition of Two vectors is …11 and 22.

3.1.11 CLOSURES:
 A closure is a subprogram and the referencing environment where it
was defined. The referencing environment is needed if the subprogram
can be called from any arbitrary place in the program.
 If a static-scoped programming language does not allow nested
subprograms, closures are not useful, so such languages do not
support them.
 All of the variables in the referencing environment of a subprogram in
such a language (its local variables and the global variables) are
accessible, regardless of the place in the program where the
subprogram is called.
 Nearly all functional programming languages, most scripting
languages, and at least one primarily imperative language, C#,
support closures. These languages are static-scoped, allow nested
subprograms, and allow subprograms to be passed as parameters.
Following is an example of a closure written in JavaScript:
The output of this code, assuming it was embedded in an HTML document
and displayed with a browser, is as follows:
Add 10 to 20: 30
Add 5 to 20: 25
In this example, the closure is the anonymous function defined inside
the makeAdder function, which makeAdder returns. The
variable x referenced in the closure function is bound to the parameter that
was sent to makeAdder.

3.1.12 COROUTINES:
A coroutine is a special kind of Subprogram. Coroutines control mechanism is
called as symmetric control model.
 Coroutines Can have, multiple Entry point, which are controlled by the
coroutines them Selves. They also have the means to maintain their
status between activations
 Coroutine have static local variables.
 Secondary execution of a coroutines often begin at points other than
its beginning. Because of this, the invocation is called a resume rather
than a call.
 For example
Sub co1()
{
………
resume co2();
………..
resume co3();
………
}
 The first time co1 is resumed, its execution begins a first statement
and executes down to and including the resume of co2, which transfers
control to co2. Then the next time co1 is resumed, its execution begins
at the first statement after its call to co2.
 When co1 is resumed the third time, its execution begins at the first
statement after its call to co3. Only one coroutine is actually in
execution at a given time. There may be only one processor, all the
coroutines are executed simultaneously (concurrently) by sharing
processor time this is called quasi-concurrency.
 coroutines are created in an application by a program unit called the
Master units, which is not a coroutine when created, Coroutines
execute their initialization code and then returns control to that master
unit.
 When all of a family of coroutines are constructed, the master program
resumes one of the coroutines, and the members of the family of
coroutines then resume each other in some order until their work is
completed.
 If the execution of a coroutine reaches the end of its code section,
control is transferred to the master unit that created it. This is the
mechanism for ending execution of the collection of coroutines, when
that is desirable. In some programs, the coroutines run whenever the
computer is running.
 For example, Suppose the game has four players who all use the same
strategy. Such a game can be simulated by having a master program
unit create a family of coroutines, each with a collection, or hand, of
cards. The master program could then start the simulation by resuming
one of the player coroutines, which, after it had played its turn, could
resume the next player coroutine, and so forth until the game ended.
Two possible execution control sequences for two coroutines without loops
PART-2
3.2.1 THE GENERAL SEMANTICS OF CALLS AND RETURNS
The subprogram call and return operations are together called subprogram
linkage. The implementation of subprograms must be based on the
semantics of the subprogram linkage of the language being implemented.
A subprogram call in a typical language has numerous actions associated
with it.
1. The call process must include the implementation of whatever
parameter-passing method is used.
2. Static local variables.
3. Execution status of calling program.
4. Transfer of controls.
5. Subprogram nesting.
The required actions of a subprogram return are less complicated than those
of a call. If the subprogram has parameters that are out mode or inout mode
and are implemented by copy, the first action of the return process is to
move the local values of the associated formal parameters to the actual
parameters. Next, it must deallocate the storage used for local variables and
restore the execution status of the calling program unit. Finally, control must
be returned to the calling program unit.

3.2.2 IMPLEMENTING “SIMPLE” SUBPROGRAMS:


By “simple” we mean that subprograms cannot be nested and all local
variables are static. Early versions of Fortran were examples of languages
that had this kind of subprograms.
The semantics of a call to a “simple” subprogram requires the following
actions:
1. Save the execution status of the current program unit.
2. Compute and pass the parameters.
3. Pass the return address to the called.
4. Transfer control to the called.
The semantics of a return from a simple subprogram requires the following
actions:
1. If there are pass-by-value-result or out-mode parameters, the current
values of those parameters are moved to or made available to the
corresponding actual parameters.
2. If the subprogram is a function, the functional value is moved to a place
accessible to the caller.
3. The execution status of the caller is restored.
4. Control is transferred back to the caller.
The call and return actions require storage for the following:
• Status information about the caller
• Parameters
• Return address
• Return value for functions
• Temporaries used by the code of the subprograms
The format, or layout, of the noncode part of a subprogram is called an
activation record. The form of an activation record is static. An activation
record instance is a concrete example of an activation record, a collection
of data in the form of an activation record.

An activation record for simple subprograms.


 Because an activation record instance for a “simple” subprogram has
fixed size, it can be statically allocated. In fact, it could be attached to
the code part of the subprogram.
 Code and activation record of program consisting of three
subprograms: A, B, and C
 These parts may be separately compiled and put together by linker
(Sometimes linkers are called loaders, linker/ loaders, or link editors.)
 When the linker is called for a main program, its first task is to find the
files that contain the translated subprograms referenced in that
program and load them into memory.

The code and activation records of a program with simple subprograms.


3.2.3 IMPLEMENTING SUBPROGRAMS WITH STACK-DYNAMIC LOCAL VARIABLES
The implementation of the subprogram linkage in languages in which locals
are stack dynamic, again focusing on the call and return operations. One of
the most important advantages of stack-dynamic local variables is support
for recursion. Therefore, languages that use stack-dynamic local variables
also support recursion.
More Complex Activation Records:
Subprogram linkage in languages that use stack-dynamic local variables are
more complex than the linkage of simple subprograms for the following
reasons:
 The compiler must generate code for the implicit allocation and
deallocation of local variables on the stack.
 Recursion adds the possibility of multiple simultaneous activations of a
subprogram, which means that multiple instances of activation
records.

When AddTwo is called, its activation record is dynamically created


and pushed onto the run-time stack.

After placing the activation record on runtime stack, the stack pointer
will move to the size of the activation record. Which is represented
below.
Consider the following skeletal C function:

In this example the array is declared as local variable.


 Activating a subprogram requires the dynamic creation of an instance
of the activation record for the subprogram.
 As stated earlier, the format of the activation record is fixed at compile
time, although its size may depend on the call in some languages.
 This stack is part of the runtime system and therefore is called the
run-time stack

The activation record for function sub


Using the activation record form given in this section, the new actions are as
follows:
The caller actions are as follows:
1. Create an activation record instance.
2. Save the execution status of the current program unit.
3. Compute and pass the parameters.
4. Pass the return address to the called.
5. Transfer control to the called.
The prologue actions of the called are as follows:
1. Save the old EP in the stack as the dynamic link and create the new value.
2. Allocate local variables.
The epilogue actions of the called are as follows:
1. If there are pass-by-value-result or out-mode parameters, the current
values of those parameters are moved to the corresponding actual
parameters.
2. If the subprogram is a function, the functional value is moved to a place
accessible to the caller.
3. Restore the stack pointer by setting it to the value of the current EP minus
one and set the EP to the old dynamic link.
4. Restore the execution status of the caller.
5. Transfer control back to the caller.

An Example Without Recursion:


Consider the following skeletal C program:
Stack contents for three points in a program
 The collection of dynamic links present in the stack at a given time is
called the dynamic chain, or call chain.
 Local variables can be accessed by their offsets from the beginning of
the activation record, whose address is stored in the EP. Such an offset
is called a local_offset.
 The local_offset of a variable in an activation record can be determined
at compile time, using the order, types, and sizes of variables declared
in the subprogram associated with the activation record.
An example with recursion:
Consider the following example C program, which uses recursion to compute
the factorial function:
 The contents of the stack for the three times execution reaches
position 1 in the function factorial. Each shows one more activation of
the function, with its functional value undefined.
 The first activation record instance has the return address to the
calling function, main.

Stack contents at position 1 in factorial


3.2.4 NESTED SUBPROGRAMS
Some of the non–C-based static-scoped programming languages such as
Fortran 95+ Ada, Python, JavaScript, Ruby, and Lua, as well as the functional
languages use stack-dynamic local variables and allow subprograms to be
nested.
All the variables that can be nonlocally accessed are in existing activation
record instances and therefore are somewhere in the stack. The process of
locating a nonlocal reference is as follows:
1. The first step of the access process is to find the instance of the
activation record in the stack in which the variable was allocated.
2. The second part is to use the local_offset of the variable (within the
activation record instance) to access it.
 The most common way to implement static scoping in languages that
allow nested subprograms is static chaining. In this approach, a new
pointer, called a static link, is added to the activation
record. The static link, which is sometimes called a static scope
pointer, points to the bottom of the activation record instance of an
activation of the static parent. It is used for accesses to nonlocal
variables. Instead of having two activation record elements before the
parameters, there are now three: the return address, the static
link, and the dynamic link.
 A static chain is a chain of static links that connect certain activation
record instances in the stack. Finding the correct activation record
instance of a nonlocal variable using static links is relatively
straightforward.
 Static_depth be an integer associated with a static scope that
indicates how deeply it is nested in the outermost scope. To illustrate
the complete process of nonlocal accesses, consider the following
skeletal Ada program:
The stack situation when execution
first arrives at point 1 in this
program is shown in below.
Implementing Subprograms is

The sequence of procedure calls is


Main_2 calls Bigsub
ARI = activation record instance
Bigsub calls Sub2
Sub2 calls Sub3 Stack contents at position 1 in the
Sub3 calls Sub1 program Main_2

3.2.5 BLOCKS
Block is a specific group of instructions with user specified scope for
variables. For example-
{
int x;
x=a[0];
a[1]=x;
}
The lifetime of variable x begins when control enters the block. There are
two methods of implementing block. These are:
(1) Treat blocks as parameter-less subprograms that are always called from
the same location - Every block has an activation record, an instance is
created every time the block is executed
(2) Since the maximum storage required for a block can be statically
determined, this amount of space can be allocated after the local variables in
the activation record.
 Blocks are treated as parameterless subprograms that are always
called from the same place in the program. Therefore, every block has
an activation record. An instance of its activation record is created
every time the block is executed.
 The maximum amount of storage required for block variables at any
time during the execution of a program can be statically determined,
because blocks are entered and exited in strictly textual order.
For example, consider the following skeletal program:

For this program, the static-memory


layout could be used. Note
that f and g occupy the same
memory locations as a and b,
because a and b are popped off the
Block variable storage when
stack when their block is exited
blocks are not treated as
(before f and g are allocated).
parameter less procedures

3.2.6 IMPLEMENTING DYNAMIC SCOPING


The variable is bound to its scope statically or dynamically.
1. The static scope is in terms of lexical structure of a program. That
means - the scope of variable is obtained by examining the complete
source program without executing it. For example C program makes
use of static scope.
2. The dynamic scope is in terms of program execution. That means-
the scope of variable can be determined during the execution of the
program. For example - LISP, SNOBOL4 languages make use of
dynamic scoping.
There are at least two distinct ways in which local variables and nonlocal
references to them can be implemented in a dynamic-scoped language:
deep access and shallow access
Deep Access:
 In this method, the stack of active variables is maintained.
 The dynamic chain links together all subprogram activation record
instances in the reverse of the order in which they were activated.
Therefore, the dynamic chain is exactly what is needed to reference
nonlocal variables in a dynamic-scoped language.
 This method is called deep access, because access may require searches
deep into the stack.
 Every activation record instance must have variable names.
Consider the following example skeletal program:

Suppose the following sequence of


function calls occurs:
main calls sub1
sub1 calls sub1
sub1 calls sub2
sub2 calls sub3 Stack contents for a dynamic-
scoped program
Shallow Access:
 In this method, there exists a central storage and one slot is allotted
for every variable name.
 If the names are not created at runtime then the storage layout can be
fixed at compile time. Otherwise, when new activation procedure
occurs, then that procedure changes the storage entries for its local at
entry and exit.
 One variation of shallow access is to have a separate stack for each
variable name in a complete program.
 In the shallow-access method, one variation of shallow access is to
have a separate stack for each variable name in a complete program.
Every time a new variable with a particular name is created by a
declaration at the beginning of a subprogram that has been called, the
variable is given a cell at the top of the stack for its name.
 Variables declared in subprograms are not stored in the activation
records of those subprograms. If the names are not created at runtime
then the storage layout can be fixed at compile time. There exists a
central table with an entry for each variable name.
 When a subprogram terminates, the lifetimes of its local variables end,
and the stacks for those variable names are popped. The variable
stacks for the earlier example is shown in below.

One method of using shallow access to implement dynamic scoping


 Another option for implementing shallow access is to use a central
table that has a location for each different variable name in a program.
Along with each entry, a bit called active is maintained that indicates
whether the name has a current binding or variable association.
Differences between Deep Access and Shallow Access:
Deep Access Shallow Access
It requires a symbol table at run It has overhead of handling
time procedure entry and exit
It takes longer time to access the It provides the fast access.
non locals
PART-3
3.3.1 THE CONCEPT OF ABSTRACTION
 An abstraction is a view or representation of an entity that includes
only the most significant attributes. It is fundamental aspect of
program. All most all the languages support process of abstraction with
subprogram.
 Abstraction is the process of hiding the implementation details from
user, only the functionality will be provided to the user. In other words,
the user will have information on what the object does instead of how
it does it. In java, abstraction is achieved using Abstract classes and
interfaces.
Encapsulation:
 Encapsulation is a mechanism for wrapping the data (variables) and
code acting on the data (methods) together as a single unit. The
logical module of C++ is class. The class defines the encapsulated
unit. It encapsulates the data members and the operations that can be
performed on these data members.
 For example
class Test
{
private:
int a,b,c;
public:
void add();
void display();
};
This encapsulation approach is useful in two ways.
 It binds the data member with operations or methods.
 It imposes the level of abstraction in a program.
The two fundamental kinds of abstraction in contemporary programming
languages are process abstraction and data abstraction.
process abstraction
 The concept of process abstraction is among the oldest in
programming language design. It specifies what a procedure does and
ignores how it does. All subprograms are process abstractions because
they provide a way for a program to specify a process, without
providing the details of how it performs its task (at least in the calling
program).
 For example, when a program needs to sort an array of numeric data
of some type, it usually uses a subprogram for the sorting process. At
the point where the sorting process is required, a statement such as
sortInt(list, listLen) is placed in the program.
 This call is an abstraction of the actual sorting process, whose
algorithm is not specified. The call is independent of the algorithm
implemented in the called subprogram.
The advantages of process abstraction are:
(1) Locality: Programmers don't need to know the implementation details.
(2) Modifiability: Replacing of one code does not affect another code.
(3) Language Independence: Doe procedural abstraction implementation
could be done in any programming language. Procedural abstractions is
normally characterized in a programming language a “function sub-function"
or “procedure” abstraction.

3.3.2 INTRODUCTION TO DATA ABSTRACTION


Data Abstraction:
The concept of data abstraction is represented by means of abstract data
type. It is also known as Information Hiding. It allows users to create data
objects (variables) of Abstract Data Types and also allows users to perform
some operations on those data objects but implementation of these types
are hidden from the users.
An abstract data type is a data structure, in the form of a record, but which
includes subprograms that manipulate its data. Syntactically, an abstract
data type is an enclosure that includes only the data representation of one
specific data type and the subprograms that provide the operations for that
type. Program units that use an abstract data type can declare variables of
that type, even though the actual representation is hidden from them. An
instance of an abstract data type is called an object.
An abstract data type is a data type that satisfies the following conditions:
 The representation of objects of the type is hidden from the program
units that use these objects.
 The declarations of the type and the protocols of the operations on
objects of the type, which provide the type’s interface, are contained in
a single syntactic unit. Other program units are allowed to create
variables of the defined type.
Advantages of data abstraction are:
 Modifications can be made easily with out effecting rest of the code.
 By hiding the data representation, user code can not directly
accessible. This helps in making the program reliable.

Data Abstraction for Built-in Data Types


Floating-Point as an Abstract Data Type:
 A floating-point type provides the means to create variables to store
floating-point data and also provides a set of arithmetic operations for
manipulating objects of the type.
 Floating-point types in high-level languages employ a key concept in
data abstraction: information hiding. The actual format of the floating-
point data value in a memory cell is hidden from the user, and the only
operations available are those provided by the language.
float f=3.14;
 We don’t know how it is implemented by the programming language,
how the hardware is managed, how it is saved in memory.
User-Defined Abstract Data Types:
 A user-defined abstract data type should provide the same
characteristics as those of language-defined types, such as a floating-
point type: (1) a type definition that allows program units to declare
variables of the type but hides the representation of objects of the
type; and (2) a set of operations for manipulating objects of the type.
 Best examples of user defined abstract data types are structures and
classes.

 A stack is a widely applicable data structure that stores some number


of data elements and only allows access to the data element at one of
its ends, the top. Suppose an abstract data type is to be constructed
for a stack that has the following abstract operations:

Differences between Data abstraction and procedure abstraction


Data Abstraction Procedure Abstraction
The focus is primarily on data and then The focus is only on procedure for
co procedure for abstraction abstraction
Data abstraction is characterized as a Procedure abstraction is normally
data structure unit. characterized in a programming
language as function sub-function or
Procedure abstraction.
The advantage of data abstraction over Due to procedural abstraction
procedure abstraction is that the data implementation could be done in any
and the associated operations get programming language.
specified together and hence it is easy
to modify the code when data changed.
Benefits of Abstract Data Types:
 Increased Reliability
 It reduces the range of code and number of variables of which a
programmer must be aware when writing or reading a part of the
program.
 Makes name conflicts less likely, because the scope of variables is
smaller.
3.3.3 DESIGN ISSUES FOR ABSTRACT DATA TYPES
Following are the design issues of abstract data types-
1. The form of the container for the interface to the type.
2. Whether abstract data types can be parameterized.
3. What access controls are provided and how such controls are specified.
4. Whether the specification of the type is physically separate from its
implementation (or whether that is a developer choice).
3.3.4 LANGUAGE EXAMPLES
ABSTRACT DATA TYPES IN SIMULA 67:
The concept of data abstraction had its origins in SIMULA 67, although that
language did not provide complete support for abstract data types, because
it did not include a way to hide implementation details.
SIMULA 67 is the first language that used the notation of class.
 Objects are called instance of class.
 Class is similar to type but incudes procedures functions and variables.
 Following code for class in SIMULA 67

ABSTRACT DATA TYPES IN ADA:


Ada provides an encapsulation construct that can be used to define a single
abstract data type, including the ability to hide its representation. Ada 83
was one of the first languages to offer full support for abstract data types.
Encapsulation:
 Encapsulation is a mechanism by which the program components can
be combined together to provide some specific functionality.
Encapsulation support for information hiding of implementation of the
modules. The encapsulating constructs in Ada are called packages.
 A package can have two parts, each of which is also is called a
package. These are called the package specification, which provides
the interface of the encapsulation (and perhaps more), and the body
package, which provides the implementation of most, if not all, of the
entities named in the associated package specification.
 A package specification and its body package may be compiled
separately, provided the package specification is compiled first. This
means that once the package specification is written, work can begin
on both the client code and the body package.
Information Hiding:
 There are two approaches to hiding the representation from clients in
the package specification. One is to include two sections in the
package specifications:
1. one in which entities are visible to clients and one that hides its
contents.
2. The second way to hide the representation is to define the abstract
data type as a pointer and provide the pointed-to structure’s definition
in the body package, whose entire contents are hidden from clients.
 Types that are declared to be private are called private types.
 Example of package specification and implementation in ADA is as
given below:
Step1: create a file containing following code and save it using .ads
extension
ABSTRACT DATA TYPES IN C++:
C++, which was first released in 1985, was created by adding features to C.
The first important additions were those to support object-oriented
programming. While Ada provides an encapsulation that can be used to
simulate abstract data types, C++ provides two constructs that are very
similar to each other, the class and the struct, which more directly support
abstract data types.
Encapsulation:
 The data defined in a C++ class are called data members; the
functions (methods) defined in a class are called member functions.
Data members and member functions appear in two categories: class
and instance. Class members are associated with the class; instance
members are associated with the instances of the class.
 Class instances can be static, stack dynamic, or heap dynamic. If static
or stack dynamic, they are referenced directly with value variables. If
heap dynamic, they are referenced through pointers. Stack dynamic
instances of classes are always created by the elaboration of an object
declaration.
Information Hiding:
 A C++ class can contain both hidden and visible entities (meaning
they are either hidden from or visible to clients of the class).
 Entities that are to be hidden are placed in a private clause, and
visible, or public, entities appear in a public clause. The public clause
therefore describes the interface to class instances.
Constructors and Destructors:
 C++ allows the user to include constructor functions in class
definitions, which are used to initialize the data members of newly
created objects. A constructor may also allocate the heap-dynamic
data that are referenced by the pointer members of the new object.
Constructors are implicitly called when an object of the class type is
created. A constructor has the same name as the class whose objects
it initializes. Constructors can be overloaded, but of course each
constructor of a class must have a unique parameter profile.
 A C++ class can also include a function called a destructor, which is
implicitly called when the lifetime of an instance of the class ends. As
stated earlier, stack-dynamic class instances can contain pointer
members that reference heap-dynamic data. The destructor function
for such an instance can include a delete operator on the pointer
members to deallocate the heap space they reference. Destructors are
often used as a debugging aid, in which case they simply display or
print the values of some or all of the object’s data members before
those members are deallocated. The name of a destructor is the class’s
name, preceded by a tilde (~).
ABSTRACT DATA TYPES IN OBJECTIVE-C:
Objective-C is similar to C++ in that its initial design was the C language
with extensions to support object-oriented programming.

Encapsulation:
The interface part of an Objective-C class is defined in a container
called an interface with the following general syntax:

 The first and last lines, which begin with at signs (@), are directives.
 The implementation of a class is packaged in a container naturally
named implementation, which has the following syntax:

 C programs nearly always import a header file for input and output
functions, stdio.h. In Objective-C, a header file is usually imported that
has the prototypes of a variety of often required functions, including
those for input and output, as well as some needed data. This is done
with the following:

Information Hiding:
Objective-C uses the directives, @private and @public, to specify the access
levels of the instance variables in a class definition. These are used as the
reserved words public and private are used in C++. The difference is that
the default in Objective-C is protected, whereas it is private in C++.

ABSTRACT DATA TYPES IN JAVA:


Java support for abstract data types is similar to that of C++. All objects are
allocated from the heap and accessed through reference variables. Methods
in Java must be defined completely in a class. A method body must appear
with its corresponding method header. Therefore, a Java abstract data type is
both declared and defined in a single syntactic unit. A Java compiler can
inline any method that is not overridden. Definitions are hidden from clients
by declaring them to be private.
Rather than having private and public clauses in its class definitions, in Java
access modifiers can be attached to method and variable definitions.

The following is a Java class definition for our stack example:


ABSTRACT DATA TYPES IN C#:
Recall that C# is based on both C++ and Java and that it also includes some
new constructs. Like Java, all C# class instances are heap dynamic. Default
constructors, which provide initial values for instance data, are predefined for
all classes.
Encapsulation:
 C++ includes both classes and structs, which are nearly identical
constructs. The only difference is that the default access modifier for
class is private, whereas for structs it is public. C# also has structs,
but they are very different from those of C++.
 In C#, structs are, in a sense, lightweight classes. They can have
constructors, properties, methods, and data fields and can implement
interfaces but do not support inheritance.
 One other important difference between structs and classes in C# is
that structs are value types, as opposed to reference types. They are
allocated on the runtime stack, rather than the heap.
 Structs are used in C# primarily to implement relatively small simple
types that need never be base types for inheritance. They are also
used when it is convenient for the objects of the type to be stack as
opposed to heap allocated.
Information Hiding:
 C# uses the private and protected access modifiers exactly as they
are used in Java.
 C# provides properties, which it inherited from Delphi, as a way of
implementing getters and setters without requiring explicit method calls by
the client. As with Objective-C, properties provide implicit access to specific
private instance data. For example, consider the following simple class and
client code:

In the class Weather, the property DegreeDays is defined. This property


provides a getter method and a setter method for access to the private data
member, degreeDays.
ABSTRACT DATA TYPES IN RUBY:
Ruby provides support for abstract data types through its classes. In terms of
capabilities, Ruby classes are similar to those in C++ and Java.
Encapsulation:
 In Ruby, a class is defined in a compound statement opened with
the class reserved word and closed with end. The names of instance
variables have a special syntactic form they must begin with at signs
(@). Instance methods have the same syntax as functions in Ruby:
They begin with the def reserved word and end with end.
 Classes in Ruby are dynamic in the sense that members can be added
at any time. This is done by simply including additional class definitions
that specify the new members. Moreover, even predefined classes of
the language, such as String, can be extended. For example, consider
the following class definition:

 This class could be extended by adding a second method, meth2, with


a second class definition:

Information Hiding:
 Access control for methods in Ruby is dynamic, so access violations are
detected only during execution. The default method access is public,
but it can also be protected or private. There are two ways to specify
the access control, both of which use functions with the same names
as the access levels, private and public.
 This resets the default access for subsequently defined methods in the
class. For example,

In Ruby, all data members of a class are private, and that cannot be
changed.

3.3.5 PARAMETERIZED ADT


To pass the parameters to the Abstract Data Types. Parametrized ADT allow
designing an ADT that can store any type elements - only an issue for static
typed languages. In a dynamic typed language like Ruby, any stack implicitly
can store any type elements.
 it is also known as generic classes
 C++, ADA, Java 5.0 and C# 2005 provide support for parametrized
ADTs

Ada:
Packages can also be generic, so we can construct generic, or
parameterized, abstract data types. The following package specification
describes the interface of a generic stack abstract data type with these
features:

A stack of given size and type could be defined in this way

declare
package Float_100_Stack is new Generic_Stack(100, Float);
use Float_100_Stack;
begin
push(45.8);
-------
end;
C++
 C++ also supports parameterized abstract data types. Templates are
considered to be the generic abstract data type. In case of templates,
the data components can be of different types however, the operations
are the same.
 Using class template, we can write a class whose members use
template parameters as types.
 The complete program using class template is as given below.

Output:
a=20 b=10
c=20.5 d=10.5
e=y f=x
Java 5.0
 Java 5.0 supports a form of parameterized abstract data types in which
the generic parameters must be classes.
 The most common generic types are collection types, such
as LinkedList and ArrayList, which were in the Java class library before
support for generics was added.
 Therefore, the collection types have always been able to store multiple
types (as long as they are classes). There were three issues with this:
1. First, every time an object was removed from the collection, it had
to be cast to the appropriate type.
2. Second, there was no error checking when elements were added to
the collection.
 In Java 5.0, the collection classes, the most commonly used of which
is ArrayList, became a generic class.
 Following is the generic class:

3.3.6 ENCAPSULATION CONSTRUCTS


Large programs have two special needs:
 Some means of organization, other than simply division into
subprograms
 Some means of partial compilation (compilation units that are smaller
than the whole program)
The solution is making a grouping of subprograms that are logically related
into a unit that can be separately compiled (compilation units). Such
collections are called encapsulation.
It is a process of hiding all the internal details of an object from the outside
real world. Encapsulation is hiding the code and data into a single unit to
protect the data from outer world.
Encapsulation in C:
 C does not provide complete support for abstract data types, although
both abstract data types and multiple-type encapsulations can be
simulated.
 In C, a collection of related functions and data definitions can be
placed in a file, which can be independently compiled. Such a file,
which acts as a library, has an implementation of its entities. The
interface to such a file, including data, type, and function declarations,
is placed in a separate file called a header file.
 The header file, in source form, and the compiled version of the
implementation file are furnished to clients. When such a library is
used, the header file is included in the client code, using
an #include preprocessor specification
 The #include specification also documents the fact that the client
program depends on the library implementation file. This approach
effectively separates the specification and implementation of an
encapsulation.
 For example, the following steps to demonstrate the encapsulation in C

Step3: On compiling the above C program, the output of above program is


30.

Encapsulation in C++:
 C++ provides two different kinds of encapsulation—header and
implementation files can be defined as in C, or class headers and
definitions can be defined.
 Because of the complex interplay of C++ templates and separate
compilation, the header files of C++ template libraries often include
complete definitions of resources, rather than just data declarations
and subprogram protocols; this is due in part to the use of the C linker
for C++ programs.

 suppose we have an abstract data type for matrices and one for
vectors and need a multiplication operation between a vector and a
matrix. The multiplication code must have access to the data members
of both the vector and the matrix classes, but neither of those classes
is the natural home for the code.
 Furthermore, regardless of which is chosen, access to the members of
the other is a problem. In C++, these kinds of situations can be
handled by allowing nonmember functions to be “friends” of a class.
Friend functions have access to the private entities of the class where
they are declared to be friends. For the matrix/vector multiplication
operation, one C++ solution is to define the operation outside both the
matrix and the vector classes but define it to be a friend of both.

Ada Packages:
 Ada package specifications can include any number of data and
subprogram declarations in their public and private sections.
Therefore, they can include interfaces for any number of abstract data
types, as well as any other program resources.
 So, the package is a multiple-type encapsulation construct. In Ada,
both the matrix and the vector types could be defined in a single Ada
package, which obviates the need for friend functions.
C# Assemblies:
 C# includes a larger encapsulation construct than a class. The
construct is the one used by all of the .NET programming languages:
the assembly. Assemblies are built by .NET compilers. A .NET
application consists of one or more assemblies. An assembly is a
file that appears to application programs to be a single dynamic link
library (.dll) or an executable (.exe).
 In .NET, the intermediate language is named Common Intermediate
Language (CIL). It is used by all .NET languages. Because its code is in
CIL, an assembly can be used on any architecture, device, or operating
system. When executed, the CIL is just-in-time compiled to native code
for the architecture on which it is resident.

3.3.7 NAMING ENCAPSULATIONS


Encapsulations to be syntactic containers for logically related software
resources—in particular, abstract data types. The purpose of these
encapsulations is to provide a way to organize programs into logical units for
compilation. This allows parts of programs to be recompiled after isolated
changes. There is another kind of encapsulation that is necessary for
constructing large programs: a naming encapsulation.
 Naming encapsulations are logical encapsulations, in the sense that
they need not be contiguous. It support in C++, Java, Ada, and Ruby.
 Namespaces are used to grouping the entities like classes, variables,
objects, function under a name. The namespace help to divide global
scope into sub-scopes, where each sub-scope has its own name.
C++ Namespaces:
C++ includes a specification, namespace, that helps programs manage the
problem of global namespaces. One can place each library in its own
namespace and qualify the names in the program with the name of the
namespace when the names are used outside that namespace.
This is done by placing all of the declarations for the stack in a namespace
block, as in the following:
namespace myStackSpace
{
// Stack declarations
}
The implementation file for the stack abstract data type could reference the
names declared in the header file with the scope resolution operator, ::, as in
myStackSpace::topSub
The other two approaches use the using directive. This directive can be
used to qualify individual names from a namespace, as with
using myStackSpace::topSub;
The using directive can also be used to qualify all of the names from a
namespace, as in the following:
using namespace myStackSpace;

Java Packages:
Java includes a naming encapsulation construct: the package. Packages can
contain more than one type9 definition, and the types in a package are
partial friends of one another. The resources defined in a file are specified to
be in a particular package with a package declaration, as in
package stkpkg;
The package declaration must appear as the first line of the file.
Java provides the import declaration, which allows shorter references to
type names defined in a package. For example, suppose the client includes
the following:

import stkpkg.myStack;

For example, if we wanted to import all of the types in stkpkg, we could use
the following:
import stkpkg.*;
Ada Packages:
Ada packages, which often are used to encapsulate libraries, are defined in
hierarchies, which correspond to the directory hierarchies in which they are
stored. packages also define namespaces. Visibility to a package from a
program unit is gained with the with clause. For example, the following
clause makes the resources and namespace of the
package Ada.Text_IO available.
with Ada.Text_IO;
Access to the names defined in the namespace of Ada.Text_IO must be
qualified. For example, the Put procedure from Ada.Text_IO must be
accessed as
Ada.Text_IO.Put
To access the names in Ada.Text_IO without qualification, the use clause can
be used, as in
use Ada.Text_IO;

With this clause, the Put procedure from Ada.Text_IO can be accessed simply
as Put. Ada’s use is similar to Java’s import.
Ruby Modules:
Ruby classes serve as namespace encapsulations, as do the classes of other
languages that support object-oriented programming. Ruby has an additional
naming encapsulation, called a module.
Modules typically define collections of methods and constants. Modules are
unlike classes in that they cannot be instantiated or subclassed and do not
define variables. Methods that are defined in a module include the module’s
name in their names. For example, consider the following skeletal module
definition:

Assuming the MyStuff module is stored in its own file, a program that wants
to use the constant and methods of MyStuff must first gain access to the
module. Consider the following code that uses our example module, MyStuff,
which is stored in the file named myStuffMod:

You might also like