And since Java 8 the language is pretty nice and offers good functional idioms.
Of course, major versions of libraries still change. But there's no match with the JS approach.
Personally I would second Go as a good answer for this. It has its limitations, but it’s simplicity and it’s standard library more than make up for that from a pragmatic standpoint imo
You can't have it both ways,
OTOH current JVM can still correctly run bytecode compiled by Java 1.0.1 (or maybe even earlier), so the backwards compatibility is indeed excellent.
I'm confident every programming language thought it was complete at some point... but eventually it's users demand some new "hot" feature and then you're back to releasing new versions again.
The C programming language just had a release in June 2018, C18. For a language released 47 years ago... and it's a pretty basic language compared to most other languages.
Fortran was released 62 years ago, and just released Fortran 2018 in November of 2018.
> You can't have it both ways,
You can have a continuously improving platform with full backward compatibility, and all the improvements that aren't just efficiency of established operations are opt-in.
With Spring-Boot you can even start treating Spring and friends like a "Black Box", and stop caring about how it does what it does.
Springboot takes an opinionated approach to a lot of things, but always lets you override it and do whatever you want wherever you want.
I suppose that's more of a greybox...
You end up making your own framework that has all that in it, so that you just change a few things here and there and can start getting to the business logic that much quicker.
Then you realize you're maintaining all of that code... when you'd much rather maintain the business logic bits...
Which leads to using Spring Boot and letting them maintain everything else.
I'm also coming around on Go. The simplicity was a turn off at first, but now that I've used it to implement a graphql server I like the simplicity. I don't want to have to be a programming language researcher to quickly get work done. IMO Go delivers in that mission.
Can you give some references for the patents issue you mentioned?
Maybe Jigsaw didn't impact you particularly hard, but you can't argue the JVM has a policy of minimal backwards incompatible changes given that debacle.
You seriously didn't suffer any of these?
It’s probably pretty helpful that the scala ecosystem doesn’t depend much on non-well trodden parts of the JDK
It's not "exceedingly good" at it, it's just alright. Go has done much better for us in this area.
If you want newer versions of the JDK, you can get them directly from Oracle[2] still, or from alternatives like AdoptOpenJDK[3].
If you want to quickly and easily switch between distributions, I highly recommend https://sdkman.io/ - it lets you install and use any of the above mentioned JVMs with a simple CLI... e.g. `sdk use 13.0.1.j9-adpt` or `sdk use java 8.0.232-zulu`.
I would guess that Oracle's JVM popularity has gone down from around 75% of Java users, to something like 20% after the changes, even though I don't actually have the numbers.
I would argue that the .NET Framework is way better. The way you can have multiple versions installed side by side and have the framework pick the correct one to run is awesome. Granted, you can do something similar with the JVM by mucking around with env vars, but it's not the same thing.
The Future is .Net Core.
Python 2.7 is not getting any kind of updates including security and bugfixes.
Standing still in the Java ecosystem is fine. Keeping on with the advances is painful and exhausting. The Java tech stack is awesome when it works, but to solve issues you have to go so deep into the tech stack that I'm starting to think it just can't be done unless you're at least a mid-sized company with JVM specialists on the payroll. Not developers, but systems people.
Why would that be the case?
> Wanna use JavaFX? You have to jump to Java 11 and hope your dependencies don't fail with module packaging errors.
Dependencies which still fail with module errors are basically abandoned and should probably be replaced. But even for those there's an escape hatch if you really want to continue using them, so that seems to be a non-issue?
> The Java tech stack is awesome when it works, but to solve issues you have to go so deep into the tech stack that I'm starting to think it just can't be done unless you're at least a mid-sized company with JVM specialists on the payroll. Not developers, but systems people.
I've worked either directly or indirectly with so many companies of all sizes using Java without any dedicated JVM specialists I'm pretty sure you're doing something very, very wrong with all the problems you seem to have.
I have a desktop Java app with platform-specific installers (.msi, .deb, .dmg). The Windows and Mac installers include a Java runtime, so the user doesn't have to worry about installing an external runtime. I'm forced to use Oracle JVM, because it's the only Java distribution that includes the tools needed. There's ongoing development on a tool that should bring these and more related features to the open JVMs, but it's not done yet.
> Dependencies which still fail with module errors are basically abandoned and should probably be replaced. But even for those there's an escape hatch if you really want to continue using them, so that seems to be a non-issue?
The issue is that the upgrade path isn't smooth. I have to upgrade everything at the same time, because what works on Java 11 doesn't work in Java 8, and viceversa. It makes everything way harder than it should be, if there was a clear migration path.
> I've worked either directly or indirectly with so many companies of all sizes using Java without any dedicated JVM specialists I'm pretty sure you're doing something very, very wrong with all the problems you seem to have.
What I do falls into a niche. It's not "very wrong" but it's uncommon. The main issue is that Java was a non-issue, a stable platform to build upon. But the recent Oracle license change forced us to move to fully open versions of Java that do not have the same features, do not bundle the same libraries, and do not have documentation detailing all these differences.
I'm not asking for a community to finish whatever feature I need, or for a company to make what I need free to use. I'm just trying to explain my own problems caused by Oracle forcing us to move to open distributions of the Java platform.
I'm currently working on a web service that was written under Java 8.
For giggles, I just ran the end-to-end tests suite under Java 8, 11, and 13. The only error I got was an incompatibility with Google's Error Prone linter, which I was able to fix with one line change.
This represents a few hundred thousand lines of production code that works just fine under every important JDK in use today.
Oracle JDK 8 contained some small parts that were proprietary. And they mostly had the proper package name. You took the risk.
> Wanna bundle a JVM with your app so your users don't have to worry about the Java runtime? Well, you can't do that anymore.
You mean, bundling a JVM exactly like all JetBrains IDEs currently do?
> Wanna use JavaFX? You have to jump to Java 11 and hope your dependencies don't fail with module packaging errors.
JavaFX is a bit of a strange thing, and yes, it can be painful. And some modules struggle with the new module system. The module system is a breaking change, and in fact it took quite a while.
> Scala
That's a problem with the Scala compiler AFAIK, not with Java.
I did not. Some libraries I depend on did.
> You mean, bundling a JVM exactly like all JetBrains IDEs currently do?
Yes. I'm researching how they do it. Previously it could be done with one command. Jetbrains use their own patched JVM and have JVM experts on their payroll. What they do goes way beyond my current skills.
> That's a problem with the Scala compiler AFAIK, not with Java.
From a JVM point of view, Scala is just one more library. The problem with Scala right now is that it doesn't support the module system. This means yet another dive at a lower level to try to fix any issue that appears.
The dance over that as we've gone from 8 to 9 to 10 to 11 is mind boggling.
This is probably why I’ve come to appreciate Rich Hickey’s talks more and more as years go by.
I think Clojure is a good fit when it comes to stability as per their own development guidelines [1]:
The Clojure development team values a measured and thoughtful approach to language evolution with a strong emphasis on maintaining backward compatibility.
FTFY
Also for BLAS, the underlying code is usually no longer Fortran.
Go is good at being Pythonic in some senses too. Some would say to a fault.
Standardized since the 80s, it has had only minor, backwards compatible revisions in 99 and 11.
According to the TIOBE index, it's the second most popular language in the world. It works on almost any platform imaginable and it has decades of tooling available for it.
Of course it doesn't have any of the good new things developed recently, but if it's stability what you look for, then I don't see a better option.
The rule has generally been that you can take a 20 year old Perl script and it will still just run. This has its own complications though, as it makes it harder to advance the language, and then people feel it's being left behind (the Perl 6 stuff came after that feeling developed).
It's a longstanding problem in language design and communities, stability vs advancement.
Core modules are all I would worry about, but I'm pretty sure those are held to the same standard as far as backwards compatibility.
One or two modules might have been ejected from core or moved into core, but those should be easily found on CPAN as well.
In the end, getting something working from scratch on a newer Perl that has a lot of CPAN dependencies (as opposed to just updating Perl) might be a little annoying in that you have to track down all the module versions, but it's far from impossible, or even all that hard.
For example, the CGI module[1], which was a core module but historically seen as fairly bad (at least as of now, and at least in some of its uses, it supported a wide set of use cases), it was removed from core and housed on CPAN. If you follow the link provided and check the past versions (dropdown as part of the module path and name), you'll see there are many versions shown, possibly every public version, and going back to 1998 for CPAN, and 1995 for 1995 for the BackPAN. Each of those is visible as an item with it's documentation at the time and the module available to download and use. You can also access the CPAN testing matrix[2], and if you dig around you can actually find the results for some tests back in 1999.[3]
If I was responsible for getting some old Perl app to run on a more modern system, I would by much more worried about the OS changing in a complex way than I would about getting the Perl code to run again as expected. Which is to say, I wouldn't be worried much at all.
1: https://metacpan.org/release/CGI
Also, if you desperately need an older version, you can usually install that older version rather than the newest.
Anyways, there's things you can do. I still work on code I started in my dorm room (in the 90's). Cranky CPAN modules aren't too big of a problem.
I usually use Python these days when dealing with SaaS apps since the ecosystem is much better, and I want to learn it anyway.
If you depend on some functions in the standard library, it's super-easy to replace them. They're leaf dependencies.
Anyway, C has about the smallest standard library you can have. And if we're talking about it's benefits in terms of compatibility, we're probably talking about the fact that it doesn't introduce new syntax / language features each other week.
https://elixir-lang.org/blog/2019/06/24/elixir-v1-9-0-releas...
That being said I like writing code that can feel “done”. No “I wish I could refactor this object hierarchy to make it easier to use, etc” notions in the back of my mind. Not every piece of code is like that, but enough.
About the only change that had a significant impact on projects I worked on was removal of the 'mysql' DB extension (replaced by 'mysqli' and 'PDO'). For an older project I created a few shim functions and it still works just fine.
While frameworks come and go, the core of the language is highly backward compatible. The choices made early on were in the UNIX style, so they were right.
To quote an earlier post[1],
--
There is something to be said about PHP's staying power. The early versions of the language weren't considered "right". Except maybe they were right for the problem at hand.
The way I see it was PHP captured the vector of change, and left ample room for future developments. Both internal changes (hello, bytecode; hello, JIT), language level features (hi there, namespaces), and runtime level features (oh hai, countless built in classes and functions).
Moreover, unlike many framework that shone brightly and burned out quickly (Rails?), PHP captured the essence of the environment: HTTP is stateless, and URLs aren't uniformly routable from either end, and well-formed HTML/XML/JSON is just a subset of tag soup.
Worse is better.
--
the XML parsing was probably the biggest BC change I hit between 4 and 5.
Even with these "cherry picked sites", we had about a 30% failure rate dealing with the new PHP. Ranging from total non-function of some random CMS, to mostly errors printing all over every page due to some deprecated or change of code behavior in the site templates.
The language is arguably complete and any syntactic changes you could wish upon yourself are doable in form of a library because it’s a lisp.
And all that piggybacks on top of already quite stable java ecosystem.
Can’t get much better than that.
Maybe C? Cobol? Ada? Fortran? Though even those languages have modern flavors & updates...
We make progress because we learn, not just new technology, bu new approaches to old problems. When I see an "old" programmer who keeps writing C89 code because "it still works", it is painful to see them rejecting decades of learnings about how to write better software.
I looked up "engraving marble" to find an example of the above, but no luck there: They use lasers for that now.
I do enjoy some of the "new" features of python 3.
We had to come up with a new name, do a find/replace, review the changes, test, fix a couple of issues because the replace wasn't perfect/complete, update the dev documentation, make a new patch release, and then create packages for the various supported platforms. Oh and looking back over it now, the filename had to be changed too, because apparently you can't use a keyword as a module name in Python either. So where the documentation linked directly to that file, that had to be updated as well.
I generally run with LANG=C, and run into Python3 issues regularly as a result.
Also, if you have to support 'async' code that someone wrote, that could be a heavy load as well.
Come on over to Javaland, it's nice, warm, and the sun is always shining!
With the exception of the Java 8 -> Java 11 transition (skipping the non-LTS versions), things are pretty stable. You don't have to use any new-fangled features if you don't want... and your Java 3 code compiled nearly 20 years ago will still run just fine on modern JVM's.
My oracle predicts much worse weather.
Funny joke, but Oracle is all but out of the equation at this point.
They've stepped back and become yet another JVM vendor that takes OpenJDK source and compiles it into a binary for users, sprinkled with some special sauce here and there, and just happens to charge for support.
That puts them in line with Azul, IBM, Amazon, AdoptOpenJDK Project, SAP, Red Hat, and a ton more.
You get your pick of JVM vendors now... That's a fantastic thing for Java.
Running code is the easy part. Writing it is the hard part.
And if running on a VM is your standard, my old DOS programs still run on DOSBox :-)
Java and the JVM themselves value backward compatibility, and I'd say Clojure takes it a notch above that.
Overall it was for the best, since prior to that it was just weird code that had a bit of a undefined behavior since it wasn't using the macro in the proper way. But it still meant we had to go and fix a few of them so they compiled again. Though in the process we realized that we were misusing the macros to begin with.
Also, new tech trends are not just hot air, there's also a lot of innovation happening. You just have to see through the hype and wait until the dust settles.
If you are successfully (i.e. the business or product keeps being developed) you still need to be aware of the internal weaknesses of your original choices and the external opportunities of updating to something more modern. The challenge is in managing the transition which is a skill in itself.
Sure, but I've worked with a number of individuals who have either resigned (on their own), or have been let go, solely because they had no desire or interest in keeping up with their craft.
I think that's effectively the same thing, though.
Ultimately, the notion of not wanting to stay abreast of the current industry trends is neither something I can relate to, nor is it something I see as being compatible with one's employability.
Reinventing wheels isn't innovation, particularly if the reinvention isn't round.
I assume that I hear about new stuff fairly early in their adoption, since I try to keep up with these things, so if it's still a thing two years later, it might have enough staying power to be worth learning. After that it still takes a while for me to get around actually learning the things.
Go and Rust are languages that have been on my todo list for a while now, for example, but I still haven't touched a JS framework because I haven't seen one with staying power yet.
Just get away from javascript and once in 20 year platform language changes like swift and most platforms don't have that much churn.
It's part of the value proposition: the language and libraries are planned for forward compatibility and stability for use ten years in the future, as well as now.
It's ideal if it has a stable community, but it should be a small group of core devs, so they don't have time to change things that aren't broken. It helps if the community has a culture of stability.
In my experience, FreeBSD and Erlang fit this bill. You may need to manage some small changes now and again when upgrading between releases, but generally the most apparent changes are things you were doing before work better. And you can run a fleet with rather divergent versions, as long as you're careful not to use new features (it helps to make sure your dev environment matches your most out of date hosts)
I hear every day: don't change a thing in D, just add these two features.
C also shows excellent stability and backwards compatibility.
Cobol is also quite stable, but IDK about the quality of open-source tools for it.
The problem of stability is that you are pinned to the moment when the interfaces were defined and committed to, and this moment goes further and further into the past. Quite often this means that you can't use the new things which give advantage to your competitors.
Rails is so-so.
Python 3 is 11 years old.
11 years is a long time to married to the bugs of the past.
20 years is a long time to be married to a fixed language.
Currently there is no all encompassing theory for the design of languages or anything. So there's no prove-able way to design a language that can always be improved and always be backward compatible.
I imagine that such a language would be incredibly simple. Minimal syntax and all sugar and conveniences would be built with libraries.