3 ms·
C is perfectly capable of type-driven design. He's already got the type (struct), and although C is a bit limited, he can: * return pointer-or-null * choose "
by kstenerud 6mo ago
C is perfectly capable of type-driven design. He's already got the type (struct), and although C is a bit limited, he can:
* return pointer-or-null
* choose "invalid" sentinel values and then use birthdate_is_valid(...) to check validity.
* Add an is_valid bool field (or even an error enum like in the C++23 example)
* Add an out field in the constructor function for the error code (similar to how ObjC does things).
- mrkeen 6mo agoCool, incredibly low bar. All four of your examples are validate. Know any languages that are worse than C at this?
- tech_hutch 6mo agoOr use an out field for the type itself, and use the return value for an error code (or just a bool). A common pattern in C#.
- wk_end 6mo agoThe point of parse-don't-validate is that the type checker prevents you from having a value of a particular type that's invalid. Pointer-or-NULL doesn't work, because all pointers are nullable in C; you can always have a Foo* (NULL) that's doesn't actually point to a valid Foo. Invalid sentinel values are definitionally values of a particular type that are invalid. Same with an is_valid field. An out field in the constructor means that whatever you actually return in the case of an error is going to be a well-typed Foo that's invalid.
- kstenerud 6mo agoMy point is that you do the checking at the call site, and then use a static analysis tool or an AI to enforce checking the result right after calling parse_birthday. Sure, Optional is more elegant, but the end result is the same: Now none of the other code needs to validate; it's already been verified valid at all points where a parse error could have occurred. C may not be an easy language, but with the right tooling you can make code safer, and idioms like parse-dont-validate possible.