4 ms·
One pattern that eliminates a lot of such bugs is never using any name that's a keyword or common name in any mainstream programming language. The existence of
by hansvm 2y ago
One pattern that eliminates a lot of such bugs is never using any name that's a keyword or common name in any mainstream programming language. The existence of `def set...` in your code was already asking for trouble, and you were unlucky enough to find it.
- maxbond 2y agoI agree, but this is a method on an object in the standard library! https://docs.python.org/3/library/asyncio-sync.html#asyncio.Event.set https://docs.python.org/3/library/asyncio-sync.html#asyncio.... Could've been called fire() or activate(), perhaps. This is also the kind of problem lints are really good for. I wouldn't be surprised if there was an lint for this already (I haven't checked).
- hansvm 2y agoOh that's annoying.
- bobbylarrybobby 2y agoThis is ridiculous, not having access to a set() method is just silly. Also I'd imagine that most languages use another language’s keyword for functions to name a callable variable, func being (I'd assume) a particularly common name. match is a perfectly good name for the result of a regex search... etc etc. The real issue here is simply that python didn't camel case its built in class names; then this would only be a problem if you violated case conventions and named your method Set() (or mistyped the case as well).
- hansvm 2y agoThose are perfectly good names, but it's also incredibly easy to avoid a few hundred words. `f` or `predicate` or what have you are easy names for functions as arguments, and something like `maybe_match` or `maybe_parsed_username` is more likely to represent the results of an arbitrary regex. You absolutely don't have to follow every piece of advice you read, but I'll argue for it once more anyway. My guiding principle is that I make mistakes from time to time, and those mistakes are incredibly expensive when they hit prod. If two things need to change in tandem then I'll derive one from the other in code (or at an absolute bare minimum put comments in both locations warning that they need to be changed in tandem, though with modern language features that's rarely necessary for any reason nowadays) (guaranteeing they actually change together). If I don't need the result of a function call I'll still give it a name and explicitly discard it (adding redundant bits of information for future readers -- indicating that I ignored the result intentionally and also reducing future git blame search time in case the result is ever valuable or the API changes). When a chunk of data has some constraints beyond being an arbitrary primitive I create a wrapper type (free at runtime in any system language) to let the compiler double-check my work. Those are all small things, but with a short library of such patterns the code I write is almost always correct if it compiles, and none of those habits are particularly hard to develop. Not using potentially reserved words, similarly, reduces the chance of certain errors. Kind of like the swiss cheese model in aviation, you add one extra (fallible) layer of redundancy against bugs like foo,set(). Since it's a cheap mitigation, it's one I follow unless I have an amazing reason to do otherwise. Yes, Python could have named things differently, but that ship has sailed. If I'm using Python (and it winds up being a good choice a few times a week currently) then I have to work around those design issues.