3 ms·
I like this advice, and yeah, I always try to make illegal states unrepresentable, possibly even to a fault. The problem I run into here is - how do you create
by 12_throw_away 1y ago
I like this advice, and yeah, I always try to make illegal states unrepresentable, possibly even to a fault.
The problem I run into here is - how do you create good error messages when you do this? If the user has passed you input with multiple problems, how do you build a list of everything that's wrong with it if the parser crashes out halfway through?
- ambicapter 1y agoMost validation libraries worth their salt give you options to deal with this sort of thing? They'll hand you an aggregate error with an 'errors' array, or they'll let you write an error message "prettify-er" to make a particular validation error easier to read.
- Thaxll 1y agoThis work if all errors are self contained, stoping at the first one is fine too.
- pmarreck 1y agoRight, but that's validation, and this article is talking about parsing (not validating) into an already-correct structure by making invalid inputs unrepresentable. So maybe the reason why they were able to reduce the code is because they lost the ability to do good error reporting.
- jpc0 1y agoHow is getting an error array not making invalid input unrepresentable. You either get the correctly parsed data or you get an error array. The incorrect input was never represented in code, vs a 0 value being returned or even worse random gibberish. A trivial example: 1/0 should return DivisionByZero not 0 or infinity or NaN or whatever else. You can then decide in your UI whether that is a case you want to handle as an error or as an edge case but the parser knows that is not possible to represent.
- lmm 1y agoYou parse into an applicative validation structure, combine those together, and then once you've brought everything together you handle that as either erroring out with all the errors or continuing with the correct config. It's easier to do that with a parsing approach than a validating approach, not harder.
- Ygg2 1y agoParsers can be made to not fail on first error. You return either a parsed structure or an array of found error. Html5 parser is notoriously friendly to errors. See adoption agency algorithm.
- akoboldfrying 1y agoAgree. It should definitely be possible to get error messages on par with what TypeScript gives you when you try to assign an object literal to an incompatibly typed variable; whether that's currently the case, and how difficult it would be to get there if not, I don't know.
- ffsm8 1y agoI think you're looking at it too literally - what people usually mean with"making invalid state unrepresentable" is in the main application which has your domain code - which should be separate from your inputs He even gives the example of zod, which is a validation library he defines to be a parser. What he wants to say : "I don't want to write my own validation in a CLI, give me a good API already that first validates and then converts the inputs into my declared schema"
- 8n4vidtmkvmk 1y agoZod might be a validation library, but it also does type coercion and transforms. I believe that's what the author means by a parser.
- goku12 1y agoApparently not. The author cites the example of json parsing for APIs. You usually don't split it into a generic parsing into native data types and then validate the result in memory (unless you're on a dynamically typed language and don't use a validation schema). Instead, the expected native data type of the result (composed using structs, enums, unions, vectors, etc) is defined first and then you try to parse the json into that data type. Any json errors and schema violations will error out in a single step.
- MrJohz 1y ago> I don't want to write my own validation in a CLI, give me a good API already that first validates and then converts the inputs into my declared schema But that _is_ parsing, at least in the sense of "parse, don't validate". It's about turning inputs into real objects representing the domain code that you're about to be working with. The result is still going to be a DTO of some description, but it will be a DTO with guaranteed invariants that are useful to you. For example, a post request shouldn't be parsed into a user object just because it shares a lot of fields in common with a user. Instead it should become a DTO with the invariants fulfilled that makes sense for a DTO. Some of those invariants are simple (like "dates should be valid" -> the DTO contains Date objects not strings), and some will be more complex like the "if the server is active, then the port also needs to be provided" restriction from the article. This is one of the key ideas behind Zod - it isn't just trying to validate whether an object matches a certain schema, but it converts the result into a type that accurately expresses the invariants that must be in place if the object is valid.
- adinisom 1y agoIf talking about UI, the flip side is not to harm the user's data. So despite containing errors it needs to representable, even if it can't be passed further along to back-end systems. For parsing specifically, there's literature on error recovery to try to make progress past the error.
- geysersam 1y agoMaybe you can use his `or` construct to allow a `--server` without `--port`, but then also add a default `error_message` property. After parsing you check if `error_message` exists and raise that error.
- mark38848 1y agoJust use optparse-applicative in PureScript. Applicatives are great for this and the library gives it to you for free.
- bradrn 1y ago> Just use optparse-applicative in PureScript. Or in Haskell!