3 ms·
Ever so slightly longer compile times. It's pretty close to a free lunch. There are only tradeoffs when we are at the frontier of what's possible with a set of
by maxbond 4y ago
Ever so slightly longer compile times. It's pretty close to a free lunch.
There are only tradeoffs when we are at the frontier of what's possible with a set of technologies, and so must trade off on something in order to move along that frontier[1]. Many languages aren't operating at that frontier, and adding static typing is free (in the marginal case, ignoring the substantial effort to implement the type system). If you start a greenfield Python project, and you start typing right away and incorporate MyPy into your CI and IDE - it's as close to free as you can get, and the benefit is substantial.
[1] Eg, like in this diagram, http://image1.slideserve.com/2488675/production-possibilities-frontier-graphical-form7-n.jpg http://image1.slideserve.com/2488675/production-possibilitie... - we only need to trade off on guns & butter if we're along the frontier (the blue line), if we find ourselves somewhere in the middle we can just make more stuff until we reach the frontier.
- closeparen 4y agoPeople using dynamic languages deeply, especially library and framework authors, regularly write abstract/generic code for which a suitable type declaration would be mind-bendingly difficult in a very sophisticated type system and impossible in a weak one. You can argue that this is ill-advised! But static typing with normally-powered type systems leads to more voluminous and more purpose-specific code. Very powerful type systems are possible, but treated as academic and too difficult to use in the real world. A way this often gets worked around is code generation. Anywhere you have or reach for codegen in a static language, you probably could have used a plain old function in a dynamic language.
- maxbond 4y agoThank you for the thoughtful response; this is something I had failed to consider (since, as you anticipated, I try to avoid creating deep or highly dynamic abstractions), and I do regularly throw in the towel on complex or deeply nested types (either by just omitting them out using a "close enough" type in Python, or by using trait objects in Rust - looking at you, `Map<Chain<RangeInclusive<...>>>`).
- throwaway2037 4y agoCan you provide a concete example? If you do, I am sure Rust/C++/C/Java/C# programmers can show you how to implement in their language.
- maxbond 4y agoNot GP, but for instance, Python web frameworks are oriented around decorators, and Rust web frameworks are oriented around macros. The syntax looks pretty similar, but like GP says, in dynamic languages you're using a (higher order) function, and in static languages you're using code generation for the same purpose.
- throwaway2037 4y agoI am confused. "Code gen" is a fuzzy concept once you have a virtual machine because you can do it at runtime. This is how mocking works in Java and C#. What you describe already exists in Java and C# -- decorators for web frameworks. I would not describe Java nor C# as dynamic. I describe them as "stricter" (types) and Python as "weaker" (types). To quote Norman Ramsey: "Every time I see a question about "strong" or "weak" typing, I kill a kitten." :-)
- LEDThereBeLight 4y agoI think this is a little disingenuous. It’s not that the type system makes highly abstract/generic code difficult, it’s more that the specific ways people are used to writing that type of code in dynamically typed languages doesn’t lend itself well to adding type annotations. But I think you’d be hard pressed to find many places where Haskell programmers, for example, haven’t found a different way to express whatever the Python code is achieving while also allowing for type annotations.