Uploaded by Harsh Saxena

ppl unit 1 and 2

POPL
Unit 1
Syntax, Semantics and Pragmatics
In linguistics of both natural and computer languages, syntax, semantics and pragmatics are
used to categorize descriptions of language characteristics.
Syntax :
describes structure, composition of allowable phrases and sentences of the language
by itself devoid of meaning, simply tell us :
what strings are valid
how they may be parsed or decomposed
Semantics :
provide the meaning of these syntactic elements
we may think of providing syntactic elements as inputs to a semantic function, which in
turn provides some representation of the meaning of the elements as output
the semantic function of a programming language may be considered to be embedded in
the logic of a compiler or intepreter which arranges for program execution
an equivalent semantic function, albeit using a different representation, should also be
found in the mind of the programmer
Pragmatics
practical aspects of how constructs and features of a language may be used to achieve
various objectives.
aims to explain how and why people use languages in the way they do
what we think of when we talk about programmers’ competence or “best practices” or
patterns and anti-patterns
Example :
consider the syntax, semantics and pragmatics of an assignment statement
Syntax : it may consist of a variable and an expression (themselves syntactic constructs),
separated by the token = as an assignment operator
Semantics : the variable denotes a location in computer memory, while the expression
denotes computation of a value based on the contents of memory. Overall, the semantics
of assignment is to perform the expression evaluation based on current memory contents
and then update the value stored in the particular location corresponding to the variable.
Pragmatics : what assignment statements are useful for. There are many possibilities: to
set up a temporary variable for the value of an expression that is needed more than once,
to communicate values from one part of a program to another, to modify part of a data
structure, or to set successive values of a variable used in some iterative computation.
Formal Translation Models
¯\_(ツ)_/¯ (https://slideplayer.com/slide/5241317/)
Variables, Expressions and Statements
Variables :
a storage address paired with an associated symbolic name, which contains some known
or unknown quantity of information referred to as a value
way to reference the stored value, in addition to referring to the variable itself, depending
on the context
separation of name and content allows the name to be used independently of the exact
information it represents
variable’s storage address may be referenced by several different identifiers (aliasing)
Expressions :
combination of one or more constants, variables, operators, and functions that the
programming language interprets and computes to produce another value
the resulting value is usually one of various primitive types, such as numerical, string,
boolean, complex data type or many others
Statements :
syntactic unit of an imperative programming language that expresses some action to be
carried out
program written in such a language is formed by a sequence of one or more statements
statements contrast with expressions in that statements do not return results and are
executed solely for their side effects, while expressions always return a result and often do
not have side effects at all
Binding Time
source file has many names whose properties need to be determined
meaning of these properties might be determined at different phases of the life cycle of a
program
examples of such properties include:
set of values associated with a type
type of a variable
memory location of the compiled function
value stored in a variable
binding is the act of associating properties with names.
binding time - the time at which a binding takes place. It can take place at :
language design time
set of possible types for a variable
set of possible meanings for an operator symbol
language implementation time
A data type, such as int in C, is bound to a range of possible values
compile time
variable is bound to a particular data type.
link time
call to a library subprogram is bound to the subprogram code.
load time
static variable may be bound to a memory cell when the program is loaded into
memory.
run time
bind a nonstatic local variable to a memory cell
A binding is static if it first occurs before run time and remains unchanged throughout program
execution.
A binding is dynamic if it first occurs during execution or can change during execution of the
program
Static vs. Dynamic binding
sb happens at the compile-time and db happens at the runtime. Hence, called early and late
binding
in sb function definition and call are linked during the compile-time, whereas in db the
function calls are not resolved until runtime
sb happens when all information needed to call a function is available at the compile-time,
db happens when all information needed for a function call cannot be determined at
compile-time.
sb can be achieved using the normal function calls, function overloading and operator
overloading while db is achieved using the virtual functions.
sb results in faster execution of a program
db is flexible since a single function can handle different type of objects at runtime
(reduces the size of the codebase, makes source code more readable)
Assignment
an assignment statement sets and/or re-sets the value stored in the storage location(s)
denoted by a variable name; in other words, it copies a value into the variable
Some languages use the idea of l-values and r-values, deriving from the typical mode of
evaluation on the left and right hand side of an assignment statement.
An l-value refers to an object that persists beyond a single expression. Has requirement
that the operand on the left side of the assignment operator is modifiable, usually a
variable.
An r-value is a temporary value that does not persist beyond the expression that uses it.
Pulls or fetches the value stored in a variable or constant.
Environments and Stores
Languages differ on where activation records must go in the environment:
(Old) Fortran is static: all data, including activation records, are statically allocated. Each
function has only one activation record — no recursion!
Functional languages (Scheme, ML) and some OO languages (Smalltalk) are heap-oriented:
almost all data, including AR, allocated dynamically.
Most languages are in between: data can go anywhere ARs go on the stack.
Activation Record
An Activation Record (AR) is created for each invocation of a procedure
Storage Allocation
Static storage allocation
names bound to storage locations.
if memory created at compile time then the memory will be created in static area and only
once.
memory is created only at compile time and deallocated after program completion.
size and position of data objects should be known at compile time.
recursion procedure is restricted.
Stack Storage Allocation
storage is organized as a stack.
activation record pushed into stack when activation begins and popped when the activation
ends.
activation record contains locals so that they are bound to fresh storage in each activation
record
value of locals is deleted when the activation ends.
works on LIFO mechanism
supports the recursion process.
Heap Storage Allocation
most flexible allocation scheme.
allocation and deallocation of memory can be done at any time and at any place depending
on user’s requirement
used to allocate memory to the variables dynamically and when the variables are no more
used then claim it back.
supports the recursion process.
Constants
a value that cannot be altered by the program during normal execution, i.e., the value is
constant.
when associated with an identifier, a constant is said to be “named,” although the terms
“constant” and “named constant” are often used interchangeably
contrasted with a variable, which is an identifier with a value that can be changed during
normal execution, i.e., the value is variable
useful for both programmers and compilers
for programmers they are a form of self-documenting code and allow reasoning about
correctness
for compilers they allow compile-time and run-time checks that verify that constancy
assumptions are not violated, and allow or simplify some compiler optimizations.
Initialization
assignment of an initial value for a data object or variable
manner in which initialization is performed depends on programming language, as well as
type, storage class, etc., of an object to be initialized
constructs which perform initialization are typically called initializers and initializer lists.
distinct from (and preceded by) declaration, although sometimes conflated in practice
done either by statically embedding the value at compile time, or else by assignment at run
time.
Statement level control structure
At least two additional linguistic mechanisms are necessary to make the computations in
programs flexible and powerful:
means of selecting among alternative control flow paths
means of causing the repeated execution of statements or sequences of statements
Statements that provide these kinds of capabilities are called control statements. A control
structure is a control statement and the collection of statements whose execution it controls.
Control Statements:
Selection statements
two-way (if-else)
n-way or multiple selection (if-elif-else / switch)
Loop statements
counter controlled loops (for)
logically controlled loops (while / do-while)
user located control mechanisms (break / continue)
based on data structures (for)
unconditional branching (goto)
Unit 2
Primitive Data Types
In computer science, primitive data type is either of the following:
a basic type is a data type provided by a programming language as a basic building block.
Most languages allow more complicated composite types to be recursively constructed
starting from basic types.
a built-in type is a data type for which the programming language provides built-in support.
Classic basic primitive types may include:
Character ( character , char );
Integer ( integer , int , short , long , byte ) with a variety of precisions;
Floating-point number ( float , double , real , double precision);
Fixed-point number ( fixed ) with a variety of precisions and a programmer-selected scale.
Boolean, logical values true and false .
Reference (also called a pointer or handle or descriptor), a value referring to another
object.
Pointers
a programming language object that stores a memory address
can be that of another value located in computer memory, or in some cases, that of
memory mapped computer hardware
references a location in memory, and obtaining the value stored at that location is known
as dereferencing the pointer
using them improves performance for repetitive operations like traversing iterable data
structures
cheaper in time and space to copy and dereference pointers than it is to copy and access
the data to which the pointers point
also used to hold the addresses of entry points for called subroutines in procedural
programming and for run-time linking to dynamic link libraries (DLLs)
in OOP, pointers to functions are used for binding methods, often using what are called
virtual method tables
int a = 5;
int *ptr = NULL;
ptr = &a;
Structured type
compound data type which falls under user-defined category
used for grouping simple data types or other compound data types
contains a sequence of member variable names along with their type/attributes
struct <struct name> {
<type> <member>;
};
members inside a structure are placed sequentially next to next in the memory layout
minimum size of a structure is the sum total of all sizes of members, considering padding
Coercion
coercion : implicit conversion of a value into another of a different data type (it is
automatically done)
casting : explicit conversion performed by code instructions
treats a variable of one data type as if it belongs to a different data type
languages that support implicit conversion define the rules that will be automatically
applied when primitive compatible values are involved
double x, y;
x = 3;
y = (double) 5;
// implicitly coercion (coercion)
// explicitly coercion (casting)
function/operator considered polymorphic one when it is permited to perform implicit or
explicit parameter/operand coercion
#include <iostream>
void f(double x) {
// polymorphic function
std::cout << x << std::endl;
}
int main() {
double a = 5 + 6.3; // polymorphic operator
std::cout << a << std::endl;
f(5);
f((double) 6);
}
Type Equivalence
Type is a property of program constructs such as expressions
defines a set of values (range of variables) and a set of operations on those values
classes are one instantiation of the modern notion of the type
Type Systems
a collection of rules that assign types to program constructs (more constraints added to
checking the validity of the programs, violation of such constraints indicate errors)
languages type system specifies which operations are valid for which types
type systems provide a concise formalization of the semantic checking rules
type rules are defined on the structure of expressions
type rules are language specific
Type Checking
is the process of verifying fully typed programs
type checking rules usually have the form:
if two type expressions are equivalent
then return a given type
else return type_error
to define when two given type expressions are equivalent.
modern languages allow the naming of user-defined types.
two possibilities.
Name equivalence : treat named types as basic types, two type expressions are name
equivalent if and only if they are identical, that is if they can be represented by the
same syntax tree, with the same labels.
Structural equivalence : replace the named types by their definitions and recursively
check the substituted trees.
Static and Dynamic Type Checking
Statically typed languages: all or almost all type checking occurs at compilation time. (C,
Java)
Dynamically typed languages: almost all checking of types is done as part of program
execution (Scheme)
Untyped languages: no type checking (assembly, machine code)
Tradeoffs
static type system :
does not have knowledge of input values or execution behaviors
disallows some correct programs, cannot predict precisely all the behaviors (some
program runs correctly will be rejected)
catches many programming errors at compile time
avoids overhead of runtime type checking
are more restrictive; can require more work to do reasonable things
rapid prototyping easier in a dynamic type system.
Object Oriented Concepts
programming paradigm based on the concept of objects, which can contain:
data, in the form of fields (often known as attributes or properties)
code, in the form of procedures/methods.
an object’s procedures can access and often modify the data fields of the object with
which they are associated (objects have a notion of this or self )
programs are designed by making them out of objects that interact with one another
Objects and classes
languages that support OOP use inheritance for code reuse and extensibility in the form of
classes
classes – the definitions for the data format and available procedures for a given type or
class of object; may also contain data and procedures
objects – instances of classes
leads to the following terms:
class variables – belong to the class as a whole; there is only one copy of each one
attributes – data that belongs to individual objects; every object has its own copy
member variables – refers to both the class and instance variables that are defined by
a particular class
class methods – belong to the class as a whole and have access only to class
variables and inputs from the procedure call
instance methods – belong to individual objects, and have access to instance
variables for the specific object they are called on, inputs, and class variables
objects are accessed like variables with complex internal structure
in many languages are effectively pointers, serving as actual references to a single
instance of said object in memory within a heap or stack
provide a layer of abstraction which can be used to separate internal from external code
Information Hiding
the principle of segregation of the design decisions in a computer program that are most
likely to change
protecting other parts of the program from extensive modification if the design decision is
changed
providing a stable interface which protects the remainder of the program from the
implementation (the details that are most likely to change)
think of information hiding as being the principle and encapsulation being the technique
Encapsulation
the bundling of data with the methods that operate on that data
restricting of direct access to some of an object’s components
to hide the values or state of a structured data object inside a class, preventing
unauthorized parties’ direct access to them
using “getters” and “setters” to access the values, and other client classes call these
methods to retrieve and modify the values within the object.
Abstraction
the process of removing details or attributes in the study of objects or systems to focus
attention on details of greater importance
the creation of abstract concept-objects by mirroring common features or attributes of
various non-abstract objects
Abstract Data type (ADT) is a type (or class) for objects whose
behaviour is defined by a set of value and a set of operations
only mentions what operations are to be performed but not how these operations will
be implemented
does not specify how data will be organized in memory and what algorithms will be
used for implementing the operations
called “abstract” because it gives an implementation-independent view.
Inheritance
mechanism of basing an object or class upon another object (prototype-based inheritance)
or class (class-based inheritance), retaining similar implementation
deriving new classes (sub classes) from existing ones (super class or base class) and
forming them into a hierarchy of classes
in most class-based object-oriented languages, an object created through inheritance (a
“child object”) acquires all the properties and behaviors of the parent object (except:
constructors, destructor, overloaded operators and friend functions of the base class)
it allows :
programmers to create classes that are built upon existing classes
to specify a new implementation while maintaining the same behaviors
to reuse code and to independently extend original software via public classes and
interfaces.
Type Parameterization
type parameterization is a frequently used mechanism used in templates to reference an
unknown data type, data structure, or class
Templates are most frequently used in Java and C++
part of generic programming, in which algorithms are written in terms of types to-bespecified-later that are then instantiated when needed for specific types provided as
parameters.
Polymorphism
the provision of a single interface to entities of different types or the use of a single symbol
to represent multiple different types
classes of polymorphism are:
Ad hoc polymorphism: defines a common interface for an arbitrary set of individually
specified types (includes function and operator overloading).
Parametric polymorphism: when one or more types are not specified by name but by
abstract symbols that can represent any type.
Subtyping: when a name denotes instances of many different classes related by some
common superclass.
Function Overloading vs. Function Overriding
inheritance: overriding of functions occurs when one class is inherited from another class.
overloading can occur without inheritance.
signature: overloaded functions must differ in function signature ie either number of
parameters or type of parameters should differ. In overriding, function signatures must be
same.
scope of functions: overridden functions are in different scopes; whereas overloaded
functions are in same scope.
Behavior of functions:
overriding is needed when derived class function has to do some added or different job
than the base class function
overloading is used to have same name functions which behave differently depending
upon parameters passed to them.
Python modules vs packages
A module is a single file (or files) that are imported under one import and used. e.g.
import my_module
A package is a collection of modules in directories that give a package hierarchy.
from my_package.timing.danger.internets import function_yo