5 ms·
> If your code is making some assumption about its input, it should validate that that assumption is true rather than assuming nobody will call it the wrong way
by andybak 9y ago
> If your code is making some assumption about its input, it should validate that that assumption is true rather than assuming nobody will call it the wrong way
This kills readability. Stuff like that belongs in tests. Code should express the intent and logic and anything extraneous should be abstracted away or not be there at all. Code should aspire to reading like pseudocode.
- dragonwriter 9y agoIf its “private” code that is not externally exposed, that may be tolerable though it increases coupling and may harm maintainability, especially if the system is large enough to have different teams supporting the function vs. some or all of the call sites. If it is publicly exposed, you are more likely to need to validate assumptions (if they aren't statically enforced), otherwise you are prone to creating undefined behavior.
- emodendroket 9y agoHow are tests supposed to prevent new callers from violating the assumptions?
- andybak 9y agoI wasn't thinking about library code but I guess that's a fair point. However I just don't recall this being enough of a problem in real world situations. And I don't recall many Python libraries that bother to do this. I just looked through a few stdlib functions and other popular libraries and I'm not seeing much trace of validity checking as a standard working practice: > from random import randint > randint(1, "strawberry") TypeError: cannot concatenate 'str' and 'int' objects This fails further down the stack - and would succeed for any types that allow addition with an int (and might fail somewhere further on in those cases) This aligns with Python's encouragement of duck typing but directly contradicts what you seem to be claiming as a universal best practice?
- emodendroket 9y agoI haven't worked in Python, so I can't speak to what Python programmers typically do. But I would much rather get an intelligible error like "you passed a float to the doMath function when it expects an int" or even "the 1st argument to the doWork method must implement the toFoo method" than that kind of error, because the fix is immediate and obvious. I'd prefer that even if we're talking about something that isn't really "library code." It may well be true that most people with this kind of view gravitate away from working in Python; I certainly hated working in Ruby.
- andybak 9y agoMaybe that's it. That error is fairly obvious to me but I admit in some cases you have to traverse the call stack to figure out where the incorrect value got introduced. I still feel I'd prefer the occasional inconvenience in tracking down a bug over some of the pain I've experienced in trying to adapt my brain to a statically typed language. As another poster commented it really only makes sense to compare a cutting edge dynamically-typed language with a cutting edge statically-typed language if you want to debate the strengths and weaknesses of each. Otherwise you're just comparing specific language weaknesses and strengths.
- emodendroket 9y agoI don't know; to me it doesn't seem like much of a cognitive tax to have some guard clauses that can easily be ignored at the beginning of a function and declaring arg types is less annoying than digging through a method trying to figure out what in the world the expected input is. It gives you a way to look at a pretty minimal portion of the code to figure out how to use it and otherwise treat it as a black box, ignoring the implementation details (well, ideally; of course there is some leakage).