| name | define-domain-types |
| description | For new modules: define type aliases as vocabulary, make code self-documenting, create domain-specific language feel. |
define-domain-types
When to Use
- Starting a new module or problem domain
- Want code to read like prose
- Types would clarify function signatures
- Building a mini-DSL
- Complex nested types (list of tuples of...)
When NOT to Use
- Simple scripts with obvious types
- Types would just add noise
- No domain-specific vocabulary needed
The Pattern
Define type aliases at the top of your module to establish vocabulary.
from typing import List, Dict, Set, Tuple, Optional
Point = Tuple[int, int]
Grid = Dict[Point, str]
Path = List[Point]
Score = float
def find_path(grid: Grid, start: Point, goal: Point) -> Optional[Path]:
...
def calculate_score(path: Path) -> Score:
...
Example (from pytudes)
Formula = str
Pformula = str
Solution = str
def solve(formula: Formula) -> Iterable[Solution]:
...
Space = set
Event = set
Probability = float
def P(event: Event, space: Space) -> Probability:
...
City = complex
Cities = frozenset
Tour = list
Segment = list
def tour_length(tour: Tour) -> float:
...
def valid_tour(tour: Tour, cities: Cities) -> bool:
...
Digit = str
Square = str
Unit = List[Square]
Grid = Dict[Square, str]
def eliminate(grid: Grid, square: Square, digit: Digit) -> Optional[Grid]:
...
Key Principles
- Top of file: Types as module header
- Simple names:
City, not CityPointType
- Comments for meaning: What does this type represent?
- Signatures tell story:
solve(formula) -> Solution
- Gradual typing: Add types where they help clarity