I stumbled upon the Nim programming language and I am not sure which one is more suited for systems programming language, Rust or Nim, Nim claims to also be a system's programming language so I don't know which one is more suited for this?
Honestly speaking, this forum is highly biased on this kind of questions. Hence the URL, even the logo! tl;dr: Use Rust, it's awesome, everyone in this forum would agree with it.
Everyone seems like this with every other programming language
Choosing a programming language is mostly about finding one that fits the way you think about the problem you’re trying to solve, so the answer will ultimately be a personal one. I don’t have any experince with Nim, but generally find Rust a joy to work with in any domain. Others think it’s lacking in certain areas and only suitable for some problems. Still others can’t get their heads wrapped around Rust at all— Only you can determine whether Rust is the right choice for you.
Also, different people have different definitions of “low-level” or “systems” programming. It can range anywhere from bare-metal programming all the way to high-performance scientific computing depending on the person you’re talking to. What are some examples of programs you’d like to write?
That is true but then if a user found Python to be easier than Rust, it wouldn't be a good idea to use Python to do certain things such as develop an operating system.
I thought Rust could do everything, in what ways is it lacking based on other people's claims?
Oh, well I guess like developing operating systems etc?
I had a quick look, one main difference would be:
"Each thread has a separate garbage collected heap"
So Nim is a garbage-collected language. This is a major difference from Rust.
I was told that Nim uses ARC rather than GC which does automatic reference counting and is much more efficient than GC.
There appear to be elements of reference counting
"The basic algorithm is Deferred Reference Counting with cycle detection."
"Cycle detection is currently done by a simple mark&sweep GC that has to scan the full (thread local heap)."
ARC is the one way to implement GC. The other way is called the tracing GC, which traces all the reachable references from the stack. Reference counting is easier to implement, but you have to deal with the cyclic references. Tracing GC is usually have better throughput but you need to have runtime to run the GC and having GC spike in mind.
Rust doesn't have any GC by default. There's a reference counted wrapper type in stdlib but you need to use them explicitly. In most code the ownership system and the RAII concept handles the resource management, entirely in compile time.
Why would anyone want to do that though?
Sometimes you need some shared ownership. For example if you have quite large
struct Config and share it all the way around your code without keep cloning it, you can instead share
Arc<Config> and it will never be gone unless every owner of it drop its ownership. Or say you have some shared state under the mutex modified by multiple thread. You can have
Arc<Mutex<State>> so each thread has shared ownership to the allocation of the mutex guarded state.
Rc, the single-threaded reference-counted wrapper type, is usually what I recommend beginners to use when they start running into lifetime issues after use of non-
'static structs, i.e. structs that contain references, that won't live for the remainder of the program. It's the topic, that most beginners struggle with (including myself).
The other case to use them is, when there is no clear owner, because of some external dependency, that causes either "owner" to drop before the other when some condition returns true.
For example, in order to represent arbitrary graphs.
Also, rust has os.phil-opp.com, which is super usefull, not only for the OS inself, but also as a guide to setting rust to make a execuatable that can be booted into/run on qemu
You might also be interested in Redox, an operating system built in rust.
I can't think of a good reason rust shouldn't be used to build an OS, but I also don't know anything about nim.
The garbage collection of nim might be convenient and the performance benefit might not outweigh that for you and your project.
I'll show my lack of knowledge about nim but what makes it more suited to systems programming, in particular an OS compared to say Go, which is commonly compared to rust?
It's a good idea to ask that question to other programmers where you cannot make that decision yourself. If you put trust in other people's judgement then you should try to find out which of these languages is used by many, which by few people. A large community helps in a lot of different ways. Languages with large communities will have more and better libraries, editor support, help online, youtube videos and tutorials.
One way to approach both languages from this perspective may be the Redmonk programming language ranking. This is their latest graph of how popular a bunch of languages are on GitHub and on StackOverflow: https://redmonk.com/sogrady/files/2020/07/lang-rank-q320-wm.png
Languages on the right and on the top are popular, those at the left and bottom are not popular. You can find both, Rust and Nim, on that graphic. Even though there is plenty of reasons to critique all kinds of language ratings you will find that on any of them Rust is plenty more popular then Nim. Your chances of finding a book from a real publisher about Rust and your topic of interest is vastly larger then about Nim and your topic of interest.
Now I am aware that this aspect will lead away from Rust towards C++ but I never advised to follow that chart exclusively. But it might be sensible to take it into account.
I have no idea about Nim. I do have demands guiding my choice of languages though.
My idea of a 'low level', 'systems' programming language is that I can get get from processor reset to executing code in that language as soon as possible. Likely with some little hardware/run time setup written in assembler to get you from reset vector to running code.
I don't really have any OS experience but I have done that for a simple cooperative multi-tasking OS on x86 using the PL/M-86 language, and a simple protected mode task scheduler on i386 in C.
Can Nim do that?
I'd also like my language of choice to be able to generate code for as wide a range of CPU architectures as possible. I don't want mu options limited by my choice of language and it's available compilers and their target architectures. Compiling to C and then having to compile that for my architecture does not cut it for me. That is perhaps a compiler implementation thing rather than an actual language thing but it's a practical reality to live with. So many times I have had to move projects to new processor architectures.
Can Nim do that?
Of course apart from technical details like: Can the language express what I want to do nicely? Can it be compiled to efficient code? Does it require some complicated run time? Etc there are all those non-technical details. Like licencing, support, community, is it likely to be around for the long haul, etc, etc.
Rust is the first language since C that ticks a lot of my boxes there.
I'd be even more confident about selecting Rust if there were other implementations, GGC-Rust for example, even MS-Rust.
Interestingly you have phrased the choice for systems programming between Nim and Rust.
Those are not the obvious choices (yet). The obvious choices are still C and C++. That has been the game for a long time and these languages still continue to evolve.
So, you landed in Rust for some reason as I just did and see also other options. That’s also a question I made myself. I always asked myself if I should invest time in D. I also heard of Crystal, Nim and Go. Should I invest time on those or Rust? My quick reading about them made me not ( Go maybe later) while I am serious now about learning Rust
So many languages over the years wanted to challenge C and C++. Rust is the first one I think it really can get some significant future
market share on systems programming.
It’s refreshingly adding some real added benefit over C and C++: memory safety without compromising performance (no GC)
It also has made many good design choices.
And it is raising fast. I think that if Rust fills this gap quickly there will be no gap for Nim or Crystal to fill. So they may fade away like most languages do.
But only the future can tell.
I think these kinds of questions are notoriously difficult to answer because I think a truly informed response can only be made by a person who has:
- Used Rust and gotten more than surface-level deep with it
- Used Nim and gotten more than surface-level deep with it, and
- Has experience in operating system design
The reason is because most people on a certain language forum have only used their own language, or at least uses it much more! It's not that everybody in Rust is just close-minded to other languages, but it does take real investment in both languages to really answer the question in an unbiased, or relatively unbiased, manner.
I would say that with Redox, Rust has proven that it can program operating systems. If you want to know whether or not it worked really well for them, then maybe you can ask some Redox developers somewhere how they feel about it ( again, though, they are going to prefer Rust most-likely ).
Even if you do get understandably biased responses, what you can still do with those responses is try to understand why they prefer Rust and the analyze whether or not their reasons resonate with your own motivations and reasons for wanting to choose a particular language.
Are you able to turn the ARC or GC off in Nim? That's Rust's biggest advantage is that it doesn't need either ARC or GC most of the time, but you can add it when you want it. If Nim has ARC or GC enabled by default, then that is probably going to hurt your general case performance compared to Rust because you don't have to work to turn off any garbage collector in Rust.
I kinda, sorta, agree with that. It's just that if I want to smash a brick wall down I don't need a deep understanding of rubber mallets to know they will not be suitable for the job. Similarly with my concept of 'operating system' I already know not to waste much time looking into Java, C#, Python, etc, etc. It might take a little bit of a look to find if Nim fits the bill or not.
I think your item 3) is key. Know what it is you want to do and how you want to do it. That is going to make whittling down your choice of tool pretty rapidly.