Comment by khaledh
2 years ago
As others mentioned, Nim is a statically typed programming language that compiles down to C, C++, and JavaScript. It has great C interop, which makes systems programming easy. As for why Nim, here's an excerpt from my accompanying site[0]:
> Why Nim? It's one of the few languages that allow low-level systems programming with deterministic memory management (garbage collector is optional) with destructors and move semantics. It's also statically typed, which provides greater type safety. It also supports inline assembly, which is a must for OS development. Other options include C, C++, Rust, and Zig. They're great languages, but I chose Nim for its simplicity, elegance, and performance.
As for the overall design goals of Fusion, I have high ambitions, which I list on the same page I referenced. I don't want to build another Unix-like OS; I'd like to experiment with fundamental issues in OS design, such as using a single-address space and capability-based security for protection. Another aspect I'm trying to explore is how processes/tasks are modeled, which I believe should be modeled as state machines with statically-typed channels to communicate between each other (this is not new, it's been done in Singularity OS[1]). There's rudimentary support in the kernel for channels and using them from user space, but it's still early.
[0] https://0xc0ffee.netlify.app/osdev/01-intro.html
[1] https://en.wikipedia.org/wiki/Singularity_(operating_system)
Are you considering user-level abstractions other than files? Perhaps a plan9-like everything-is-a-file-system?
A file is a manufactured concept that has served us well for a long while. But I'm not convinced that it's the right abstraction for everything. Files are just binary blobs (even if they're text), with no uniform interface to interact with them other than open/read/write/close. In order to compose processes around files, they have to agree on a certain format (e.g. lines of text for most Unix commands); there's no structure other than what each process assumes it to be.
My idea is that processes should compose in a statically typed manner, where opening a channel for reading gives you a Channel[T] to read entities of type T. Two sub-abstractions of Channel[T] would be Source[T] and Sink[T], where they can be used to read and write to any source/sink (including files) as long as there's a registered (de)serializer for T.
This sounds like a great idea to me.
Have you played at all with nushell? It's fun in a composing-processes-via-types kind of way, although it's a bit more on-the-surface than what you're describing.
My impression is that much gets done via builtins--you have to start writing nushell plugins for everything if you want to extend the fun to arbitrary programs which nushell knows nothing about. (unless you're happy with json I/O, but you're talking about static typing here).
It sounds like the source/sink type registry that you're describing would solve that problem in a much nicer way.
2 replies →
This sounds similar to some of the concepts in the robotics framework I'm writing. It's pretty powerful to be able to separate out the transport data has from the serialization it has.
You might enjoy reading about Ethos's Etypes. My understanding is that they punted a bit and their design still has byte streams, but the operating system provides helpers to parse them and injects filters to guarantee well-formed input/output, including over the network. They failed to produce anything but papers, but the papers are interesting.
https://www.ethos-os.org/~solworth/petullo14ethosTypes-20140...
https://www.ethos-os.org/