I focused on front-end for 10 years. Starting with motools and IE6, jQuery, into React + Redux. I moved on exclusively to backend development after a few years of the latter.
You couldn't pay me enough to maintain a highly available/scalable system that wasn't written in a "verbose," strongly typed and compiled language. I'm done with that pain. If you're going to pick Node, I hope you're using TypeScript. Python, no thanks.
Refactoring and implementing new features in Java with IntelliJ feels like cheating, in comparison.
Even Go, which I actually really like, starts to lose specificity at large scale due to its intentional terseness. I deeply dislike implied interfaces, and the error handling in a large codebase is really noisy (one of Java's main complaints), without much net benefit.
There definitely was a learning curve with Java. To the untrained eye it looks very noisy and magical, but once you learn to visually parse it and understand what all the annotations do you can move very quickly with low risk.
Your mileage may vary. If you can move fast without breaking things using some other technology, go for it. But I hope you're prepared for success, when 30+ devs are contributing code to your house of cards. You'll want all the natural protections you can get from your choice of stack.
As someone maintaining a hugely complex system in Python: type hints make it bearable, but not good. A strongly typed, verbose language is an absolute, fucking, *must* for all but the simplest of systems. You can make it work if you're building web services where the type contract is in the web/RPC API (and hopefully strongly enforced), but for basically anything else, use something with a good type system. I cannot stress enough how important it is for scaling complexity.
If you must use Python, turn on mypy with the `--strict` flag, and do it early in your project's lifecycle. Do NOT make exceptions or allow for "gradual" typing, it's monumentally more difficult to add typing after the fact than early on. Type hint as much as you can, including tests. Pytest's fixtures can be type hinted both at the `def` and with their results as function args.
We should form a support group. Even though I'm pushing Mypy as hard as possible, there's some notable areas it can't help, like unittest.mock call assertions.
No, it's one of the fastest ways in software development you can ship software features to the customer.
Scripting language, dynamic typing, microservices and a message queue is shockingly effective.
There is no way to compete with that if you are using traditional development techniques.
It's why we watch videos online on Youtube and not Google videos. The Google developers got beaten up by the much smaller group of Youtube Python developers.
To be honest, I find it shocking that the average user on hacker news doesn't know that software development using dynamic typing is considerably faster than software development using static typing.
Nowadays, the speed of development for statically typed languages is much faster, thanks to improvements in tooling. Going further, if you choose a modern language that supports type inference, static typing becomes a pure win, and in my opinion, there's no longer any good reason to use something like Python on the back end. If I had to pick a language for the situation you're describing, I might pick something like Kotlin.
My background for context: in 2000-2009 or so I wrote a lot of C++ and often wrote Python bindings using Boost::Python because of how much quicker and more convenient Python was for scripting and exploratory work. I also wrote a lot of Java in that era, and Java was indeed incredibly verbose and ugly. Like C++, it imposed heavy costs for the benefits it gave you. After 2010 I worked mostly in Scala, and for a year now I've been working primarily in Python. The simplicity of working in Python still feels liberating, and doing Pandas work in Jupyter is great fun, but in most ways it feels like a relic to me now, because I can write code that looks almost as simple and reads just as easily in Scala as Python. (Sadly, I wouldn't recommend picking Scala for a tech stack in a business, because it's hard to find Scala developers who want to write stupid simple code.)
> Nowadays, the speed of development for statically typed languages is much faster, thanks to improvements in tooling
What you static camp guys don't seem to understand is that tooling is not that important, it's just a minor multiplicator that caps out pretty fast. You can't turn nurse into a surgeon by giving her a sharper scalpel.
Most engineers that had Java background I interacted with had a tendency to over-engineer. It's not because they had bad tools, it's because Java has a culture of over-engineering, which they soaked in and embraced. Tools & language are getting better - that's great. But that does not automatically fix the culture, which might take another decade or two.
"It is practically impossible to teach good programming to students that have had a prior exposure to BASIC: as potential programmers they are mentally mutilated beyond hope of regeneration."
At this point, Java is like BASIC. You can fix the language all you want, but you also need to fix the culture. It's not going to happen while most people won't even admit there is a problem.
We're talking about backend development, and in that domain Python has its own set of pretty awful drawbacks.
Starting with needing a level of testing that would make even the most paranoid static-language devs spit their coffee out. If you have any untested code and need to make changes that affect it, you are incredibly screwed. I can make sure my own code has the necessary level of testing, but when I'm at the mercy of other people's test coverage, I'd rather have the help of a compiler.
The performance of tools and tests is noticeable every day. Unit tests and linting are palpable interruptions. One thing I notice constantly is the delay when asking my IDE to add imports. With Scala, I can get it done almost as fast as my eyes and brain can work. With Python, it takes a few seconds before it can offer me the right import.
Speaking of performance, we were excited to discover ruff on HN a few days ago, which advertises a >100x speedup over flake8 -- it's written in Rust, flake8 is written in Python.
Writing C++ and Scala, the attention paid to performance in 95%+ of the code we wrote amounted to using efficient algorithms and not making stupid mistakes. Computers are amazing these days, and if you write straightforward code with good data structures and algorithms, code on the JVM runs incredibly fast, almost always much faster than you need it to. With Python, sometimes you use the right representation and the right algorithm and the result is still disappointing, because in the absence of a JIT, good Pythonic code is a huge multiple slower than it needs to be.
In many cases where performance has been disappointing, we've decided to live with the slowness, because making it faster would mean departing from the straightforward Pythonic style that gives us easy-to-read, easy-to-test code.
> At this point, Java is like BASIC. You can fix the language all you want, but you also need to fix the culture. It's not going to happen while most people won't even admit there is a problem.
This is one thing I agree with. Java and Scala development both have culture problems. The Java world has a disproportionate number of programmers who believe that the imperative, mutable-everything, deep inheritance hierarchies OO style of the 1990s and early 2000s is an eternal truth of software development, and programmers are either virtuous and enlightened OOP warrior-monks, or benighted stray sheep. Apparently most people who don't believe that have jumped ship to other languages, making the problem worse than ever. Scala's cultural problems have been adequately discussed here, so I won't repeat them. In my experience, the best Java code, and the best Scala code, is written by people who are deeply suspicious of the culture associated with both languages.
> If you have any untested code and need to make changes that affect it, you are incredibly screwed
But you aren't. If your software isn't landing airplanes, you shouldn't treat all bugs as critical. Build safety nets, not guard rails.
Python might have 10% more non-critical bugs, but also allows you to ship 5x faster. That's a great tradeoff for vast majority of projects.
> Unit tests and linting are palpable interruptions.
I do believe some teams have this problem, but mine never had. To me it's a signal of many tangential issues (bloated codebases, obsession with unit testing). I don't believe it's a language-specific problem. Also, you should just lint-on-save anyway, slow linting in CI is a minor nuisance.
> Speaking of performance, we were excited to discover ruff on HN a few days ago, which advertises a >100x speedup over flake8 -- it's written in Rust, flake8 is written in Python.
In order to create a better flake8, you have to create flake8 first. The reason flake8 exists in the first place might be that it was easier to create in Python. First succeed, then optimize, not vise versa. Also flake8 is a CPU-intensive command line tool, not your typical environment for Python.
> Apparently most people who don't believe that have jumped ship to other languages, making the problem worse than ever
> In my experience, the best Java code, and the best Scala code, is written by people who are deeply suspicious of the culture associated with both languages.
I believe that. I think culture will simply push good engineers out of those communities. If you have to fight both language and community, why would you stick around?
Have you ever of this little company called Youtube?
Youtube did the dynamic typing thing in Python with 20 developers and Google did the static typing thing with several hundred developers in C++ for their Google Videos.
Nice anecdote, but was it because of the language or because a small motivated team gets much more done than a big enterprise that is bogged down in meetings?
You seem to be quite close-minded, every piece of evidence is not good enough. Are you only going be satisfied by a 20-year long peer-reviewed independent study?
How about this: Python is only ~1.5 times more popular than Java, and Ruby is way below Java, and yet if you look top successful YC startups, Python has 17% of valuation, Ruby has 52% and Java is merely 1%. You can, of course, choose to interpret it in a multitude of ways, but at least one of them is that if you pick Java for your startup, you are unlikely to be successful (or, alternatively, people who are unlikely to build a successful startup are more likely to choose Java).
Idk, I have written Java EE (and Jakarta EE) projects, and I found everything to be so much worse than e.g. Next.js + TypeScript. It feels like everything is broken in the Java web-dev ecosystem, except spring. I had plenty of struggles with the JPA, where some SQLite JDBC wasn't straight up working or MySQL8 was not supported. This was just to get the project running.
Then, JSPs have like 300 different ways and 300 different opinions on how to do stuff. Should you do routing via XML? Should you put your routes in annotations? Or do implicit navigation in the JSPs? Managing sessions is a pain too.
Setting up and deploying Java application servers in prod is way too complicated compared to Node, Deno, Python, Ruby, Whatever.
> Starting with motools and IE6, jQuery, into React + Redux
Anyway, I hope you didn't have to write pure react without any framework on top of it. I mean, the library is fine, and the React patterns mostly stay the same, but React.js is missing a lot. Personally, I wouldn't touch pure react, unless I have to write my own framework on top of it, but that hasn't been the case yet.
P.S. I also had to work on JavaFX applications in the past. I used IntelliJ too, and the tooling of JavaFX is broken to the point, where you can't even use place controls in your great FXML. Which just made me think about another thing I dislike: Java's XML fetish. I don't hate the format, but knowing what XML namespace is the correct one is often beyond me.
Writing new Java is probably fine, but older Java codebases are the often PITA. :(
>It feels like everything is broken in the Java web-dev ecosystem, except spring.
"Except Spring?" Spring IS the modern Java web-dev ecosystem. You can't write it off as a small exception. With Spring Boot it is very easy to get something working quickly.
It sounds like you may be suffering from the Paradox of Choice when it comes to the broad Java ecosystem(s). For new projects, just pretend nothing exists except Spring Boot and use annotation/java config for dependency management.
There's obviously a lot of legacy Java out there, but it's so massively popular that there's an immense amount of greenfield development going on as well. Don't take jobs working on Java EE stuff unless nowhere else will hire you and/or they are paying you a massive amount of money to do it.
> It sounds like you may be suffering from the Paradox of Choice when it comes to the broad Java ecosystem(s). For new projects, just pretend nothing exists except Spring Boot and use annotation/java config for dependency management.
Spring Boot is passable, as long as what you are trying to do fits within what you're allowed to do and you don't have to dig into the internals too much. Regular Spring is painful, attempting to migrate a project that's been around for close to a decade from Spring to Spring Boot without a rewrite is even worse, especially if it is stuck on an older version of Spring, even worse if you need to go from JDK 8 to JDK 11+.
In a limited set of circumstances it can be useful to opt for something simpler, that's built on a bunch of other boring, mostly "standard" or at least idiomatic packages. Some might advocate for Quarkus, others for the likes of Vert.X - both are interesting and pretty usable, but perhaps it's a bit too early for either of those. For those interested, ktor might also be worth an exploratory look in non-prod projects (if you like Kotlin too).
There is something to also be said about the likes of Ruby and Ruby on Rails, or PHP and Laravel, or .NET and ASP.NET, or maybe Python and Django - sometimes having fewer options can also make you more productive, especially if a lot of ecosystem is grown around those "main" solutions. Perhaps that's an argument in the favor of Spring Boot.
Just wanted to add that I'm currently building and shipping a 60K+ LOC product based on vert.x. I never used Spring or Spring Boot and I personally would like it to stay that way. Vert.x has been such a pleasant surprise to me: the docs are great and the community is quite active.
XMLs, JSPs, Java EE are relics of the old age. They were built during late 90s and early 2000s. No new projects use them. You can’t say Java is bad because of how things were 20 years ago.
Java EE is an evolving spec and includes basic things like JSON processing, REST, JMS, JPA, even the servlet API itself - these things are very popular in greenfield projects. If you're writing a web app, you're using Java EE unless you're writing your own server.
Static types are great, but they can be quite painful in languages like Java that don't support Sum Types/Tagged Unions. I just want to represent "OR" goddammit.
It should also be noted that statically typed doesn't necessarily imply verbose. Many statically typed languages support type inference which more or less gives you the best of both worlds.
> Refactoring and implementing new features in Java with IntelliJ feels like cheating, in comparison.
This shines especially in large monoliths. Refactoring microservice interfaces is hell (which means it's rarely done and they rot), refactoring module interfaces in a Java monolith is a breeze.
Very few projects benefit from microservice architecture.
> Very few projects benefit from microservice architecture.
I think the pendulum will swing in the other direction, as it usually does. The previous (NoSQL) hype burned out in about ten years, hopefully this one will go out a bit quicker.
I don't know. NoSQL is still going strong and kinda makes sense for unstructured data. I attended a tutorial earlier this year and the DB they wanted to put in was Mongo rather than SQLite say, even though they were storing structured data in it -- which I didn't understand.
Also the problem with microservices in my mind is the tooling. Right now microservices are deployed with k8s in docker containers which is still heavyweight for what they're supposed to be. It could be that a language (maybe go) introduces features to allow for tooling to make easier refactoring.
It isn't just refactoring them that is hell. Even testing things can be hell - those unit tests just became integration tests or you're rolling the dice with mocks. If you don't get the result you expect from a service call, the lack of a single call stack you can debug up and down means tons of time wasted jumping around.
They're hell for new developers coming on to a project too, since they can't just follow IDE links to trace execution paths, and too few projects implement full REST call request/response type safety for endpoints.
I find java mentally exhausting. I have only ever worked with java once, and it was long ago when I just began my career over 6 years ago.
Since then I mostly work with typescript and go on backend, and the languages are quite simple and strange code can be understood quickly without having to dive too much into documentation and navigating a million folders/layers of OO abstraction.
I've tried getting back into java and each time I just get exhausted looking at the code.
The problem with Kotlin is that Java copies its features pretty quickly. So as time progresses, the benefit gap between the two languages diminishes, and eventually will not justify switching ecosystems. For example, Project Loom is the answer to coroutines. Sealed classes, etc. Up until recently, Kotlin was not a 1st class supported language for Bazel, gRPC, etc.
In addition to Loom being superior to async/await, Java's pattern matching is shaping up to be better than Kotlin's, and Java's string templates (https://openjdk.org/jeps/430) are also superior to Kotlin's.
That's not necessarily due to java. I have a guy on my team (we're a java shop) with completely exhausting code. Everything is layers and miles of indirection. No one else here does that. It is admittedly more common in the java world though.
No, it is fairly common among Java devs. In fact the culture there is that way. Most happen to come from banking sector, and other deep enterprise structures where things tend to move slowly. Design Pattern abuse is super common, and is widely used as a 'smartness signalling' tool. Generally it is not that much of a problem given attrition rates in those places is low. But it does cause lots of pain for people who join the team.
I was the happiest with when Python grew, not having to deal with things like 300 classes just to make a ping to some REST end point was a welcome thing.
Yeah Java people don't go the 'quite easy' way. They want some 10 indirections of builder classes to merely build the url alone. Then a factory class to create the connection etc. Then some response handlers to deal with the response. Then some dozens of classes to parse the response.
By the time you work around this you are lost in the forest of classes.
Not sure why the hyperbole. It's literally one class for the client, and one for the request, probably the least you could do without things getting too hard coded.
Yep Java rocks and is well suited for larger projects. If I have a small team and need to move super fast - then I use Django. If it's > 10 devs and is going to be a large project then it's Java all the way.
> Another important factor is that the team of engineers building the first version of Picnic’s platform already had ample experience using Java and the JVM.
> Remember how Twitter had to re-platform from Ruby to Java to support its growth? Definitely not an enticing prospect, so our choice was geared towards the long run. Unlike Twitter, Picnic embraced Java from the get-go!
Once again, it must be said that almost no app will ever be twitter scale. Time to market is more important than needing to do some architecture in the future. Twitter was also early in both Rails and doing globally distributed web apps, a lot of lessons have been learned since and rails itself is much better, it's been almost 12 years after all.
It seems like this article could have stopped with, most Dutch developers already write Java professionally.
A competent Java programmer is not slower than a competent Python programmer. Time to market won't suffer.
There is definitely a higher barrier to entry with Java, and starting new projects involves a bit more setup, but that is never the bottleneck. You start a project once. You work on it every day after that. The time it takes to set up the build system is a drop in the bucket compared to the rest of the work. Maybe it will take your company a few more hours to get to market because of that? Big deal.
> There is definitely a higher barrier to entry with Java
This is what is missing from the conversation. Most of us Java fans have been doing Java for a while. I started in '96. We know the JVM. We grew up with Java and were exposed to various aspects of this platform for over 2+ decades. Java the language is not that hard to pick up, but the platform in its total glory is formidable to those new to the language.
I myself never realized this until a few years ago when in course of quizzing a very vocal anti-Java front-end dev in a startup, he blurted "it intimidates me".
It does seem to me that Java's default tooling is clunky and hard to get running, which is indeed be a big barrier for new devs. The fact that after writing java for ~10 years I'd still need to google how to setup a manifest file for a basic no-frills Java CLI program is silly. I've been tuned out of the last few Java releases, so maybe they fixed that recently though?
It's always sad to see people in the tech industry who are opposed to learning things. Quite a lot of the anti-Java, anti-abstraction, anti-complexity crowd seem to actually just be people who are one step above a sysadmin in their mental model of programming, don't see how large-scale programming is different from imperative scripting, don't understand that complex problems sometimes require complex/systematic solutions, and resist leaving their comfort zone.
There are certainly valid arguments against everything I just said, but quite often they are not the true motivation.
>>Quite a lot of the anti-Java, anti-abstraction, anti-complexity crowd seem to actually just be people who are one step above a sysadmin in their mental model of programming, don't see how large-scale programming is different from imperative scripting, don't understand that complex problems sometimes require complex/systematic solutions, and resist leaving their comfort zone.
May be you are the one refusing to leave the comfort zone. Fairly large chunks of programming ecosystem has moved to Golang, Rust and even other JVM languages like Kotlin for a reason. Most Python programmers today are Java refugees too.
Its just that the overall culture of Java is loaded with programmers who like to use senseless abuse of design patterns as some 'smartness signalling' mechanism. Endless layers and indirections to achieve even simplest of the tasks.
Using something like Golang and Python feels instantly less stressful and liberating when you go from Java to these languages.
How can a programming language stressful or liberating at all? There is no real difference between imperative languages regarding what you can do, and minuscule one regarding how you can do them. I’ve seen hardly maintainable and understandable code in all mentioned programming languages, regardless of used framework.
I have come to form a strong opinion regarding software development people: In general we are more comfortable with operational complexity than conceptual complexity. (A somewhat wider sense of conceptual, to include architecture, structure, etc.)
Some of us, like me and possibly you, are more comfortable with conceptual complexity but abhor operational complexity. This [division] mirrors the society at large, imo, but was masked during the early days a couple+ of decades ago when software geeks were truly geeks. That subset of demographics never was upset by complexity per se, only un-necessary complexity was a cause for getting upset. The general demographics is bothered by complexity, period.
Companion theory partly based on this opinion is that as the community grew by orders of magnitude from say late '80s to '10, it began to more closely resemble the general population. So the degeneration of keep it simple, stupid (KISS) to mean keep it stupid and simple is an economic and social phenomena.
We are workers in a field with an arts and craft mentality on the production side and global industrial demand on the consumer side. The factory worker plugin iPhones together is not asked to think conceptually. The factory worker making software widgets in some IT department however has to come up with an ad-hoc 'assembly-line' with his or her teammates. Of course they are going to poo poo conceptual complexity. What does it bring to the table for them or the production line?
In contrast, learning (or copy/pasting) n chants for m different infra-beasts to get your widget online seems far more reasonable and far more bangs for mental bucks.
I don't want to start a flame war, but I don't think there are "pro-complexity" and "anti-complexity" sides in programming debates, but really different views on where that complexity should be placed. Is a complex language unnecessary and design patterns are enough, or are design patterns symptoms of a language that's not powerful enough? I hope nobody is adding complexity for its own sake, at least.
IntelliJ comes with a step by step GUI to set up Spring Boot for you with all kinds of bells and whistles, with the choice between Gradle or Maven for your build chain (last time I checked, maybe they're moving away from Maven at this point). You follow the steps and get going. You can set up a project as fast as the time it takes to Google the exact name of that npm/pypi package.
Sure, you'll want to check your settings before pushing your first code to prod, but the same is very much true for any other "default" deployment.
The same is very much true for other "boring" platforms as well, such as dotnet these days. Getting started is quick and easy.
Java will have a significantly longer setup process if you decide to throw out all the work that's been done for you and implement your own boutique web server and routing system, but that's not a realistic scenario for most companies.
I imagine most of the Java horror stories people recall come from the days where there were no good Java libraries and everyone was reinventing the wheel. Sometimes there are weird dependencies that stop being maintained and rather than fix the problem, companies opt to stick to ancient versions of Java and the JVM, but that's not really a Java problem either, that's a supply chain issue.
I don't understand what the higher barrier to entry is supposed to be like in practice. If you know the basics of backend development in any language, you can get started. Learning to place annotations on top of endpoints is a five minute tutorial process, not dissimilar from how setting up routes in any other language takes reading a page or two to get right.
The only barrier to entry I can think of is that you probably want the full version of IDEA which costs money, though you can use all of its features for free by sticking to the EAP release if you're tight on money.
> I imagine most of the Java horror stories people recall come from the days where there were no good Java libraries and everyone was reinventing the wheel.
My memory of java is from about 2007 and I had a pretty negative memory of it. I recently joined a company that primarily does java development and it's amazing what 15 years of progress can do. It's night and day. Using IntelliJ instead of eclipse alone is a big jump.
The thing is, as a C#/.NET dev, those tools weren't that great 15 years ago, either. But I'd been keeping up with the progress in that ecosystem, using it day to day, so it's easy to forget.
> A competent Java programmer is not slower than a competent Python programmer. Time to market won't suffer.
A fast horse is not slower than a fast car.
Languages and ecosystems shape how people think. For example, you will find that Java and Python programmers have very different values and principles. Given same options, they will make extremely different choices. Clearly this is going to have at least some effect on time to market.
I found Java to be a land of overengineering, verbosity, and anti-patterns. The infamous "Hammer Factories" [1] post screams Java to me.
In what way? Sure, gradle can build faster, but the amount of compilation time the frontend need that barely does anything is orders of magnitude more than any maven run.
Because nothing in Python is magic. There isn’t a single language feature in Python that somehow magically makes you more productive. All of the Python language features are also present in other languages.
And productivity to me is not how fast I can bang out a solution to a small problem. I can do that in many languages no problem. Productivity to me is being able to effectively maintain very large (million+ lines) code bases. Not having types is a productivity killer in that scenario. And Python being a slow languages (when not calling C libraries) makes it even worse.
But hey if you feel more productive using Python that’s great! More power to you.
People generally do interviews in Python if given the choice. Coding in Python being quicker is well known in the community.
For why Python is more productive:
Dictionaries (maps), sets, (generic) lists, tuples are first class citizens of the language with simple syntax.
Typing is dynamic, which means generics, abstract base classes, interfaces and tons of typical boilerplate code, which you would use in Java, are simply speaking omitted entirely.
Extensive library, which is easy to access by pip.
It would be very weird indeed for a developer not to be more productive in Python than say Java.
It should be fairly obvious why the hundreds of Google engineers were run into the ground by a small team of Python developers.
Nothing you mention is unique to Python. C# (for example) has all of that. And no there is no agreement in “the community”. Just look at the very long dynamic vs. static typing discussions we have all the time on HN.
And if you think that typing a few fewer characters will make you more productive then we clearly don’t agree on what it means to be productive. Programming is not about typing fast :)
And pick any two random developers using the same programming language and you will probably find that they vary dramatically in productivity.
And please don’t worship Google developers like they are made of magic fairy dust. I have worked with people who ended up joining Google and they were OK but not great developers.
Honestly the biggest reason we had to re-platform to the JVM was latency (fail whale was a 5s timeout) and not growth. Ruby was just too slow for all the stuff we wanted it to do. It ended up being 10x fewer servers AND 10x lower latency.
I feel like this is a pretty important comment that busts a popular myth about Twitter and Ruby. The notion that Ruby was a poor choice even for a young Twitter that hadn't hit scale makes Ruby (or at least, late 00s/early 10s Ruby) look even worse than it already does.
Java was designed to, and still delivers, rapid development.
Is it possible for java developers to entangle their work through poor choices such that development becomes slow? Absolutely; the java ecosystem has accumulated a number of such tar pits. Competent java developers avoid these.
Unfortunately incompetent java developers abound. The world is full of java developers that haven't learned anything new since Java 6 appeared 16 years ago.
The above argument is also used by C++ advocates; C++ is great if you know what you're doing and apply the solutions provided in modern iterations. Ironic since java was Sun's 'fix' for C++. Given the rapid rise of competitors to C++ I believe that argument isn't working terribly well.
I think people confuse "I don't personally know Java" with "Java has a slow time to market." Sure, for people that don't know Java, learning Java to that level is definitely going to cost you time.
I've worked with plenty of languages [1] since 2001 when I entered the job market . Recently I've been doing coding interviews for developers for a Java shop who theoretically knew Java. It pains me to see what they need to do to implement what I ask them (simple tic-tac-toe game) using Java. Something that in Ruby would be: puts(row.join('|')), in Python would be: print('|'.join(row)) in JavaScript would be console.log(row.join('|')) in Java requires either a StringBuilder monster or a third party library [2] to make it bearable.
And like that, there are other crazy things that make me glad I don't have to write Java anymore (I worked 4 years with it in total in the early 2000s).
[1] (VB6, VB.net, C#, Java, PHP, ActionScript3, C++, JavaScript, TypeScript Python, Ruby, 8086 asm, top of my head).
Right? I mean I think what GP is saying that they aren't qualified to interview Java programmers? Hasn't used it since 2010??? Yet they had the hubris to think that they were qualified, and used the interviewees lack of knowledge to confirm his priors about Java?
I have mentored coworkers who didn’t know Java on how to use Java at work. I would definitely rather hand a random person Java to learn for work than others.
True enough. But Java (and other options) have changed in the meantime too. Are the productivity arguments equally true today as they were when Twitter decided on Rails?
I haven't kept up with Rails or Java for a couple of years, but Rails has always been laser focused on rapid feature delivery. If I knew up front I'd end up with twitter I might not start with Rails, but I wouldn't choose Java either. The truth is, there are a lot of good options today and hiring will be a consideration. I think the big negative for Java there is that almost every dev sort of knows it, so the signal to noise ratio there isn't very good.
Java has been improving pretty fast and is starting to close the gap in spots where it's been seen weaker to Go etc.
Fact still remains that it has excellent lib ecosystem, tooling, observability and large code bases with multiple teams are much easier managed in static languages.
At this point most of the downsides are from legacy frameworks. A modern framework + Kotlin is very productive.
Isn't Kotlin slow to compile though? I created a simple hello world Kotlin multiplatform website the other day and it took like 30 seconds to recompile any time I changed anything.
Really interested what you mean by Java having gaps compared to Golang. You can basically write Golang like code in Java, just leave out any useful language features and you've got it.
I have used both professionaly and am not a fan of either. (I really like typed and compiled languages, so those are not my issues with them).
For fast startup, look at GraalVM/native-image which compiles Java to native code and works very well.
Downsides are that highly dynamic and reflection-happy Java code bases/libs won't run OOTB, that using profile-guided optimization (for achieving or surpassing HotSpot perfornance levels) requires a commercial EE license from Oracle (about 300-400 bucks per seat last I checked, not required for mere development until used in prod or at customer sites, and bundled with commercial JRE/JDK subscription since about a year), that even with EE your garbage collector choices are limited, and the somewhat overwhelming number of optimization flags to pass to native-image, not unlike earlier JVM runtime arg excesses.
Although note that using PGO with Go isn't really common either. Actually, JVM languages and JS are amongst the very few that use PGO regularly as setting it up and using it with AOT compiled toolchains takes more work.
Java starts very quickly (like a second). If it doesn't, that's typically down to pulling in slow libraries. Spring Boot in particular is awful for start time, can add like 30 seconds to start time.
Plenty of rationalization of how java (the language) is "subjective for developers" in terms of productivity and happiness. From a non-engineer view though, let's be real : nobody ever got fired for picking java.
This was just a decision made in favor of managers over the poor engineers that will have to deal with maintaining a large Java code base over time.
As an engineer, Java would be one of the languages I would choose for maintaining a large codebase over time. It is far better for that than most other popular languages.
If that is because of static types then I might agree with you, however once Spring and other reflection-heavy frameworks are added to the mix then I'm not so sure. Java's biggest problem is not the boilerplate, but the culture of over-engineering.
Luckily, the culture of over-engineering has shifted significantly thanks to modern approaches for designing Java-based systems.
The "Triple Crown" of Java frameworks, namely Spring Boot, Quarkus, and Micronaut, but also with the influence of smaller contenders (Dropwizard, Javalin, SparkJava, and a few others) have helped developers focus on business code rather 'design patterns' because these frameworks have embedded a lot of the "over-engineered" concepts into their 'opinionated' approaches.
Developers are no longer thinking too much about layers, and just writing components by following the guidelines and best practices of these frameworks. The final result is pretty similar among all of them, especially for microservices.
I like the sounds of that but I would definitely note that this requires _significant_ technical leadership. If you try to hire Java developers, 95% of the resumes you're going to get are people who learned Spring the bad way and have very little experience shipping efficient or reliable code.
The general problem I’ve seen is complexity and action at a distance - basically many things where anyone trying to figure out how it works or make changes has to understand a lot of code in multiple places.
A mundane version of this problem is dependency management: every Spring app I know is constantly patching CVEs, almost always in optional code for features they aren’t even using, and sometimes upgrades are not trivial because you have to push around a lot of framework code. Node is similar but at least the tools are better.
None of that is specific to Spring, and I’m sure someone will pop up to say that’s doing it wrong but it’s been 100% of the work I’ve seen from multiple contractor teams so perhaps the way to characterize it is that the community doesn’t have enough culture of pushing back against support burden or complexity.
In my long time java shop we're doing pretty much the opposite - using less frameworks and libraries to minimize time spent on constant upgrades to the frameworks and their myriad dependencies for exposed vulnerabilities.
These things are changing - Quarkus and Micronaut are gaining a lot of popularity, and both use compile-time DI, not reflection, and Quarkus in particular is designed to target GraalVM, and Graal does not like reflection at all.
Agreed. Even if we buy into the argument that Java is just wordy and slow to work with, once we're doing with long-lived code that needs maintenance, that's less of a concern than code that's hard to decipher, so the trade-off seems like a good one.
Yep. The wordy nature of Java is just giving you more info to work with when you dive into code you haven't seen before. Java is also a lot less wordy than it used to be, and if you use the right tooling you don't need to actually type everything by hand anyway.
What matters most for maintaining large codebases that a lot of people work on is the type system and the tooling. A large ecosystem of good tooling exists for working with Java, and it is empowered by the static type system to do some very impressive things. Some of the .net stuff is probably close to that with Visual Studio and the ecosystem around it. Everything else is pretty far behind, including Python and Ruby and Go.
I know people who work on a massive Java codebase that is almost 20 years old and has over 1000 people currently working on it -- and thousands more have passed through that codebase in prior years. It's not a lot of fun. But if it was a Python codebase, it would actually be impossible.
The type system isn’t impressive. You can find usages and thereby get navigation and refactoring via excellent Java-centric IDEs. But it seems like that’s it(?). On the other hand you have to constantly exercise your code because of lurking NPEs. Although hopefully we can get good annotations through third-party tooling (Facebook’s looks good).
That's a lot on its own, and being able to understand the argument and return types solely by signature is a big productivity boost compared to environments where that isn't possible.
Java can be hard to decipher in its own way. Mostly because of a culture of favoring just-in-case indirections, a propensity towards making deep call stacks as the codebase evolves (maybe because IDEs make that navigation tolerable, although it never makes it easy to see the whole context), and pretty imperative constructs outside of streams and lambdas.
But on the whole Java is not bad. I think it’s perfectly OK. I am more afraid of Java culture.
I disagree that it's a tradeoff, because those two are orthogonal. Java is often hard to decipher because there are many things that can happen dynamically outside the visible code path that affect execution logic, like annotation processing, classloading, dynamic bytecode manipulation, AOP, dynamic proxies, reflection, etc.
Most of those strategies are equally popular in Ruby but without the guardrails that at least make them cumbersome enough to make you think "is this really how I want to approach this?" The pitch for Ruby has always been productivity because it's terser so I'm trying to be charitable here and grant them their greenfield case.
In my experience (and our experience at TransFICC building middleware for financial trading systems, which is extremely throughput and latency sensitive), Java is the fastest language to work with simply because the tooling support is second to none.
I've worked on a lot of codebases that appeared to be put together by developers who took that as a challenge - IME Java developers LOVE global variables (but they call them "public static" to make themselves forget they're using global variables).
Have you compared and contrasted Java and C# (especially with regards to let's say larger frameworks)?
Both of those put a strong emphasis on types, but only one of those (it's Java) is the sort of language that really attracts developers that love types like AbstractWidgetBoundaryFactoryWrapperFactory.
I can definitely understand the "Citizen Kane" effect of looking at a modern Java framework and going "yeah looks just like any other language, except with types and IDE support". Java didn't get there from nowhere. It got there after 20 years of being overly verbose and frustrating to work with.
My only real gripe with the language is JRE versioning and updating and that's the only legitimate complaint I've seen from others. It seems that you can sidestep that issue by baking in the JRE to your executable.
Honestly, I think the only reason C# is winning at all right now is because MS controls Windows and can silently keep .NET infrastructure up to date all the time. There must surely be a parallel universe where Oracle created their own OS where they enjoy the same benefits as MS.
Search for the memo where google employees were saying, "we the developers of google are losing to Youtube, as Youtube engineers use Python and we use Java. And iteration in Java is slower than Python." That's before google purchased youtube.
YouTube was based on Python from the very beginning. And since then has migrated more and more pieces to Golang. PHP was never a major component of their stack, if it was ever used at all.
Search for the memo where Twitter migrated to the JVM. That one actually did happen.
The link from your linked page states that Google were using C++, not Java. Which is correct. I was there. Writing web servers in C++ is a good idea if your web server is 1% HTML rendering/UI and 99% complex algorithms over large binary data structures i.e. a search engine. It's not so great if your web server is 95% UI.
Are you reading these links carefully enough? The first link you posted was talking about Google's use of C++, but you presented it as an argument against Java and in favour of PHP (which YouTube weren't using). This second source also doesn't say Java vs Python was the problem. They say:
"We're constrained on UI/Java development resources", "we have 1.5 engineers working on UI things and that is slowing us down" and "I think if we had one more good Java/UI engineer we'd be kicking butt vs YouTube".
So the problem was a lack of people ("resources") assigned to the UI side, i.e. too much of their headcount is being consumed by the C++ infrastructure leaving very little time for UI-centric work like social features. Google Video's problem is stated here to be too little Java development, not too much.
As someone who was there at the time and who read the internal post-mortem written by the Video team, Google Video vs YouTube wasn't primarily about implementation language. It was pretty much as the emails you cite say:
"They're cranking interesting features a lot faster than we are, but don't likely have a backend that will scale or a plan to make money. We, otoh, have these"
The YouTube guys did the now classic VC play of focusing on growth hacking without any idea of how to pay for it all beyond being acquired. At the time Google bought them the site was close to total collapse; the project to stop it running out of bandwidth was literally called BandAid. The Google Video team was also small but focused more on stable and scalable infrastructure, and product-wise they'd been chasing professional content as they couldn't see any obvious path to monetizing hobbyist produced video. In turn that pushed them away from the Flash plugin towards a more HD video oriented custom plugin, which hurt adoption. These were the wrong calls clearly, but, YouTube didn't really have a plan either. In the end both sides needed each other. One of the first things that was done after the acquisition was start moving core YT functions like video and thumbnail serving off Python and onto the Google C++/Java infrastructure. The web server UI on the other hand remained in Python for a long time so their (social) feature throughput wouldn't be disrupted. I think that codebase did eventually stop scaling and got rewritten, but my memory starts to fail there and I can't quite recall what the state was back when I left.
> Before Google acquired Youtube, the majority of the code was initially written in PHP, but there were many restrictions and clutters in PHP at the time, so after acquiring Youtube by Google, they moved to Python as one of the core parts of its backend programming.
Python started after google's acquisition. It's not that youtube was "never written in PHP".
The more common and recent hate I hear is that so much has been layered on top of it that it's difficult to manage or really understand what's happening in the code. Mentioned in other comments, but things like loads of annotations, Spring abstractions, and so on.
Recently coming from a Python/Flask codebase to a Java/Spring codebase, I would say that the amount of "magic" is not all that different.
It's just that with Spring, I can go to an extremely well-written user manual, or to StackOverflow and get my questions answered. With the Python/Flask codebase, I had to splunk my way through all the layers of random libraries the original developers slapped together, in an attempt to reproduce something resembling out-of-the-box Spring.
I suspect that those original developers had fun making all of those custom choices back in the beginning. I don't know for sure though, since of course they've all left the company since then. The company chose to migrate because it wasn't maintainable once that tribal knowledge left.
That sounds more like a microframework vs a kitchen sink opinionated framework issue though than a language issue. eg Flask is a DIY collection of libraries with your own architecture vs say Rails or Django where you have 95% of those decisions made for you and baked in.
I'm sure there are Flask style frameworks in Java land too. And there was a port of Spring for Python a while back too :)
At some point I realized I was doing more programming via XML files and Spring decorators than via actual Java code. Mostly because Java itself isn't a great abstraction for a CRUD server.
If you did it recently, you should not have needed XML. Even a decade ago, XML-based configuration was on its way out. The transition from Spring to Spring Boot enabled us to use regular code to configure our injectors, for example.
I haven't touched XML for nearly a decade as a full-time Java developer.
I've only ever developed Java at places that had their own infrastructure for everything, so this question may sound uninformed, but isn't Maven still the de-facto package manager used for most Java applications and isn't Maven configured with XML?
Yes it's using XML for all the wrong reasons - as a config and even scripting format (hello ant plugin) when XML is for markup/text. Fscking Maven doesn't even allow basic XML/SGML features such as entities/text macros. And yes Maven's pom.xml is used for package metadata on maven-central and elsewhere even if you don't use Maven directly.
BUT I have to say, every project using gradle as alternative so far has receded into bizarre ad-hoc deployment scripting. Maybe that's just because gradle can do stuff that was hidden away in jenkins build files, but still ...
XML is pretty rare in Java code written this side of 2010. Not that it doesn't exist, but the whole spring mess is not something you really have to touch to set something up in Java.
I usually enjoy Spark[1] for bootstrapping a simple REST-like interface. There are other options, but in general, you don't really need glue-languages at all if you stray away from old-fashioned EE-style frameworks.
Yikes! You can't attack someone like this on HN, regardless of how wrong they are or you feel they are. Obviously it's completely against the site guidelines.
I can only tell you my own lived experience, and that was it.
It is possible there's a better way to do these things my team was unaware of (I was aping an existing server and replacing its RPC handlers with our own, not starting from scratch), but yep. XML and I can't be arsed to remember if they call their @-forms "decorators" or "annotations" because I use too many languages that have some variant of them to keep track.
Point is, I wrote more of both than actual Java, and the annotations make debugging much harder than slapping a tracing debugger on.
ETA I think the peer comments and this one underestimate the stickiness of methodologies in old languages. The fact that there are better ways to do it now is irrelevant... Because there was a previous best practice that is no longer a best practice, that best practice lives forever in the code bases and shared knowledge passed by peer review of existing institutions. Hell, I can go to my bookshelf and pull down two Java tutorials that show how to do an RPC server with Spring and XML... Once it's committed to paper, it lives forever. One can make the assertion that a team should be constantly developing their process, but management is a lot more comfortable with standing up a new server that looks exactly like the old one than with trying a new methodology that is unproven at this company. If for no other reason than so we don't have multiple ways to approach debugging servers depending on what team set it up.
Has those people have any understanding of what is their computer? It is layers upon layers of abstractions, plenty in hardware and even more in software. In fact, the only tool we have to actually solve complex problems is (good) abstractions. So those haters should probably find better arguments.
Large codebases in dynamic languages are the pits. Determining if some bit of code is used and how is a probabilistic exercise. Eventually you learn to give up or YOLO and see what happens.
If I write the tests, maybe. Some tests make refactoring even harder. If I couldn't already refactor my own code we're also in pretty bad trouble. If I've written more than 10% of the tests overall, things have already gone badly.
Verbosity is not a problem. The problem is being able to navigate and understand a large codebase. Terseness and dynamic typing are the enemy of that goal.
Attempts I've seen to quantify it have found that you hit a productivity peak in a team of 5-8 people. Then you need to add processes to avoid n^2 communication overhead. You don't get back to the same productivity until you have a team of 20-25 people.
If you've never worked on a small team, the productivity difference from staying small may not sink in. But they are real and large. And companies should not lightly cross that threshold.
I agree with you that, on a large team and in a large organization, terseness and dynamic typing are bad. But I don't agree that verbosity is not a problem. It absolutely is. It makes you have to go to large teams sooner.
Why is that verbosity never mentioned as a negative for Go, when in fact, Go is more verbose than Java?
Also, I really have a hard time believing that java would be significantly longer than any other mainstream language, it is at most longer by a small constant amount.
Modern Java isn't remotely as verbose at scale. The language is very different and the API+3rd party support is so vast you can usually build huge things with very little code.
20 years ago, the rule was that Java took an average of 10x as much code to say the same thing as a scripting language did.
In all the time since I keep hearing "modern Java this" and "modern Java that". But every time I venture into some Java, well, my limited experiences haven't fit what I was told about "modern Java".
Maybe I just haven't encountered modern Java?
As for the API+3rd party support argument, the productivity of third party libraries has been used as an argument for ages. I remember when it was being made about Perl with CPAN. My experience of it has always been that libraries make a great start to the extent you have a common problem. Which is wonderful for demos. But once you're in the weeds, you still have to write lots of code. Maybe there isn't a library for your unique needs. Maybe the standard library has bugs. Maybe you wrote code because there wasn't a library but now there is.
No matter how it comes about, you wind up writing code.
20x was always an exaggeration. It counted class boilerplate and compared stuff like hello world which was always "decorated". As scale that overhead gets minimized. Java will always be a bit more verbose than some other languages. It's strict. By definition that's more verbose. It also forces declarations (e.g. public). Again, a choice to keep things clear.
But that's not the code that takes time to write or read. In that department Java isn't more verbose in a significant amount. If you're the type of person that gets upset that every line ends with a semicolon or that we need to repeat the word public for many methods. Then sure. Java is verbose.
Looking at the body of a Java method I don't see something I can significantly cut down with TypeScript or Python.
even modern Java 18 codebases with exclusive use of records instead of classes, and with enabled enhanced support for instance pattern-matching instead of old-school conditional blocks and switches, are still significantly more verbose than Scala codebases, especially if the latter use `cats` or `scalaz` for all traversal/mapping/folding logic. Java developers would just manually encode all these patterns into series of nested loops by hand by default every time, because the required tooling as well as the compiler help to aid that tooling is not available in the language.
It's the (static) types, not the type annotations that matters in IDEs these days. Even in Java there are (very limited) situations where you can omit the type and the compiler infers it. And the ide handles it just fine. And in, say, Scala, which has more inference, the ide works fine (albeit not as well as Java but that's more down to maturity).
>This was just a decision made in favor of managers over the poor engineers that will have to deal with maintaining a large Java code base over time.
What's wrong with maintaining large Java code bases? Say what you want, but the language is built for that.
The worst code-bases I've seen tend to come from dynamic languages. Try to maintain hundreds of thousands of lines of python or ruby code over several years, and see how fun that is.
>From a non-engineer view though, let's be real : nobody ever got fired for picking java.
No. That's not a correct framing. Java is one of the few languages that able to strike a great balance between performance, development productivity, 'debuggability", cross-platform support (i.e. works just as well under Windows as Linux), language safety, and library and framework ecosystem. Honestly, it's hard to come up with a use-case where Java isn't a natural right answer.
I disagree. The alternative is some rockstar developer saying "let's pick Elm!" or "let's pick Elixir!" and then leaving the company after a few months. I'd take Java (or C#) over several other languages in a heartbeat. I'll leave the more esoteric stuff for the weekend, thanks.
I picked Elm once and I managed to convince my boss to let me got rid of it 6 months+ before I left. Turned out it's a good move! (well.. a not that bad move)
Most of the flak that java gets is from people who have never used/maintained java codebase. I moved from java to python and I actually miss java. It’s much easier to navigate and refactor java code. Yeah, you can write code faster in loosely typed languages like python, but maintaining it is a different story.
At my workplace I would pick Java 8/10 times. I would only pick something else when Java is really not an option (e.g. Scala/Python for Apache Spark, Typescript for CDK).
Maintaining a larga Java code base is very easy (I think much easier than e.g. Python).
The tooling is awesome, there are countless libraries, last but not least Java is the easiest to hire for.
Java seems to be getting a lot of flak. I would very much prefer to maintain a large Java code base over large JS, Python, Ruby code base hands down. Trust me, you don't want to be in a position to maintain a 100KLOC mess of an app written in JS by long goners.
> Sadly there’s very little evidence supporting productivity differences between programming languages, especially in bigger real-world contexts.
Only because it's almost impossible to quantify and is so contextual. However there is a good reason why Java is getting many extra language features from functional programming, e.g. streams, records, "sealed classes", pattern matching. Yes, productivity. Personally I am far more productive in OCaml, Haskell and Rust than Java; and that's after spending many years getting a lot of Java experience. But these are not necessarily good choices for the risk averse, which really comes down to the real reason why you chose Java.
Streams are not a language feature, they only depend on generics and lambdas. There are surprisingly expressive FP libs available for Java written with only existing tools (vavr for example).
Also, Java deliberately move slowly, it is a huge benefit for the platform as it can better avoid potentially vain features that would have to be maintained forever even if they are not popular. Algebraic datatypes debuted many many decades ago, yet they only become sort of mainstream in the last couple of years.
Both lambdas and generics did not ship with Java originally. Yes Java moves slowly, but it would move even more slowly if they waited for published studies proving the productivity gains of these features.
> Another important factor is that the team of engineers building the first version of Picnic’s platform already had ample experience using Java and the JVM.
And the author of the blog post is a book author on the language and Java Champion, so uhh, yeah, it would be very weird not to go with Java in this case.
> Pick the language that you know and can hire for cheaply.
That's exactly what they did.
> Go make your thing already.
This article is about a company founded in 2015 that now has a 300-person technical team. They already made their thing and this post is a retrospective looking back at that experience.
> Please don't comment on whether someone read an article. "Did you even read the article? It mentions that" can be shortened to "The article mentions that".
Also, my comment that is about making their thing is not about this article specifically, but in general as this type of article is very common, but I removed it to clarify my main point.
I feel like they wanted to make this article because of the bad rap that Java gets in the developer world compared to some “trendier” languages. The article was advocating for the exact approach that you say should be followed when picking a language.
I suppose - every article I've read in this vein always has the same conclusion - use what you know, and everything else is just a rationalization. What would be more interesting is the opposite.
While there are things I wish it did better for the sort of stuff I use it for (foreign memory API can't arrive fast enough), Java is a pretty solid pick.
It's boring and unsurprising to a fault, which is a great selling point if you want to build something of nontrivial size and scope.
Another strength is that it has a large well rounded standard library and a large set of mature libraries you can pull in when needs must. Not quite as batteries included as python, but not far off.
The tooling is best in class, the available IDEs are great, debuggers and profilers are ridiculously powerful even at face value, and that's not going into the iceberg of weird shit you can do, like you can attach a debugger to live production process like no big deal.
There are pitfalls when it comes to frameworks. Like both Spring and Spring Boot are quagmires that tank your performance. Like whatever velocity you gain from starting off with those is lost waiting 90 seconds for the planets to align every time you want to run your unit tests.
Have you got a chance to read "Java Puzzlers: Traps, Pitfalls, and Corner Cases"?
Java is a very surprising language with a lot of strange corner cases (a lot of them related to reified generics and wrapper types).
There is also a lot of magic going on in JVM e.g. there is one optimization that causes stack trace to be omitted if the exception is thrown from a given place a lot of times. Beginners then see an exception without a stack trace and are stuck. SO rel: https://stackoverflow.com/a/3010106/1779504
Spring can be a source of confusing problems when defining beans (especially when you have to use Qualifier's). Most of the juniors that I had a change to work with had very hard time getting used to Spring bean model. And I am not mentioning here strange Spring Proxy behaviour that can defy even programmers with 10+ years of exp
Yeah. Generics is arguably Java's weakest point. They're an afterthought in the language's design and should in general probably be avoided in all but the most trivial cases. A lot of problems go away if you stop trying to make Java into Haskell or C++ and just avoid the feature unless absolutely necessary, which you rarely do.
That said, I did once sorta port a somewhat tortured definition of Haskell's parser monads to Java's type system for an event at work, mostly as a joke. Like it's doable. Wouldn't want to maintain that code, but it's doable.
In general I don't think "does it confuse beginners" is a great metric for what makes a good programming language. You'll be able to find a beginner who is confused by almost anything. Beginners are hopefully not the same people who will write or maintain the code.
While it is surely an afterthought, it is imo very well executed knowing that — while you can’t have proper Monads, quite a lot can be accomplished, just have a look at some FP libs written in Java.
I have read that book, and while it is a great read, it rarely employs realistic code you would run into (will you really cast some number literal multiple times and try to guess the resulting value in actual prod code? And things like that)
I have yet to be bitten by this stack trace behavior, thanks for the heads up, but I think every platform has its idiosyncrasies. I would still not change it for UBs everywhere :D
And I really don’t think that the spring model is all that difficult, we just have plenty of bad developers and not enough focus on proper education of juniors (often done by “senior”, bad devs)
> I have read that book, and while it is a great read, it rarely employs realistic code you would run into (will you really cast some number literal multiple times and try to guess the resulting value in actual prod code? And things like that)
There is some admittedly unintuitive behavior when it comes to type conversions, especially in bitwise operations. Like this is just nasty:
long f(int a, byte b) {
long ret = 0;
ret |= b;
ret |= (long) a << 8;
return ret;
}
System.out.println(Long.toHexString(f(100, (byte) 64))); // 0x6440
System.out.println(Long.toHexString(f(100, (byte) 129))); // 0xffffffffffffff81
// you need to do
long f(int a, byte b) {
long ret = 0;
ret |= Byte.toUnsignedLong(b);
ret |= Integer.toUnsignedLong(a) << 8;
return ret;
}
The problem is that in Java byte is _signed_ type. So `(byte) 129` is the actual source of the problem, the number is simply out of range (-128 to 127). Since there is no byte literal and numbers by default are integers you always have to cast when calling a function with byte parameter. There is simply no distinction between safe and unsafe cast...
The correct language to chose as a start up is one that your team has expertise in and allows you to move with speed. It seems silly to over optimize for future "re-architecting"
This is interesting because there's so much negativity towards Java, particularly new projects. But Java continues as an enterprise-class language, just as C++ does.
When we started our company 9 years ago (after many years as a freelancer in bloated Java-based enterprise projects), I had only one condition: no Java! With 2022 Java, I definitely would not have asked for that.
> In retrospect, it seems that Scala’s popularity has peaked, and we’re happy that we chose the Java programming language.
This doesn't sound like a thorough assessment of Java alternatives one would normally expect from an engineering team. There's hardly any technical reason to choose Java in favour of Scala3 today, except one: the team's lack of Functional Programming expertise. Otherwise, choosing Scala for JVM would almost certainly result in better quality software in terms of safety and internal components design suited for long-term maintenance.
>There's hardly any technical reason to choose Java in favour of Scala3 today, except one: the team's lack of Functional Programming expertise.
I disagree about your premise at multiple points, but I want to focus on just one point - In my experience, Functional Programming is a large enough of a technical reason to not choose Scala in a company of a reasonable size. It's actually such a big reason that it deserves more than as an afterthought as you have it written.
I worked in Scala for 10 years. Not only was it difficult finding seasoned Scala devs, but also we often had to compromise by hiring Java devs and training them on Scala. Time and time again, functional programming was always the most difficult hump for them to grasp and it took experienced devs forever to learn the language and a new paradigm at the same time. Sure, you could hire someone who knew functional programming already and came from a background writing Haskell, but they were rare and usually commanded exorbitant salaries that made sure they were never in the equation to begin with.
Not to mention, you better have a disciplined team with strict linting rules and styleguides, otherwise your devs will go off the rails using Scala in ways that the team isn't prepared to learn. Or if you have Java-trained-Scala devs, they might revert to their old OOP ways.
Because of that, it actually causes more problems, resulting in worse quality software and worse deliveries overall.
It's too much of a risk, really. Especially when Java is not really a terrible choice in a large enough organization - same huge JVM ecosystem, large pool of devs, mature toolset, etc..
> I disagree about your premise at multiple points, but I want to focus on just one point - In my experience, Functional Programming is a large enough of a technical reason to not choose Scala in a company of a reasonable size.
You say you disagree with my premise, yet you seem to be confirming the point I made. Your arguments revolve around difficulties with finding devs for a team and with training them to actually understand FP at a level that would allow them to untangle their algorithmic thinking from OOP. It's exactly what I said about the only proper reason to choose Java over Scala: team's lack of FP expertise. Other than that, my point still holds: type algebra and explicit nulls opt-in bring better quality software overall. And it does require FP expertise, not just awareness or vague familiarity with.
> otherwise your devs will go off the rails using Scala in ways that the team isn't prepared to learn
This also contributes to my initial point. But I'd like to know what are your examples of off-the-rails, as I've been to situations where a couple of folded traversals had been called similarly "too much" in a Scala codebase, but for someone writing Haskell it was just a regular application of a familiar pattern.
> Sure, you could hire someone who knew functional programming already and came from a background writing Haskell, but they were rare and usually commanded exorbitant salaries that made sure they were never in the equation to begin with.
This is a specific argument that could be made within your organisation. I don't know your budgets and the requested salaries by respective candidates, and you didn't clarify the level of expertise your teams were looking for, so I can't make an informed judgement about the merits of this argument and to what extent it could be applied onto the tech stack in general. I've been doing FP for a meaningful amount of time, mostly in Haskell, and the common theme over all these years has always been a visible shortage of FP positions compared to the number of capable candidates willing to compromise on their salary in exchange for an opportunity to use Haskell at their workplace. Many of them were instead compromising on Haskell in exchange for a regular Java-grade salary for writing Scala. And I've never heard of people commanding better salaries just for the fact of being able to write Scala instead of Java. Usually it was due to additional set of skills, like strong algorithmic training or extra years of business domain expertise, and these traits bring additional value to organisations, if they are able to utilize them within their teams.
> Especially when Java is not really a terrible choice in a large enough organization
It certainly isn't terrible, but it also is neither safer nor more productive. For a developer who has a good command of both paradigms, Scala would be a better choice on JVM.
Interesting that the choice was vs other JVM languages, and vs Scala specifically. The starting point to align tech choices with "realities of the hiring market" does make Java come out as the obvious choice then. But of course lots of companies hire developers for learning ability and the expecatation that they pick up the used language on the job, which also selects for other desireable qualities... no right or wrong answers here of course.
I don't like Java although I have to use it at my current job. There is simply no other alternative that is both widely known and supported (think a lot of programmers and a lot of libraries). I see only 2 other candidates C# & Go, switching to either of them means significant effort and temporary performance drop for the entire company.
Java is a very backward language, at my current job we use Lombok to generate boilerplate code. Lombok itself is a compiler hack, I don't like it. Why is that Java 17 records does not have supports for builders or for "withers" (point.withX(3)), C# & Scala offer both of those things. This makes records unusable for most of my use cases.
The other hard miss is lack of named parameters. This either makes code very verbose or less readable.
And my last complain is about lack of support around Futures/async/await. Yes there will be project loom, maybe even in next JVM release but currently we don't have it and a lot of libraries will need at least a year to support it. So instead of await's I have to manually compose CompletableFutures into spaghetti like code. I really hate this. We propose to our architect to use Project Reactor but the idea was discarded (after all Reactive Programming is not very popular among "commodity" programmers).
If I had to start a company now I would probably also pick Java (or Go), my main points would be:
- Free compiler and IDE
- Good library support for wide range of use cases
- Programmers available on the market (Java) or willing to learn (Go)
- Good build system, static analysis tools, best practices, learning materials & stack overflow
- Language is battle tested (sorry Haskell, Ocaml & Lisp)
Yeah this reduces it to Java for JVM, C# for .NET, Go if you are adventurous. If someone pick something more ambitious like Scala 3 or Rust I would gladly join that company, but if it was my own I would not risk it.
> Language is battle tested (sorry Haskell, Ocaml & Lisp)
do you mean battle-tested by yourself? Otherwise it's kind of FUD opinion, as Haskell is battle-tested across industries in quality-demanding domains[1], and I'm sure the other two have similar lists of industrial application.
I am mainly a dotnet developer but even I think that if you already have a team full of Java developers there is little to gain from switching to C#. Just the effort of learning a completely new set of libraries and frameworks would give me pause.
C# seems to be the pick for those programmed in microsoft ecosystem in the past, it's not attractive for beginners or non-microsoft-ecosystem developers per se, esp in this cloud and internet era.
I’m dumbfounded that anyone would believe that C# is not attractive for cloud development - Microsoft’s platform or otherwise. C# is a fantastic language and dotnet is a great, modern platform. IMO c# is a tad more beginner friendly than Java.
Also any time I have to use Java I'm always trying to use LINQ before I remember that's a C# feature. C# is really solid, especially .NET Core 3.1 and later.
I think that's unfair to the Streams API. It wasn't intended to solve the same problem as Linq and the problem it does solve it does very well. Streams transform collections. Streams API statements are usually elegant and the party piece of Streams is concurrency with parallelStream(), which will distribute stream operations across threads safely and transparently.
Perhaps java should have a Linq equivalent, but the fact that the Streams API isn't that isn't actually a knock on Streams. In the meantime there is JOOQ and others that deliver elegant query syntax with compile time type safety.
This sounds like a pretty serious misunderstanding of what LINQ is. LINQ is a general query capability of which there are multiple providers - one of them is for SQL, which may be what you are thinking LINQ is, but another is for in-memory enumerables ("LINQ to Objects"). LINQ to Objects and Java Streams actually are intended to solve the exact same problem.
If you think Streams API statements are elegant compared to LINQ, I again don't think you are familiar with LINQ. C# has language features Java does not have which usually makes LINQ much more succinct. For example, imagine a list of order items where each item has a double "Price" property. If you want to sum the price of all the items, here's how you'd do it in C# vs Java:
C#:
double sum = items.Sum(item => item.Price);
Java:
double sum = items.stream().mapToDouble(Item::getPrice).sum();
Java lacks extension methods, so stream() must first be called to get at any stream methods. Worse, Java has generic type erasure, so I have to to call "mapToDouble" to get this hacky concoction called a "DoubleStream" which actually has the sum method.
Not the end of the world, for sure, but definitely crappy compared to LINQ. There are lots of other irritating problems, such as Stream itself not being enumerable and the need for calling collect with a Collector.
Read the authors argument why they don't use Kotlin, a better language is not always nicer, especially when you risk being left behind. That is the reason why I don't touch C#.
Java has a massive community and a community that shares knowledge. This is what makes Java the greatest tool for any business.
Couple jobs ago worked a startup that was a hoard of Java developers from Cars.com. Pretty much their defining factor around why they picked Java since it was the team they could build to get the company off the ground. Undervalued factor considering what teams you can build early on and the skills they possess.
I mean, it's perfectly fine to pick language you're most familiar with, but maybe let's not pretend you're not biased? I wouldn't want to work for a leader that is full of BS.
Not that complicated, really. I'm part of Picnic now for quite a while. That's the 'we'. Of course I've discussed the origin story as used in the post at length with my close colleagues who were there from the beginning. Also, I'm very much part of the current choice not to migrate to e.g. Kotlin based on such discussions. So yes, this is our story which we want to share widely. It comes up every now and then, so now we have something to point people to. Didn't expect this to get picked up by HN, though!
Is it true that Java isn't slower than Python/Ruby/.Net? What are the fast ORMs and MVC frameworks for it that let you build a web app quickly the way ROR / Django / whatever .net people use?
Python and Ruby are probably the slowest commonly used languages, they are on the order of 10x slower than comparable C code. Comparatively Java/JS/.NET sits around 1-2x C speed, with .NET exposing some lower level details allowing manually fine tuning the performance, while Java has hands down the best GC implementations out of these 3. So one can’t objectively order them, for CRUD apps all 5 are great, and I think that there are very very few areas where C#/Java is not a good choice for performance reasons and you have to go lower level to C/C++/Rust.
I am starting to check this ecosystem but Spring Boot for the MVC framework is the ref. Used by so many big and small startup. I know a famous fintech using it too. Netflix etc also... Then JPA as the ORM and Hibernate. For the migration Flyway or liquidbase.
And then everything in Spring and stuff you can plug from the ecosystem.
I focused on front-end for 10 years. Starting with motools and IE6, jQuery, into React + Redux. I moved on exclusively to backend development after a few years of the latter.
You couldn't pay me enough to maintain a highly available/scalable system that wasn't written in a "verbose," strongly typed and compiled language. I'm done with that pain. If you're going to pick Node, I hope you're using TypeScript. Python, no thanks.
Refactoring and implementing new features in Java with IntelliJ feels like cheating, in comparison.
Even Go, which I actually really like, starts to lose specificity at large scale due to its intentional terseness. I deeply dislike implied interfaces, and the error handling in a large codebase is really noisy (one of Java's main complaints), without much net benefit.
There definitely was a learning curve with Java. To the untrained eye it looks very noisy and magical, but once you learn to visually parse it and understand what all the annotations do you can move very quickly with low risk.
Your mileage may vary. If you can move fast without breaking things using some other technology, go for it. But I hope you're prepared for success, when 30+ devs are contributing code to your house of cards. You'll want all the natural protections you can get from your choice of stack.