Q: has the GC of Nim caused any challenges?
(And if not, would you attribute that to Nim unique GC that does NOT “stop-the-world”?)
Keep in mind that I also need to use ptr (as opposed to ref) types in a lot of cases when working at a low level, so there might be a need for some manual memory management as well.
"Nim gc" on Google indeed puts you at the 1.4 doc page.
ReadMe, Docusaurus, Mintlify, etc?
Task switching. It's a very intricate process, you really have to understand how to structure everything (especially the task stack) so that you can switch everything from underneath the CPU as if nothing has happened (the CPU is obliviuous to which task is running, including the kernel itself). Add to that switching between user mode and kernel mode (during interrupts and system calls) and it becomes even more challenging.
> Also, any tips if anyone want to write an OS from scratch, aswell?
As @deaddod said, you need to read a lot. Two invaluable resources for me were the Intel Software Development Manuals (SDM), and the osdev wiki. The SDM can be daunting, but it's surprisingly very readable. The osdev wiki has great content, but it can be a hit or miss. I complement them with various blog posts and code on github to really understand a certain topic.
That being said, the most important aspect of this process is to have tons of curiousity and to be passionate about low-level systems programming. I love to learn how things really work at the lowest level. Once you learn it, you'll discover that there's no magic, and that you can write something yourself to make it work.
[0] https://www.intel.com/content/www/us/en/developer/articles/t...
Basically, OSDev is one of the few realms you can't really take shortcuts in. It's kind of like learning Rust, in that you'll have a lot of foundational work until you get some real payoff. Unlike rust, however, there isn't just some cliff where you start getting it; it's a constant uphill trudge.
Learning the boot process of your target architecture, adding core functionality (process scheduling, filesystem/VFS support, IO management, etc), adding driver support, supporting your video device (just getting a basic framebuffer, and then adding each piece after that), supporting USB, supporting CRT and POSIX (if you choose to do so), etc are all herculean tasks of their own.
That being said, it's a super incremental process, so you'll get to watch it grow and expand at each step.
Reading up on the FreeBSD and Linux kernels are good starts. As well as reviewing other hobby OSes such as Serenity, TouruOS, Haiku, etc. And the OSDev wiki is invaluable.
Also, accepting you probably aren't going to build the next big OS or trying to compete with the big dogs is something you'll have to humble yourself with.
(since they seem very similar at this point, yet Swift is more battle tested)
- it's close to Python in syntax (less noise, more readable)
- has no garbage collector by default (it uses ARC)
- has great C interop
- can be optimized through the C backend compiler
- can target bare-metal with minimal effort
- supports inline assembly
- has great template/macro system (I do use templates, but I haven't had the need for macros yet)
There's probably other reasons, but those are the ones I could think of now. As for why not other languages, I think the only other languages suitable for this kind of work are: C, C++, Rust, and Zig. Here's my take on each:
- C: The mother of all system languages, but outdated with lots of UB gotchas
- C++: I don't like/need OOP, so why pay the prices of C++ complexity and manual memory management
- Rust: I find the language too complicated for my taste. I know it's subjective, but it just doesn't feel right for me. Also writing a kernel involves a lot of unsafe code anyway.
- Zig: I tried Zig and also found its syntax to be a bit too noisy. Also having to worry about allocators in most of the code distracts from the core logic I'm trying to focus on.
Any reasons why you would not recommend Nim?
Or things Nim could improve?
(Nim seems like this unicorn of languages, that's completely overlooked. And I don't understand why it's overlooked)
There are genuine shortcomings, of course. Every language has them.
It is something of a unicorn though. It's so pleasant to use at many levels of the stack from bare-metal to applications. People even use it for games.
__MatrixMan__ and SJMG have good points. If it's anything, it wouldn't be a technical issue in the language. It's like a Tesla when it first came out; it was obvious that EVs are the future, but they had less investment, less adoption, not enough charging stations, shorter range, and not a lot of certified shops for repairs. So naturally a lot of people held back until it became mainstream.
The issue is, will it become mainstream one day? Maybe, maybe not. But I'm betting on it myself.
If you wear enough hats to appreciate Nim in more than one of its dimensions, your attention is necessarily split enough to not evangelize so loudly for it in any one. People don't want practical, they want provocative.
Q2: What would you do different? (and what unexpected positives did you find)?
Yes. It's a pleasant language to work with.
> What would you do different? (and what unexpected positives did you find)?
A couple of things I think need improvements are: (1) better IDE support (especially for JetBrains IDEs), and (2) better support for true sum types and pattern matching[0].
As for unexpected positives, I found that the standard library covers a lot of functionality that I rarely (or ever) need a 3rd party package. Maybe that's because I'm not doing anything exotic.
[0] https://github.com/nim-lang/RFCs/issues/548, https://github.com/nim-lang/RFCs/issues/525
I like languages that disallow null by default (e.g. Rust, OCaml etc) because it seems to be a huge source of errors.