CSC 432 With PQ
CSC 432 With PQ
CSC 432 With PQ
Programming Language
- It is a computer language that is used by programmers to communicate with computers.
- It is a set of instructions written in any specific language.
2. Understanding different programming languages can also help you choose the most
appropriate language for a given task. Without this knowledge, it's easy to fall back on
the language you're most familiar with, even if it's not the best fit for the job.
3. Knowing the concepts behind different programming languages can also make it easier
to learn new languages. For example, if you know the concepts behind object-oriented
programming, it will be easier to learn a language like Java that uses these concepts.
4. Studying programming languages can also give you a better understanding of the
significance of implementation. How you implement an algorithm can have a big impact
on how well it performs and how easy it is to maintain.
5. Knowing the concepts behind different programming languages can also help you use
the languages you already know more effectively.
APPLICATION DOMAINS
1. Scientific Applications
2. Data processing Applications
3. Text processing Applications
4. Artificial intelligence Applications
5. Systems Programming Applications
6. Web software
3. Logic: This is Rule-based (rules are specified in no particular order). Computations here are
made through a logical inference process. Examples are PROLOG, Mercury, oz, and CLIPS.
This may also include OO concepts. It uses logical statements to express desired behavior of a
program.
1. Reliability Vs. Cost of Execution: For example, Java demands that all references to array
elements be checked for proper indexing, which leads to increased execution costs.
2. Readability vs. Writability: - APL provides many powerful operators (and a large number of
new symbols), allowing complex computations to be written in a compact program but at the
cost of poor readability.
3. Writability (Flexibility) vs. reliability: The pointers in c++ for instance are powerful and very
flexible but are unreliable.
IMPLEMENTATION METHODS
1. Compilation – Programs are translated into machine Language & System calls
2. Interpretation – Programs are interpreted by another program (an interpreter)
3. Hybrid – Programs translated into an intermediate language for easy interpretation
4. Just –in-time – Hybrid implementation, then compile sub programs code the first time they are
called.
5. Pure Interpretation
COMPILATION
- Translates high level program (source language) into machine code (machine language)
- Slow translation, fast execution
- Compilation process has several phases
*Lexical analysis converts characters in the source program into lexical units (e.g.
identifiers, operators, keywords).
*Syntactic analysis: transforms lexical units into parse trees which represent the
syntactic structure of the program.
*Semantics analysis checks for errors hard to detect during syntactic analysis; generate
intermediate code.
*Code generation – Machine code is generated
INTERPRETATION
- Easier implementation of programs (run-time errors can easily and immediately be displayed).
- Slower execution (10 to 100 times slower than compiled programs)
- Often requires more memory space.
- Interpreters are usually implemented as a read-eval-print loop:
*Reads the expression in the input language (usually translating it in some internal form)
*Evaluates the internal forms of the expression
*Print the result of the evaluation
*Loops and reads the next input expression until exit
- Interpreters act as a virtual machine for the source language:
*Fetch execute cycle replaced by the read-eval-print loop
*Usually has a core component, called the interpreter “run-time” that is a compiled
program running on the native machine.
HYBRID IMPLEMENTATION
- This involves a compromise between compilers and pure interpreters. A high level program is
translated to an intermediate language that allows easy interpretation.
- Hybrid implementation is faster than pure interpretation. Examples of the implementation occur
in Perl and Java.
*Perl programs are partially compiled to detect errors before interpretation.
*Initial implementations of Java were hybrid.
JUST-IN-TIME IMPLEMENTATION
Just-in-time (JIT) compilation is a method of improving the performance of a computer program
by compiling the program into machine code at the time it is executed, rather than ahead of
time. This implementation initially translates programs to an intermediate language then
compiles the intermediate language of the subprograms into machine code when they are
called. JIT compilation is often used in virtual machines, such as the Java Virtual Machine
(JVM) and the Common Language Runtime (CLR), to improve the performance of interpreted
languages such as Java and C#.
Why is it useful for a programmer to have some background in language design, even
though he or she may never actually design a programming language?
1. Understanding how languages work.
2. Problem-solving skills
3. Debugging and performance optimization
4. Innovation: Understanding the history and design of programming languages can inspire
a programmer to come up with new ideas for programming languages and tools that can
improve the development experience.
Interpretation: The source code of a program is read and executed by an interpreter, which
converts the code into machine instructions on-the-fly.
Transpilation: The source code of a program is translated into the source code of another
language. That source code is then compiled or interpreted.
Which produces faster program execution, a compiler or a pure interpreter and how?
Generally, a compiled program will execute faster than a program interpreted by a pure
interpreter. This is because a compiler generates machine code, which the computer's
hardware can execute directly, whereas an interpreter must interpret the source code line by
line and convert it into machine instructions on-the-fly.
Expression Notations
B * C: This type of notation is referred to as infix since the operator is in between the two
operands that it is working on. Consider another infix example, A + B * C. The operators + and *
still appear between the operands, but there is a problem. Which operands do they work on?
Does the + work on A and B or does the * take B and C? The expression seems ambiguous.
Each operator has a precedence level. Operators of higher precedence are used before
operators of lower precedence. The only thing that can change that order is the presence of
parentheses. The precedence order for arithmetic operators places multiplication and division
above addition and subtraction. If two operators of equal precedence appear, then a left-to-right
ordering or associativity is used.
One way to write an expression that guarantees there will be no confusion is to create a fully
parenthesized expression. (one pair of parentheses for each operator). There is no need to
remember any precedence rules. The expression A + B * C + D can be rewritten as ((A + (B *
C)) + D).
Prefix expression notation requires that all operators precede the two operands that they work
on.
Postfix, on the other hand, requires that its operators come after the corresponding operands.
They talked about how postfix and prefix works using stacks. How they can be
rearranged / Converted
Page (5-12) CSC 432 Lecture 3.pdf
Infix notation: operators are written in-between their operands. X+Y. The language uses
operator precedence and associativity, and brackets ( ) allow users to override these rules.
Postfix notation: operators are written after their operands. XY+ . It is also called reverse polish
notation. The order of evaluation is left to right.
Prefix notation: operators are written before their operands. +XY. It is also called polish notation.
Although Prefix operators are evaluated left-to-right, they use values to their right, and if these
values themselves involve computations then this changes the order that the operators have to
be evaluated in.
Conversion using parse tree.
Prefix is often used for operators that take a single operand (e.g. negation) and function calls.
Although Postfix and Prefix notations have similar complexity, Postfix is slightly easier to
evaluate in simple circumstances, as the operators really are evaluated strictly left-to-right.
(Read about it somewhere else if you want to, it is poorly explained here)
Language Semantics
Semantics is the study of the relationship between words and how we draw meaning from those
words. Semantics is the study of meaning in language.
Semantics involves the deconstruction of words, signals, and sentence structure. It influences
our reading comprehension as well as our comprehension of other people’s words in everyday
conversation.
Since meaning in language is so complex, there are actually different theories used within
semantics, such as formal semantics, lexical semantics, and conceptual semantics etc
Formal Semantics is the study of grammatical meaning in natural languages using formal tools
from logic and theoretical computer science.
Formal semantics uses techniques from math, philosophy, and logic to analyze the broader
relationship between language and reality, truth and possibility. This is a branch of mathematical
logic that studies the meaning of formal languages, such as those used in programming and
mathematics.
Lexical Semantics - Lexical semantics deconstruct words and phrases within a line of text to
understand the meaning in terms of context. This is the branch of semantics that deals with the
meaning of individual words, and the relationships between words.
This can include a study of individual nouns, verbs, adjectives, prefixes, root words, suffixes, or
longer phrases or idioms
Conceptual Semantics - Conceptual semantics deals with the most basic concept and form of
a word before our thoughts and feelings add context to it. For example, at its most basic we
know a cougar to be a large wild cat. But, the word cougar has also come to indicate an older
woman who’s dating a younger man. This is where context is important.
Connotation Semantics - on the other hand, refers to the associations that are connected to a
certain word or the emotional suggestions related to that word. It focuses on the emotional or
cultural associations that words and phrases may have, in addition to their literal meanings.
Statements
Statements are roughly equivalent to sentences in natural languages.
The following types of expressions can be made into a statement by terminating the expression
with a semicolon (;):
Assignment expressions
Any use of ++ or --
Method calls
Object creation expressions
Statements in programming are the basic building blocks of a program, and are used to specify
the actions that the program is to perform.
Some types of statements are input/output statements, function calls, looping statements,
conditional, assignment, return statements. Etc.
Blocks
A block is a group of zero or more statements between balanced braces and can be used
anywhere a single statement is allowed.
A regular expression is a sequence of characters that defines a search pattern. They are often
used in text processing and searching applications, such as text editors and search engines.
Regular expressions can be used to match a single character, a set of characters, or a range of
characters.
Declarations
A declaration is a statement describing an identifier, such as the name of a variable or a
function. A declaration is a statement that defines a variable, constant, function, class, or other
programming construct. Function declaration in JavaScript: function add(x, y) { return x + y; }
Implicit declaration or default declaration: They are those declarations which are done by
the compiler when no explicit declaration or user defined declaration is mentioned.
Example $abc='astring'; $abc=7; In 'perl' the compiler implicitly understands that $abc ='astring'
is a string variable and $abc=7 is an integer variable.
Explicit declaration of data object: In explicit we or user explicitly defined the variable type.
Float A, B;
In this example it specifies that it is of float type of variable which has name A & B.
Purpose of Declarations
Application of stack
1. Stack is used to evaluate a postfix expression.
2. Stack is used to convert an infix expression into postfix/prefix form.
3. Tracking function calls in programming languages.
4. Stack is used by compilers to check for balancing of parentheses, brackets and braces.
5. A browser's forward and backward navigation
6. Undo/Redo functionality in text editors and word processors.
An algebraic expression can be represented using three different notations. They are infix,
postfix and prefix notations.
Elements of a Program
If you are going to construct a building, you need two things: the bricks and a blueprint that tells
you how to put them together. In computer programming, you need two things: data (variables)
and instructions (code or functions). Variables are the basic building blocks of a program.
Instructions tell the computer what to do with the variables.
Comments are used to describe the variables and instructions. They are notes by the author
documenting the program so that the program is clear and easy to read. Comments are ignored
by the computer.
Structure (in C and C++) is a collection of variables of different data types under a single name.
It is similar to a class in that both hold a collection of data of different data types.
Keywords: These are reserved words in a programming language that have a specific
meaning. ex "if", "else", "for", and "while".
Identifiers: These are names given to variables, functions, and other program elements.
They typically follow specific naming conventions and rules set by the programming
language.
Constants: These are fixed values, such as numbers and strings, that are used in a
program. They don't change during the execution of a program.
Operators: These are special symbols that perform operations on variables and values,
such as mathematical and logical operations. Examples include "+", ">", and "&&".
C++ Semicolon
The semicolon is a statement terminator. Each statement must be ended with a semicolon.
Otherwise, the compiler will raise a syntax error.
{//start of block
//block of statement(s)
}//end of block
The <iostream> which is a standard file that should come with the C++ compiler, is short for
input-output streams. This command contains code for displaying and getting an input from the
user.
"using namespace std;" is a C++ directive that allows the use of names from the standard C++
library without the need to qualify them with the std:: prefix. The standard C++ library is defined
in the "std" namespace, and it contains many useful functions, classes, and objects, such as
cout, cin, string, vector, and many more.
Bytecode Languages
Bytecode languages are a type of programming language that fall under the categories of both
compiled and interpreted languages because they employ both compilation and interpretation to
execute code. Java and the .Net framework are easily the most common examples of bytecode
languages (dubbed Common Intermediate Language in .Net). In fact, the Java Virtual Machine
(JVM) is such a common virtual machine to interpret bytecode that several languages have
implementations built to run on the JVM.
In a bytecode language, the first step is to compile the current program from its human-readable
language into bytecode. Bytecode is a form of instruction set that is designed to be efficiently
executed by an interpreter and is composed of compact numeric codes, constants, and memory
references. From this point, the bytecode is passed to a virtual machine which acts as the
interpreter, which then proceeds to interpret the code as a standard interpreter would.
A type, also known as a data type, is a classification identifying one of various types of data.
Type checking is the process of verifying and enforcing the constraints on data types of
variables, function arguments, and return values in a program. It is a way to ensure that the
values used in a program are of the correct type and format, and to prevent type errors that can
lead to unexpected behavior or crashes.
Type systems is a collection of rules that assigns a data type to various constructs in a program.
pointers - a type which holds as its value a reference to a different memory location
Compiler Interpreter
Memory usage Static type checking can dynamic type checking can
optimize memory usage, as it detect errors and report them
can detect and prevent type at runtime, it may not
errors before the program optimize memory as well.
runs
Common Misconceptions
A common misconception is to assume that all statically-typed languages are also strongly-
typed languages, and that dynamically-typed languages are also weakly-typed languages.
This isn’t true, and here’s why:
A strongly-typed language is one in which variables are bound to specific data types, and will
result in type errors if types do not match up as expected in the expression – regardless of when
type checking occurs. A simple way to think of strongly-typed languages is to consider them to
have high degrees of type safety. Ex. x = 1 + “2”. Weak will not give an error, ex php.
Garbage Collection
Garbage collection is a mechanism used in programming languages to automatically manage
the memory used by a program. It works by periodically scanning the memory used by a
program and identifying any memory that is no longer being used, also known as "garbage."
The garbage collector then frees up this memory, making it available for future use.
Why Do We Need GC
GC helps save the developer from several memory-related issues – the foremost being memory
leaks. As you allocate more and more memory to the heap, if the program doesn’t consistently
release this memory as it becomes unneeded, memory size will begin to add up – resulting in a
heap overflow. Even if heap memory is diligently managed by the developer – all it takes is one
variable to be consistently left undeleted to result in a memory leak, which is bad.
Heap memory is a region of memory that is used to store dynamically allocated memory during
runtime.
Heap overflow, also known as a buffer overflow, occurs when a program writes more data to a
heap buffer than the buffer can hold. This can cause the program to crash or, in the case of
maliciously crafted input, can be used to execute arbitrary code, leading to a potential security
vulnerability.
Even if there are no memory leaks, what happens if you are attempting to reference a memory
location which has already been deleted or reallocated? This is called a dangling pointer.
This depends entirely on the algorithm used for GC. Sometimes the garbage collector will run at
predetermined time intervals, and sometimes it waits for certain conditions to arise before it will
run. The garbage collector will just about always run on a separate thread in tandem with your
program. And depending on the language’s implementation of GC, it can either stall your
program to sweep out all the garbage at once, run incrementally to remove small batches, or
run concurrently with your program.
1. Reference Counting: it is the most basic form of GC, and the easiest to implement on
your own. Anytime you reference a memory location on the heap, a counter for that
particular memory location increments by 1. Every time a reference to that location is
deleted, the counter decrements by 1. When that counter gets to 0, then that particular
memory location is garbage collected.
This method is used in languages like Python, and some implementations of C++.
Disadvantages
a. Circular references can’t be garbage collected – meaning that if object A has a
reference to object B, and object B has a reference back to object A, then neither
of these objects can ever be garbage collected according to reference counting.
b. Reference counting is very inefficient because of the constant writes to the
counters for each memory location
Disadvantage
A. The entire program has to be suspended while it is running. (Stop-the-world GC). And
because tracing GC can happen at any time, you don’t ever have a good idea of when
one of these stalls will happen.
B. Heap memory is also iterated over twice – which slows down your program even
more
3. Mark-Compact: The mark-sweep algorithm works by first "marking" all of the objects in
the heap that are still in use by the program, and then "sweeping" through the heap to
identify and free all of the objects that were not marked. This can help prevent memory
leaks caused by objects that are no longer needed by the program but are still taking up
space in the heap.
5. Generational GC takes concepts from copying algorithms, but instead of copying all
surviving members to a new memory region, it instead splits up memory into
generational regions based on how old the memory is
Past Question
1a. The programming language semantics can be described by various techniques. Outline the
most commonly used techniques in programming language semantics (3Mks)
- Formal Semantics
- Lexical Semantics
- Conceptual Semantics
- Denotation Semantics
- Connotation Semantics
- Axiomatic Semantics
- Operational Semantics
- Syntactic rules: These determine the structure of formulas which are the statements of interest
- Axioms: These describe the basic properties of the system.
- Inference rules: These are the mechanisms for deducing new theorems from axioms and other
theorems.
Declarations provide information about the name and type of data objects needed during
program execution. What are the two types of declaration?
- Implicit declaration or default declaration: They are those declarations which are done by the
compiler when no explicit declaration or user defined declaration is mentioned. Ex.
$abc='astring';
- Explicit declaration: In explicit we or users explicitly defined the variable type. Ex. Float A,B;
- Choice of storage representation: AS Translator determines the best storage representation of data
types that is why it needs to know primarily the information of data type and attribute of a data
object.
- Storage Management: It allows us to use best storage management for data object by
providing its information and this information tells the lifetime of a data object.
- Polymorphic operations: In most languages, some special symbol like + to designate any
one of the several different operations which depends on type of data or argument is
provided. This operation has some name like as we discussed + in this case the operation
symbol is said to be overloaded because it does not designate one specific operation.
- Type Checking: - Declaration is basically for static type checking rather than dynamic.
What is the difference between a break statement and a continue statement as used in object
oriented programming?
- The break statement is used to exit a loop prematurely. When the break statement is encountered
in a loop, it immediately terminates the current iteration of the loop and transfers control to the
next statement after the loop.
- The continue statement is used to skip the current iteration of a loop and move on to the next
iteration. When the continue statement is encountered in a loop, it causes the current iteration to
be skipped and the next iteration to start.
- Context-Free Grammars: a type of grammar that defines a set of rules for generating strings in a
language. It specifies the structure of the language, but does not specify the meaning of the
strings.
- Regular Grammars: a type of grammar that defines a set of rules for generating strings in a
regular language. Regular grammars are a subset of context-free grammars and can be used to
describe simple, repetitive patterns.
- Context-Sensitive Grammars: a type of grammar that defines a set of rules for generating strings
in a language, taking into account the context in which the strings are used. Context-sensitive
grammars are more powerful than context-free grammars, as they can capture more complex
patterns and relationships in the language.
Note: There is a fourth type of grammar but it is not used for programming languages because it is called
unrestricted grammar and it is unrestricted.
Using good examples, differentiate between Static Type Checking and Dynamic Type
Static Type Checking: Type checking is performed at compile-time, before the program is executed and
cannot be changed at runtime. For example, in a statically typed language like Java, C++, C, typescript.
Dynamic Type Checking: Type checking is performed at runtime, during the execution of the program. In
dynamic type checking, the type of a variable is determined at runtime, based on the value assigned to it,
and can change during the course of the program. For example, in Python, Ruby, and JavaScript.
What is the difference between Linker and Editor?
● Linker: A linker is a program in a computer system that takes one or more object
files generated by a compiler and combines them into a single executable file. It
resolves any external references, such as libraries, and merges all the object files
into a single executable that can be run on a computer.
● Editor: An editor is a software application used for editing and creating text-based
files. It provides features for adding, deleting, and modifying text and can also be
used to write, debug and run computer programs.
Write a simple C++ program to show the use of block variable declarations and definitions
#include <iostream>
int main()
{
// Block variable declaration
int x;
// Block variable definition and initialization
int y = 10;
return 0;
}
State the kind of variable a class can consist of using java program
● Instance variables: Also known as object variables, they are defined within a class
but outside any method. They are unique to each instance of the class and store
data that is specific to an individual object.
● Static variables: Also known as class variables, they are shared by all objects of a
class. They are declared using the static keyword and are created when the class is
loaded into memory.
● Local variables: They are defined within a method and are only accessible within
that method. They are created when a method is called and destroyed when the
method returns.
● Readability: The language should be easy to read and understand, with a syntax
that is clear and concise.
● Scalability: The language should be able to handle large and complex programs,
with efficient support for large data structures and algorithms.
● Interoperability: The language should be able to interact with other languages and
systems, allowing for seamless integration of existing software.
● Performance: The language should have efficient run-time performance, with low
overhead and quick execution times.
● Error handling: The language should provide adequate error handling and
debugging support, making it easy to identify and fix problems.
● Community: The language should have a large and active user community, with
readily available resources such as tutorials, libraries, and tools.
● Support: The language should have strong commercial and academic support,
with ongoing development and maintenance to ensure its continued evolution and
improvement.
Write a Java program segment to create an array of 100 with integers from 1-100
What is JVM and how is it considered in context of Java's platform independent feature?
JVM stands for Java Virtual Machine. It is a software component that provides a runtime
environment for executing Java code. JVM is responsible for managing the execution of
Java applications, including memory allocation, security, and garbage collection.
The JVM is one of the key factors in Java's platform independence. When a Java program
is compiled, it produces bytecode, which is a machine-independent format. This bytecode
can be executed on any platform that has a JVM installed, without modification. This
means that a Java program can run on any device, such as a laptop, desktop, or
smartphone, that has a JVM installed
Write a short note on the following programming methodologies
Write a C++ structure student defined with three members: name, matric no and department fees
#include <iostream>
#include <string>
struct Student {
std::string name;
int matric_no;
float department_fees;
};
int main() {
Student student1;
student1.name = "John Doe";
student1.matric_no = 123456;
student1.department_fees = 1000.00;
return 0;
}
There are 3 types of comments that Java supports in programming. Show how these comments
can be implemented.
- Single Line Comment: It starts with // and continues until the end of the line.
For example: // This is a single line comment.
- Multi-Line Comment: It starts with /* and ends with */.
For example: /* This is a multi-line comment */
- Document Comment: It starts with /** and ends with */. This type of comment is used for
generating API documentation using the javadoc tool.
For example:
/**
* This is a document comment.
* It can be used to generate API documentation.
*/
Each of these comments serves a different purpose and can be used in different contexts
depending on what the programmer wants to communicate.
Show that the union of two regular sets is regular. Given two regular expressions: RE 1 = a(aa)*
and RE2 = (aa)*
A regular set is a set of strings that can be recognized by a finite automaton, which is also known as a
regular expression. The union of two regular sets is also a regular set, as it can be recognized by a finite
automaton that consists of two separate automata, one for each of the original regular sets.
In this case, we have two regular expressions: RE1 = a(aa)* and RE2 = (aa)*. To show that the union of
the two regular sets is also a regular set, we can construct a finite automaton that recognizes both RE1 and
RE2. The automaton for RE1 would have a start state, an accepting state, and intermediate states that
correspond to the possible states of the string being matched. The automaton for RE2 would be similar,
with its own start state, accepting state, and intermediate states.
To create the automaton for the union of the two sets, we simply create a new start state and connect it to
the start states of both RE1 and RE2. The accepting states of both RE1 and RE2 are also connected to a
new accepting state.
This creates a new automaton that recognizes the union of the two original sets, which is also a regular
set.Thus, the union of two regular sets is a regular set and can be recognized by a finite automaton
Write a simple C++ program to show the use of block variable declarations and definitions.
Already done
Explain the following line used under Java Program: public static void main (String args[])
"public static void main (String args[])" is the starting point of a Java program. The "public"
keyword makes the "main" method accessible to any class. The "static" keyword allows the main
method to be called without creating an instance of the class. The "void" keyword indicates that
the main method does not return any value. The "main" method is a standard name for the
starting point of a Java program. The "String args[]" is an array of strings that represents
arguments passed to the main method. This line of code specifies that the program will receive
an array of strings as input, which can be accessed within the main method.
class Dog {
String breed;
int age;
String color;
Type checking is the process of verifying and enforcing the constraints of data types, and it can
occur either at compile time (i.e. statically) or at runtime (i.e. dynamically). (Like making sure that
if you declare variable age to be an integer, then it must only contain integer value)
1) A + B 2) A + B * C 3) A + B * C + D 4) A + B + C + D
- Compilation
- Interpretation
- Hybrid
- Just in time compiler: compiles source code into machine code as the code is executed,
rather than ahead of time.
- Pure interpretation
Briefly describe the two main types of garbage collection activity that usually happens in Java
- Mark Sweep: This is a basic type of garbage collection that involves marking all the
objects that are still in use and then sweeping up the rest, freeing up the memory
occupied by unreferenced objects.
- Generational Garbage Collection: It divides the memory into different sections, called
generations, based on the age of the objects stored there. The youngest objects are stored
in the youngest generation, and objects that have lived longer are moved to older
generations.
ii) print list[0] if list = [‘abcd’, 786. 2.23, ‘john’, 70.2]? – abcd
iii) print list[1:3] if list = [‘abcd’, 786. 2.23, ‘john’, 70.2]? – [786.2, 2.23]