Java is typically used in larger or long-lived organizations. It is rare to start new projects from scratch. Most development is maintenance and extension of existing systems. Even if you start a greenfield project, it would be most prudent to chose the same platform and language which is already used in the organization. An alternative language would not only have to be better, it would have to be very significantly better to make up for the overhead and headache in maintaining code in multiple languages - never mind the increased difficulty in hiring and training developers.
Geeks tend to evaluate language based on how appropriate they would be for a greenfield project with no organizational baggage. But this is an extremely rare use case for most business.
HN often has reports about startups rewriting everything from scratch every four months, when a new language or platform becomes fashionable. But this is not the world where most developers live.
Anecdotally, I see a trend of greenfield projects moving from Java to NodeJS. I can't think of too many organizations that have zero web presence, and basically any modern web presence requires the use of JS, so there's almost always some JS expertise built into the organization.
In contrast, our Java upgrades remain painless. Many of our JS services have been merged back into older Java back ends
That is usually part of the front-end team that don't do the backend SQL work. Tho team that would get assigned the work for a backend greenfield would be versed in Java.
That’s an outgrowth of most projects being quite small. Paying a team or 20+ people to work on one thing is freaking expensive to the point where it needs major benefit or huge company to be worth it. On the other hand maintaining lots of little projects that all automated something can easily pay for a single developer at even fairly small companies. Across tends of thousands of small and midsized companies you get a lot of such teams which grow and shrink, split off and merge over time.
THIS. The product is blended and so must the teams be. Among all the full-stack developers I've worked with, the "frontend" or "backend" designators tended to describe preference or strength, rather than limitation.
I think you underestimate the number of huge companies that see major benefit from large teams working large development efforts.
1,829,875 companies with 5-9 employees 779,922 companies with 10-19 employees 467,634 companies with 20 - 49 employees 170,749 companies with 50 - 99 employees
Of that a few are pure software companies, but it’s far more common to want to automate something. Which often means outsourcing it, but then they simply can’t afford these kinds of large projects.
At the other end only 23,553 companies have 1,000+ employees. Yet even at that scale it’s not guaranteed to have large development teams in house, a single hospital can have 1000+ employees and use mostly 3rd party software with a few generalists to stitch everything together.
Starting from the other end, the Stackoverflow survey has 50% of devs identifying as full-stack. Most surveys have Java as the #2 programming language, where it’s been for the last 20 years. That says nothing about how those devs are organized among teams, but I don’t think it points to such arrangements being “rare”.
I always took that kind of a breakdown to mean most website developers where full stack with embedded etc being their own categories. With majority full stack teams including various specialists as needed, which fits my experience over the last 20 years.
However, Android is Java and is frequently used as a front end. As things grow I normally see teams split by system, so I can see mobile being split off as their own team becoming more common even if it’s the still the minority. That said, it’s teams managing the backend teams which would be considering Java vs NodeJS and based on that 55% I think most teams are familiar with JavaScript.
It's orthogonal to my point though.
Java is like you say not the greatest at anything but it is also not the worst at anything. Its great for projects where the you don't know what you should optimize for or don't care.
If java is to boring maybe kotlin is the way to go. I really like kotlin and in my personal experience the only downside is that the IDEs is not as good as the java counterparts yet.
But my main complaint about Python is trying to use someone else's software. Then it degenerates into a maze of twisty little passages of trying to install the correct set of dependencies, not knowing where those files are installed (which makes it difficult on a cluster, as you may need to do the install on every node separately). Then you try using pip and it fails because some element of what it is trying to install isn't compatible with your operating system for reason 1. So you try anaconda instead, and that fails in a different way, like it runs a C compiler on some file (!?) which fails because $REASON. I have numerous examples of Python software where I have followed the (detailed, precise) installation instructions, and it doesn't work.
Whereas with Java, you just dump the necessary jars into a directory, include them in the classpath, and it works.
Don't get me started on R.
The reason packaging is still a problem in Python are linked to the language:
- to get perfs, you need compiled extensions, which java doesn't need. So a Jar can be fast and portable, while in Python it's an "or" proposition. Wheels help, but they still are OS dependent, so you need a build per OS.
- PYZ arrived very late in Python, while WAR were a very early thing in Java. Few people even know you can distribute a whole Python program in a single zip file with dependencies using something like shiv (shiv.readthedocs.io). So few people do it, and it's a shame. We do it for 0bin though: https://github.com/Tygs/0bin/releases. And it doesn't solve the wheel problem, although nuitka does but it a higher prices to pay.
- packaging tooling have been a mess for 2 decades. Setuptools/distutils/setuptools2, easy_install/pip, and setup.cfg/setup.py/pyproject.toml. We failed as a community on this one. It's getting better, but it's a slow process.
- the Python community is at least half composed of amateurs. It's a good thing for the dynamism of the community, but it also means the software are not very polished. Hard packaging + amateurs = packages that are releases when they reach "just good enough" stage, not one inch more. It also means you'll get things like leaking stack traces, config files in src and the likes.
So yeah, compared to Java, Python packaging and distribution sucks.
But compared to rust all packaging and distribution for all languages do, so there is that.
or, even worse, scientists.
The previous crowd with love for monkeypatching everything and hate for abstraction other than dictionaries wasn't too pleasant, too.
Code style! Hah. First day on the job I asked about that and was told nobody cared and everybody had their own preferences.
... I'm very bitter today. I'm working on it.
Everything is jupyter notebooks, to the point where example documentation is delivered as notebooks and services run notebooks as it’s apparently easier to do that than to get people to write their code properly. “Oh but data exploration” they say, which is fine, but you shouldn’t be doing data exploration in your prod ML pipeline anyway, and you’re writing code, it’s really not that hard to follow some even rudimentary practices.
I'm forced to use Python at work, because data scientists demand it, and I can rant about your "good for data" language for at least 24 hours straight.
Python isn't great at anything specifically, but it's crap in a few specific places. No multithreading? Fine! But then Python core libraries are crap at IPC, when multiprocess is the preferred way of parallel computing!
I don't know where you read either of your propositions in any of my comment.
You've listed things that rely on full stack of libraries and deployment options.(except scripting) As someone who has the pleasure to work with Python - Python is horrible at a lot of these things, in spite of the beauty of the language itself.
Python is the best language in the world for small tools under 500 lines to solve glue and data munging problems.
There are two main exceptions to this rule. One is when an actual software engineer ends up working as a scientist and having to write papers (like me). Then, the paper is more likely to be about the software itself, and the citations of the paper are from people who have also used the same software. This creates an incentive to make the software high quality, in order to get those citations. The other exception is when an institute decides that the world needs a decent piece of software to fulfil a vital role, and actually funds its development.
Oh, I should probably mention - I just helped out with a programming course for undergraduate medical science students. Most of the time I was tearing my hair out about the terrible programming practices being taught by the module leader, who admittedly had absolutely no computer science qualifications whatsoever (and in fact didn't know the difference between a forward slash and a backslash).
I think a solution to this is to recognise software quality as a common benefit, and divert funding towards it, allowing real software engineers to have an actual meaningful career in university. Universities are usually all over common benefit stuff, so you would have thought this would be easy enough. The Research Software Engineer programme in the UK is a start.
Pyinstaller builds bundle the python binary with the project. It works without a Python installed on the system, is not portable and the resulting binary is fat. It also can fail in numerous way and be slow, but end users will find it the easier to use when they work.
Pyz files just contains python code. Shiv produce them by bundling your code and the dependencies, but you still need a Python installed on the system to run that. You pay the cost of zipping only on the first run though, after that, it's unzipped. And their are portable if you use no binary wheel. It's light and easy to get right.
In that sense, they look more like War files in Java.
Pyinstaller, like cx_freeze and nuikta are for end users.
Pyz are for devs.
> with Java, you just dump the necessary jars into a directory, include them in the classpath, and it works.
Ant, maven, or gradle, and then some jars, somewhere? What's the classpath and whats $JAVA_HOME for this project?
Oh and now I have to make it work in the IDE too, click through a billion menus and dialogs, sync the build system, sync the dependencies, configure runtimes and classpaths, try to rebuild for the 10th time, pray.
> Oh and now I have to make it work in the IDE too, click through a billion menus and dialogs,
You click "Project from existing sources" in IntellIJ and it will recognize both Maven and Gradle projects and just work?
Sync the dependencies? configure runtimes and classpaths? What? With Maven and Gradle? Your talking Ant here.
- Install and set the right java version system-wide
- Copy some config files for the project system-wide (granted, this is not java specific, but still)
- Click in some IDE menu to enable some build settings
- Click in some IDE menu to install some "Lombok" plugin
- Click in some IDE menu to select the right jdk
- Click in some IDE menu to edit the run configuration:
- select main class
- paste program args
- paste env vars
- select right “Use classpath of module:” option
- Click in some IDE menu to fiddle with "Spring Loader path": modules, dependencies, reorder the dependencies (!)
- Click in some IDE menu to configure getting the actual logs
- Click maven-sync, rebuild-project multiple times, restart IDE until it suddenly works
The first guy who got it to work had to write a guide with screenshots!I know you will say, this is all fault of whoever made this crap project, or my fault for not fixing it. However this was my experience, and it has been similar every time in my life that I had to touch some java project (although this last one is the worst).
In my experience (sample size of hundreds of projects), Maven projects are <<by far>>, on average, easier to build and manage than most other languages. The repo structure is standardized, the build cycle is standardized, the built packages are always in the same place, etc.
The Java installation is a 1-time think. It's also a quick google away. I see this complaint a lot, I never understand it. It's plain and simple bikeshedding: someone complaining about a 1-time task that takes 5 minutes in total.
The rest of the stuff is IDE specific and I have no idea why you'd have to configure "getting the actual logs"?
Treating the IDE like a separate problem is not realistic with java.
With e.g. Rust, I can use vim, vscode, whatever floats your boat.
> no idea why you'd have to configure "getting the actual logs"?
Some genius java logging library, I can only guess.
With Rust you code in VIM because there's nothing better. Improving Rust IDE's has been one of the teams big focuses for years. Everyone codes in random text editors because there's no amazing IDE.
You don't need to constantly "extract method", move to class, generate all these mountains of classes by rightclick. This says a lot about the language.
But the main point is that with rust it actually just works: there is one way to set global toolchain and per project/dir. You're not required to also click through a million menus and dialogs and copypaste stuff and sync and rebuild and restart to get the editor barely working.
In Rust, macros generate code on build. In Java, Annotations Processors do. I don't see a big difference between these approaches, besides Java's mechanism being older and crustier. Rust macros generate tons of code.
> if you have rust-analyze you get inline errors, code completion, jump to definition, autoimport, autoformat...
Last time I checked, Rust analyzer was in alpha/beta. Java has all this and it's battle-tested. Including language server for VScode and other lightweight editors, and several options for build plugins that auto format.
> You don't need to constantly "extract method", move to class, generate all these mountains of classes by rightclick.
Lombok, or one of the popular Builder libraries, gets rid of all this boilerplate. I don't generate anything using IDE. In my experience, most Java user don't. There's many mature libraries for geting around class ceremony.
> there is one way to set global toolchain and per project/dir. You're not required to also click through a million menus and dialogs and copypaste stuff and sync and rebuild and restart to get the editor barely working.
You are right. Rusts build system is simpler and better integrated. But Java has amazing build tools, maybe the best out there. A properly configured maven project will compile, test, and run with one command. And it will import into your IDE with a simple "import project, yes"
I have worked on a ton of Java projects over the years and never had to deal with most of what your describe.
True, but with IntelliJ 99% of what you wrote is auto-configured.
Eclipse needs a bit of hand-holding, but almost everything you described is due to project configuration.
> Some genius java logging library, I can only guess.
That's your problem, you're assuming that Java is dumb and its libraries are dumb. They're not. I'm reasonably sure that <<all>> mainstream Java logging libraries log to console by default.
The previous engineer must have been a marvel of a developer to manage to screw even that up.
What I'd say is: Java, especially older enterprise code, had a ton of over-engineered patterns. These are slowly fading away, except for Spring, and even Spring's simpler these days. Java also tends to have some low quality and a ton of average but unmotivated working devs on Java projects. So yeah, there's that ecosystem problem.
But for example, if you'd start a new project and you approach Java with an open mind, it's one of the most powerful and flexible techs available. And it's much more modern than the stereotypes imply.
It is not, that's what I'm saying. And I don't understand why, if IntelliJ is the de-facto IDE. I'm sure that a fresh project is a one-click import, but an average project that isn't fresh anymore, always have similar IDE-setup-magic problems. At least in my experience over the years.
I know plenty of people who don't use a formal IDE. This "I don't use an IDE" is a stupid flex.
It's not a flex, simply a matter of preference: I find using the mouse too irritating, others prefer it because it's simpler.
But that's not my gripe, my gripe is that setting up IntelliJ, the one defacto standard IDE to actually work is some voodoo ritual of a dozen steps and restarts and so on.
However I'd expect Lombok users to outnumber Lombok devs 100k to 1 :-)
I frequently find that the particular constellation of build tooling and libraries particular projects have requires a particular version of the jvm and all the environment variables set up correctly. In some other languages there is widely used tooling to manage the install and use of the appropriate platform version for the project.
If you're working with a variety of projects, fiddling with the installed jvm and java_home and friends is not a one time thing.
It is. There's really no excuse for that. If it's been similar every time then you've worked on crap every time.
Building a java project should be (and is on projects I work on) as easy as installing a jvm and running either maven or gradle to build it. End of story.
"Install some lombok plugin" is only necessary if you want the IDE to understand lombok, IntelliJ will just pop up a box saying "Want this?" and you click "Yes". I don't see what's so onerous about that.
The rest you describe is really down to poor developers.
So "no offense", but shove it.
Yeah that’s a crap project. My experience was always that mvn install / ./gradlew run will just work. On all three OSs. And if I happen upon a decade old random jar file, and run java -jar something.jar, it will just work in the great majority of time. I think no other platform has it this smooth.
The project could have been set up instead with the "Maven wrapper"(1) which provides "mvn.cmd/sh" scripts at the top level of the project to fetch and run the proper Maven. So after cloning the project, all you have to do is set a proper JAVA_HOME if it's not already set, and then do "./mvn clean package" at the top of the project to do a complete build. The IDE's will then set themselves up properly if you import the project as a Maven project, and will sync with changes to the Maven pom.xml whenever it changes (Intellij does at least). That's really hard to beat.
(1) https://github.com/takari/maven-wrapper (Being integrated into Maven itself soon).
We occasionally do remote debugging at work. It’s just a matter of copy/pasting the correct JVM incantation into the IDE.
Even if your project is so messy, then you should be able to just to version a working setup (maybe needing to figure out how to make the correct JDK version be used across different machines) and after that it'd become a question of just having to check out the project from the version control system and click a green button in IntelliJ.
This most likely wouldn't solve all of your issues, but at least would help make onboarding slightly less painful and slow.
The run configuration can be automatically created by Intellij by attempting to execute a runnable class. You only need to set program args and env vars if needed - and that would be true for ANY language or program.
The spring loader path appears to be specific for this project.
The run logs are independent of Java. Thats just getting program logs.
There is no need to maven-sync and rebuild-project multiple times, unless you are explicitly refactoring the project module/build structure. Once you have imported a maven project, you can simply click build.
Create new Java project in IDE Add no dependencies Use the built in IDE tooling to create a runnable JAR and tick the box to export the Ant build to a build.xml file.
Why would I want to complicate things by adding Maven/Gradle to the mix?
And I will also give you the secret trick of superninja senior developpers: be the one who manages the build process, so you will never EVER be fired.
Non-networked applications don't tend to need to be so paranoid about keeping up to date with the latest versions of dependencies.
My point is there are a wide variety of application types out there, not everything is a web application, not everything needs to use a complex build and dependency management system.
So just use Maven and save anyone coming after you a bunch of trouble when they have to extend your project ;-)
Dependency management is a mess in the Python world and my number 1 complaint. You have pip, pipenv, poetry, anaconda, to manage your 3rd parties. And if you want to avoid conflicts and have consistent runtime you need to create a virtual environment to install these libraries and redownload everything.
Otherwise libraries are installed user or system wide, in a directory that depends on the Python version that you use but they are not versioned there.
With Maven you don´t have the issue. Your 3rd parties are downloaded in a global cache directory (the Maven repo) and are all versioned. For the delivery you can either provide them all and have the runner set the CLASSPATH or have them packaged into a single jar.
I am not saying Python's packaging is any good, it sucks. But you can't realistically ignore Java's IDE shitshow.
All needed is having the correct version of Java, and maybe give maven a password so it can access private libraries. It's dead simple.
And more importantly: it's the same everywhere.
I haven't used Maven in a bunch of years.
But source code goes in src/main/java. Test code goes in src/test/java, resources (images, files, whatever) go in src/main/resources, test resources go in src/test/resources. There is a pom.xml file that contains dependencies, and if it doesn't, it points to a parent which <<does>> contain them.
There might be submodules and they all are folders containing another pom.xml. That pom.xml generally points to the main pom.xml.
Etc. There's a bit of tedium in there, but <<it's always the same>>!
The level of consistency is something most ecosystems dream about.
And you know what? That means that you can use your spare brain cells for actual creativity or hard work.
That is not my experience at all. I dont have to rebuild work project many times. Creating new scratch project for playing in is easy and fast. Dependencies are managed by maven and I rarely have to deal with that beyond added dependency tag.
Maven can build a nice fat executable jar, with just one XML block added to the pom.
I've opened a 5year unmaintained project with IntelliJ yesterday - click package and got a working executable.
I opened another project built with SBT... and guess what? No errors!
Let's try that with a Python project (LOL!)
That's an interesting take; my experience has been (at least the community) is quite proudly dogmatic on the One Right Way To Do It, for all values of "It".
I also don't like Python, but I think for different reasons and perhaps a bit less than you.
Never used R, but I understand it to be quite fiddly.
This hasn't been true lately. Python is growing ever more complex.
But, for people still working in "computer science-y" domains, I haven't seen the historical dogmatism lessen; in many cases people are digging in.
In other words R is wrong tool to use for building the software just from maintainability standpoint.
I've seen very complex R packages that have been around for 30+ years. They are actively maintained. Applying good design principles, unit testing, modularity - all that is very much doable in R.
And you will want to write software in R, especially if the purpose is to support the very activity of working with R packages and to expose the R statistical environment over HTTP. Case in point, the software I link to, in my comment above.
As a Java/Python/Go developer I can say that packaging is a solved problem as of 2021.
I like to point out Airflow as an example. It's still a complete nightmare to deal with and it has many steps for just packaging the application.
https://github.com/apache/airflow
I have less trouble packaging and running a 3 year unmaintained Maven Java application, than actively maintained Airflow. And let's not forget that I can target Java 8, without having to install Java 8 on my machine. (Which only adds to Python's complexity)
Like you mentioned, wheel files are not nearly as customizable as JARs. You can easily pick & choose the dependencies to include in JARs (fat JARs) and change namespaces of dependencies via shading to prevent collisions.
I've generally found it easier to add JARs to Spark clusters compared to attaching wheel files to PySpark clusters.
It's my guess that you are using a lot of Python libraries that are wrappers around C or C++ libraries which have dodgy cross-platform support, because I can't see another way this is happening. If so, it's hardly fair to blame Python for that...
Java is far worse on this front. Let's take a look at JEE or Spring - The entire experience is akin to summoning a demon with waving reciting correct incantations in correct places while having no idea about what even goes on in the background. There are MessageChannels, MessageProducers, ClientFactories that interact in mysterious ways and initiated in also very mysterious ways. And then there's EJB's and their containers which are just blackboxes of automagic.
Or how about Hibernate?
It now has 2 dependencies. It is a 1000 times easier to use than hibernate, despite being one of the worse ORM in Python.
That the problem with old Java libs like Swing or Hibernate: they have been designed for the 90' and don't leverage the potential of what a modern Java version can do.
There are many modern java libraries that are very lean and mean out there and package into small-sized redistributable assemblies.
You know the joke: a dev has a problem, uses Java, and now has a ProblemFactory :)
Not to say Java is not a great language for big projects, it certainly is well equipped for that, especially because it has superb tooling available on the market.
But I've done plenty of big projects in Python, some ended badly, some ended great. Not to mentions dropbox, youtube and instagram are testaments to Python can be used in large projects.
So I don't think Python is unsuitable for big sized projects. You certainly do have to worry about different problems than in Java, especially for projects that started without type hints. In my experience though, you reach less architecture dead ends with Python because the language is so flexible that a bad decision early on can easily be transformed or worked around even very late in the project without much fuzz.
So I don't use "size of the project" in my consideration to not user Python/Go/Rust/etc over Java.
I LOL’d at this joke (again) because it’s true, but if we’re honest, it’s also unfair. ProblemFactory is a bad idiom, rather than anything to do with Java The Language. You could (and IMO, probably should) just use a new Problem().
Java The Language was very stable for a very long time, so IMO the hype and fads got built on top. First we have a constructor - no, now we need a factory, but how to construct a factory? I know, let’s use another factory! All in the same unmodified language.
Likewise, how do we configure an object? First we have methods, but languages are cooler, so let’s build a DSL, no wait let’s use a fluent API so it just looks like a DSL!
I one had a dev replace a constructor call with a fluent builder, so now in the single use case where the object was ever created, we got five LOC where previously we had one.
His code was idiomatic, it was bad engineering, but it wasn’t Java the language.
Java is a pretty great language, but some of the crap people stuck on top of it was (and still is) a nightmare for readability and reusability. I use Go these days, and prefer their more basic approach to engineering, but there is much I miss from Java-the-language.
The Factory pattern’s pervasive use in Java was in large part a fairly direct consequence of JavaBeans requiring nullary constructors, so that the normal constructor work for a Bean had to be done elsewhere, i.e., by a Factory. Now, Beans was just a core part of the first-party enterprise framework that was central to the ecosystem and not strictly part of the language, but its not completely unrelated, either.
But my memory is that pervasive use of Factories came along many years later, and seemed to be driven by the perceived needs of TDD, for example to provide instances of mock classes in unit tests. And I thought the factory pattern itself came from the GoF, but I might be misremembering.
That said, I’m not trying to contradict you. It’s likely that there was more than one driver for the pervasive adoption of factories. In any case it was a bit of a nightmare for a while, hopefully things are improving there now.
It did, and GoF certainly influenced OOP outside of Java, too. But EJB created a need into which the Factory pattern was really the only solution. (GoF precedes EJB and even Java.)
But certainly its not the only thing; Java hit popularity right around the time GoF was most influential; OOP languages whose ecosystems developed earlier (e.g., C++) or later (e.g., C#, though GoF-heavy code isn’t unheard of there) wouldn’t be as influenced by it, all things being equal. Java just had the perfect combination of language features, early specs like JEE (which included Beans), and timing to be naturally inclined for maximum naive GoFism.
Stuff like "everything is a class".
I know the excuse that they are just meant to be used to wrap the return value of a function that might be null, rather than as a guard against NPEs, but that just means we’ve got a crappy, verbose Optional class ... and NPEs.
It was the most half assed attempt to fix the billion dollar mistake [0] anyone could have come up with. It needed syntax and compiler support, not a stupid wrapper class.
I don’t really get your other arguments. I think the problem has been solved better in other languages including Swift, Kotlin and Rust, and Java could have learned from them, but didn’t. I can’t see why direct language support couldn’t have been added to solve this “billion dollar problem”. Even the Elvis operator would have helped.
I'm absolutely convinced that's true for some of them. I was never 100% convinced it was true for all of them.
Java also had the unfortunate destiny of becoming popular at the time where "OOP all the thing" was a mantra in tech circles. Also design pattern were all the rage.
Those things have a huge inertia, and while Java is not a much more flexible language, the image stuck, to the point that new comers still implement singletons in the wild.
Java was a product of “OOP all the things”, it wouldn’t have existed without it.
It was very much a marketed language and a language designed to be sold to top heavy corporations. This fueled a lot of the crappy design decisions, the hype and the culture.
“OOP all the things” predated (and led to) Java, it wasn’t a product of Java (C++, Objective-C, Object Pascal and, well, a bunch of other things from the late 1980s and early 1990s were where it got started.) Java was about a decade into it.
I know not everyone will agree with me, and that’s fine, but I always found Java to be far more pragmatic than, for example, C++, which well and truely predated Java.
I think that applies to literally every language. Bad programmers write bad code, regardless of whether it's Go, Java, Python, Bash, or Assembly.
Same goes for Python. Reading the hacky code of a geographer for his SIG system is rarely a fun day.
I think this joke is probably about as dated as the versions of java it was made about.
Singleton is still a design pattern used in the wild.
Why bother setting things up explicitly in the way you want when you can declare things as injected, other things as singletons, and then have no real idea why it all went horribly wrong?
Inertia is huge in our industry, and the HN bubble doesn't gives a good picture of it.
Behind corporate firewalls I now see things done the way they were 10 years ago: packaging, string handling, concurrency...
I assume it's the curse of being popular and old.
And java has been popular for longer than Python, so inertia is even stronger. It doesn't matter if it has lambda since V8 if people still believe the best practice is to pass fat objects around.
(Poe's Law disclaimer: yes, that was light sarcasm.)
It's a funny joke, but it maligns a harmless pattern identical in FP to a function returning a function.
While FP coders would brag about how awesome high-order functions are, we just keep mocking our own style for some reason. Factories are very powerful when used right.
And me too.
Scaling a Python project complexity is not harder than scaling Java, the things you have to be careful about are just different.
In comparison one of my personal projects is in Rust and while that’s currently maybe only a thousand lines it’s already significantly easier to deal with.
Mypy is excellent. It has two-way type inference like Haskell. Good usage means catching almost all type errors before running.
So is PyCharm, which is IntelliJ for Python.
Fwiw, I’m normally on a beefy desktop so I might just be brute forcing this issue.
I think the main problem is that Gradle doesn't have the same support as Java for ABI compatible changes, so invalidation of modules are more common.
https://blog.jetbrains.com/kotlin/2020/09/the-dark-secrets-o...
I think you're right - ABI compatible changes are likely the culprit.
How do you mean? What IDEs are you referring to? Kotlin is fully (and very well) supported in IntelliJ Idea - unsurprisingly so, given that it's JetBrains own invention...
The reason Java does compete so successfully is that it is high level and yet provides a virtually unmatched combination of performance, maintainability and observability (including always on, low-overhead deep profiling). None of the alternatives you mentioned come close. This is why it continues to be a top choice at Amazon, Apple, Netflix, Google, Alibaba, Uber, Soundclous, and almost all Fortune 500 companies. Saying it is "out of the loop" is either wishful thinking or delusional, depending on your perspective. It's just not the reality.
I'm just saying, "to me, that's why I never end up using java".
Java is good enough for the vast majority of things. But so is Python.
And for specialized things, there are better choices available to me.
I'm not a Fortune 500 though.
For a very different definition of "good enough," i.e. unless you're working on a large codebase maintained by a large team for years, need high performance, or need deep low-overhead observability. So Java is "good enough" for a much wider selection of "serious" (large/mission-critical/long-lived/ high-performance) software.
> And for specialized things, there are better choices available to me.
That's OK, but in reality Java does very successfully compete with almost all the languages you've mentioned; it is they that, in practice, find it very hard to compete with Java.
But even when the language became the bottleneck, they went the road of rust and go, not the road of java.
Again, not to say Java is not used by those companies with great success.
Performance critical, lower-level servers are typically written in C++ at Google - think things like Spanner or GCS. Google only allows a very restrictive C++ subset.
Application servers are typically written in Java or Go. Which is preferred depends on the organization.
Google of course makes extensive use of Guava and Guice, and Bazel, which itself is written in Java.
Plus all the boilerplate coming not from the language but the OOP design patterns.
Trending does have an impact.
But by experience, having a killer feature, and a good adoption story usually does much more.
E.G:
- PHP: easy to make web page in 2001
- JS: monopoly on the client side web
- Go: simple concurrency and binary production
- Rust: borrow checker
- Python: "yes, you can do that too. Also in 2 lines"
Etc.
https://excel.uservoice.com/forums/304921-excel-for-windows-...
Any long time developer on MS stack knows that actually means "thank you very much but no".
So, I would not be so sure.
As for Dex,
> Research language for array processing in the Haskell/ML family
> This is an early-stage research project, not an official Google product.
Where is Python?
But it’s also a google side project, so previous experience dictates that it’ll be dead somewhere between arrival and 5 years time.
"Running Java" requires detailed system engineering / ops expertise specific to how the JVM works and can be tuned, and all too often, how specific frameworks internally pile their abstractions on top of each other. Problem is, a modern "Java app" is a pile of large frameworks and libraries.
As a system engineer, I HATE Java applications written by clueless programmers. They are difficult to handle and I often have to dig in and fix bad usage of framework features that somehow passed code review by equally clueless "senior" developers. I then get to spend a day to find out why this or that connection pool in there managed by this or that library does not handle its connections correctly, just to find the magic framework level variable that tunes that specific screw. Stuff of nightmares.
Every Java project is also __severely__ underdocumented. That's because even if you write documentation for YOUR code, the framework has books of documentation on ITS specifics, and includes high-level libraries which THEMSELVES have heaps of specific documentation. Climbing the tree until one arrives at actual standard library calls is like climbing into clouds and hoping to see the sun some day.
Endless abstraction, loading giant things into RAM, looping over every item in huge arrays. Blocking server threads for minutes at a time. In most languages you would be punished severely with awful performance or OOM. Java chugs along until things get horrifically bad.
> almost completely disregard how that code works on the JVM
As an occasional clueless programmer, I've had occasion to touch systems written in Java. Could you point me at some resources?
Reality is complex, and for non-trivial programs complexity is going to be somewhere.
This weaknes stems from Java being OO. On larger projects you start to have abstractions which tend to be insucfficiently documented or the documentation not being updated with changes. Throw in some helper classes here and there, from a certain point of complexity of the project from an outside perspective the whole thing looks like being obfuscated.
No one dreams about garbage trucks or puts one in a car show but they’re there and ready to go right back to work when you are.
- you can integrate code from hundreds of developers fairly safely (knowing that no one has changed the default behaviour fo builtins and different dependencies won't clash).
- the syntax, although not the most succinct is fairly easily readable and maintainable by other developers.
I dislike that people conflate simple languages with easy to read code.
Low level verbose abstractions make code harder to read - going through the layers of IFactoryRepositoryLocatorBullshit because the language abstractions suck doesn't make it easier to read code.
It makes the code more accessible, in the sense that you can probably find some 20$/hour devs to read through that and spend a day solving something that should take a couple of hours most.
Good high level code express the problem domain without boilerplate and let's you focus at problem at hand - Java is terrible at that.
What specifically is Java terrible at? I find Java to be as expressive as most mainstream languages. Certainly no less expressive than, say, Python or JavaScript.
Java can't even have a free standing function without 6 lines of boilerplate minimum and 2 levels of indentation to start.
Nominal static typing with weak generics and no almost no compile time programming support - you end up mucking with reflection or code generation if you want to do anything metaprogramming related or non trivial higher order functions - JavaScript and Python just deal with it at runtime, and if you need to type it out - you can still generate types that convey to the user what the result will be (the underlying code doesn't have to be typed)
Function<String, String> fn = parameter -> parameter + " from lambda";
Using annotations and cglib, you can do all the meta-programming you want.
Annotations and CGLib -> reflection nonsense and boilerplate - if you tried that and compare it to something like a dynamic language with open types (eg. JS/TS) you are just being dishonest if you're saying the two are anywhere close to comparable.
I remember doing a node ORM extension where I just injected standard revision management primitives into the entity as a part of repository. That would take an insane ammount of work in Java in comparison to get the same API functionality (namely it was mostly transaparent to the consumer)
Just like anything else. Put it in a package and just static import it from where-ever you need it.
Umm, cglib https://github.com/cglib/cglib is not reflection - its bytecode enhancement. You can inject, create types dynamically, modify types dynamically - all of it is possible. What you just stated is quite straightforward in Java actually and can be fully transparent to the consumer. It's by no means an "insane amount of work".
Now, if you bring up hot language features - sum types, etc - I agree that Java falls behind. But the stuff you offered as criticisms, Java actually excels.
It's exceedingly rare for this to be untrue of Python — it's technically possible to hack builtins but there's intense community pressure against doing that.
> - the syntax, although not the most succinct is fairly easily readable and maintainable by other developers.
This is sort of true but it misses the aspect which makes Java hard to maintain: the language being less capable means that you end up with more boilerplate syntax which has to be understood when reading it and the patterns that produces tend to be the long-term maintenance issue instead.
The boilerplate syntax you talk about comes from like java 1.4.
Modern Java is quite expressive with streams and lambdas. If one does employ the Java Beans convention than yeah, he/she has to autogenerate a few getters setters, but those don’t occlude the actual logic.
And frankly, empirically, Java is anything but hard to maintain. You would be hard pressed to find many languages that continue to manage at the scale Java apps routinely handle.
Yeah, it’s (typical business monstrosity) hard to understand, probably has many thousands hours of technical debt, but it just works, and more things can be added to it (and occasionally with much more work, removed as well).
I was thinking about things I've recently seen in new Java 15 code, so no. There are lots of old APIs in the Java language and popular libraries, and while things like streams are quite powerful, they're far from universal. I still see developers cranking out code which has to do what is built-in in other languages.
As a simple example, not having multiple return means that you end up with worse APIs in some cases or small classes which exist to wrap a couple of things — not necessarily terrible but it means that you've just taken on maintenance work for something which would be trivial in other languages. That extra code isn't exactly a huge lift but when you add things like that up regularly it's not hard to understand why all of the good Java developers I know are keenly following things like Kotlin which give more expressiveness without giving up all of their familiar tools.
But I do agree that there is space for improvements here.
For example: imports inside functions instead of at the top of the file (because the import does work, but the configuration hasn't been set up yet).
An example of this is an internal package at my workplace which makes a external service request at import time.
But even for Python (which syntactically speaking is probably the easiest to read of all the list), if your team scale, you just scale the tooling with it.
The Python ecosystem is very rich in tooling for enforcing best practices. Poetry will manage dependencies cleanly. pylint will let you check that builtins are not overriden. Mypy will check for types.
So of course, it's not as good as Java, but again, the post is about compromises the language make, which are not the proper ones for me, personally.
The language itself isn’t great though. Java solutions tend to be bloated and make it hard to decipher the underlying domain logic.
I certainly wouldn’t pick Java for a small team of experienced developers.
Though it seems java in general attracts a culture of slow moving bureaucrats which doesn't necessarily translate into higher quality (in fact, I'd argue it translates into worse quality).
You are conflating to different layers. Not being able chase a competitor's big feature can be the death knell to your company, yes. But this does not mean that building your business software on stable and proven foundations is a high risk. On the contrary you want to be fast moving with your business features not with keeping up with quicksand under your feet. I.e. a stable well understood basis, is IMHO a prerequisite to moving fast above of it.
In addition to my arguments above, one still has to consider whether a tool matches the problem. Writing an Excel plugin in Java is probably a very bad idea (I really don't know, I just assume that anything based on .NET would be a better fit), although both Excel and Java value long term compatibility. If you want to follow the latest trends in AI without really understanding what is going on, it is probably best to follow all the tutorial about AI and use Python. But if you plan to hire people that understand the details of AI libraries, you might come to the conclusion that the AI libraries on the JVM also provide the basic blocks you need, the higher levels are customized to your application anyways.
To come back to the original point, a technology or programming language is not good if it moves fast, it is good when it fits your problem, doesn't create too many new problems, is well understood by you and your team and is maintained.
In practice, I've barely ever seen this assumption truly come to fruition. I see java codebases degrade, become undecipherable messes filled with reflection, inflate themselves to become incredibly hard to understand or work with, at similar rates. I still see JSPs throwing garbled stacktraces that barely help understand what's wrong. Still see business shoot itself in the foot because it said "this should never happen", so the code is made under the assumption it doesn't happen, because null is still available and no one uses optionals, and 2 months later you have clients show you another NPE after going through 15 layers of business-modifying logic and people spend a week uncovering how the situation can take place (or worse, it is retroactively sealed up and the actual bug is still there). If there's some magic spell that helps java become less messy than other static languages or even some dynamic languages, I have yet to see it.
At that point, one has to question: what are we losing the sprint for? Are we truly increasing the odds of us winning the marathon? Not even its most espoused benefits, libraries, write once work everywhere, etc., seem to be remotely unique anymore. The only two answers I see, are legacy, and the number of java devs available. Lose a java dev, no problem, just pop in another. Want to rewrite the app in a different language, or even in less verbose, modern java? Good luck convincing management firmly believing that a rewrite of one month is more costly than pushing out features at 1/10th the speed post-refactor for another 2 years.
Java isn't the problem. People lacking a broader view are.
Now, from a project success perspective, I think it's not. I've seen a lot of Java projects fail, over engineered, full of spaghetti code, riddle with inscrutable abstraction, stuck in a glue of badly designed architecture that has been fossilized by the type system.
I'd say from a project risk perspective, it's a pretty average language, it has pros and cons, but they balance each other.
> I've seen a lot of Java projects fail, over engineered, full of spaghetti code, riddle with inscrutable abstraction, stuck in a glue of badly designed architecture that has been fossilized by the type system.
Sure, but do you really think the same organization would have produced perfect simple elegant error-free code is Haskell or Smalltalk (or whatever "better" language you are comparing to) under otherwise same requirements, deadlines, resources and management?
I'm not saying languages doesn't matter. A better/more appropriate language is like having a bigger screen or a better chair. All else being equal, it will increase productivity and make developers happy. But it will not make or break a project. The things that will break the project: Bad/unclear specifications, bad management of change requests, lack of testing, unrealistic scheduling, lack of customer feedback, bad communication or conflicts among developers.
Choosing a less popular platform (like say Clojure or CoffeeScript or whatever) might very well increase productivity compared to the conservative choice. But slightly increased productivity will not save a project, while the additional risks involved could very well sink the whole project. Which is why most businesses seek to reduce risk rather than maximize productivity when it comes to development platforms.
Many languages haven't been popular long enough to have a nice pool of experienced engineers to pick from. Java has that advantage, which not many languages have.
these are properties of a poorly designed project, and isn't due to it being java.
You may be able to causally link the failure to the people on the project being "incompetent" - but that's not really the fault of java!
i say java is a pretty good language, if you have large teams, with varying levels of competency amongst the members. As long as you have somebody good to do the overarching design and direct the project, it would do relatively OK.
if you have a small, elite team, then it may not be the right choice (depending on the team).
"So weak"? You do realize that this is basically where every language was less than a decade ago?
We're in 2021, not decade ago.
The language is underwhelming, the JVM is great.
I haven't seen any benchmarks, but I doubt a Scala app written idiomatic style would be any slower than the Java version written in idiomatic style.
Also, what is this C spirit we are trying to stay close to? I'm certainly not interested in any "C spirit"
If I needed to waste more time on hacking a setuptools script, to get a file placed into /usr/local/lib/shared... I'd rather use Go or Rust.
It's way easier than C++ and will get you 80 percent of the way there in terms of performance
They cannot fully embrace the JVM while targeting ART, JS and native at the same time.
That 3D graphics library using SIMD and value types from JVM on ART or JS?
Good luck achieving the same perfomance and memory semantics.
Kotlin/Native has already been rebooted as its memory model was incompatbile with JVM libraries.
From the app side you just don’t use classes that you can’t use?
It will be interesting to see how things like Valhalla and Loom will pan out.
The main company behind Scala changed its name and now also offers Java consulting.
Unless the project requires Spark, there is little reason to even care Scala exists.
Then there is the version 3.0 where they started having brain damaged ideas like changing the whole syntax.
Scala today is Kotlin in 10 years.
One benefit of being old in this industry is having survived multiple fashion waves of guest languages on each platform, then watching how those guest languages fade while the platform languages adopt some of their features.
Or even how whole platforms become irrelevant making it a complete moot point regarding whose languages are on the platform.
There has been a consistent increase in Scala jobs in the last 12 months according to Indeed.com
We are talking about Java as a language, not the JVM as a platform.
You can also run Python on the JVM.
Although, some Java compromises are definitely linked to the JVM.
Jython is stuck on 2.7 and unmaintained.
But Erlang was just such a good fit for this project. I wasn’t so huge on the Java version of Akka. I also briefly looked at Scala, but I avoid Scala for similar reasons to C++ and Haskell. The nativess of a lot of the features I wanted to Erlang just looked better and it will be a cool homage to the language’s roots.
Also this is probably more my fault, but I don’t really understand how distribution works anymore. Supposedly Oracle JDK is no longer supported and you’re supposed to package a JVM with your application, but all the big Java apps still require me to have a system wide JVM to run them? OpenJDK seems to work fine for now.
Also after toying with a LAPB implementation, I’m so mad other languages don’t have a good type for dealing bit level data. Bitstrings are a godsend.
So you can just install OpenJDK from a package manager, use the jlink tool and create your own small “JRE” that you want to bundle. Jpackage can create a platform native executable from that, that is either an installable exe, .deb, rpm or MacOS’s format (I forgot it’s name)
Scala has a "tunable" level of PL feature usage; you can write very Java-esque Scala at the beginning and slowly incorporate more advanced features.
The key thing about these features are that once you understand what they do, it allows you to write fewer lines of code overall. Fewer lines typically means fewer bugs, and it communicates intent with more clarity (at least to developers who are familiar with the patterns).
This makes it easy to onboard new devs who may not know a lot of Scala and let them be productive from day 1 (writing Java-style Scala) while advancing their skills towards more fancy idioms.
I have stayed away from JVM-land after taking a different tack in my career trajectory, but I worked at Twitter about a decade ago when they were transitioning to a JVM-based stack and were early adopters of Scala. It was really a joy to be able to simultaneously get my work done while uncovering all of the new cool language features!
IMHO, YMMV etc.
If I don't need performance, Python is ok.
If I do, I won't go Java, I will choose something that is built for performance. Python is good enough for 99% of my performances need. The last 1%, jumping to java is not a big difference, I'll use rust or go.
I won't use go for the ecosystem, but it's unique characteristics: easy concurrency, dead simple binary production. Java can't beat that. IF I need an huge ecosystem, I'll go Python.
For the need for Java, I would need this very specific sweet spot where I need just enough speed, and just a rich ecosystem enough to justify it, and nothing that is a killer feature in alternatives. And a situation where compromise over this is not possible.
It never happens to me, that's all.
Whilst I roughly agree, that's still a bit too simplistic.
In particular, we might prefer something like Rust to write a performance-critical algorithm, but that forces us to make a decision:
- Do we stick with Rust for everything else (networking, data plumbing, etc.)? This forces us to confront the ecosystem problem.
- Do we wrap our algorithm as a library for other languages (like Python)? This forces us to confront interoperability (ABIs, FFIs, cross-language dependency management, etc.).
There's lots of room in between these extremes for other pareto-optima, like Java.
Also, we often need to consider latency and throughput separately, rather than just "performance". Java is a pretty stark example, since it's pretty slow to start but reasonably fast when left running (compared to native binaries like Rust, which are low latency and high throughput, or scripting languages like Python which are high latency and low throughput).
And Go is better if you do I/O.
That's my points. Compromises.
I'm not saying "Java is bad". I'm saying, "I have no use case where I, personally, would use Java over something else."
I do know other people have use cases for it.
I just don't, because those compromises don't make sense for me.
Its only saving grace is that all other cross-platform GUI systems also suck, and if you're doing everything else in Java it might be the path of least resistance.
"Filthy Rich Clients" by the nowadays Android UI architects
"Swing Hacks: Tips and Tools for Killer GUIs" by Joshua Marinacci, well know in the UI research community
https://www.amazon.de/dp/0596009070
And then commercial libraries like
(Though I haven’t tried its mobile “backend”)
Java does have android right now, although it has to share with ReactNative, Xamarin and flutter. Again, for different compromises.
Java also has the IDE ecosystem between Netbeans, Eclipse and all JetBrains offerings, with exception of Apple and Microsoft offerings.
You are trying to move the debate toward the quality of java, which is was never my point.
> If I do, I won't go Java, I will choose something that is built for performance. Python is good enough for 99% of my performances need. The last 1%, jumping to java is not a big difference, I'll use rust or go.
So given that, I am curious where are those GUI alternatives with the required perfomance in Go and Rust.
- you need a GUI
- you need perf beyond what Python is capable and you identified it clearly in advance
- you can't use numpy / multiprocessing / cython, pypy or they won't give you the perf you need
- you can't find a main hotpath you can optimize with a 5 lines c or rust extension and write 99.99% of your app in python. Or you don't want to bother.
If you ever find yourself in this very use case, then yes, use Java.
But I never found myself in this very precise use case.
Please.... That's literally the worst option for python on this planet. For all "just do multiprocessing" the tooling is horrible garbage. Then we get to Twisted and Gunicorn the Spring Framework of Python world.
It's hard to separate the absolute performance of Java the language from Java the culture where inefficient patterns or attempts to implement dynamic behaviors in some framework code defeat the JIT (not to mention the benefits of type-checking). If you have a team which cares, it should be faster but the average business app I see does not have that team and will, if lucky, perform within the same order of magnitude as Python.
Speed doesn’t matter always, but when it does it Java feels snappy. Our programs our command line based so our framework use is limited. Also the built in data structures are nice. I still find getting Java’s set up painful, which is a huge impediment for us using it more.
(yeah I know it has type hints now)
import random
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
def hello(seconds):
print(f"Starting hello in {seconds}s")
time.sleep(seconds)
print(f"End of hello in {seconds}s")
return seconds
# At the end of this blocks, it automatically join() and clean
with ThreadPoolExecutor(max_workers=2) as executor: # 2 tasks in parallel max
# this send jobs to threads via safe queues
a = executor.submit(hello, random.randint(0, 5))
b = executor.submit(hello, random.randint(0, 5))
# this collect results from queues in order of completion
# sync is automatic
for future in as_completed((a, b)):
print(future.result())
And if about network I/O only, you can get even more perfs using asyncio.Threads in Python are only inferior to Java threads when it's about using several CPU.
I do enjoy in python that it is quite easy to utilise multiple processes in a code-light fashion, but some things are more natural as threads.
I got into Go for a while, but if I'm honest, it's a kludgey language. Half the reason it has taken off as it has is simply down to the fact that it's backed by google.
That's where you're wrong, kiddo.
But that's not the point. The point is that, for the 99%, staying on a slower language is ok. For the last 1%, I'll skip Java and go to Rust/Go. If I have to do a rewrite for perf sake, I'm not going to go half way.
And for IO, you will get faster perf in Go more easily. Sure, you can finely tune your Java code to get there, but it's a lot harder.
It in both cases it will eat up way more memory.
There is a reason Google, that did use heavily Java internally, is now moving to Go, a language they custom designed for concurrency.
Basically every language is more expressive there (even Java), GC is much much better - in benchmarks it is not as obvious only because Go avoids creating garbage most of the time, but it can’t always be avoided; and the platform is incomparably richer on the JVM side.
* performance is not really an issue for most software ("97% of the time, premature optimization is evil"). A well designed software doesn't suffer from performance issues with current computer performance, unless you do AI or bleeding edge graphics or science simulation.
* there are ways to speed up performance sensitive parts with something else than java, for example by using C/C++, would it be with a python module or cython. Not ideal, but generally you gain performance by adapting your design, not by changing languages. A garbage collector is rarely predictable, hence java is not a good fit for performance.
* I remember playing minecraft with friends, and the server was regularly crashing because it was out of memory, or something like that.
> I remember playing minecraft with friends, and the server was regularly crashing because it was out of memory, or something like that.
I've seen this, but I don't think you can really use one server program running out of RAM as indicative of much. I do still find the pre-setting of max memory on the command line a little bit odd though.
A lot of graduates think that compsci jobs involve optimizing algorithms or some shit coz they did that type of thing as undergrads, so they port that attitude across.
It's also the reason why pypy was massively hyped for a while and then not really used all that much. It was solving the performance problems python never really had.
I have noticed some younger engineers on C++ projects doing some kooky things "because it's more optimal", and have taken time to explain to them that the micro-optimisations they're using impact readability, are going to be done by the compiler anyway if they're at all useful, and are likely to be several orders of magnitude less relevant than some lock somewhere, or a bit of IO, or whatever.
Handling process memory usage pre-docker wasn't so easy.
> well designed software
Ah, there's my problem. Maybe at some point I'll get a chance to work on one of those.
Could be a problem with the logic/design of the server rather than a problem with Java? Despite memory being GC'd, you can still run out of it if you just keep allocating stuff. The important thing about Java is that it doesn't suffer from the usual C or C++ memory exploits.
I think that there are use-cases in which java is more performant than his low-performance options, and can be as performant as his high-performance options, while providing a much larger ecosystem.
I think the parent poster actually makes a very weird set of choices - "when my high level choice, python, is not cutting the mustard, I am happy to throw away breadth of support entirely in the name of optimisation."
It's up to him what his preferences are, of course, I'm not saying they're wrong as much as personal.
The OP even says they're just posting their own selection criteria in other comments.
What I love about Java is, that I can update the runtime without being afraid to break something. I also love the mature eco system. What's also great is that the compiler catches most code issues before you try running your code.
What I don't like is the module support introduced with Java 9, which is vastly inferior to OSGi.
- Python: 1991
Furthermore Python and Java set out to solve very different problems, which is reflected in their design decisions.
- cryptography: It has a wide range support of symmetric/asymmetric algorithms from legacy to modern ones.
- XML and SOAP with Web Service Security in particular.
- Modeling large business concepts because of static typing, Objects inheritance and polymorphism, no memory management while still being performant. I would not use Python for that but other languages can compete C#, Scala, Kotlin, maybe Typescript.
The cryptography module in Python is awesome. lxml and sud deals with XML and Soap in a blink.
Modeling large business concept is a joy with dataclasses, and the language will never be the perf bottleneck.
Now I understand that if you are experienced with Java, it would solve all those problems perfectly.
But again, I would not, personally, gain anything by using it for this.
Startup times are not an issue on servers as processes are typically long-lived anyway. It is a bit of an issue on serverless (lambda etc.) but that’s a relatively new thing. High memory usage is generally poor tuning - if you give the JVM 1gb it will use it and avoid GC until it needs to. Sometimes it’s poor coding too, I’ve seen web APIs accepting files as base64 encoded json strings which is horrific server side.
look at this graph: https://alvinalexander.com/sites/default/files/inline-images...
from: https://alvinalexander.com/scala/graalvm-native-executables-...
Obviously I don't have their dataset, so it's not exactly the same test.
edit: In fact the numbers in the blog are so far off mine they may accidently have been testing /usr/bin/find.
There was just not much interest in it, because performance gets worth, and startup time is seldom interesting. (Pretty much only command line tools would require faster startup, and recent serverless)
And memory usage is a tradeoff. Though most of the time java could run with almost half of the currently used memory, it is unnecessary work to GC if memory is available.
I learned Java on gcj (gcc support for Java), and it generated executables. I've no idea why they killed it. Maybe someone more in the know can explain.
Interesting - you seem to be saying that Lisp is very opinionated. If that was your intent, may I ask why? Your experience doesn't jibe with my experience as a Common Lisp user, which is that Lisp isn't opinionated enough, and gives you too much flexibility (in some cases).
I think the opinion you're trying to convey is "not untyped enough".
WELL SUPPORTED???? Have you ever coded a real thing in python?
I'm getting "Warning, no longer supported" console messages in all my basic well established tools and libraries written in python because a guy that lives in a world of academics and theory and not in a world of business and delivery dates decided that python3 was not going to have backwards compatibility with python2 because they made a massive irreparable disaster when they designed python2.
That is not a professional tool for multi-million dollar companies, that is a toy for spoiled nerds. Exactly the same that Visual Basic 5-6 were when I was starting. Extremely easy to use and extremely fast, at the price of been garbage for anything larger than a toy app.
And because all the kids learned that at uni and went to create the next thing in it like PyTorch and TensorFlow, now you have to do all the real code in C / C++ to handle what python can't in terms of speed an reliability, doubling you code base, your Dev teams, and the needed skill set.
I have been programing in java in large multinationals for 10 years and I used python every single day for the past 3 years for what its useful: small hacky scripts to increase productivity. The real sh*t that manages you cellphone towers, you home-banking, you online shopping, your logistic chain and your android cellphone apps, all things that I have worked on, gets done in Java.
I myself have coded a streaming platform getting half a million user every day in Python. Baring the CDN to store the content, it runs on 2 servers, one for the DB.
So real things get done in Python pretty well.
_But as the company grew, new engineers who joined couldn’t understand the code. Clever code is usually short and cryptic, written by and for the individual who came up with it, but is hard for anyone else to understand—and nearly impossible to maintain. Guido called this “cowboy coding culture”. He recognized its value in our early stages of trying to implement things quickly, but knew it wouldn’t be sustainable over time, so he decided to speak up in his own quiet way._
And now they'll have to rewrite everything in programming languages where maintenance is not a burden.
[0] https://blog.dropbox.com/topics/company/thank-you--guido
Here you go:
https://dropbox.tech/infrastructure/rewriting-the-heart-of-o...
- not high level enough to compete with Python/Ruby/JS/PHP, etc
- not low level enough to compete with Rust/D/Nim/Zig
- not specialized enough to compete with Erlang/R/Go/Julia
- not opinionated enough to compete with Lisp/Haskell
So why use Java ? It's good, it's fast, it's productive, it's well supported, battle tested and documented for decades with a huge pool of devs. And many companies already use it and the tooling is excellent.
But those are not sufficient reasons for me.
Python is older than Java, well supported, battle tested, documented with a huge pool of devs. But it's way better for high level stuff, data mangling, scripting, gluing, and for most web dev stuff.
If I want a distributed system or something with a lot of I/O, Erlang and Go will always be better than Java. Sure, they are less widespread, with all the stuff it implies, but for such a nice need, I will pay the price hapily: my goal is optimization for the use case. Same for stuff that needs to go fast or have a small footprint, I'm not going Java if I can go Rust.
If I want to have fun, Java is out of the loop. Better sharpen my inner weirdness by fighting with some exotic lisp. Why try productive ? I wanna enjoy myself, not run a business.
So Java is not a bad choice. It's an excellent tech. I just don't have a use case for it.