"Parse, don't validate" through the years with C++
3 days ago
- #Type Systems
- #Programming Paradigms
- #C++
- The post applies the 'Parse, don't validate' paradigm to a simple date-parsing problem in C++ across different versions (C++98, C++11, C++17, C++23).
- The key idea is using the type system to parse unstructured inputs; successful type instantiation ensures data validity, eliminating downstream validation control flow.
- The initial naive approach uses a simple struct and sscanf, which fails silently on invalid inputs, kicking validation down the road.
- In C++98, a Birthdate class is designed with a private constructor and static parsing method, enforcing constraints (year, month, day ranges, leap year) and returning error codes without exceptions or heap allocations.
- C++11 version leverages std::get_time for parsing and uses exceptions to handle errors, with a public constructor that validates inputs.
- C++17 introduces std::optional for explicit failure handling without exceptions, using string_view and manual parsing for better control.
- C++23 utilizes std::expected to provide rich error information, improving error handling clarity and user feedback.
- Compilation benchmarks show increasing compile times across C++ versions, with C++23 being significantly slower.
- The author reflects on real-world applications, noting that many languages fall between strict (Rust/Haskell) and loose (Python) type systems, and LLMs often require heavy revisions to generate correct code for such paradigms.