Skip to content

Course Orientation — Why This Series Exists

Functional programming in Python is often presented as a grab-bag of tricks. This series takes a correctness-first, production-focused path instead: you will build and evolve a real FuncPipe RAG pipeline while learning how to reason about purity, effects, streaming, async backpressure, and domain modelling without magic. Module 00 is your map, expectations, and setup checklist before you start writing code.


Who This Is For

  • You ship Python services, data pipelines, or ML workflows and need predictable, testable behavior under change and load.
  • You know Python well (classes, typing, packaging) and want FP tools without category-theory detours.
  • You want patterns that survive refactoring, concurrency, and production debugging, not just cute one-liners.

How to Use the Course Book

  • Read, then run. Every module pairs narrative with runnable code in src/ and tests/. Apply ideas to the evolving FuncPipe RAG project.
  • Keep effects at the edges. Expect constant reminders to isolate I/O; you will refactor toward purity, not away from it.
  • Treat claims as contracts. Assertions and property tests back the concepts; extend them when you adapt patterns to your codebase.
  • Use the docs locally. make docs-serve renders this book (Material theme) and supports live reloading while you edit or experiment.

Progression Map (10 Modules)

Module Focus What You Gain
01 Pure functions & substitution Spot impurities, refactor to pure call graphs, prove equivalence with Hypothesis
02 Closures & expression style Partial application, data-first APIs, configuration-as-data, debugging compositions
03 Iterators & laziness Streaming pipelines, chunking, safe fan-in/out, observability on lazy flows
04 Recursion, folds, resilience Memoization, Result/Option for per-record failures, structured error aggregation
05 Algebraic data modelling ADTs, functors/applicatives, monoids, Pydantic edges, serialization contracts
06 Monadic flows bind/and_then, layered containers, Reader/State patterns, configurable pipelines
07 Effect boundaries Ports/adapters, capability protocols, idempotent effect design, resource safety
08 Async + backpressure Async generators, bounded queues, retry/timeout policies as data, rate limiting
09 Ecosystem interop Stdlib/toolz/returns facades, dataframes in FP style, config-driven pipeline specs
10 Refactoring & sustainment Systematic migration, performance budgets, property-based regression, governance

Module 00 keeps you oriented; Modules 01–10 are the build-up; the repository state matches the end of Module 09, and you will keep refactoring it as you learn.


What “Progress” Looks Like

  • Conceptual: You can state the law or invariant in one sentence (e.g., referential transparency), and explain when to violate it.
  • Practical: You have a small, runnable diff that proves the idea on the FuncPipe RAG code (or your own code).
  • Testing: You write at least one property test or contract check per module to keep changes honest.
  • Operational: You know where side effects live and can trace them with logs/metrics without breaking purity in the core.

Track your progress by annotating the module markdowns or adding small “checkpoint” tests in tests/ as you finish each core.


Setup Checklist (Before Module 01)

  1. Create a fresh virtualenv: python3 -m venv .venv && source .venv/bin/activate.
  2. Install dev + docs tooling: make install (or pip install -e '.[dev,docs]').
  3. Run the doc server: make docs-serve and open the local URL for live updates.
  4. Run tests to ensure baseline correctness: make test.
  5. Skim README.md for the current project shape and module progression notes.

If anything fails here, fix it now—later modules assume this baseline works.


How to Read Each Module

  • Start with the core question at the top of each module—know what you must be able to answer.
  • Work through examples in order, running them in a REPL or test; avoid jumping ahead to async or ADTs before nailing purity.
  • Mirror each pattern in your own code (e.g., isolate I/O, swap mutable globals for explicit parameters).
  • Leave behind evidence: a property test, a small refactor, or a note on when a pattern should not be used.

What You’ll Notice in the Style

  • Data-first APIs: Functions accept data and return new data; side effects are explicitly threaded.
  • Small, composable helpers: Prefer tiny combinators and clear contracts over clever one-liners.
  • Evidence over assertion: Every claim should have a runnable snippet or property.
  • Production realism: Logging, retries, backpressure, and type boundaries show up early.

Carry this mindset into every module; it keeps the growing FuncPipe RAG pipeline understandable and testable.