4 ms·
It looks over-engineered, complicated and non-intuitive. In 90% of cases, vanilla business logic will be concise enough. I've used validation modules like Meteo
by anonytrary 8y ago
It looks over-engineered, complicated and non-intuitive. In 90% of cases, vanilla business logic will be concise enough. I've used validation modules like Meteor's check[0] before, and I think that's a good example of how much surface area a validation library API should have.
[0] https://docs.meteor.com/api/check.html https://docs.meteor.com/api/check.html
- coldtea 8y ago>It looks over-engineered, complicated and non-intuitive. In 90% of cases, vanilla business logic will be concise enough Typical top HN comment. Yeah, very complicated: v8n() .number() .between(0, 100) .even() .not.equal(32) .test(74); // true
- anonytrary 8y agoApart from the contrived example you cited, why do we need an abstraction for detailed value checking? Conditional statements are already a thing. Just use modules and readable function names: // helpers.js const isNumber = typeof n === "number" && isFinite(n) const isTestScore = n => isNumber(n) && n >= 0 && n <= 100; // business-logic.js const uploadScore = (n, cb) => { if (!isTestScore(n)) return cb(new Error("invalid test score")); // super contrived, but let's do it if (n === 32 || n%2) return cb(new Error("we don't like oddities and we hate 32")); // do something with valid test score n } IMHO, a validation library should validate types and structure and should know nothing about the specific values of your data. The values are likely relevant to your business logic and should be handled there for finer-grained error handling, logical branching, etc.
- coldtea 8y ago>Apart from the contrived example you cited, why do we need an abstraction for detailed value checking? We don't "need" an abstraction for anything, in the sense that we need oxygen. We _want_ abstractions, and they usually make us more productive, which is something different. Case in point the above horribly noisy procedural code for something that this library abstracts into neat, purpose specific, calls. I think the code answers its own question.
- anonytrary 8y agoWhat happens when you want to know why your value failed the test? Easy, just break up your chained v8n call into smaller chunks and handle each one individually -- but wait, now we're back to the same procedural code we started with! Never fear; the devs implement hooks that let you do something when a certain part of the chain fails. Cool -- but now all of our code is tightly coupled to the structure imposed by the hook syntax. Okay, better solution: how about an array of "reasons" is returned that tells you why your test failed. Now we've got to tell v8n what reason text we want (if any) for each part of the chain that fails, so we're back to having to declare a bunch of messages somewhere, which is what people already do. Yeah, we want abstraction, but we want the right abstraction. Premature generalization/abstraction is a common pitfall among even the best developers. This library could be useful for some cases, but I'm not convinced it should be used for everything it can be used for. Is this 32?
- coldtea 8y ago>What happens when you want to know why your value failed the test? Easy, just break up your chained v8n call into smaller chunks and handle each one individually You seem confused. You just need to substitute .check() instead of .test() and you get a ValidationException if your value doesn't validate that tells you exactly which rule failed. And that's just the two two basic result values (true/false on validation or Exception) that the devs implemented. Nothing in this kind of design prevents returning any kind of detailed error or array of errors etc if one wants too. >kay, better solution: how about an array of "reasons" is returned that tells you why your test failed. Now we've got to tell v8n what reason text we want (if any) for each part of the chain that fails, so we're back to having to declare a bunch of messages somewhere Woooosh. The validation library is not about not having to write our own messages for the user. It's about not writing our own tests when the dozens of built-in ones are just as good. Plus they give structure that's better than a bunch of if/elses. >Yeah, we want abstraction, but we want the right abstraction. Premature generalization/abstraction is a common pitfall among even the best developers. Premature generalization/abstraction? You might be seeing this pattern for the first time, but this library follows a very standard pattern for validation libraries, that has been with us, and used in tons of production code, for over 2 decades. Apache Commons did that since ages. Even the fluent interface take on such libs is nothing new.
- coldtea 8y agoYou even answered your own question. Your validation code is 293 characters and 8 lines, the example code is 95 characters and 6 lines and does more tests. And that's not even including your helpers which if one uses that lib, they wont have to write. So, you wrote like 4 times the code, and made it even less flexible (eg. hardcoding the test for 100 in your isTestScore check).
- sidlls 8y agoThat's terrible for the amount of superfluous text that has to be written for this test.
- coldtea 8y agoNot sure what you even mean.
- deleted 8y ago[deleted]
- btown 8y agoIt’s the AppleScript Uncanny Valley: the closer you get to allowing all natural language in your programming language or API, the more likely it is that users will be confused, because they expect something to be possible and it isn’t. This feels similar.
- sbr464 8y agoCheck and Match are so well written. JSON schema/ajv also. Validation shouldn’t rely on a module/codebase to work and should be able to be built dynamically or stored in a database without needing eval/hacks. Runtime validation is important, not just dev experience/typescript.