Where it gets tricky is in an environment like the JVM where programming in that style was not anticipated, and introducing any optimizations along these lines for the benefit of the proverbial Scala fans needs to be balanced against the obligation not to adversely impact idiomatic Java code.
That said, even without that, it's not necessarily crazy. It's just a value call: Do you believe that more functional code is easier to maintain, and perhaps value that above raw performance? I'm old enough to remember similar debates about how object-oriented C++ code should be, and to have at least encountered Usenet posts from similar debates about how structured C code should be. I don't bring this up by way of trying to weasel in some "historical inevitability" argument - these are legitimate debates, and there are still problem domains where coding guidelines may discourage, or even prohibit, certain structured programming practices. For very good reasons.
(If this sounds harsh, it's not my intention. In another HN thread I had someone "explain" to me how Java and Java's OOP is "not suitable for business software development". If this seems like a bizarre statement which disregards more than a decade of business software development -- this is why I ask for actual experience and not opinions or "I think this can't be right").
How so? Performance? Reliability? Verbosity? Which language is suitable in your opinion?
To me this kind of opinion-based... um, opinions... fly in the face of evidence. Java has been used for more than a decade to deploy business software to great success. What more evidence does one need? It'd be like arguing "COBOL is unsuitable for banking".
In the meantime, opinions have shifted on best engineering practices, and Java has naturally run the gamut of all these opinions. And because there are tons of Java systems, there's no shortage of examples of failed/bad projects one could pick on. I wonder how many languages/platforms would have fared better...
What I mean is that I think using Java meant the company was required to spend more resources than should have been necessary to accomplish their goal.
BTW, when I say "Java", I mean the language, not the platform. Java-the-platform is very suitable to business software. Java-the-language, less so. Java OOP brings with it a ridiculous amount of incidental complexity, boilerplate, and impedance mismatches. Of course you can make it work, I do it every day. I just think it's a poor choice. It's certainly not the worst choice, and the platform + available libraries is definitely a plus.
And as I mentioned in my original post, there are way to make it more suitable through various hacks (like Lombok) and libraries, but other languages are more suitable out of the box (including other JVM languages).
https://www.techempower.com/benchmarks/
The source code is published too (https://github.com/TechEmpower/FrameworkBenchmarks)
There are certain things you might have trouble getting Java to perform, such as strict latency requirements. Another language might be more suitable for that. But that generally doesn't describe business software.
Desktop software is somewhere you probably don't want to use Java. Although if it's business desktop software, it might be a good fit since it can be cross platform (but ugly - but if it's business, it might not matter). We've built several desktop apps for warehouse computers in Java.
Getting the JVM on a machine may or may not be a hurdle. This is one of many reasons why Go is getting popular - you can just build a binary.
The positive of Java is that if you want to do something in it, someone else has probably tried. It has several large organizations backing professional quality libraries and frameworks that have had a ton of resources poured into them. It's easy to build on the shoulders of giants while relying on 3rd party libraries that don't have a bus factor of 1 - this is rare in many other languages.
If you want stability and well trodden paths, it's hard to go wrong with Java. We've had projects that continued to just work from Java 1.4 to Java 8 - a span of almost 15 years without ever having to touch the code. Java 9 was a bit of a hurdle because of project Jigsaw.
Understood, but I'm specifically excluding those opinions because they tell me nothing and are unrelated to suitability. Some Smalltalk folk will tell you nothing that is not Smalltalk is suitable for anything; how much would you value their opinion when determining whether a language is suitable for development?
"I hate $LANGUAGE, therefore it's unsuitable for $DOMAIN" is the lowest, less useful form of opinion. It belongs in the realm of flamewars, not of informed decisions.
Suitability to me is not related to whether I hate or like a language. I hate COBOL. I've worked with it. I'd never in a million years argue it's not suitable for banking systems, because that would run contrary to established history.
As for other applications: I agree Java is not suitable for everything. I specifically argued about business software. That said, what about Minecraft, a hugely successful desktop game? :)
jlink[1] makes it pretty easy if you're using a recent JDK.
This was/is one of Java's mistakes. It's always been oddly hostile to JVM bundling, although some projects do so anyway (e.g. Jira). More generally, Java makes the mistake of making itself known to the user. The user is expected to install a JVM, rather than one being bundled with the application, and they're then expected to ensure it updates itself appropriately, complete with an annoying taskbar icon and always-resident auto-updater (on Windows, that is).
The user shouldn't even know the word 'Java'. Applications written in Pascal, for instance, are just applications. The user isn't made aware of the technology used.
Especially unfortunate considering that, as far as I can tell, JavaFX is really a pretty good GUI toolkit (I've only dabbled). Perhaps things will change as ahead-of-time compilation for Java becomes more mainstream.
I understand JIT compilation is pretty advanced these days. Wouldn't this go against it? Or maybe the approach can be mixed, but if so, you'd still need the runtime environment ("the JVM").
I imagine JIT compilation should help with this, as you suggest.
"One can, with sufficient effort, essentially write C code in Haskell using various unsafe primitives. We would argue that this is not true to the spirit and goals of Haskell, and we have attempted in this paper to remain within the space of reasonably idiomatic Haskell. However, we have made abundant use of strictness annotations, explicit strictness, and unboxed vectors. We have, more controversially perhaps, used unsafe array subscripting in places. Are our choices reasonable?"
http://www.leafpetersen.com/leaf/publications/ifl2013/haskel...
Programs for the n-body and spectral-norm procedural benchmarks game tasks, perform kind-of the same in Haskell and Java
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
Come on... that's not what you typically get with Haskell, is it.
Not talking against Haskell or FP; The disadvantage is being hard to reason about performance. Ensuring compiler will optimize something will take more cognitive load than simply writing straightforward code.
Imagine having a map() method on an array that produces another array. In a long chained pipeline of such things, compiler may be able to elide extra allocations and generate asm very near to handwritten for loops. But the abstraction breaks when the method does I/O or has side effects - you can't reorder anything in order to elide allocations. (Well this example may not make sense in Haskell because Haskell is lazily evaluated).
However there is a limit to what compiler can do, and it might manifest in edge cases like variation in order of imports. I'd rather have straightforward code than relying on compiler optimizations.
I am not arguing "against abstractions" like some Go fanboys tell you map and filter are less efficient. It is always possible to apply same map filter to iterators/lazy streams instead of arrays and get same performance in straightforward code. But that's not same as keeping in mind what heuristics compiler uses to optimize the code.
High level languages produce a lot less code than than less optimized implementations. Difficulties with reasoning about execution/performance is the penalty you potentially have to pay.
In my experience it indeed may be hard to understand performance with Haskell. That said, it comes with excellent tooling to overcome it in most of the cases.
We have so many cores now that it tends to be a positive trade-off to have many threads doing some wasteful work (copies, extra GC pressure, potentially multiple threads duplicating the same work) than trying to have a perfectly optimized single thread.
It's just a bad idea.
It depends how it's implemented. It's possible to get very nice performance with immutability and copying through use of an arena allocator, as your stuff will essentially always be in cache (due to reusing the arena), and allocation/deallocation is just bumping a pointer. Of course, not everything easily fits into this approach, but a surprisingly large amount of code can, if designed with it in mind (and using a language that supports it without too much pain, like C/C++).
The language Zig is particularly interesting in this regard because everything that allocates takes the allocator as a param, and it has built-in arena allocators in the standard lib.
I believe you can express your problem (and solution) better using FP, once you have it solved you can zoom in and replace the most demanding segments with iterative programming, or go down lower to the bare metal.
Unfortunately, the legacy Java semantics of == means that they can't do this proactively. But didn't Java get opt-in value types recently?