To run games I'm making now, I have to have the correct versions of Grunt, and all the related dependencies - working CoffeeScript converters etc. In 2024 it's going to be tough to set up a working environment to modify and run 10-year-old code: certainly a lot harder than just double-clicking an html file.
I was thinking about exactly that a couple of days ago trying some WebGL. The web is a moving target and you're not guaranteed that anything advanced today will last :(
On the other hand I wrote a shoot'em up in C and SDL in 2003 and still compiles and works as well as it did back then.
JS will soon be 20 years old, but in terms of a language community, outside of jQuery plugins it's only ~5 years old.
You're not wrong, though. I can only imagine the nightmare of finding copies of all the library dependencies will be five or ten years down the road ("oh this needs jquery 1.9 but we're at jquery 5 now, and what was underscore?") not to mention the actual execution environments ("Works best in 20 versions of Chrome ago").
The web at least is a tractable problem. Did you ever have a game that you really liked that only worked in iOS 4? Tough shit.
I don't know why the web is different, but it is, and it makes using the newest stuff a little bit uncertain.
The only situation where I could see this being problematic would be enterprise-type applications written on something like the Java stack or the .NET stack, where you do get tied, at least somewhat, to whatever version of the framework you are using at that time.
I also wonder if Rails is more analogous to say, the LAMP stack (I'm not directly comparing Ruby to PHP, mind you)?
I don't think that the reason why they don't upgrade is because it's too hard. It's just that their current system works fine as is.
On the other hand, I have upgraded dozens of Rails apps from 2.3 to 3.0, from 3.0 to 3.1 and 3.2 to 4.0. Sometimes it was extremely easy, sometimes it required a little bit more effort, but I would not consider it as being difficult or painful.
Sometimes the upgrading problems arise due to gem dependencies, as a lot of gems set hard constraints on other gems' versions so it can be a little tricky to update everything at once.
All the other upgrades where rather easy, but of course it depends heavily on the size of the project, the test coverage or the underlying server infrastructure.
PDP-11 had only 8 8kB "pages" (segments really) available for a program. Pages could be marked read-only, but making one read-only was a huge expense. A common trick was to smash code and data that were only used when initialising the program.
That would seem like a straightforward optimisation, but then the code presented in the article would break subtly if you were to invoke ed twice at the same time since both instances would try to modify and use the /tmp/eXXXXX string at the same time.
It's one of the advantages of using shared libraries as well, several programs can share the same code and read-only data, saving in storage and memory space.
Rodata sections are a modern idea, the a.out binary format never had it. A.out explicitly documents the data section as writable. Rodata came with ELF.
I was also trying to put a OS X App from 2009 on GitHub, but gave up before I could get it to compile with the latest X Code. Wasn't worth the effort.
In the old days it was possible to access members of
structs inside unions without having to name the
intermediate struct. For example the code in the sed
implementation uses rep->ad1 instead of rep->reptr1.ad1.
That’s no longer possible (I’m pretty sure this shortcut
was already out of fashion by the time K&R was published
in 1978, but I don’t have a copy to hand).
gcc and other compilers have also supported this functionality for a long time, although as a non-standard extension. This technique is also still widely used in systems-level programming and is hardly "ghastly" although I'll readily admit that there are better ways to accomplish what this particular case was doing.
> Beguiled by the example of PL/I, early C did not tie structure pointers firmly to the structures they pointed to, and permitted programmers to write pointer->member almost without regard to the type of pointer; such an expression was taken uncritically as a reference to a region of memory designated by the pointer, while the member name specified only an offset and a type.
However, I stand corrected in two regards. The first is that as of gcc 4.6+, the sed example the author provided is no longer allowed even if the structs are unnamed. (I was testing with gcc 3.4.) I verified that gcc 3.4 would happily allow me to use the provided sed example as long as I removed the names from the structs.
Second, the C11 standard specifically does not allow for the sed example provided because the structs in the unions contain duplicate members.
I had seen reasoning that hinted at what you're saying in one of the comments posted on the author's blog entry.
Regardless, thanks for encouraging me to dig deeper.
Amusingly, version 7 Unix didn't even have a header file that declared malloc().
I noticed something similar with the old f2c code. It is about a decade older than Version 7, and came with its own malloc implementation.  Apparently some Unix still didn't provide a good implementation.