Does Nim have some kind of "standalone" or "no backend" mode? Because it feels like an "incomplete" language without a direct-to-machine-code standalone compiler. Also it adds another layer of needless complexity the need to install and interface with, for instance, a c compiler. And its a shame, because it have probably the most elegant syntax I've seen in a programming language.
PS: I get that having different backends makes it applicable in more contexts, but it would be nice to have another, more direct, choice.
it feels like an "incomplete" language
no
adds another layer of needless complexity the need to install and interface with, for instance, a c compiler
you dont have c compiler already installed?
1 Performance. C compilers have thousands of years of effort put into them. That's hard to beat. You could use some thing like LLVM, but its basically C anyways. You could go Go or D route which emit their own native code but it took years for them to get close to the vcc, gcc and llvm speeds.
2 Compatibility. C/C++ compilers are very platform depended LLVM can't interface with steamsdk on windows for example only Visual C++ can. Emscripton which emulate many of the normal C things only exist for C/C++. Android NDK only works with C/C++. And same thing with iOS. You would have to build native compilers for tons of platforms, some times not documented or priority platforms. Why? Just emitting C gets you there.
3 Ecosystem. Building on the compatibility, Nim does not have that many libraries, but C/C++ has a ton. Yes you can wrap any C/C++ with your a hypothetical native code generator - but thats a ton of work. With Nim it's a lot easier. You can nearly just include the headers. It's great. I have created many wrappers for C libraries that just statically link.
At first I was skeptical, but it turns out emitting is one of Nim's strengths.
Here is a question for you: how does this impact you or anyone else that writes Nim software?
I can list a few positive impacts:
The only downside is needing to have a C compiler installer, but that's really not that difficult and Nim makes it effectively transparent. The feeling of "incompleteness" is just a feeling, if there is nothing concrete to back it up then it's not worth spending effort on fixing.
This is how C++ was originally implemented. Mom doesn't produce cross platform C, it produces platform and arch specific C. You can use whatever C compiler you want with Nim. Same with linker, etc...
I disagree with a lot of what is posited in this thread. The C backend has numerous advantages over LLVM including being able to easily debug IR and faster compile times.
Nim gives you lots of options. If you want an LLVM backend, use nlvm as Araq suggested.
This discussion very much feels like theory vs practice.
Can you beat C compilers with unlimited time, money and "ideal" programmer using inline assembly only ? Yes.
Is this a useful consideration when trying to actually produce something ? No.
Software development is about producing a result with limited resources. The rest is just theoretical conjecture.
How much resources would actually be necessary to create a compiler as robust, optimized and portable as gcc (keep in mind that gcc usually gets outclassed by proprietary C compiled such as IAR and ICC) from Nim AST ?
In practice, C compilers will generate better, faster assembly than what 99.99% of C programmer are ever going to write - and even then it would be un-maintainable over time as you'd need to re-implement every C library out there.
Yes, there are some case where writing inline assembly can be useful (reverse engineering, patching buggy start-up code given by a manufacturer, optimizing a specific operation on a critical function etc...) but it's still very limited in scope.
We don't target the C/C++ standards though but the concrete implementations clang, gcc and msvc and we exploit their language extensions. The standards also keep changing. And yes, the C standard does change too and often in subtle ways.
Still, the situation is not too bad. But I'm happy we also have an LLVM backend.
For what is worth in my spare time I'm looking into how to use AI to help with a custom native code generator.
IAR and Keil are mostly used with ARM cortex-M, which Nim supports very well via arm-none-eabi-gcc.
In fact, exactly thanks to Nim's piggybacking on gcc, Nim supports many embedded targets including ARM (many versions, including stuff like GBA and Nintendo Switch), RISCV, AVR and MIPS. Would that be the case if Nim had to implement its own machine backend from scratch for every target? Certainly not, and certainly not with the level of optimization and robustness that comes with the decades of development behind gcc.
Also it adds another layer of needless complexity the need to install and interface with, for instance, a c compiler.
I have yet to see a linux distribution or Mac distribution where installing anything for development or sysadmin doesn't start with installing the C toolchain in something similar to sudo apt-get build-essential or xcode-select --install. The only platform where it's annoying is Windows but well all languages have issues on Windows.
Having worked on another language that targetted the C language, and having looked at that time for a LLVM backend, the most problematic thing with the C backend was when the C code had errors and failed to compile. You get C errors that are difficult to trace back to the original code.
However, as user of Nim, I never felt this way. The C backend must be strong enough that it appears completely transparent. As a matter of fact, I had forgotten that Nim did not compile to native code because it's so well integrated.
Other reasons why you would like to avoid targetting C directly would be to link to symbols that are reserved keywords in C (and would not compile), or to use other low level features that C does not give access to: specific memory layouts, use of registers, ...