!! Recitations are starting this week !!
The lectures will follow this list of topics (this is somewhat tentative, and subject to mild changes if needed).
Introduction & Paradigms: Overview of different programming paradigms.
Lambda Calculus: The theoretical foundation of functional computation.
Scopes, Bindings, and Substitutions: How variables are defined, accessed, and have their names resolved and replaced.
Introduction to OCaml: Using a functional language to explore core concepts, including:
Basic syntax, functions, and operators.
Currying and partial function application.
Pattern matching for data deconstruction.
Higher-order functions (functions that take other functions as arguments or return them).
Data Types and Type Systems: The philosophy and mechanics of how languages categorize data.
Scalar, Composite, and Recursive Data Types: Building complex types from simpler ones.
Pointers and Pointer Arithmetic: Low-level memory management and manipulation.
Algebraic Data Types: A powerful method for data modeling, particularly sum types (variants) and product types (tuples/records), heavily featured in functional languages.
Core OOP Concepts: Objects, classes, and polymorphism.
Inheritance and Type Hierarchy: Building new classes from existing ones.
The Diamond Problem: A classic multiple inheritance issue.
Abstraction and Encapsulation: Interfaces, signatures, abstract classes, and information hiding.
Generics / Parametric Polymorphism: Writing code that operates on data of many types.
Type parameters and bounded parameters.
Type erasure vs. reified types.
Variance (covariance, contravariance, invariance).
Compile-time vs. Runtime Types: The differences in how types are handled.
Java Streams API: Using a functional, declarative style for processing data collections.
Higher-Order Polymorphism in Java: Using generics with functional patterns.
Operational Abstraction: The Iterator design pattern.
Lambda Expressions and Anonymous Classes: Implementing functional interfaces concisely.
Lazy Evaluation: Deferring computation until necessary (e.g., with streams and suppliers).
Modularity & Design Patterns: Concepts like the Singleton pattern.
Evaluation Strategies: How arguments are passed to functions.
Lazy Evaluation and Thunks: Implementing pass-by-name by wrapping an expression in a function for later execution.
Object-Oriented Programming with Dynamic Typing: How OOP concepts (like methods, attributes, and inheritance) work in dynamically typed languages (e.g., Python, as suggested by "magic methods").
Magic Methods / Dunder Methods: How operators and built-in functions are implemented.
Class-level vs. Instance-level: The distinction between static methods, class attributes, and instance attributes/methods.