Unit-1 - Introduction to Programming Paradigm Programming Languages – Elements of Programming languages - Programming Language Theory - Bohm- Jacopini structured program theorem - Multiple Programming Paradigm – Programming Paradigm hierarchy – Imperative Paradigm: Procedural, Object-Oriented and Parallel processing – Declarative programming paradigm: Logic, Functional and Database processing - Machine Codes – Procedural and Object-Oriented Programming
Introduction to Programming Languages What is a Programming Language? A programming language is a formal set of instructions that can be used to produce various kinds of output. Programming languages are used to create software that controls the behavior of a machine, particularly a computer. Purpose of Programming Languages Programming languages allow humans to communicate with machines in a way that is both understandable to the machine and accessible to the human programmer. They bridge the gap between human logic and machine instructions. Types of Programming Languages Low-Level Languages : These are closer to machine language (binary code) and include Assembly Language. They provide more control over hardware but are more difficult to write and understand. High-Level Languages : These are closer to human languages and include languages like Python, Java, and C++. They are easier to write, read, and maintain. Domain-Specific Languages : These are specialized for particular tasks, such as SQL for database queries or HTML for web development.
Object-Oriented Languages: These languages emphasize the concept of objects, which encapsulate both data and the functions (methods) that operate on that data. Examples include Java, C++, C#, and Python. Functional Languages: These languages treat computation as the evaluation of mathematical functions and avoid changing state or mutable data. Examples include Haskell, Lisp, and Erlang. Domain- Specific Languages (DSLs): These languages are designed for specific domains or problem areas, with specialized syntax and features tailored to those domains. Examples include SQL for database management, HTML/CSS for web development, and MATLAB for numerical computing. Programming languages have different strengths and weaknesses, and developers choose a language based on factors such as project requirements, performance needs, development speed, community support, and personal preference. Learning multiple languages can give programmers flexibility and allow them to solve different types of problems more effectively.
Categories of Programming Languages Imperative Languages : These languages focus on how to execute tasks by specifying step-by-step instructions (e.g., C, Java). Functional Languages : These emphasize the evaluation of functions and avoid changing state or mutable data (e.g., Haskell, Lisp). Object-Oriented Languages : These languages use objects and classes to organize code in a way that models real-world entities (e.g., Java, C++). Logic Languages : These are based on formal logic and allow programmers to declare what they want rather than how to achieve it (e.g., Prolog). History and Evolution The first programming languages were developed in the early 1950s, with Assembly Language being among the first. Over time, languages evolved to be more abstract and user-friendly, leading to the modern languages we use today. Significance of Programming Languages Programming languages are crucial for the development of software, which runs almost every aspect of modern life—from operating systems to applications, from websites to embedded systems in devices.
Programming Language Theory Formal Languages : Programming languages are often defined by formal languages, which use formal grammar to describe the syntax and structure of programs. Type Systems : A type system is a set of rules that assigns types to various program constructs, such as variables, expressions, functions, and modules. It ensures that operations are performed on compatible data types. Language Paradigms : These are different styles of programming, such as imperative, functional, logic, and object-oriented paradigms. Each paradigm offers different approaches to solving programming problems. Compiler Theory : This deals with how high-level programming languages are translated into machine code that a computer can execute. Abstract Interpretation : A method used to analyze programs by simplifying and approximating their behaviors, which helps in understanding program properties and potential errors.
Elements of Programming Languages Syntax : Refers to the rules that define the structure of a programming language. It includes how symbols, keywords, and punctuation are arranged to form valid programs. Syntax is like the grammar of a language. Semantics : Describes the meaning of syntactically valid programs. It defines what the program does when it runs. For example, the semantics of an if statement is that it executes a block of code only if a certain condition is true. Pragmatics : Focuses on how programming language features are used in practice, considering aspects like efficiency, readability, and ease of use. Types : Programming languages use types to classify data and determine what kind of operations can be performed on that data. For example, integers, floats, and strings are different types in many languages. Variables and Scope : Variables are names given to data that can change over time. The scope of a variable defines where it can be accessed in the program. Control Structures : These are constructs that dictate the flow of control in a program, such as loops ( for , while ), conditionals ( if , else ), and branches ( switch ). Functions and Procedures : Functions (or procedures) are reusable blocks of code designed to perform a specific task. They allow for code modularity and reduce repetition. Data Structures : These are ways to organize and store data in a program, such as arrays, lists, stacks, queues, and trees.
Bohm- Jacopini Structured Program Theorem Overview : The Bohm- Jacopini theorem, proposed by Corrado Böhm and Giuseppe Jacopini in 1966, is a fundamental result in programming language theory. It states that any computable function can be implemented using just three control structures: sequence, selection (branching), and iteration (loops). Significance : This theorem laid the groundwork for structured programming, which advocates for the use of these control structures to create clear, understandable, and maintainable programs. It implies that " goto " statements, which were common in early programming, are unnecessary and can lead to "spaghetti code." Control Structures Defined : Sequence : The execution of statements in a linear order, one after another. Selection (Branching) : Making decisions in a program using conditional statements like if-else. Iteration (Looping) : Repeating a block of code multiple times using loops like for, while, and do-while. Structured Programming : The practice of structuring programs using these three control structures to enhance readability and reduce complexity.
Machine Codes Definition : Machine code, or machine language, is the lowest-level programming language, consisting of binary digits (0s and 1s) that the computer's central processing unit (CPU) can execute directly. Characteristics : Binary Format : Machine code is written in binary, which makes it difficult for humans to read and write. Hardware-Specific : Machine code is specific to a computer's architecture, meaning that code written for one type of CPU won't necessarily run on another. Fast Execution : Programs written in machine code are executed directly by the hardware, making them extremely fast but difficult to debug and maintain. Use Cases : Machine code is primarily used in low-level programming, such as writing operating system kernels, firmware, and device drivers.
Procedural Programming Definition : Procedural programming is a programming paradigm based on the concept of procedure calls, where procedures, also known as functions, are a sequence of instructions that perform a specific task. Key Concepts : Functions/Procedures : Central to procedural programming, functions encapsulate reusable blocks of code. Sequence, Selection, Iteration : Control structures in procedural programming include sequences of instructions, conditional statements (like if-else ), and loops (like for , while ). Global and Local Variables : Variables can be defined globally (accessible throughout the program) or locally within a function. Advantages : Simplicity : Procedural programming is straightforward and easy to understand, especially for small programs. Reusability : Functions can be reused across different parts of a program, reducing redundancy. Limitations : Scalability : Procedural programming can become unwieldy in large projects, as it doesn’t naturally support concepts like data encapsulation. Maintenance : Managing and modifying large procedural codebases can be challenging as they grow in complexity. Examples : Languages like C, Pascal, and BASIC are well-known for procedural programming.
Object-Oriented Programming (OOP) Definition : Object-Oriented Programming is a paradigm that uses "objects"—which are instances of classes—to design and structure software. It models real-world entities using objects that encapsulate both data and behavior. Key Concepts : Classes and Objects : A class is a blueprint for creating objects. An object is an instance of a class containing attributes (data) and methods (functions). Encapsulation : Bundling data and methods that operate on the data within a single unit, or class, and restricting access to some of the object’s components. Inheritance : The ability to create a new class based on an existing class, inheriting attributes and behaviors from the parent class. Polymorphism : The ability to process objects differently depending on their data type or class. For example, the same method name can be used in different classes. Abstraction : The concept of hiding complex implementation details and showing only the essential features of an object.
Advantages : Modularity : OOP helps in organizing code into manageable sections or classes. Code Reusability : Inheritance allows for code reuse across multiple classes. Maintainability : The modularity of OOP makes it easier to update and maintain code. Scalability : OOP naturally supports more complex and scalable systems compared to procedural programming. Limitations : Complexity : OOP can be more complex to learn and implement, especially for beginners. Overhead : The abstraction layers in OOP may introduce overhead, which can affect performance. Examples : Java, C++, Python, and Ruby are popular object-oriented languages.
Direct Procedure Call : What it is : In a direct procedure call, the method to be invoked is determined at compile-time. This is typical in languages with static binding. Overhead : The overhead is minimal because the address of the method is known at compile-time, allowing for efficient calls. There's no need to determine which method to execute at runtime.
Dynamically Dispatched Message Calls: What it is : In dynamically dispatched calls, the method to be invoked is determined at runtime. This is typical in object-oriented languages with dynamic binding (e.g., polymorphism in Java, C++). Overhead : The overhead is higher than in direct calls because the runtime system must determine the appropriate method to invoke. This typically involves looking up a method in a table (such as a vtable in C++), which adds additional processing time.
Key Differences: Method Resolution : Direct Procedure Call : The method is resolved at compile-time. Dynamically Dispatched Call : The method is resolved at runtime. Efficiency : Direct Procedure Call : More efficient due to compile-time resolution. Dynamically Dispatched Call : Less efficient because of the additional runtime lookup.
Direct Procedure Call: class A { void display() { System.out.println ("A's display"); } } public class Main { public static void main(String[] args ) { A a = new A(); a.display (); // Direct call to A's display method. } }
class A { void display() { System.out.println ("A's display"); } } class B extends A { void display() { System.out.println ("B's display"); } } public class Main { public static void main(String[] args ) { A a = new B(); a.display (); // Dynamically dispatched call to B's display method. } } Dynamically Dispatched Message Calls