IMPORTANT QUESTIONS AND ANSWERS
Subject: Principles of Programming Languages
UNIT 3:
Short Answer Questions:
Q: Define Subprogram.
A: A subprogram definition describes the interface to and the actions of the
subprogram abstraction. A subprogram call is the explicit request that a specific
subprogram be executed. A subprogram is said to be active if, after having been called,
it has begun execution but has not yet completed that execution.
Example:
In C, the header of a function named adder might be as follows:
void adder (parameters)
Q: Define Parametric Profile and Protocol of a Subprogram.
A: The parameter profile of a subprogram contains the number, order, and types of its
formal parameters. The protocol of a subprogram is its parameter profile plus, if it is a
function, its return type. In languages in which subprograms have types, those types
are defined by the subprogram’s protocol.
Q: Mention the Design issues of functions.
A: 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?
Q: Write about global scope in programming languages.
A: The methods of C++, Java, and C# have only stack-dynamic local variables. In
Python, the only declarations used in method definitions are for globals. Any variable
declared to be global in a method must be a variable defined outside the method.
A variable defined outside the method can be referenced in the method without
declaring it to be global, but such a variable cannot be assigned in the method. If the
name of a global variable is assigned in a method, it is implicitly declared to be a local
and the assignment does not disturb the global. All local variables in Python methods
are stack dynamic.
Q: What is Coroutine?
A: A coroutine is a special kind of subprogram. Rather than the master-slave
relationship between a caller and a called subprogram that exists with conventional
subprograms, caller and called coroutines are more equitable.
In fact, the coroutine control mechanism is often called the symmetric unit control
model. Coroutines can have multiple entry points, which are controlled by the
coroutines themselves. They also have the means to maintain their status between
activations.
Q: What is Closure?
A: Defining a closure is a simple matter; 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.
Q: Differences in between Coroutine and Closure.
A: A coroutine is a special kind of subprogram. Rather than the master-slave
relationship between a caller and a called subprogram that exists with conventional
subprograms, caller and called coroutines are more equitable. In fact, the coroutine
control mechanism is often called the symmetric unit control model.
Coroutines can have multiple entry points, which are controlled by the coroutines
themselves. They also have the means to maintain their status between activations.
This means that coroutines must be history sensitive and thus have static local
variables. Secondary executions of a coroutine often begin at points other than its
beginning.
Because of this, the invocation of a coroutine is called a resume rather than a call.
For example, consider the following skeletal coroutine:
sub co1(){
...
resume co2();
...
resume co3();
...
}
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. Explaining a closure is not so simple.
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.
Q:Explain Strong Typing in a Programming Language
A: A programming language is strongly typed if type errors are always detected. This
requires that the types of all operands can be determined, either at compile time or at
run time.
The importance of strong typing lies in its ability to detect all misuses of variables that
result in type errors. A strongly typed language also allows the detection, at run time,
of uses of the incorrect type values in variables that can store values of more than one
type.
Long Answer Questions:
Q: Explain the differences among Shallow, Deep and Adhoc Bindings with an
example.
A:
• 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)
• The following example program, written with the syntax of JavaScript,
illustrates these choices:
function sub1() {
var x;
function sub2() {
alert(x); // Creates a dialog box with the value of x
};
function sub3() {
var x; x = 3;
sub4(sub2);
};
function sub4(subx) {
var x; x = 4;
subx();
};
x = 1;
sub3();
};
Consider the execution of sub2 when it is called in sub4. For shallow binding,
the referencing environment of that execution is that of sub4, so the reference to
x in sub2 is bound to the local x in sub4, and the output of the program is 4. For
deep binding, the referencing environment of sub2’s execution is that of sub1,
so the reference to x in sub2 is bound to the local x in sub1, and the output is 1.
For ad hoc binding, the binding is to the local x in sub3, and the output is 3.
Q: Discuss in detail Generic Sub Programs
A:
❖ One way to increase the reusability of software is to lessen the need to create
different subprograms that implement the same algorithm on different types of
data.
❖ For example, a programmer should not need to write four different sort
subprograms to sort four arrays that differ only in element type.
❖ A polymorphic subprogram takes parameters of different types on different
activations.
Q: Explain about Parameter Passing Methods.
A: Parameter-passing methods are the ways in which parameters are transmitted
to and/or from called subprograms.
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; or (3) they can do both. These models are
called in mode, out mode, and inout mode, respectively.
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.
The advantage of pass-by-value is that for scalars it is fast, in both linkage cost
and access time.
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.
void Fixer(out int x, out int y)
x = 17;
y = 35;
...
f.Fixer(out a, out a);
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. In fact, pass-by-value-result formal
parameters must have local storage associated with the called subprogram.
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.
Pass-by-Name
Pass-by-name is an inout-mode parameter transmission method that does not
correspond to a single implementation model.
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.
Explain about Design issues of Subprograms.
• 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?
Q: Write briefly about overloaded subprograms.
A: 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). Although it is not necessary, overloaded subprograms usually implement the
same process. C++, Java, Ada, and C# include predefined overloaded subprograms.
For example, many classes in C++, Java, and C# have overloaded constructors.
Q:Explain about Local referencing environment in programming languages.
A: The referencing environment of a statement is the collection of all variables that are
visible in the statement. The referencing environment of a statement in a static-scoped
language is the variables declared in its local scope plus the collection of all variables
of its ancestor scopes that are visible.
In Python, scopes can be created by function definitions. The referencing
environment of a statement includes the local variables, plus all of the variables
declared in the functions in which the statement is nested.
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.
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;
int count;
for (count = 0; count < listlen; count ++)
sum += list [count];
return sum;
}
UNIT 4:
Short Answer Questions:
Q: List the various ways of concurrency control
A: Concurrency in software execution can occur at four different levels:
• Instruction level (executing two or more machine instructions simultaneously),
• Statement level (executing two or more high-level language statements
simultaneously),
• Unit level (executing two or more subprogram units simultaneously),
• Program level (executing two or more programs simultaneously).
Q: Define a functor in Prolog
A: A compound term is composed of two parts: a functor, which is the function
symbol that names the relation, and an ordered list of parameters, which together
represent an element of the relation.
Q: When does an exception raise?
A: An exception is raised when its associated event occurs. In some C-based
languages, exceptions are said to be thrown, rather than raised.2 Different kinds of
exceptions require different exception handlers.
Q: Explain about user defined ADT’s.
A: Packages can also be generic, so we can construct generic, or parameterized (user
defined) abstract data types.
Integer type elements:
package Integer_Stack is new Generic_Stack(100, Integer);
One could also build an abstract data type for a stack of length
500 for Float
elements, as in
package Float_Stack is new Generic_Stack(500, Float);
These instantiations build two different source code versions.
Q:Define Generic class in C++.
A: Generic class in C++.
• C++ also supports parameterized abstract data types. To make the example C++
stack class of generic in the stack size, only the constructor function needs to be
changed, as in the following:
Stack(int size)
{
stackPtr = new int [size];
maxLen = size - 1;
topSub = -1;
}
• The declaration for a stack object now may appear as follows:
Stack stk(150);
• The class definition for Stack can include both constructors, so users can use the
default-size stack or specify some other size.
Q: Define about Semaphores.
A:
• A semaphore is a simple mechanism that can be used to provide synchronization
of tasks.
• A semaphore is an implementation of a guard. Specifically, a semaphore is a
data structure that consists of an integer and a queue that stores task descriptors.
• A task descriptor is a data structure that stores all of the relevant information
about the execution state of a task.
Q: Write about Competition Synchronization.
A:
• Competition synchronization is required between two tasks when both require
the use of some resource that cannot be simultaneously used.
• Mechanisms for synchronization must be able to delay task execution.
• A run-time system program called a scheduler manages the sharing of
processors among the tasks.
Q:What are applications of Logic Programming.
A:
Applications of Logic Programming:
• Relational Database Management Systems
• Expert Systems
• Natural-Language Processing
Long Answer Questions:
Q: Explain the ADTs in Ada and C++
A:
ADTs 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
• 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.
• Not all packages have a body part (packages that encapsulate only types and constants
do not have or need bodies).
• A package specification and its associated body package share the same name.
ADTs in C++:
C++ classes are types; as stated previously, Ada packages are more generalized
encapsulations that can define any number of types.
• A program unit that gains visibility to an Ada package can access any of its public
entities directly by their names.
• A C++ program unit that declares an instance of a class can also access any of the
public entities in that class, but only through an instance of the class. This is a cleaner
and more direct way to provide 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.
Q: Explain about ADT’s in java with an example.
A:
ADT’s in Java
• Java support for abstract data types is similar to that of C++. There are,
however, a few important differences.
• 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.
• An Example:
The following is a Java class definition for our stack example:
class StackClass {
private int [] stackRef;
private int maxLen,
topIndex;
public StackClass() { // A constructor stackRef = new int [100];
maxLen = 99;
topIndex = -1;
Q: How the Object Oriented Programming implemented in Smalltalk?
A:
• In Smalltalk, the concept of an object is truly universal.They all have local
memory, inherent processing ability, the capability to communicate with other
objects, and the possibility of inheriting methods and instance variables from
ancestors. Classes cannot be nested in Smalltalk.
• All computation is through messages, even a simple arithmetic operation.
• All Smalltalk objects are allocated from the heap and are referenced through
reference variables, which are implicitly dereferenced. There is no explicit
deallocation statement or operation. All deallocation is implicit, using a garbage
collection process for storage reclamation.
• In Smalltalk, constructors must be explicitly called when an object is created.
• A class can have multiple constructors, but each must have a unique name.
Q: How the Object Oriented Programming in C++ supports?
A:
• C++ evolved from C and SIMULA 67, with the design goal of support for
object-oriented programming while retaining nearly complete backward
compatibility with C.
• C++ classes, as they are used to support abstract data types.
Inheritance:
• A C++ class can be derived from an existing class, which is then its parent, or
base, class. Unlike Smalltalk and most other languages that support object-
oriented programming, a C++ class can also be stand-alone, without a
superclass
Dynamic Binding
• All of the member functions we have defined thus far are statically bound; that
is, a call to one of them is statically bound to a function definition. A C++ object
could be manipulated through a value variable, rather than a pointer or a
reference. (Such an object would be static or stack dynamic.)
Q: Differentiate between Cooperative and Competition Synchronization.
A:
Cooperation Synchronization
• cooperation synchronization, such a buffer must have some way of recording
both the number of empty positions and the number of filled positions in the
buffer.
• The counter component of a semaphore can be used for this purpose.
• One semaphore variable
• Ex: emptyspots—can use its counter to maintain the number of empty locations
in a shared buffer used by producers and consumers, and another—say,
fullspots—can use its counter to maintain the number of filled locations in the
buffer.
Competition Synchronization
A semaphore that requires only a binary-valued counter, like the one used to provide
competition synchronization in the following example, is called a binary semaphore.
Q: Basic elements of Prolog
The Basic Elements of Prolog:
Terms
• A Prolog term is a constant, a variable, or a structure. A constant is either an atom or
an integer. Atoms are the symbolic values of Prolog and are similar to their
counterparts in LISP.
• A variable is any string of letters, digits, and underscores that begins with an
uppercase letter or an underscore ( _ ).
• Variables are not bound to types by declarations. The binding of a value, and thus a
type, to a variable is called an instantiation.
• The last kind of term is called a structure. Structures represent the atomic
propositions of predicate calculus, and their general form is the same:
functor(parameter list)
• The functor is any atom and is used to identify the structure. The parameter list can
be any list of atoms, variables, or other structures.
Fact Statements
• Prolog has two basic statement forms; these correspond to the headless and headed
Horn clauses of predicate calculus. The simplest form of headless Horn clause in
Prolog is a single structure, which is interpreted as an unconditional assertion, or fact.
Logically, facts are simply propositions that are assumed to be true.
female(shelley).
male(bill).
female(mary).
male(jake).
father(bill, jake).
father(bill, shelley).
Rule Statements
• The other basic form of Prolog statement for constructing the database corresponds
to a headed Horn clause. This form can be related to a known theorem in mathematics
from which a conclusion can be drawn if the set of given conditions is satisfied.
• The right side is the antecedent, or if part, and the left side is the consequent, or then
part. If the antecedent of a Prolog statement is true, then the consequent of the
statement must also be true.
• Conjunctions contain multiple terms that are separated by logical AND operations. In
Prolog, the AND operation is implied.
female(shelley), child(shelley).
Goal Statements:
The syntactic form of Prolog goal statements is identical to that of headless Horn
clauses. For example, we could have
man(fred).
to which the system will respond either yes or no. The answer yes means that the
system has proved the goal was true under the given database of facts and
relationships.
UNIT 5:
Short Answer Questions:
Q: Explain the term "Lazy Evaluation"
A: Nonstrict languages can use an evaluation form called lazy evaluation, which
means that expressions are evaluated only if and when their values are needed.
Q: How to assign values to multiple variables in one line ? Give two Examples in
Python
A: Python allows you to assign values to multiple variables in one line:
x, y, z = "Orange", "Banana", "Cherry"
print(x)
print(y)
print(z)
o And you can assign the same value to multiple variables in one line:
x = y = z = "Orange"
print(x)
print(y)
print(z)
Q: List the key features of a Functional Programming Language
A: The functional programming paradigm, which is based on mathematical functions,
is the design basis of the most important nonimperative styles of languages. This style
of programming is supported by functional programming languages.
Mathematical Functions:
• A mathematical function is a mapping of members of one set, called the domain set,
to another set, called the range set.
• A function definition specifies the domain and range sets, either explicitly or
implicitly, along with the mapping. The mapping is described by an expression or, in
some cases, by a table.
Q: Write about data types of FPL.
A: Data Types
• There were only two categories of data objects in the original LISP: atoms
and lists.
• List elements are pairs, where the first part is the data of the element, which
is a pointer to either an atom or a nested list.
• The second part of a pair can be a pointer to an atom, a pointer to another
element, or the empty list.
• Elements are linked together in lists with the second parts.
• Atoms and lists are not types in the sense that imperative languages have
types.
Q: Write about Different functional programming languages.
A: The functional programming paradigm, which is based on mathematical functions,
is the design basis of the most important nonimperative styles of languages. This style
of programming is supported by functional programming languages.
Ex: LISP, Scheme, ML,Haskell
Q: Write about scripting languages.
A:
• Scripting languages have evolved over the past 25 years. Early scripting
languages were used by putting a list of commands, called a script, in a file to be
interpreted.
• The first of these languages, named sh (for shell), began as a small collection of
commands that were interpreted as calls to system subprograms that performed
utility functions, such as file management and simple file filtering.
• Example: Perl, Javascript, PHP
Q: Write a Function to calculate the factorial in ML& Haskell
A: In ML, the factorial function could be written as follows:
fun fact(0) = 1
| fact(1) = 1
| fact(n : int): int = n * fact(n − 1);
In Haskell, the factorial function could be written as follows:
fact 0 = 1
fact 1 = 1
fact n = n * fact (n – 1)
Q: Write in detail Lambda Function in Lisp with an example
A:
A lambda expression specifies the parameters and the mapping of a function. The
lambda expression is the function itself, which is nameless.
For example, consider the following lambda expression:
λ(x)x * x * x:
Long Answer Questions:
Explain about the features of LISP Language.
A:
❖ Many functional programming languages have been developed. The oldest and
most widely used is LISP (or one of its descendants), which was developed by
John McCarthy at MIT in 1959.
❖ Data Types and Structures
❖ There were only two categories of data objects in the original LISP: atoms and
lists.
❖ List elements are pairs, where the first part is the data of the element, which is a
pointer to either an atom or a nested list.
❖ The second part of a pair can be a pointer to an atom, a pointer to another
element, or the empty list.
❖ Elements are linked together in lists with the second parts. Atoms and lists are
not types in the sense that imperative languages have types.
❖ In fact, the original LISP was a typeless language. Atoms are either symbols, in
the form of identifiers, or numeric literals.
❖ Lists are specified in LISP by delimiting their elements with parentheses.
• The elements of simple lists are restricted to atoms, as in
(A B C D)
• Nested list structures are also specified by parentheses. For example, the
list
(A (B C) D (E (F G)))
A D
B C E
Q: Differentiate between Imperative and Functional Language.
A:
❖ Functional languages can have a very simple syntactic structure. The list
structure of LISP, which is used for both code and data, clearly illustrates this.
The syntax of the imperative languages is much more complex.
❖ This makes them more difficult to learn and to use. The semantics of functional
languages is also simpler than that of the imperative languages.
❖ Execution efficiency is another basis for comparison. When functional programs
are interpreted, they are of course much slower than their compiled imperative
counterparts.
❖ However, there are now compilers for most functional languages, so that
execution speed disparities between functional languages and compiled
imperative languages are no longer so great.
❖ Another source of the difference in execution efficiency between functional and
imperative programs is the fact that imperative languages were designed to run
efficiently on von Neumann architecture computers, while the design of
functional languages is based on mathematical functions. This gives the
imperative languages a large advantage.
❖ Functional languages have a potential advantage in readability. In many
imperative programs, the details of dealing with variables obscure the logic of
the program.
Q: Why Haskell is called as a Pure Functional Programming Language .
A:
❖ Haskell is a pure functional programming language, meaning it has no
expressions or statements that have side effects, whereas ML allows some side
effects (for example, ML has mutable arrays).
❖ Functions in Haskell can be overloaded (functions in ML cannot).
❖ Non strict semantics are used in Haskell, whereas in ML (and most other
programming languages) strict semantics are used.
Q: Explain about ML in functional programming language.
A: ML (Milner et al., 1990) is a static-scoped functional programming language, like
Scheme.
❖ However, it differs from LISP and its dialects, including Scheme, in a number of
significant ways.
❖ One important difference is that ML is a strongly typed language, whereas
Scheme is essentially typeless.
❖ ML has type declarations for function parameters and the return types of
functions, although because of its type inferencing they are often not used.
❖ The type of every variable and expression can be statically determined. ML, like
other functional programming languages, does not have variables in the sense of
the imperative languages.
❖ A table called the evaluation environment stores the names of all implicitly and
explicitly declared identifiers in a program, along with their types. This is like a
run-time symbol table. When an identifier is declared, either implicitly or
explicitly, it is placed in the evaluation environment.
❖ Another important difference between Scheme and ML is that ML uses a syntax
that is more closely related to that of an imperative language than that of LISP.
❖ For example, arithmetic expressions are written in ML using infix notation.