Fundamentals
"The best way to predict the future is to invent it... The second best way is to fund it. The third best way is to map it."
– Neal Stephenson, Cryptonomicon
Every Java developer has, at some point, stared at a screen wondering why updating a single field in an immutable record requires reconstructing half the object graph. The standard approach (manually copying and rebuilding each layer) works, technically speaking, in the same way that crossing the Atlantic in a rowing boat works. Possible, certainly. Pleasant, no.
Optics offer a rather more civilised alternative.
At their heart, optics are simply composable, reusable paths through data structures. A Lens focuses on a single field. A Prism handles cases that might not exist. An Iso converts between equivalent representations. None of this is particularly revolutionary in concept (functional programmers have been using these tools for decades), but the practical benefit is considerable: once you've defined a path, you can use it to get, set, or modify values without writing the same tedious reconstruction code repeatedly.
This section introduces the fundamental optics: Lens for product types (records with fields), Prism for sum types (sealed interfaces with variants), and Iso for reversible conversions. By the end, you'll understand not only how each works, but when to reach for one over another.
The composition rules table at the section's end is worth bookmarking. You'll refer to it more often than you might expect. The Optics landing page carries the overall optics hierarchy if you need to see where these four fit in relation to Traversals, Folds, Getters, and Setters.
Practice this section in the Lens & Prism Journey (30 exercises, ~40 minutes).
- Annotations at a Glance, every optic in this section is generated by an annotation.
- Lenses – Focus on exactly one field within a record. A Lens guarantees the field exists and provides both get and set operations.
- Prisms – Handle sum types (sealed interfaces) where a value might be one of several variants. A Prism can attempt to match a variant and construct new instances.
- Affines – For optional fields that may or may not be present. An Affine targets zero-or-one values, making it perfect for nullable fields or conditional access.
- Isomorphisms – Bidirectional, lossless conversions between equivalent types. An Iso can convert in both directions without losing information.
- Composition – Chain optics together to navigate arbitrarily deep structures. The composition of a Lens with a Prism produces an Affine, following predictable rules.
- The Composition Rules – A reference table showing what optic type results from composing any two optics. Keep this bookmarked; you'll need it.
- Coupled Fields – When record fields share invariants, sequential lens updates fail. Learn how
Lens.pairedprovides atomic multi-field updates.
Chapter Contents
- What Are Optics? - Introduction to composable, reusable paths through data
- Lenses - Focusing on required fields within records
- Prisms - Safely handling sum types and optional variants
- Affines - Working with optional fields (zero-or-one focus)
- Isomorphisms - Lossless conversions between equivalent types
- Composition Rules - A reference for what type results from combining optics
- Coupled Fields - Atomic updates for fields with shared invariants
Next: What Are Optics?