5 ms·
I agree that it can be harder in dynamic languages, but it's a continuum and not a dichotomy. On one end you have completely dynamic languages like Smalltalk w
by mumblemumble 6y ago
I agree that it can be harder in dynamic languages, but it's a continuum and not a dichotomy.
On one end you have completely dynamic languages like Smalltalk where basically everything is late-bound, and it's perhaps hard to imagine that much of anything can be determined statically. On the other end you have completely static languages like ML where the compiler knows all and it's very difficult to escape its all-seeing gaze.
And then there's this huge gulf in the middle where the language leans in one direction or the other, but programmer discipline is perhaps even more important. Python code that's scrupulous about type hinting and doesn't go hog-wild with the metaprogramming, for example, can be easier to refactor safely and with the support of tools than Java code that makes heavy use of reflection might be.
Source: I currently work with, and occasionally have to refactor, examples of both.
- npsimons 6y ago> but programmer discipline is perhaps even more important. Honestly, I think this trumps everything else. If you don't care enough to write good code, you won't. Yes, some languages make it easier than others to write good software, but that won't matter if you're just banging out code without a care. That said, I do miss the typiness of C/C++ when I'm writing Python. I'd be interested to know how one enforces things a bit more strictly, even if it's only by running a separate tool (so something to be run on every checkin via CI, much as I run static linters for C and C++ code).
- mumblemumble 6y ago> running a separate tool That's how. There are so many Python linters out there.
- npsimons 6y ago> That's how. There are so many Python linters out there. Ah, okay. I've been using pychecker, pyflakes and pylint for quite some time, was just hoping there was something more that would help do stricter type checking. I'm aware of python-contract as an orthogonal way to enforce things, but was a little disappointed it's not included with standard python (at work I don't always have the option of installing external packages).
- tech2 6y agoIs using mypy for gradual typing not an option open to you? http://mypy-lang.org/ http://mypy-lang.org/
- npsimons 6y agoIt is at home! Thanks for the pointer!
- jmholla 6y agoThere's mypy[0] which does actual type checking with effort on your end. It is an external dependency, but you've already printed to a few external dependencies you're leveraging. [0]: http://mypy-lang.org/ http://mypy-lang.org/
- npsimons 6y ago"External" is relative; at home, I can install whatever I please, although I do prefer to stick to what is included with Debian stable, which is pretty comprehensive (it includes pychecker, pyflakes, pylint and python-contract). And indeed, mypy is there to! Thanks for the pointer! At work, we are limited (for the most part) to what is included in RHEL repositories, and even more by the fact we are still on 6.9 on some projects. Hence why I mentioned python-contract, as it's not in RHEL repos (that I could find). Thankfully pyflakes/checker/lint are. I will have to check for mypy.
- mumblemumble 6y agoFollow up thought: To me, dynamic features are useful, and a net win for maintainability, when they allow you to write smaller, simpler code. Just picking some magic numbers out of thin air, say I can get the same job one in 100 lines of Python or 1,000 lines of Java. It's likely, if not guaranteed, that the Python code base will end up being easier to maintain in the long run. I think that sometimes maintainability comparisons fail to be entirely fair because they rely on cross-language comparisons of codebases of similar size, rather than of similar levels of functionality. Which is only natural, since substantive opportunities for the latter kind of comparison are rare in the wild, but still. To take a concrete example: The original Smalltalk system was this enormously featureful piece of software, even by today's standards. And it was written in one of the most dynamic languages ever, but it was also famously maintainable. My impression (admittedly based only on poking around at the edges a bit and not actually living in Smalltalk in any serious way) is that the reason for this is that the whole thing was implemented with so little - and such simple - code that, in stark contrast to just about any other GUI environment, it was feasible for a single person to read and understand the whole thing in a reasonable amount of time.
- drchopchop 6y agoPerhaps, but: * As the size of the codebase increases, dynamic languages fare worse. Refactoring 10K lines of Python in a sweeping fashion is much harder than 100 * How many of those 1000 lines of Java are boilerplate, and could be generated/hinted at by IDE's? * The more you're abstracted away from what's actually going on (types, memory, etc), the harder it is to optimize for performance, or even let it become part of your initial design/thought process. This rears its head later in the process * How much does static analysis prevent you from creating bugs in the first place? If it takes longer to write error-free code, then the line count comparisons aren't always that meaningful
- Nextgrid 6y agoI'd argue that if the code is boilerplate and can be auto-generated then it shouldn't be necessary in the first place, the compiler should be able to infer it by itself.
- drchopchop 6y agoGood points, and I agree that it's a continuum. Ease of development comes at a cost - the cuteness of Ruby is great for enumerables and lambdas, but also allows you to shoot yourself in the foot. Personally, I don't think type specifications are incredibly onerous, and I'd rather err on the side of a compiler catching my dumb typo instantly, instead of waiting for a 15-minute CircleCI run to finish.
- scroot 6y ago> And then there's this huge gulf in the middle There are some interesting experiments in the Smalltalk world right now with a kind of "gradual" typing. Because Smalltalk uses and image and VM, as you use the system you can see what "kinds" of objects are passed with specific messages. The system then builds up a knowledge base about what works and what doesn't, and you can make use of that. It's pretty cool!