Versioning and deprecation

These thoughts were born when I was thinking about Python2-Python3 revolution and bloat of C++. Python and C++ use different approaches to versioning and both of them have their flaws. These flaws have so dramatic effects that I think that both approaches are not suitable for Panda.

Python’s revolution

I call it revolution because there were no easy way to port programs written with Python2 to Python3 (Python3). This caused huge split in Python community and many popular python libraries got Python3 support years later Python3’s initial release. And Python2 is still supported. Almost all popular libraries still (as of January 2019!) support both Python2 and Python3. This dramatically slows down both language development and library development, because developers need to support double set of features.

It is just my “humble” opinion, but this python revolution is one of the reasons why python is still not the most popular language in the world, because where JS developers create two frameworks, python developers can create only one with support of two pythons (now it is not entirely true, because Python3’s codebase is more rich than Python2’s; just 5-9 years passed…).

Also this duality of python scared off many developers, who would use python for their projects in every other situation. Heck, back in 2013 there were a lot of holy wars between python2 and python3 adepts. It was very unclear which version to choose for new projects and it cost a lot of time and nerves to migrate from python2 to python3 later, when usage of Python3 got more advantages.

I hope that changes between Python3 and Python4 will not be so dramatic and smooth evolution will be possible.

Bloat of C++

Another extreme is C++ (same true for JS and some other languages, but let’s stick with JS). C++ never drops any features. NEVER. C++ is some kind of black hole of programming languages for features. If feature gets in C++, it stays here forever. You can’t drop macros support, though there is no need for it in modern C++. You can’t drop pre-increment (i.e. ability to increment variable by ++i instead of i++) which would increase language convenience.

Modern C++ is overwhelmed with features and it is hard to create new (even experimental) compilers for this language because of its monstrous weight. Because of C++'s monstrosity we didn’t get support of modules in 2017. It was just too hard to find a convenient implementations for them and shoot out major corner cases. I bet that “speed” of C++ will decrease even further and sooner or later Rust will “eat” it.

How does it concern Panda?

Panda has a small community, every new member is precious. Newcomers shouldn’t be confused which version to choose when they start their new projects and it should’n cost them a lot of time if their choice was bad. Actually, there should be only one obvious choice: latest stable version. Despite that, every new revolution will spawn new Panda and will cause a lot of problems to those users, who decided to stick with older versions. It may cause them to abandon Panda and I think that it is undesirable. It also will draw developers’ attention to support different old versions, which means that they will have less time to improve Panda.

The way of C++ is undesired too, though it is less painful for end users. The reason is the same: it slows down development. If the development slow down could be avoided it should be avoided. Couldn’t it?

True Evolutionary Approach

Since improvement is not only adding new required features, but also removing redundant features, there are no improvement without pain for both end users and maintainers. But I think that evolutionary approach could be applied. For example, current version is 1.10.x and there is set of features {A, B, C}. Version 1.11.x is in development and maintainers have thoughts of version 2.0.0. Let’s say that during development of v1.11.x, maintainers understood that it would be good to replace feature B with feature D, because D is faster and more convenient.

C++ way is to just add feature D in version 1.11.x and never drop feature B no matter what. Python way is to add feature D in version 1.11.x and drop feature B in version 2.0.0. Even with blog post, change lists and other notifications, I think it would be a bad surprise for users of feature B when it would be dropped.

Evolutionary approach would be to deprecate feature B in v1.11.x, add feature D in v1.11.x and drop it in v1.13.x (for example). Deprecation should be as painful for end users as possible because maintainers want to discourage them from usage feature B, and not just inform that this feature would be dropped in v1.13.x. How to do it is up to discussion. When to finally drop feature B and how long they should coexist with feature D is up to discussion too. Anyway, it is more a state of an art than an actual science.

Well, what do you think, folks?

My opinion

When you are dealing with a big project, you need stability. Anything (python, C++, Panda3d, operating systems, etc) needs to be stable to support long term projects. This is imperative if you care of having something usable by the wide (and I mean wide) community.

THIS is why you have python2 and python3. And is why Windows 98 is still alive (though slowly disappearing). I do not agree that having python2 and python3 stifles language development. Python3 has grown independently from Python2 at its own pace. If module writers support both, it is not an issue for the language development. Additionally most of Python code is trivially (almost) adaptable to both version, so supporting the two at the same time may be annoying but in many cases not a big issue. Of course there are exceptions and big projects like this, where the story might be different. Regarding C++: I wrote code generators, and machine code generators in C++. You have essentially total control. It is a great language, but as a user and C++ programmer I am not going certainly to change decades of code because of feature deprecation. This is one of the things I love of C++. When times comes, code can get revised at the appropriate time and occasion. You can go back to a project of five years ago and it still works perfectly. On the contrary, I have an interesting graveyard of Java code that does not work anymore… If features were deprecated and removed after 2 revisions, then C++ would have been replaced by a more stable language. In addition, deprecation should be the result of serious needs: in your example you cite macros as there is no need in modern C++. While it is true that with templates and all the various constant declarations macros are almost not used anymore. However, they still gets very handy to do useful staff in specific occasions. Maybe it is because I work with code generation, but there are things that I can only achieve using a preprocessor. The C preprocessor and macros still are handy.

I use Panda3D because it is a unique framework for 3d rendering and game development (although I use it for game development in free time and use the rendering capability for staff related to research activity). I love the fact that you can program everything via Python, and I made the change from Python2 to Python3 recently. However I am always worried for its stability. To give you an example, the deprecation of the packaging system has been a (small) blow. I cannot really appreciate why this was required, although I presume it was due to maintenance problems. I am wondering whether it can still be revived. The pandatools does not work for me. I am using pyinstaller as a replacement, but I have a few issues with embedded multifiles. And it does not build packages,

Alternative 3D rendering engines are not as usable as Panda3D. Commercial alternatives are out of budget and also not as usable as this amazing engine. I simply love Panda3D, but if features get deprecated after a few releases, it becomes a non usable tool for serious staff.

I will disagree on some point.

First of all, I disagree that C++ code written 10 years ago runs smooth. I’ve tried to compile Doom (which is actually written with C) and I didn’t managed to do it. Even readme to Doom’s repo says that code tends to rot when nobody keeps an eye on it. So I think that there is huge graveyard of dead C/C++ code. As of Python, I mostly agree with this guy.

Secondly, I disagree that graveyard of dead code is a bad thing. The only constant is change and coding environment is ever changes, so there is no surprise that some code doesn’t run anymore. It sucks when it happens with your profitable project. Oops…

Thirdly, I strongly believe that often improvement is reducing the number of supported features. The best is the enemy for the good. And, let’s take a look for a Panda-related example: DirectGui. It is flawed by many means, but I use it, because it comes out of teh box. Maybe, in some future point better GUI API will be implemented, which will render DirectGUI redundant. Supporting two GUI systems is very time-consuming, so sooner or later support of DirectGUI have to be dropped. I think, if someone would appear 10 years later with demand for DirectGUI support, one must pay for it.

This is not the only issue of such kind and they will pop up one after another, eventually. The key question I’m asking is how to deal with such issues, so Panda’s users would not be hurt and annoyed.

Also, supporting two python version sucks! I want to create small fix for makepanda and should keep in mind that might not work as I intend it to work for another python version. Urgh!