4 ms·
I never got it, but on a reread: > Is it really parsing anything, or is it merely validating its input and returning a result? Ok. Now I guess I’m on board. J
by dfee 4y ago
I never got it, but on a reread:
> Is it really parsing anything, or is it merely validating its input and returning a result?
Ok. Now I guess I’m on board. Just feels like the word is wrong.
> Consider: what is a parser? Really, a parser is just a function that consumes less-structured input and produces more-structured output. By its very nature, a parser is a partial function—some values in the domain do not correspond to any value in the range—so all parsers must have some notion of failure.
Ok. It still feels like there’s a better word. “Constrain” might sit better with me, though I’ve not spent enough time to really worry about its fit.
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/ https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-va...
- Snarwin 4y agoMaybe "decode"? As in "decode a Unicode string", or "decode a JPEG image", or "decode an MP3 audio file."
- lalaithion 4y agoThe key of the idea is you're not asserting that predicates on values are true, you're recognizing whether a value (of a type with few guarantees) conforms to the guarantees of a type (implicitly, a type with more guarantees), and transforming the value into a value of the output type. Parsing might not be the right word, but it's definitely an example of the above; we transform a string into a tree of tagged nodes.
- aatd86 4y agoYes, I think another simpler way to do it is to have a set theoretic interpretation of types with subtyping. In which case, we can check that a variable can be type-asserted to a given subtype. A (sub)type being a set of propositions (i.e. defines a set of values).
- gavinray 4y agoI didn't get it any of the times I read it either FWIW, it just randomly clicked one day for me while coding and I connected it back to the article I'm not the smartest tool in the shed, if I could dumb it down a little (sorry Alexis, and hopefully I'm doing you justice here!), I think it boils down to this: In many programs, you have logic like the below: function processOrderRequest(items: List<Item>, customer: Customer) { if (items.isEmpty()) { throw new IllegalArgumentException("Items cannot be empty") } if (customer.isBanned()) { throw new IllegalArgumentException("Customer is banned") } // ... orderAPI.placeOrder({ // .. final order object with some logic }) } This makes sense, but if you look at it another way, what you're trying to encode is some function like this: function processOrderRequest( items: ValidatedItemList, // A non-empty list of items we've know are okay to send customer: VettedCustomer // A customer we've vetted and know is okay to place an order ) -> PlacedOrderRequest { // ... } What this does is allow you to move the domain of validation away from the fragile business logic of your program, and into the deeply-embedded domain of your data types. It also allows you to control and refactor the validation logic much easier, since they live in your data-types and at boundary points Once I grokked this I was like, whoa. Neato idea.
- ohwellhere 4y agoRather than "parsing", is it a form of type casting? To me it feels like downcasting in OOP from a parent class (more general) to a child class (more specific). In Swift there is the "conditional downcast" operator `as?` which does what the article discusses with the potentially failing conversion to `Maybe thing`: it returns the new more constrained as `.Some(thing)`, or returns `.None` if it is not the appropriate type. You can also go between non-hierarchical types with casting in most languages, like from ints to floats to strings, etc. Following from all of that and your language suggestion, I might call the practice a "constraining type cast". --- Although, all of that written, and I expect it's conversion rather than casting.
- dkersten 4y ago> It still feels like there’s a better word. “Constrain” might sit better with me, though I’ve not spent enough time to really worry about its fit. In clojure’s “spec” library, it’s called “conform”. Confirm will validate and parse the input data based on the supplied spec and will either return a special “invalid” type or a structured value based on the structure the spec defined (which often pulls things out of the input data structure and returns this data as named fields in an output data structure — basically it passes abr structures the input).