Might have been true back in the JDK 6 or JDK 7 age but from JDK 8 to JDK 19 it has become a better functional programming language than most functional programming languages.
If the author likes he can keep coding in C++ where strcpy is Turing complete.
Bogus comment. This is very far from the truth. Lambdas and streams don't make a functional language.
So far I'm still seeing complex class hierarchies with deep inheritance, dependency injection and unit tests produced by ex-Java developers for something that can be solved with a couple of simple methods in Python.
I noticed that complexity makes Java folks proud. Conversely, simplicity makes Python folks proud.
Seeing Java on a resume is not yet a reason not to hire for me. But it's a signal that indicates greater risks.
I wrote my own competitor at
http://gihub.com/paulhoule/pidove/
which looks lispy because it uses static imports for everything. I started on a fluent syntax version but wound up working on another project. The odd thing is that I wound up studying the streams API in enough detail that I got over many of the complaints I had about it. If I was going to put more work into pidove it would be developing it to make the most of the Collections API so if you, say, map a list, it returns a list that lets you get(7) to only map that item.
They are great for libraries with well defined and slowly evolving interfaces. But unless you're doing open-source, you will rarely work on those.
Write tests. Not too many. Mostly integration.
Perhaps this turns into another round of clarifying what the discussion participants deem "unit" vs "integration".
Edit: my experience is mostly between seed - series B startups. If you're Google, then of course you're going to have a ton of internal libraries. But I'd put it in the same category as open source.
- Haskell
- Scala
- Kotlin (not FP but better than Java at it)
- Clojure
- Scheme
- Common Lisp
- Erlang
- Elixer
- PureScript
- Elm
- TypeScript (not even FP but moreso than Java lol)
I really doubt you can say it's clearly better than even one.
I have frequently seen Scala programs that allegedly use monads for error handling that actually blast right past errors with no handling. That use some kind of snake oil concurrency that never gets the same answer twice (race conditions) but also uses just 2.5 cores on a 8 core machine.
(In general few people appreciate the wide range of of concurrency primitives that Java offers. People want to believe that you can write correct and performant concurrent code with a small set of primitives but it just isn’t true.)
Books on Scala try to seduce you with examples that look concise but they are all structurally unstable and get an order of magnitude more complex when you change anything. (I’d contrast that to Cold Fusion, PHP, and other poorly regarded languages where I’ve sometimes met a correct program.)
I am also unimpressed w/ Kotlin. It beats the pants off JDK 7 but not JDK 19 particularly if you use an IDE that does static analysis.
LOL
uhh, let me know when they add the ability to define a standalone function that exists outside of a class.
> If the author likes he can keep coding in C++ where strcpy is Turing complete.
c++ certainly has its warts. but having worked with both professionally, I find java to be by far the more frustrating of the two.
some random gripes off the top of my head:
I can't invoke a no-args constructor like this: `MyType var;`
I can't do something like `public MyType() = delete` to make my class nonconstructable (which would at least partially help with the "no standalone functions" issue).
there is no notion of tuple in the standard library. I have to define a new class (or abuse Map.Entry) every time I want to return more than one value from a method.
I can't construct a collection (or POD) type like this: `MyCollection c = { a, b, c };`. Yes, I can do stuff like `List<T> list = Arrays.asList(a, b, c)`, but then I have an immutable array enclosed by a mutable list, where any attempt to modify it is a runtime error?!
in my experience, java somehow manages to be more verbose and less ergonomic than c++, which is really saying something.
disclaimer: I have not worked much with JDK versions >11, so maybe they've addressed some of above.
People who write functional libraries in Java frequently write Pair<A,B> and sometimes Triple<A,B,C> but they independently discover there is no point in declaring a Tuple27. Recovering LISP programmers point out the ‘nameless tuple’ problem is one of the many reasons the idea of LISP is better than the reality. In modern Java you can write a record if you need to bundle together a few results.
It has become popular to hate Java, but again that goes back previous JDK's.
JDK 19 is a strong functional language that should not be dismissed lightly.
I programmed Java way back in 2003 and I didn't like it then. C# was quickly catching and surpassed it. Almost 20 years later I have no reason to even try and go back to it. There are plenty of better options now.
That's hardly a drawback. If every Electron app can get away with shipping a Chromium instance with every installer, you can ship a JVM with your app.
Of course, it's not an either-or - I'm sure many of those containers would have Electron inside...
I have a Stack Overflow question at https://stackoverflow.com/q/8913543/303363 which taught me how to identify the right version of the runtime library and how to fetch it. I don't do software development for Windows in C++ these days but once in a while I do look back at this question to fondly remember the days of C++ programming on Windows.
Except for the tiny "SideBySide" glitch (which was quite confusing at first), software development with C++ on Windows using Visual Studio as the IDE was a pleasant experience. Backward compatibility was (probably still is?) a strong suit of Windows. A software written in the 1990s worked fine all the way up to 2015 or so, often with no changes or no recompile/rebuild required. The binaries and DLLs would just work fine without issues on newer versions of Windows as long as the CRT the software was built with is also packaged in the software distribution.
I would think, also, given the trade embargo, you'd have to write and maintain (somewhere within your borders) all the software which an American company might buy off-the-shelf.
Of the few talents who decided to remain in the country, even fewer want to do boring enterprise work and they prefer staying on the "bleeding edge". Therefore there are very few companies doing java which can compete with foreign firms in payment(and so can keep talent and code quality).
As for Java... I don't get the hate. It's not perfect by any means, but I generally enjoy working in it. Maybe just because I've been doing it so long and I've normalized whatever pains there are. That said, given a choice between pure Java, and Groovy, I will generally go with Groovy instead. It takes away enough of the sharp edges to make what I consider a quite fine language.
I don't hate Java like I use to and it has definitely got better over the years, but it's not the first tool I reach for or consider for new projects because of past experiences. I understand that a lot of the issues were because people were not "leaving their ego at the door" but regardless it still created a negative experience that followed me for years.
Just because it changed, doesn't invalidate people's past experiences/grievances.
Personally, as I stated I don't hate it like I use to and will use it when it's the right solution to the current problem but just because it's better now days doesn't mean it has to be my first choice.
Edit: Your reply is basically the equivalent of. "Back in the early days your ex cheated on you twice... but she's changed and you should give her another shot"... A Disney/Lifetime/Hallmark movie life is not. I may talk to her and eventually be a friend, but I'm going to be weary of knives aimed for my back.