I am have doing some work around updating the dynamic libraries used by Racket for Windows. As part of this, I have been learning more about the rktio library. It seems to me that there is a lot of code that is there to support very old versions of Windows and well as older version of Linux (and other Unix systems).
I am wondering if bring things more up to date makes sense. I honestly see no reason to officially support older versions of Windows and target Windows 10/11 (and related server versions) only. As an example, I was able to simplify the console code in rktio quite a bit because newer versions of Windows are better behaved (and don't require workarounds).
But, I think this needs broader discussion and support before going to far. To be clear, this isn't about changing the code base to be completely different, but to use less workarounds and newer APIs where they make sense.
For example, the new PseduoConsole API in Windows might really help bridge the gap on on things like polling on stdin/stdout and bring it closer to how Unix works. Or not, but if there is agreement that Windows 10 is a minimum, then that API can be used.
Such a change would not affect me directly because I use Linux exclusively.
But I do get the impression that there are many users who are stuck on older versions of Windows, because they find the new versions offensive or incompatible with their applications.
Your changes could prevent them from continuing to use Racket.
I normally favor supporting old systems, and if I were making the changes, I would probably start out trying to use GetProcAddress — at least, if only a handful of functions are needed. But if that's is too much of a hassle (which could easily be the case), then Windows 10 seems like a reasonable place to draw a line on Windows versions going forward.
Beyond Hendrik's impressions and Matthew's predeliction, there is also the point that we have a fairly large (thousands of downloads per day) user base that is mostly invisible to us here, namely students and teachers who use HtDP. Historically we interacted directly with them more and learned that they often have old computers in rarely refreshed computing labs.
Of course, since they are invisible to us, it is possible they don't exist (well, they probably exist, given the downloads, although their characteristics are unclear) but, all else being equal, it seems wise that we try to avoid breaking racket on old systems.
Isn’t one of the (premises|promises) of Racket to be accessible to middle school and high school students? Who are likely to be stuck with obsolete Windows systems?
I'd hate to see support for older platforms removed. I think it is worth some extra complexity to keep racket working on older systems. Of course, I'm not the one actually maintaining the code.
Personally, I still occasionally use racket on a powerpc mac and have a goal of building racket for windows xp(I think this is still possible to do but I have yet to track down an older version of visual studio to try it.)
Thanks for the feedback. I have some responses and instead of reply to each post, I thought it best to just address it in one post.
Firstly. nothing is stopping users on outdated and unsupported versions of Windows from using older versions of Racket and the related tools.
As to middle and high schools, Chromebooks are replacing the computer lab as we know it, so that's a whole different set of challenges. In general, any lab that is running versions of Windows older than version 10 has way more issues than potentially not being able to run Racket 1x in the future. Those labs have the option to move to Linux if they don't want to update hardware.
There are a number of libraries that may not be officially be supported for older versions of Windows. Even if they may work, so we can't do very much in terms of ensuring older versions of Windows will actually run effectively.
There is more than just Windows issues here, but assumptions about old versions of Unix and OS/X as well.
In terms of how the API functions are loaded, it would be the same model (using GetProcAddress) as is currently used. Of course, if fallbacks can be used, that is preferred. I am concerned that the code might get too convoluted in certain cases or that will nullify certain advantages.
In general, if there is significant enough gains in simplifying the library and potential performance benefits, then I think it is very reasonable to say that Windows 10 or newer is required moving forward.
ETA: Also, this would allow the use of the UCRT library, which has some notable benefits (UTF-8 locale support, C11) as well.
This is true, but a racket developer who would like their application to run on deprecated platforms would have to restrict their use of new features that are unsupported on those platforms. In most cases developers wouldn't make these considerations and over time more packages would break on the deprecated platforms.
The racket developers have done an outstanding job ensuring that new releases do not break existing code. This doesn't extend to guaranteeing new code works on older racket releases, however.
Probably because Racket (the "core") has been so good about systems backward compatibility, the tendency has been for Racket (the non-core set of language and tool features) to expand in the form of newer versions of Racket.
So if someone on an older system needs/wants a newer feature in DrRacket or some new variation of an API, to get that they often must use a newer version of Racket.
Furthermore, some third-party libraries require a newer Racket (directly or transitively) so they can use some new thing.
What you're proposing could work, I suppose, if there were a sharper distinction between Racket-the-core-platform vs. everything else. But I think it would require "everything else" to adopt a different approach? So that newer features/tools/libs would run on older core versions of Racket.
For example, DrRacket the app and its supporting libs would need to be managed and versioned differently. Third-party tools/libs would need to (say) make more use of dynamic-require for new functionality they prefer but don't absolutely need. And so on.
That might even be a better world, in some ways (??). But only if enough people want that, and do the work to change the non-core parts and the third-party ecosystem. Getting there would probably be non-trivial and bumpy.
So I suspect the status quo will continue so long as some smart people are still willing to keep Racket working on older systems?
I appreciate all the thoughts in favor of supporting old versions. I'll offer a few two more observations:
Windows 10 was released in 2015. For comparison, Mac OS 10.9, the oldest version that we support for x86_64 (as opposed to i386 or PPC) was released in 2013. Requiring Windows 10 is not ideal in my mind, but it's not exactly requiring cutting-edge hardware.
Part of the problem for rktio on Windows would be having to use GetProcAddress and similar awkward, dynamic mechanisms to access to functionality from newer version of the OS. A compile-time choice can avoid that, but then you need separate builds for each choice. A workable approach might be that i386 is compiled for older versions of Windows and behaves less well, while x86_64 and Arm64 are compiled for Windows 10 and up. (It's not even a question for Arm64, of course.) That would be consistent in a way with how we handle old Mac OS versions. Maybe the i386 build could even sacrifice some functionality to work on XP. The things that end up getting sacrificed tend to be in corners, like how well sync works on an input port for a console. This doesn't address @ndykman's goal of cleaning out complicated old code, but maybe it's a good compromise in at least allowing reasonable access to modern and reliable OS functionality for the main builds.
So, I have been looking into the library some more and here's what I found so far.
I was looking into if the Pseudoconsole (ConPTY) API would be a big help here. Of course, that is only in Windows 10 and greater. Looking at, there doesn't seem to be a good use for the API.
My first question, is having the officially required version to be Windows 7 more acceptable?
A lot of the complexity on the Windows side comes from the (lamentable) fact that select() style code can't be used on file descriptors and sockets. There is also code to deal with some versions of Unix in which some fds are also not selectable (or don't have poll at all).
As part of this, the code has two options for windows, controlled by a compiler directive
USE_BACKGROUND_THREAD_FOR_CONSOLE_INPUT
The code has a comment as to why this was done. But that doesn't apply to Windows 10 at all because there are new flags available as part of the console API. Thankfully, this is pretty easy to deal with using checks defined in versionhelpers.h.
I will continue to look for low hanging fruit here.
There is a bigger question here in terms of I/O. For threaded applications, the use of one thread for input and another for output is consider a best practice to reduce congestion and contention.
So, taking out the code for using background threads risks having to put in a updated version later on. However, the code paths as they stand are pretty convoluted.
As context, this is in regards to updating the core libraries that Racket (and popular racket packages) use.
Firstly, in MSYS2, all the libraries (core libs, gtk) are available as system packages that can be installed with pacman. I am looking to see if those packages can be installed via Arch. However, this means the workflow is vastly simplified. Gathering and building sources isn't needed, you just copy the DLL files from the installation and include them in a raco package.
The major issues:
32-bit packages are being phased out and this will ramp up in 2026. As MSYS2 notes, the very small number of people using 32 bit OSes is small enough that they can't justify the costs anymore. I concur with dropping official 32 bit builds. Two-thirds of the work I have done is in getting x86 to work and it still is ongoing.
GTK3 or GTK4 are the only versions available. Honestly, given the rise of Wayland, getting onto GTK4 makes sense not just for Windows.
These libraries all use the Microsoft UCRT, which means Windows 7 and 8.1 users will have to install an MSU (update package) that installs the UCRT. These MSU packages are still available to download from Microsoft. Getting rid of any library that supports msvcrt.dll is important.
I have been building a version of Racket that uses up-to-date libraries (including GTK4) that have been built with MSVC. All of the draw unit tests pass. There are issues with the gui unit tests right now. These MSVC versions were built with the help of vcpkg, and they include x64, x84 and arm64 versions. This work is to make sure that MSVC can be used for unofficial builds.
I am continuing to see if I can get vcpkg to build versions in the msys2/mingw environment.
I made those changes for loading the libraries. Thanks for the heads up on making sure the gtk3? conditional is working as expected in my branch, it might not be.