Comment by throwaway2037

13 hours ago

This is a great post. How does someone write software that needs to run for ~50 years where the hardware will need to be replaced with non-equivalent, newer hardware? If I were facing this issue today, I might start with an OS that has excellent emulation. Example: Can I run 32-bit MS Windows 95 via emulation on a variety of current 64-bit OSes, like MS Windows, Linux, AIX, HP-UX, etc. If yes, then we can assume(?) this emulation will remain relatively stable even if we upgrade our hardware later. Maybe I am overthinking the whole problem: Can VMs do exactly what I want today? Will VMs running ancient OSes, such as 32-bit MS Windows 95, continue to be stable/viable in the future? I am unsure.

Make sure that you have as thorough a specification of what the system is supposed to do as you can.

Then define the version control system and the build process, specifying the dependencies, and so on.

Think about any opaque blobs in the system and try to eliminate them so that you have plain text source code so that no tools are needed to read the code.

Make sure that the build process runs entirely locally and never fetches anything from outside.

Simplify everything, use only tools and languages that are well understood and supported.

The real problems are not strictly technical but social: how do you prevent loss of the code, the tools, the specification, how do you maintain the expertise needed to maintain it. How do you ensure that all those things that are obvious to you now are written down in all their gory detail so that your great grandchildren will not apply their new and different preconceived ideas to the system?

Document all this on paper as well as electronic storage, make sure that version ids are recorded on every page as well as being available to the user of the machine or program.

In the industry in which I worked for the last thirty years of my career it was not uncommon to have things come back for repair after fifty years use and to be able to consult the original drawings and bill of materials so that exact replacement parts could be made.

DOS emulation is available more widely than Win32 emulation, and there is HX DOS Extender. I would try sticking to Win32 dlls runnable in HX DOS Extender. rundll32 or some other exe host. HX DOS Extender has no paging support and has problem loading multiple exe having no relocation info to the very same 4Mb base address they all usually pretend. DLL should have relocation.

I thought "but what is the problem to generate EXE with relocation?" and tried GCC GNAT (from 2017), and GCC said no. EXE and DLL formats are very much the same, but GCC is completely unable to generate relocatable EXE. A very suprising discovery. More recent toolkits became aware that adding relocation to EXE is not a rocket science, just do the same like in DLL. But these recent toolkits may call APIs that HX DOS Extender does not support yet.

Wasn't there some idea that went like "if something has been around for x years, it will likely be around for x more years"?

Maybe follow that. It's 2026 right now. What way of writing code would have worked 50 years ago (1976) that still works today?

Well, C, SQL and Lisp were all around 50 years ago and still exist today.

In terms of hardware, 50 years ago there was intel 8080. apparently code for that can still work via emulation today.

So if you wrote C for low level, Lisp for high level, and compiled the software to run in an Intel 8080 emulator, that combo would likely still work in 50 years.

  • C is very different C. There is C where programmer rushes to call fork(), just because he likes the idea of entering room once and exiting room twice. And this program has got excuse for his behavior. He has fork() in POSIX standard. So programming is using fork() here and there even if not strictly needed. Using fork()/exec() instead of more portable posix_spawn(). Using fork()/accept() instead of multithreading.

    Then it becomes impossible to introduce database connection pool. Well, probably possible, but in single-process multithread server this is BSc grade job, and in multi-process server this is PhD grade job. libmysqlserver and others maintain some context near to the socket, in opaque way. Hard to pass context between processes. At least, hard to return used connection back to pool in main process. Proxy is also not an easy walk.

    On client side although Windows NT had POSIX layer, and XP/2003 still had Interix SFU. But Windows Vista broke SFU. But then Vista has got SUA. But SUA was not binary compatible, required recompilation. And as of Windows 10 there was surely no SUA. Was it dropped in Windows 8? Windows 10 has got WSL eventually, but there was a gap between SUA and WSL. And deploying Windows application with SFU, SUA or WSL part is not easy walk. Writing installer is MSc grade job.

    Then comes iPhone OS and Android. They are POSIX OSes. Kind of. But spawning external processes is prohibited or not desirable. This is what was blocking LaTeX adoption on mobiles.

    • Well I think if you were doing the 1976 way you might not even have multi processing or multi threading. Just a single process with a single thread. And so you don't have a database connection pool, you just have a single database connection and do one query at a time maybe.

      That may not work for network connected software with lots of requests per second. But such software did not exist too much in 1976 either as there was not very much networking going on.

> How does someone write software that needs to run for ~50 years where the hardware will need to be replaced with non-equivalent, newer hardware?

Some ideas:

Write it in a popular language/ecosystem, stick rigidly to well-defined APIs, use commodity hardware, flatten out any malignant cleverness, maintain documentation on why every part does the thing it does, and make the source code readily available.

This is based on working with some very old systems, and each point above is the opposite of something that made life harder.

  • Unfortunately, “popular language/ecosystem” includes JavaScript and PHP.

    I’d go for “universal and timeless”, which has meant C for several decades now. There is, I’d concede, a reasonable chance that Rust obtains that label in our lifetimes.

    • Yeah agreed. Popular is a good first approximation, but to be more precise I think you want tools where the incentives in the community reward stability over features that require breakage, which would include languages and runtimes like Erlang and Clojure.

      Neither is popular when compared to for example Python or PHP, but they both have cultures that care about stability in the core runtime and the libraries. Most folks probably don’t know that about Erlang and maybe think it’s some new whiz-bang thing, but Erlang is incredibly stable and well supported by a dedicated team that has been doing it for years and years at this point. I don’t know if Erlang will be more or less popular in 20 years but it 100% will be around and be receiving updates, I would put money on it.

run for ~50 years where the hardware will need to be replaced

If it needs to run for fifty years, specify hardware that has a long support cycle such as Mil-Spec.

That’s why the Z80 was around for so long and why so many companies in the 80’s and 90’s still deigned around it. (1)

If you let programmers drive system design, winding up with an “Amiga” in your certified design is a more probable outcome…

(1) there’s a moderate chance that new hardware that can run Z80 code will be around fifty years from now.

> how does someone write software that needs to run for ~50 years where the hardware will need to be replaced with non-equivalent, newer hardware?

Make it open-source, or don't buy without source.

  • It's interesting to think about this in the context of parent poster's story about the Amiga emulator in the nuclear power plant.

    Or, more broadly, in the context of any situation where the software is closely coupled to a specific operating system and/or hardware.

    Having the source code would have helped tremendously, but might not have been sufficient because of the hardware story and the regulatory approval factor.

This was one of the promises of Java. You write your application and then you get a virtual machine (JVM). As time goes on you only maintain the virtual machine while the application remains the same.

  • The funny thing happened and verified this promise. There were several architects working on IBM System Object Model (SOM). In 1996-1997 many good things ended, and SOM was terminated. But the work was so good that two architects did not stop and wrote the book: Putting Metaclasses to Work (1998). That book has got reference implementation in Java. So we have IBM SOM as closed source binary and we have Java source codes.

    IBM SOM executes on Windows 10. I have checked Visual Age for C++ Direct2SOM extensions, OpenDoc for Windows. Very good. 32-bit i386, but otherwise runnable, usable.

    And Java is hard to build, hard to execute on modern Java toolkit. Java seemingly had no List, and authors made their own List, but when Java also got its List, that breaks the build. When building problems are resolved, runtime problems come. Original Java was seemingly fine with Property key being object, but modern Java only wants strings. And Property-based dictionaries are all around. PMtW is about building VMT, and there is multiple class inheritance in PMtW model, not matching Java's comparably limited OOP. So PMtW is building dictionaries for methods to support what is described in book, and foundational Java class is malfunctioning.

    I did not finish this road, don't know so what does it take after all to run Java code from 1998 on modern Java toolkit. So far looks pathetic compared to Win32 programming.

> How does someone write software that needs to run for ~50 years

You in a lot of ways have to respect the ability to have done this in the first place, compared to todays slopware which manages to break within 1-2 mandatory OS update cycles.

I'd recommend not having it so dependent on the hardware and choose an OS that is relatively hardware agnostic (e.g. Linux). Also, ensure that the software is open source and if compiled, has an open source toolchain to do so.

Though people often decry it (due to the many, many footguns), writing something in Shell/BASH will make it trivial to move to newer machines.