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.
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.
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.
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.
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.
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.
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.
I looked up "engraving marble" to find an example of the above, but no luck there: They use lasers for that now.
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.
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 :-)
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.
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.
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.
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)
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.
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.
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.
Rails is so-so.
I hear every day: don't change a thing in D, just add these two features.
We get it, some people are unhappy that py2 is deprecated. But whatever sympathy I might hold for that viewpoint is drowned out by the incessant and unproductive whining I keep seeing here.
Can we please move on now?
There's nothing "simple" about "list of characters" in Unicode. Discussed at length at: https://news.ycombinator.com/item?id=18154667
Here's how a Unicode export with 20 years of experience in Unicode explained it: https://blog.golang.org/strings
> Some people think Go strings are always UTF-8, but they are not: only string literals are UTF-8. As we showed in the previous section, string values can contain arbitrary bytes; as we showed in this one, string literals always contain UTF-8 text as long as they have no byte-level escapes.
> In fact, the definition of "character" is ambiguous and it would be a mistake to try to resolve the ambiguity by defining that strings are made of characters.
> [Exercise: Put an invalid UTF-8 byte sequence into the string. (How?) What happens to the iterations of the loop?]
If you aren't in Unicode, then "character" is the same as "byte" so splitting the types gets you nothing of vlaue.
Assuming you are not implementing a low-level Unicode library, what's your use case for "list of Unicode characters" ?
This would help a lot in preparing code incrementally to work on python3.
In the mean time, mypy in python 2 mode doesn't warn about str <-> bytes either :/
I would call it more something like upgrade debt or time debt, as it's a problem that appeared because an external situation changed over time. Similar problem in that regard are operating systems which change and let old software behind, or in case of linux old packages not working anymore, repos disappearing, etc.
What I'm talking about can't be improved or fixed, or higher-ups refuse to improve or fix it. Instead, it has to be completely replaced. It's like a Replicant with a four-year lifespan. You literally know it's going to die in four years, and nobody orders a new one until the old one is practically dead, and everyone has to rush to replace it.
Being a CADD person, I had a lot of contact with A/E/C, facilities management, space planning, etc.
Seems like everyone suffers legacy, neglects maintenance, prefers do overs.
Cultural? Misaligned incentives? Bad accounting? Complexity catastrophe (when cost of any change outweighs benefits)?
If someone knows, please tell.
Sustained operations are hard unless you have growth, because flat budgets are cuts given inflation, etc. Given the choice between stocking the toilet paper or doing a preventative maintenance on the elevator that may impact your successor a few years from now, what do you choose?
The only times that facilities are run well is when there is a retired senior military nco in charge. Usually someone who was a chief of the boat in the Navy.
Businesses think once it's written it will always just work...and that's true if the underlying OS and hardware never change, and the business never changes, and requirements never change. But even if it's a completely niche application whose requirements never change, after a while the hardware breaks, and we can't buy the same, and we can't license the old OS or it has documented problems that won't be fixed, so we have to use a new one, and we can't get the old software dependencies to work on the new one, etc etc.
It's not too late though. We could add better backward compatibility into Python 3.
Not all companies have the big tech or mid/early stage VC money to throw around. Who knows what kind of other tech debt Dropbox has accumulated.
He also spent large amount of time working on mypy (type checker) which my understanding is also is used for the migration to address unicode issues.
It says "He has already put into motion the conversion of the Dropbox server code from Python 2 to Python 3. "
"already" refers to "sometime in the past 6 years".
Perhaps it’s already done, in which case this word choice is poor.
No really, what was the relevance of that comment? A task from a decade ago, with maintenance reaching end of life in two months, and they're off-topic boasting about "already starting" it. What, they think it's early and applause-worthy? They're trying to show that even Guido had to deal with it? Or that even with Guido they couldn't complete it quickly? "Here are some words about Python to make the PR representative look hip and with it"?
Nothing about that interjection reflects particularly well on Dropbox - it's far off the tone of the rest of the post, they would have been better off not mentioning it at all.
People migrate when the allure of Python 3 outweighs the hassle of juggling 2 versions. Naturally, people who grew up on Python 2 are more hesitant than people who started later on Python 3.
Fundamentally the issue is that the Python language is too dynamic for static analyzers to fully understand the code and perform conversions. I'm not just talking about type systems, but also monkey patching, reflections, etc.
What we really need is a tool that runs your Python 2 code, records types and other dynamic manipulations, and then produce Python 3 code. But I'm not aware of such a tool.
That's a great idea, but it sounds pretty intense to implement. I ended up becoming addicted to ML-family languages pretty early (Scala, F#, OCaml, Rust) for a variety of reasons, but I never fully grasped how much strong/static types help for refactoring until I tried refactoring some Ruby code. I can't imagine trying to write an automated tool for the task.
[1] https://github.com/dropbox/pyannotate [2] https://github.com/instagram/MonkeyType [3] https://github.com/google/pytype
For example in python 3 they actually made import statements more predictable they are now absolute by default, it was a bit ambiguous in python 2. Ignoring the ambiguity (which is a problem by itself) some people were creative and instead doing standard imports like god intended decided to do it dynamically using importlib, that can't be easily fixed if the file you're importing is a variable.
Another problem: unicode, actually most python 2 code is broken and it can crap out whenever you use characters outside of ascii. That's because it conflates bytes with text, python 3 makes the distinction strict, so you have to properly address it. Though for 99% of application user meant text, so perhaps this assumption could be made?
- division, in python 2 division worked similar to C, if both the parameters were integers you get integer as a result, python 3 changed it to be more what most people would expect, although python 3 also introduced // which had the prior behavior so I guess this could be automated
There are probably others too.
Dropbox's server code base is literally millions of lines of Python 2. The "stop all development" approach simply won't work there. The only thing that works is to port the whole code base to "straddling code" that works on both interpreters, then switch interpreters. Automated tooling to prevent regressions is essential.