4 ms·
No. It's that when people who prefer type systems go to use a popular dynamic language, they try to drag in features that they like from other languages. Very
by btilly 2y ago
No. It's that when people who prefer type systems go to use a popular dynamic language, they try to drag in features that they like from other languages.
Very honestly, optional type systems tend to be the worst of all worlds. Because people who don't care, don't need to use it, you don't get safety. But people who enjoy ceremony can inflict verbosity on others. While missing the most important reason to do it.
- paulddraper 2y agoOptional types are the best.* I can prototype, script, move fast. Then I can solidify, stabilize, collaborate. * To get top performance, of course you'll need compiler, types, static dispatch.
- binary132 2y agoI find that good types help me model the problem and solution with clarity, and the procedures and functions take a back seat. After all, most procedures are just transformations of structured data, so putting the datastructure first makes good sense and keeps the code clean and lean. I used to believe in the “moving fast with no types” thing but in practice I find myself modeling the problem either way, it’s just clumsier without strong types.
- paulddraper 2y agoIt depends how large the problem is.
- josephg 2y agoYep. And even when prototyping, I make a lot more dumb mistakes without a type checker watching my back. It’s amazing how quickly a few interfaces / typedefs repay the time you spent typing them in.
- btilly 2y agoCommon Lisp was the first language I'm aware of with optional typing. In theory, what you're saying is true. In practice there's a lot of pressure to ship the working prototype, and retrofitting types on it later doesn't actually happen. The result was a reputation for being slow. (This was back when computers were slow enough that the overhead of being dynamic was pretty painful.)
- paulddraper 2y agoYep, hence the perf caveat.
- binary132 2y agoI’m not into the whole optional typing thing either. I would consider that far down the “worse typesystem” end of the spectrum I mentioned, only slightly better than “types are just arbitrary labels the language doesn’t even know about”, which is maybe even worse than lean dynamic typesystems, because you might make the mistake of believing in the shadows on the wall.
- jimmaswell 2y ago“types are just arbitrary labels the language doesn’t even know about” is ok if you're aware of the limitations. I add typedefs and other jsdocs to javascript just because it makes it easier to work with in an IDE. it's nice to hover over a variable and see what it's "supposed" to be (if all went well this object should have a .id, might have a .name, etc), sometimes even declared as two types like "this variable is either an int or a boolean". I don't really want to bother learning typescript or trying to get coworkers to do so/put it in the pipeline so it's the best I can do and it certainly makes life a bit easier.
- pistoleer 2y ago> if all went well this object should Why not make it easier for yourself and be able to turn that into > The compiler will tell me when this object won't
- jimmaswell 2y agothe JavaScript language standard is sadly out of my control, and I'm stuck with it.
- gklitz 2y ago> No. It's that when people who prefer type systems go to use a popular dynamic language, they try to drag in features that they like from other languages. Very much. The “problem” people try to solve with things like dependency injection isn’t even a problem in python. 99.99% of the time you can just import you dependencies everywhere they are needed. So many times now I’ve had to unteach bulky OOP patterns for people coming from strictly typed languages to python believe are “good practices” or are “needed for reliable code” and you go from 20 different interdependent classes down to 3 functions that just directly do what they are supposed to do. And you always end up with someone being disappointed that all of these complex patterns they learned to solve problems that don’t exist in python aren’t needed, rather than someone just happy that you can proceed directly to a value adding solution and skip the crud and design pattern spam. And then they start arguing crazy stuff like the 200 extra lines unneeded code makes the solution “more readable” or “more reliable”, when in reality it’s just a desire to use the solutions they are used to even when the problems don’t exist.
- indigo945 2y ago> The “problem” people try to > solve with things like > dependency injection isn’t > even a problem in python. > 99.99% of the time you can > just import you dependencies > everywhere they are needed. That's... Just not the problem DI fixes in any language? Sure, in C++ or Java you can just create a global static instance and use that everywhere. That's pretty much equivalent to just importing the same thing everywhere. But the downside of both approaches is testability: it becomes much harder to test units in isolation when they access global resources. Consider a function with `import datetime`, that gets the current time and does something with it. You want to make sure that this function still does the right thing in the extreme case of the current time being 23:59:59. How do you write this test without DI?
- wizzwizz4 2y agoEasily. from datetime import datetime, timedelta def f(): now = datetime.now() future = now + timedelta(seconds=1) return now.time() < future.time() from unittest.mock import patch with patch('__main__.datetime', spec=datetime, side_effect=datetime) as mockdt: mockdt.now.return_value = datetime(2024, 10, 3, 23, 59, 59) assert f() If `datetime.datetime` were implemented in pure Python, one could even use `patch.object` here, saving a line.
- HelloNurse 2y agoPython type annotations are a good source of lightweight, easy to maintain metadata for many frameworks that provide valuable automatic handling of specific data types (for example defining deserialization and deserialization of nice class types with field declarations, like attrs/cattrs or Pydantic, or defining command line interfaces with function parameter declarations, like Appeal). Expecting type annotations to be more generally useful is mostly projected, baseless declaration anxiety: tools and methods that are useful in other languages are expected to be relevant in Python, certainly comforting for the type-addicted programmer but not necessarily useful. Declaring types is perceived as normal, as a necessary burden and dynamic typing is perceived as missing important structural elements. Consider the error pattern of accessing a value as if it had a different type: in C or C++ consequences are dire (possibly undetected and cascading memory corruption), likelihood is very high due to specific language features (pointers and references, raw arrays, casts, weak typing in general) and detailed type declarations are a useful mitigation because they turn run time catastrophes into actionable compile time reports, while in Python, thanks to robust duck typing without dangerous complications, consequences are mild (reasonable error messages or wrong results, before corrupting memory), likelihood is low (specific instances of unexpected and malformed data or gross API misunderstandings) and type declarations do nothing.