This is definitely not a waste of time. But though building a physical ALU from TTL is feasible, constructing a reasonable amount of memory would be a waste of time and money.
Once you have written the nand2tetris HDL for the hardware, you could translate it to Verilog and burn an FPGA quite easily.
For learning C and starting to poke at low-level embedded stuff I would recommend starting with Arduino (and then into plain AVR) - and not go anywhere near a GUI toolkit.
There is a reason we don't actually throw kids into the deep end when teaching them to swim. Most of them would just drown...
But a new GTK2 book sounds like teaching Python 2 for beginners.
GTK 2 and GTK 3
One thing worth mentioning at this point is that there are two versions of GTK in use. The current version is GTK 3, and this is still under active development – it changes quite a bit between releases.
For this reason, many people prefer to use the older version, GTK 2. This offers most of the same functionality, but it is stable code which doesn’t change very much any more. Some say that it is always better to use the latest and greatest version of anything, but more cautious old engineers (like your author…) tend to prefer the older version that has had a lot more testing and with which people have stopped fiddling about! In terms of the examples we are looking at here, there aren’t that many significant differences between the two, but just to be clear, the examples in this book will use GTK 2.
10 years being the mainline version, and having a supported compatible version for 16 years is pretty darn impressive! If GTK4.0.0 comes out next year, then GTK3 will have had 8 years being the mainline version. Its not quite win32 levels of stability, but it is not like they break this stuff every year or something...
At this point it doesn't matter that it was released 17 years ago, what matters is that there are programs using it.
Honestly, i can see Gtk1 to Gtk2 breaking compatibility since they probably did some blunders and all and it wasn't very long lived anyway, but Gtk2 to Gtk3 should have kept backwards compatibility - GUI libraries are important foundation for a platform and breaking changes breaks every application that relies on them. Instead what the developers did was not only break Gtk3 but not even try to design an API with Gtk3 that would allow Gtk4 to be backwards compatible.
It is frustrating if as a developer you want to ensure your program keeps working in the future and have the foundation it relies on sabotage you. I can release a Win32 application today and i'm certain that if people are still using x86 Windows desktops, it will work in 20 years. Hell, chances are it'll still work in Linux thanks to Wine - whereas the only way i'd get the same sort of compatibility with a "native" UI library would be to write my own toolkit and use X11 directly (and even that assuming Wayland developers wont have convinced everyone to drop X11).
Sometimes i'm just considering to just target Win32 for my stuff and tell people use Wine for Linux and macOS, it'll be more likely to work in the future than any native UI library.
Outside of games, for software that touches the Internet you probably also want libraries to get shared security updates.
And of course having to bundle 50+MB of libraries and data (themes, etc needed by a GUI toolkit and any other data by other libraries) for a small executable is a ridiculous idea by itself.
No, a desktop system should provide some minimum functionality that desktop applications can rely on and keep that functionality stable so that application can keep on working.
Systems like Flatpak have a framework system where it is possible to have a shared runtime of dependencies that multiple applications can use. A GTK1 runtime could exist (or maybe does?), for example.
Or perhaps more fitting to modern Linux desktop, Gtk1 and Gtk2 will not support Wayland nor any new functionality introduced for scaling (did you know that, despite common narrative from Wayland fanboys, X11 already provides the necessary functionality to implement per-monitor and even per-window scaling with pretty much 99% of the same code that a toolkit would need for Windows 8+ scaling, that is most likely already written? It only needs some cooperation from the window manager and this sort of code could even be implemented for XWayland.... but it needs a bit of modification from the toolkit's side too and while it could be done for Qt5 and perhaps Gtk3, it'd need Gtk2 and especially Gtk1 to be worked on, which wont happen - on the other hand, if Gtk2/3/4 were backwards compatible, all programs would benefit from such new functionality).
Also, in this universe Win32 API was released in 90s, not 80s.
Yeah, well, kinda... technically you are correct but Win32 is 99.998% backwards compatible (as an API, not ABI) with Win16 which was first released in the 80s.
Actually, IMO if you are using closures for events that are more than 5 or so statements (i'd say lines but people love to pack their lines with multiple statements), you are doing a disservice for every poor soul who will have to understand your code later.
As far as being turing complete, CSS is supposedly that, also, so good luck with that.
Here's a guy who developed a closure "library" for C: https://nullprogram.com/blog/2017/01/08/
It's clever, but he actually had to resort to assembly...
But I never found a decent beginner friendly resources.
Anyone reading this comment, please chime in with your suggestions.
https://github.com/bztsrc/raspi3-tutorial
It's also fairly popular for emulators, since it's types are orthogonal and it's low level design is well suited to designing a pseudo-machine. It's definitely being displaced in that realm by C++/Rust/Nim/etc though.
If you can figure out pointers and how to actually get the size of things (sizeof(*char) doesn't get you the size of what it is pointing at... it gets you the size of a pointer which varies depending on the architecture. sizeof(myArray) doesn't give you the number of elements in an array, it gives you the number of bytes your array can hold, to get the number of elements you must do sizeof(myarray)/sizeof(myarray[0]). sizeof() is a compile-time operator, it knows nothing of runtime) you will be pretty much 99% of the way there.
I.e. why is it that C and assembler is “fundamental”, but electronics is not?
(I have written about this before: https://news.ycombinator.com/item?id=19106922#19113359 )
It teaches you fundamentals, especially on an embedded system such as R-Pi.
The first language I learned was C on an ARM processor. Learning about registers, bit manipulation, seeing how compiler optimizes the code based on GCC flags, understanding pointers, memory management, the whole thing is difficult for a beginner but to me, it was immensely helpful. I also love Python/Julia/Java/JavaScript but man it makes you appreciate neat things higher languages offer.
One day I want to build my own 8-bit computer from discrete gates. I’m sure it won’t be a waste of time.