6 ms·
The problem with verbosity and repetition is not that it takes longer to type the code, at all. The problem is that it creates dependencies which you have to ma
by one-more-minute 12y ago
The problem with verbosity and repetition is not that it takes longer to type the code, at all. The problem is that it creates dependencies which you have to manage by hand.
Changing `Foo a = new Foo()` to `Bar a = new Bar()` doesn't seem that bad... except when you have to propagate that change through the code base. Half of Java's tooling is dedicated to solving a problem that doesn't exist in good duck-typed languages or those with type inference.
Verbosity is also a warning sign for lack of expressive power. If you have a pattern like `if (cmd == "run") run();` in multiple places in your codebase, you want to make it so that changing one changes them all. Java won't let you factor this out easily, but worse, it won't catch you when you make a mistake (better languages will either do first-class functions or pattern matching and exhaustiveness checks).
Note that this has nothing to do with static vs. dynamic; verbosity is a problem that can be solved in many ways, but it is a problem. The author also spends a lot of time equating statically typed with fast; well, there are plenty of very fast dynamic languages.
There certainly are reasons to like Java, but these aren't them.
- rzwitserloot 12y agoDISCLAIMER: I write mostly java, at home and at work. Refactoring goes a lot further than just renaming types. A refactor script _WILL_ rename both sides of 'Foo x = new Foo();' to 'Bar x = new Bar();', so given the right utilities (and if you use java for everything, it's _MUCH_ easier to become an expert at the tools!) this is not any more effort at all. However, there are refactors for things that are much more difficult in a duck typed language. For example, if I have a bunch of methods named 'execute()' in my code, and I decide that this is a sad state of affairs and ripe for a refactor, I can refactor one of them to a different name and the tools will 'get it right', renaming the right calls (calls into this type) and not renaming the wrong ones (calls to another type's execute() method which has no relation to this type's execute() call). In python, you just can't do that. You'd have to rename all of them, defeating the point. Similar concerns crop up for 'find callers', or 'add argument to method'. There are also refactor scripts that are equally possible in both python and java, but which nevertheless require either a lot of manual editing, or an intelligent tool that can automate it, such as 'extract method' (taking the selected code and turning it into a (helper) method, figuring out which variable(s) would have to be passed along to make it all work as needed. The point is: Duck typing does not obviate the need for refactors. It does make certain refactors impossible to 'safely' automate ('safely' in the sense of ensuring that, post-refactor, the code does the same thing as it did pre-refactor). As far as 'dynamic == slow, static == fast' being a bit of an oversimplification, yup, that's true. Java _IS_ a heck of a lot faster than python, but that's mostly an implementation detail; you could make a pretty quick python. dynamic definitely does not help, but it can be worked around. Javascript JIT engines are seeing a lot of serious improvements right now, and a large part of it is guesstimating type info. They're getting pretty fast. In the spirit of the article, though, static typing isn't just a boon for speed reasons (based on the practical upshot that java IS fast, and most dynamic solutions simply aren't, even if they could be with more engineering efforts): It becomes quite useful when you start having to read the additions to your code written by someone else, or rereading your own code half a year down the line when updates are required. explicit static typing also helps with refactoring, which is useful especially when you have to fix or extend your project.
- desdiv 12y agoRefactoring goes a lot further than just renaming types. A refactor script _WILL_ rename both sides of 'Foo x = new Foo();' to 'Bar x = new Bar();', so given the right utilities (and if you use java for everything, it's _MUCH_ easier to become an expert at the tools!) this is not any more effort at all. Ctrl-Shift-R B A R No, not much effort at all. Just twice as many keystrokes. I wouldn't even mind the verbosity if it actually gave me some speed improvements, but it doesn't. There are plenty of statically typed languages where you just write x = new Foo() and the compiler will figure out the types for you.
- pjmlp 12y agoF2 on my IDE. One key, no need for Ctrl-Shift-R
- mytochar 12y agoOne hand position still over the keys and uses common fingers, and is easy for emacs users (Ctrl + Shift + R), versus leaving the typing keys entirely to climb to a command key that's used sufficiently infrequently that you have to look at where it is. At least that's my experience. Oh, and more fun. If you're on a modern keyboard, you have to type the function key since apparently volume up and down and expose are more important than function keys. Long story short: what's faster and 'less' for some, is more for others. And this is why we have options! :D
- tormeh 12y agoIt will give you faster compilation speed, though.
- desdiv 12y agoThink about it, does it really? To parse Foo x = new Foo();, javac has to perform type inference on the right hand side to figure out its type, and then check whether that type is a subtype of the left hand side. Telling the compiler: "hey, trust me, variable x is of type Foo" doesn't make the compiler's job any easier at all.
- jim_greco 12y agoIt's a pain when you are first learning and typing every keystroke, but with a modern IDE (IntelliJ) you don't really need to worry about things like this.
- KajMagnus 12y agoIn the strongly typed language Scala you get the same benefits as in the duck type languages, and even better :-) You can do: val usersById = HashMap[UserId, User]() if elsewhere you have defined: `type UserId = String`. This is very readable I think :-) And changing the type of UserId is done in one place only.
- pimlottc 12y ago> Changing `Foo a = new Foo()` to `Bar a = new Bar()` doesn't seem that bad... except when you have to propagate that change through the code base. Half of Java's tooling is dedicated to solving a problem that doesn't exist in good duck-typed languages or those with type inference. A sweeping change like that is hard in Java, but it's nearly impossible in Python. That is, unless you're willing throw up your hands and assume your new duck looks enough like the old one, and cross your fingers that you don't find out in production one day. With a modern IDE like Eclipse, it's a fairly trivial matter to find all references to the class, navigate call hierarchies and make the necessary changes to adapt to the change in type. In a sizable Python program, good luck. You're pretty much forced to rely on string searches - hope you picked a distinctive function name - or interactive debugging. Ease of refactoring is a huge win for static types IMHO.
- one-more-minute 12y agoI'll be the first to agree that Java-style class hierarchies and duck typing don't mix well, but not every dynamic language is Python. Clojure, for example, is very easy to refactor when it's (very rarely) necessary. Not saying static typing doesn't have it's advantages – tooling is probably Java's greatest strength – but there are other, equally valid, solutions to the problem.
- SixSigma 12y agoThat's why I like Limbo and later Go's implicit typing: a := Foo(): a now has whatever type Foo() returns. If you change the definition of Foo then you don't have to cascade your type change through all of your source code.
- diltonm 12y agoI hesitate to even begin to imagine the kinds of bugs this could lead to.
- TheCondor 12y agoIf you are prone to having the "if (cmd == 'run') run();" pattern in multiple places, no language is going to fix your copy pasta and the maintenance issues it has. Java absolutely has mechanisms to fix that and factor it out, it just bs to say otherwise.
- andor 12y agobetter languages will either do first-class functions Modern Java has first class functions. https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html https://docs.oracle.com/javase/8/docs/api/java/util/function...