12 ms·
Java's verbosity made us all hate type systems in the early 2000s so many of us migrated to dynamic languages such as Python, Ruby in the mid 2000s that allowed
by ericmoritz 8y ago
Java's verbosity made us all hate type systems in the early 2000s so many of us migrated to dynamic languages such as Python, Ruby in the mid 2000s that allowed us to work fast and loose and get things done.
After about 10 years of coding in a fit of passion we ended up with huge monolithic projects written in dynamic languages that where extremely brittle.
Fortunately languages with type inference (Rust, Golang, OCaml, Scala, etc) started becoming the answer to our problems. (We also collectively decided that Microservivces were another solution to our woes though that cargo cult is being questioned).
So we have a decade of code and packages written in Python and JavaScript that work well for our use cases (Data Science, MVP web apps/services, Database integration, etc) that is hard to give up. Often because alternatives aren't available yet in the statically typed languages (Hurry up Rust!).
There is often a lot of friction to get new languages introduced. I love Rust, but I don't think I can introduce it into our Golang/NodeJS/Javascript environment anytime soon.
- notheguyouthink 8y ago> I love Rust, but I don't think I can introduce it into our Golang/NodeJS/Javascript environment anytime soon. Rings especially true for my shop as well. I had to introduce Rust or Go, and went with Go. Seeing the mild pushback I get from Go's type system makes me especially glad I didn't choose Rust. ... though, in some cases, Rust+Generics would be easier than Go.
- masklinn 8y ago> Rings especially true for my shop as well. I had to introduce Rust or Go, and went with Go. Seeing the mild pushback I get from Go's type system makes me especially glad I didn't choose Rust. An other possibilities is that Go's static types feel like a lot of ceremony for too little benefit. That was one of my biggest issues with Java, and though Go's lighter it also provides less benefits… By contrast, Rust is in the camp of requiring a higher amount of ceremony but providing a lot of benefits from it (sometimes quipped as "if it compiles it works").
- skybrian 8y agoWhy do you think Go's type has "less benefit" than Java's type system?
- josteink 8y agoJava has generics for one. Failed generics with type-erasure sure, but definitely better than Go which has nada.
- leshow 8y agoType erasure on it's own isn't necessarily a bad thing, Haskell implements type erasure also.
- unscaled 8y agoI guess this was your point, but the problem is how Java does does type erasure. With Haskell type erasure is an implementation detail, but with Java it leaks into the compile-time type checker. For instance, you can't have both these overloads: public void foo(List<String> list) public void foo(List<Integer> list) This just wouldn't compile.
- masklinn 8y agoThe difference is that Haskell has very little RTTI, so you can't really see the missing types at runtime. For Java it's much more noticeable, because runtime type manipulations are way more common.
- adamnemecek 8y agoWell, Go's type system is a butt of many jokes.
- pdeuchler 8y ago>> (We also collectively decided that Microservivces were another solution to our woes though that cargo cult is being questioned) I wouldn't really say that, I think it's more that we all discovered huge monoliths don't work in an "agile cloud" environment where you have 10 teams deploying on their own cadences with no coordination (which you have with on premise binary delivery, or waterfall, or when you have implicit coordination by operations because they have to build out the physical infra). Further, I think modularity has become much bigger in the past 15-20 years as more and more people contribute to open source, more problems become "solved", and languages/domain spaces mature. Whether microservices are the best solution to those observations is still up for debate, but cargo cult or not I doubt many engineers these days would use a magical wand to go back to monoliths even if they live in microservice hell right now.
- tootie 8y agoVerbosity is usually the worst argument against a language. Your coding efficiency is not limited by how fast you can type. I've been using Kotlin recently which is basically just Terse Java and it's very nice but hasn't turned my world upside down.
- kccqzy 8y agoVerbosity absolutely hurts comprehension of code. It's easy to hide hugs in code that seems to be just boilerplate. It also means that given a fixed screen estate you can less of the actual logic of the code at a time.
- BerislavLopac 8y agoI personally love introducing lots of hugs in my code.
- lgas 8y agoWrite hugs, not bugs!
- ethbro 8y agoAbsolutely this. For whomever tells me verbosity isn't a limitation to a language: find me the single incorrect statement in a 100 line function vs a 10 line function. And no cop outs with "I use {bolt-on sub-language that makes parent language more concise}" (that's not a mainstream language then) or "Well, you can just ignore all the boilerplate" (bugs crop up anywhere programmers are involved). Or give me an ad absurdum concise counterexample with APL. :P Ultimately language verbosity is mapped directly to proper abstraction choice. In that the language is attempting to populate the full set of information it needs, and can either make sane assumptions or ask you at every turn.
- Buttons840 8y agoI keep a mental list of the qualities of good code, "short" and "readable" are on the list. I've sometimes wondered whether "short" or "readable" should be placed higher on the list, and I eventually decided that short code is better than readable code because the shortness of code is objectively measurable. We can argue all day over whether `[x+1 for x in xs]` is more or less readable than a for-loop variant, but it is objectively shorter. Of course, it's like food and water, you want both all the time, but in a hard situation you prioritize water. Likewise, in hard times, where I'm not quite sure what is most readable, I will choose what is shortest.
- DoofusOfDeath 8y ago> Java's verbosity made us all hate type systems in the early 2000s so many of us migrated to dynamic languages such as Python, Ruby in the mid 2000s that allowed us to work fast and loose and get things done. You may be overgeneralizing, depending on whom you mean by the term "we". More often than not, the code I've written has to be very well trusted when deployed. For me, "getting things done" means getting to effective and trustworthy code ASAP. Static type systems have been invaluable for that work.
- the_af 8y agoI interpreted the comment as "Java's verbosity made us think all static type systems were also verbose". Which I know is what a lot of people still think ("but the lack of REPL!", "but the boilerplate!", "but the elegant code", disregarding that other statically typed languages have all these features and more).
- bunderbunder 8y agoI don't really want to get into a flamewar about static vs dynamic. I'm a polyglot, I use several languages with multiple flavors of type system, I think that most options have at least a couple things to recommend them. However, the grandparent has a point: Java's type system makes static typing much more painful than it needs to be. I didn't start working in Java until fairly recently, and it was only then that I started to understand how many fans of dynamic languages could say that static typing mostly just gets in the way. But, if the only static language you've spent much time with is Java. . . now I get it. Java's type system mostly just gets in the way.
- jrs95 8y agoFor me it was less about the verbosity and more about the overuse of patterns and general overengineering present in many (most?) Java APIs. Java doesn't strike me as being much more verbose than Go, but the differences in the API designs make a huge difference in how it feels to work with the language.
- erik_seaberg 8y agoGo can be terse if everything is a interface{} and you ignore errors. But production quality Go is huge because there are so many things the compiler won't help with. I want a language that would generate the same boilerplate Go other people spend actual time on writing and reading.
- AlphaSite 8y agoEven java has type inference now.
- duggan 8y agoIt's just as possible to have huge, monolithic, and highly brittle projects written in languages with stronger typing support. The only difference is that you get to eliminate a class of trivial annoyances.
- baq 8y agoyeah, trivial annoyances like AttributeError: 'NoneType' object has no attribute 'method' when you just don't expect it.
- deleted 8y ago[deleted]
- duggan 8y agoJust to clarify, I'm using trivial here in the technical sense. YMMV on what counts as trivial to you, of course, after three days straight tearing your hair out!
- ptx 8y agoRight - this trivial annoyance, the Python equivalent of a NullPointerException, is not actually prevented by the static type system in Java and some other popular static languages. (Kotlin does prevent it, though!)
- leshow 8y agoIf your type system only prevents trivial errors then it's not sufficiently 'strong'.
- scarface74 8y agoThe big difference is that there are tools that allow automatic and guaranteed safe refactors for such languages. For instance, I can't guarantee that something as simple as renaming a method won't cause runtime errors in a dynamic language.
- duggan 8y ago
- deleted 8y ago[deleted]
- pjmlp 8y agoActually I went the other way around. The performance problems dealing with Tcl on a 2000 startup made me never ever again use programming language without JIT/AOT support for production code. To this day, Java, .NET and C++ stacks are my daily tools.
- stcredzero 8y agoJava's verbosity made us all hate type systems in the early 2000s so many of us migrated to dynamic languages such as Python, Ruby in the mid 2000s that allowed us to work fast and loose and get things done. This was actually a replay of what happened with Smalltalk versus C++ in the 80's and 90's, which was a part of the history of how Java came about. And even that was a replay of what happened with COBOL and very early "fourth generation" languages (like MANTIS) from a decade before that!
- tomrod 8y agoI don't know this history. Would you mind expanding on it, or giving a link where I could learn more?
- neves 8y agoC++ is a utterly complex language. Java appeared as an option to simplify programming compared with all the bureaucracy of C++: no need to manage every bit of memory (GC), no multiple inheritance, no templates, no multi-platform hell, a big library included etc.
- fulafel 8y agoSmalltalk was not available to most programmers back then, it needed an expensive machine with a lot of memory and the implementations were very expensive. Apps were also much smaller, so the disadvantages of C were less pressing.
- pjmlp 8y agoIt was already clear by the mid 90's. Bare bones C vs something like Turbo Pascal 6.0 with Turbo Vision framework on MS-DOS 5.0.
- stcredzero 8y agoSmalltalk was not available to most programmers back then, it needed an expensive machine with a lot of memory I was programming back then. It ran just fine on fairly standard commodity hardware from the time 486 stopped being "high end." Also, at one point the entire American Airlines reservations system was written in Smalltalk and running on 3 early 90's Power Mac workstations. the implementations were very expensive. More or less true. At one point there were $5k and $10k per-seat licenses. Apps were also much smaller, so the disadvantages of C were less pressing. There was a major DoD project that let defense analysts do down-to-the soldier simulations of entire strategic theaters. (So imagine this as an ultra-detailed, ultra realstic RTS.) They did this as a competition with 3 teams, one working in C++, one in another language I can't recall, and one in Smalltalk. The Smalltalk group was so far ahead of the other two, there was simply no question. That was a complex app. There were countless complex financial and logistics apps. So, small apps? Not so much.
- dllthomas 8y agoI think that "Java bad" isn't all of the story of the move away from static type checking. Type checking in programming probably originated, and certainly featured prominently, in selection of representation of values. I think it's a valid insight of the dynamic camp that for most purposes we don't care how things are represented so long as we know how to work with them. What's often missed is that types can be a powerful tool for talking about other things, too.
- dep_b 8y agoStatic typed languages are harder to test. So if you do cover 100% dynamic is not so bad. However well built static languages reduce the things that need to be tested in the first place. Like non-nullabilty in Kotlin and Swift.
- hugofirth 8y agoI have to ask: what makes you think that staticly typed languages are harder to test? My experience is precisely the opposite. Large testing codebases can benefit hugely from the increased refactorability. In addition, the types help to explicitly define the contracts you need to test.
- majewsky 8y agoI think what dep_b refers to is that, in dynamic languages, you usually have an easier time injecting mocks and doubles. In a staticly typed language, it's usually much harder to inject mocks for IO, network, clock, etc., unless the original code has already been written to afford that (e.g. that whole Dependency Injection mess in Java).
- dep_b 8y agoThat's exactly what I meant, thanks
- jsanders67 8y ago> We also collectively decided that Microservivces were another solution to our woes though that cargo cult is being questioned I'm genuinely curious (and probably absurdly naive), but can you explain why you believe that microservice architecture is being questioned, what alternatives there are and why they are better?
- ungzd 8y agoI don't think lack of type inference is the primary reason of un-attractiveness of Java compared to dynamic languages. The main reason is bad expressiveness of java's types itself. You can't even have tuples. Neither tuple-like named types and named records. You have to make class every time, and OOP discipline tells you to hide data in it and make "behavior" public (this approach is definitely not for everything, so "beans" with getters and setters became hugely popular). Ubiquity of hashmaps in dynamic languages is huge relief after that. Scala has reputation of "rubified java" rather than "FP for java" because of hugely improved expressiveness of types (presence of data types).