5 ms·
This illustrates one of the biggest downsides of dynamic languages - refactoring. Compile-time checking saves you from having to detect copy/paste/delete errors
by drchopchop 6y ago
This illustrates one of the biggest downsides of dynamic languages - refactoring. Compile-time checking saves you from having to detect copy/paste/delete errors at runtime. A good IDE can help, but it's no substitute.
This is especially problematic in Ruby, as the author mentions, as the language is so dynamic that you're stuck having to write 100% coverage to ensure that variables are even named correctly.
- horsawlarway 6y agoI don't really know how much type systems help here. I'm not really aware of a type system that enforces code actually be called. I know lots of linters do check for unused code, but generally only at the local level (ex - you imported/included X but never called it) I agree 100% that it saves time during refactoring, but it's not going to catch that your NicheHelper class that was only called in one place is not called anymore. Nor is it going to find and highlight css that can be ditched as well.
- thrower123 6y agoAll of the JetBrains tools will do complete project analysis and find unused code, and Visual Studio is approaching this level of functionality out of the box - with extensions and Roslyn plugins it is possible to do some very powerful checks. Dynamic language tooling is really like banging goddamn rocks together, and people take pride in that...
- PaulKeeble 6y agoPMD for Java does as well with the right settings.
- Scarbutt 6y agoI will take a dynamic language over bad statically-typed languages any day, no matter how good the IDE is.
- thrower123 6y agoWhy? I cannot comprehend this mindset.
- sullyj3 6y agoThe difference is that you can delete code with confidence that the compiler will tell you if you did something wrong, rather than things failing at runtime at some indeterminate point in the future.
- steveklabnik 6y agoIt depends on exactly what you mean by "called." Rust will warn you if your function is: * Not marked public * Not called from somewhere in the call graph of a function that's marked public, or your main function. This isn't just simply public though, to be clear. It's "externally callable," that is, it can see transitively if something is just locally public or not. You also can't dynamically generate functions at runtime, or do things like method_missing, so this ends up being much more complete than a similar analysis in a language with those sorts of features.
- cgenschwap 6y agoYou're right the type system isn't really the solution for catching dead code. But compilers can easily check for this, if the language is restricted enough. The issue with a lot of dynamic languages is things like monkey patching and reflection, which means that functions can be called at runtime but otherwise there is no way of checking beforehand. Some people swear by this dynamic flexibility and the benefits it brings, but there are some serious downsides in terms of refactoring.
- marcosdumay 6y ago> but it's not going to catch that your NicheHelper class that was only called in one place is not called anymore Your NiceHelper function gets one type as argument and returns the same type? Is it `void NiceHelper(...)`? Severely restricting the number of `void X(...)` functions on your code helps a lot. Also `a someF(a)` is a type that is useful once in a while, but if it's useful all the time something may be broken.
- mumblemumble 6y agoI 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).
- soheil 6y agoYou can turn most dynamic languages into a strict compile-time-like language with all the checks thrown in your face usually by turning on a simple setting (eg. in php: error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE); ruby has something similar.) You cannot turn a compiled language into a language that offers the same flexibility as a dynamic language.
- tomjakubowski 6y ago-fdefer-type-errors begs to differ. https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#defer-type-errors https://downloads.haskell.org/~ghc/latest/docs/html/users_gu...
- soheil 6y agoMaybe Haskell does allow that but most compiled languages don't.
- blast 6y agoThis argument is weakened by the fact that the first refactoring tools were produced for Smalltalk, years before anything similar appeared for static languages. And then it took many years of development before the tools for Java etc. caught up.