Course

Computer Science III: Programming Paradigms

Stanford University

This course covers a variety of programming paradigms, focusing on:

  • Advanced memory management in C and C++.
  • Differences between imperative and object-oriented paradigms.
  • Functional programming using LISP.
  • Concurrent programming in C and C++.
  • A brief survey of modern languages like Python, Objective C, and C#.

Prerequisites include knowledge of C++ and programming concepts at the Programming Abstractions level. Students should be comfortable with arrays, pointers, references, classes, methods, dynamic memory allocation, recursion, linked lists, binary search trees, hashing, iterators, and function pointers. The ability to write clear and maintainable code is essential.

Course Lectures
  • The introductory module provides essential administrative details about the course, including:

    • Exams: time limits and conflicts.
    • Course grade breakdown.
    • Assignment submission and grading policies.
    • Communication through email, newsgroups, and social media.
    • Course prerequisites and the programming languages and paradigms to be taught.

    It also introduces key concepts such as procedural and object-oriented paradigms, assembly, and concurrent programming, along with an overview of functional programming through Scheme.

  • This module delves into data types within C/C++. It covers:

    • Interpretations and sizes of C/C++ data types.
    • Breaking down bytes into bits and understanding character representations.
    • Negative number representations and two's complement addition.
    • Conversion between different data types, such as chars, shorts, ints, and floats.

    By understanding these data types, students will gain deeper insights into memory representation and data manipulation in C/C++.

  • This module focuses on converting between types of different sizes and bit representations using pointers. Key topics include:

    • Little Endian vs. Big Endian data storage.
    • Storage and access methods for structs in memory.
    • Pointer arithmetic and casting arrays to different types.
    • Dynamic memory management for strings and character arrays.
    • Generic functions utilizing memory and pointers.

    Students will learn practical techniques for managing data and memory in C/C++ through hands-on examples and exercises.

  • This module teaches students how to create a generic swap function applicable to data types of arbitrary size. Important topics addressed include:

    • Using void* type for generic pointers.
    • Implementation of swap functionality using memcpy.
    • Pros and cons of generics in C vs. C++.
    • Error handling for improper use of generics.
    • Implementing generic linear search functions.

    Students will gain experience in the concept of generics, advancing their programming capabilities in C.

  • This module focuses on the implementation of a generic linear search algorithm. Key learning points include:

    • Understanding the prototype and comparison functions.
    • Using void pointers and handling byte offsets in generic searches.
    • Implementing more complex data types for searches, including C-strings.
    • Creating C data structures like non-generic stacks.
    • Preallocating memory and managing internal states.

    Students will apply their understanding of generics and data structures to implement a robust linear search function.

  • This module covers the construction of an integer stack, focusing on constructors and destructors. Key areas include:

    • Implementing Stackpush and Stackpop functionalities.
    • Memory reallocation strategies when stack size exceeds limits.
    • Generic stack implementations and handling memory with memcpy.
    • Static functions in stack operations.
    • Best practices for managing dynamic memory in C.

    Students will strengthen their understanding of object-oriented principles in a procedural language context through stack implementation.

  • This module highlights ownership issues in memory management. Topics include:

    • Common pitfalls when freeing dynamically allocated data.
    • Implementing custom free functions for stack implementations.
    • Understanding C library functions like memmove and qsort.
    • Exploring memory layout including stack and heap segments.
    • How heap managers allocate and free memory effectively.

    Students will learn strategies for proper memory management and the implications of ownership on program stability.

  • This module provides insights into heap management, focusing on how allocational information is stored. Key discussions include:

    • Consequences of improper memory freeing.
    • Algorithms for managing free blocks in the heap.
    • Techniques for reducing memory fragmentation.
    • Understanding activation records and stack layout during function calls.
    • How assembly code interacts with the stack and heap.

    Students will gain practical knowledge of memory allocation and management, crucial for optimizing performance in C/C++ applications.

  • This module explains how code snippets are translated into assembly instructions. It covers:

    • Basic operations such as store, load, and arithmetic logic unit (ALU) operations.
    • Optimizations for 4-byte addresses in assembly.
    • Translating loops and branch instructions into assembly code.
    • Pointer and array arithmetic representations.
    • Encoding assembly instructions in memory.

    Students will learn the fundamentals of low-level programming and how high-level constructs are represented in assembly.

  • This module provides detailed insights into activation records, focusing on memory layout during function calls. Topics discussed include:

    • Storage of return addresses on the stack.
    • Construction of activation records during function executions.
    • Setting up function parameters on the stack.
    • Housekeeping at the end of functions using RET instructions.
    • Illustration of recursion in assembly.

    Students will enhance their understanding of function execution and stack management, which is vital for optimizing code performance.

  • This module transitions students from C code generation to C++ code generation, focusing on swap implementation. Key points include:

    • Understanding pointer swap functions in C.
    • Exploring the C++ version of swap using references.
    • Impact of class declarations on stack memory.
    • Exploration of class methods and their "this" pointers.
    • Compilation and linking processes in C++ programming.

    Students will grasp the differences between C and C++ in code generation and memory management techniques.

  • This module introduces preprocessing commands in C/C++. Key learning objectives include:

    • Understanding the #define directive for macro creation.
    • Using preprocessing macros with arguments.
    • Managing circular #include loops.
    • Analyzing the output of the preprocessor.
    • Visual representation of the preprocessing and compilation processes in C/C++.

    Students will become proficient in using preprocessing commands to enhance the flexibility and efficiency of their code.

  • This module reviews the compilation process of a simple program into an object file. Key points include:

    • Understanding the impact of commenting out standard library header files.
    • How GCC infers prototypes and retains output consistency.
    • Identification of issues during linking processes.
    • Debugging examples of seg faults and bus errors.
    • Analyzing array overflow scenarios and their consequences.

    Students will gain insights into the challenges and nuances of the compilation and linking phases in C/C++ programming.

  • This module explores the differences between sequential and concurrent programming. Key concepts covered include:

    • Impact of writing beyond array limits.
    • Data sharing issues and their implications in function interactions.
    • Understanding variable argument functions like printf.
    • Contrast between sequential and concurrent process execution.
    • Real-world examples of concurrency in programming.

    Students will learn how concurrent programming enables more efficient processing through effective resource management.

  • This module transitions from sequential to concurrent programming through a ticket sale example. It covers:

    • Identifying problems with the sequential model.
    • Using threading interfaces to enhance program performance.
    • Realizing issues with shared data access in threads.
    • Implementing semaphores to control access to critical regions.
    • Understanding deadlocks and their implications.

    Students will apply threading concepts to create more efficient and responsive applications.

  • Semaphores
    Jerry Cain

    This module reviews semaphore concepts, focusing on their syntax and usage in multithreading scenarios. Key topics include:

    • Semaphore types: full buffer vs. empty buffer.
    • Modeling race conditions and ensuring data integrity.
    • Implementing reader and writer threads with semaphores.
    • Understanding semaphore patterns and potential deadlocks.
    • Real-world threading applications, including the Dining Philosopher problem.

    Students will learn to manage concurrent processes effectively through semaphore usage.

  • This module provides a detailed review of the Dining Philosopher problem, emphasizing concurrency challenges. Topics include:

    • Modeling philosophers as threads and their interactions.
    • Understanding deadlocks and strategies to avoid them.
    • Implementing solutions using semaphores and shared resources.
    • Analyzing additional threading examples like FTP downloads.
    • Ensuring proper synchronization in thread interactions.

    Students will deepen their understanding of concurrency issues through practical examples and theoretical implications.

  • This module introduces the Ice Cream Store Problem, involving multiple threading scenarios. Key learning points include:

    • Defining roles of customer, cashier, clerk, and manager threads.
    • Implementing thread interactions and constraints.
    • Handling manager-clerk inspections using semaphores.
    • Managing customer queues and ensuring orderly processing.
    • Writing main functions and spawning threads effectively.

    Students will apply concurrency concepts to a real-world scenario, enhancing their understanding of multithreaded design.

  • This module provides an introduction to the functional paradigm using Scheme. It covers:

    • Comparison of imperative and object-oriented paradigms with functional programming.
    • Basic Scheme function definitions and their applications.
    • Scheme primitives, lists, and operations.
    • Understanding the significance of list structures in functional programming.
    • Writing recursive functions and exploring their behavior.

    Students will gain foundational knowledge in functional programming concepts and their practical applications in Scheme.

  • This module delves into car-cdr recursion problems in Scheme, focusing on practical applications. Key topics include:

    • Writing recursive functions to sum elements in a list.
    • Examining type checking during runtime versus compile-time.
    • Implementing a flatten function for nested lists.
    • Using conditional structures to handle recursion.
    • Generalizing functions by passing comparison functions as parameters.

    Students will enhance their skills in recursive function design and its implications in functional programming.

  • This module introduces the Kawa development environment and evaluates expressions in Scheme. Key areas include:

    • Loading and executing function definitions from .scm files.
    • Mapping functions over lists using the map operation.
    • Implementing apply and eval functions for dynamic execution.
    • Writing functions that utilize lambda expressions.
    • Understanding the implications of defining functions within functions.

    Students will learn to navigate the Kawa environment while applying functional programming techniques in practice.

  • This module focuses on writing recursive power set functions in Scheme. Key topics include:

    • Using lambda functions to create recursive mappings.
    • Implementing let bindings to optimize recursive calls.
    • Exploring permutations of lists through recursive functions.
    • Understanding immutability of lists in Scheme.
    • Examining memory allocation and the read-eval-print loop.

    Students will deepen their understanding of recursion and its applications, while also exploring memory management in Scheme.

  • Scheme Memory Model
    Jerry Cain

    This module examines the Scheme memory model, focusing on linked list operations and layout. Key discussions include:

    • Two approaches to laying out lists in memory.
    • Implementing a generic map function to handle multiple arguments.
    • Understanding garbage collection and its high-level mechanics.
    • Exploring other functional languages, such as ML and Haskell.
    • Comparative analysis of functional programming features across languages.

    Students will gain insights into memory management and garbage collection in functional programming, enhancing their understanding of language implementations.

  • This module provides an overview of Python, highlighting its overarching features. Key areas include:

    • Understanding Python as a scripting language with dynamic typing.
    • Exploring Python's object-oriented and functional paradigms.
    • Examining string and list manipulations within Python.
    • Utilizing Python modules and libraries effectively.
    • Understanding dictionary implementations and their applications.

    Students will develop foundational skills in Python programming while understanding its versatile paradigms and data structures.

  • Python Object Model
    Jerry Cain

    This module dives deeper into Python's object model, covering essential topics such as:

    • Understanding how objects are implemented and how they are stored in memory.
    • Exploring Python's dictionary-based class structures.
    • Using classes and objects effectively in Python.
    • Implementing class constructors and understanding initialization.
    • Accessing object data through Python's object interface.

    Students will enhance their understanding of Python's object model and learn to implement classes efficiently.

  • This module examines XML processing in Python, highlighting different processing models. Key points include:

    • Understanding XML parsing through tag handlers.
    • Implementing XML parsers using Python libraries.
    • Defining functions for RSS feed parsing and handling.
    • Exploring tree-based vs. stream-based XML rendering.
    • Examining practical applications of XML processing.

    Students will acquire practical skills in XML parsing and data handling using Python, enhancing their programming versatility.

  • This module serves as an introduction to Haskell, exploring its unique features. Key discussions include:

    • The history of Haskell and its language safeguards.
    • Understanding expressive functions and lazy evaluation.
    • Exploring types, including user-defined data types.
    • Working with lists and recursive type definitions.
    • Comparative analysis of Haskell's functional programming approach.

    Students will gain insights into Haskell's paradigms and its approach to programming, broadening their understanding of functional languages.