Join the discussion
Write your take first — we'll ask for email only when you're ready to publish.
- Hacker News
- I tend to think of this a bit differently, and would say that C is a low-level language, independent of implementation architecture, because it provides a small set of primitives with relatively simple behavior.
Reason being, I don't see any fundamental difference between an x86 CPU that translates x86 instructions into simpler microinstructions for execution and a machine that translates, say, Haskell code into simpler microinstructions for execution, and I'd still consider Haskell a higher-level language than C.
by jasomill - This is one of my favorite papers; it stole about a year and a half of my time. I still pine for Lisp processors although array languages can now self-host on GPUs, which, APL-pilled, I now feel is better. It'd be so cool (...for compiler writers) to be able to control precisely which kernels stay in which cache levels etc.by veqq
- From the preface of first edition The C Programming Language. Just interesting to note the authors never claimed it was low level, just not "very high level."
---
C is a general-purpose programming language with features economy of expression, modern flow control and data structures, and a rich set of operators. C is not a "very high level" language, nor a "big" one, and is not specialized to any particular area of application.
But its absence of restrictions and its generality make it more convenient and effective for many tasks than supposedly more powerful languages.
- Maybe not then, but we basically have our own poor man's template system now:
With (rumors of) lambdas and defer on the way, C is going the way of classic WoW.#define array(T, N) struct array##T##N { T value[N]; } void copy(array(int, 32)* x, array(int, 32)* y) { *x = *y; } int main() { array(int, 32) x; array(int, 32) y = { 1, 2, 3, 4 }; copy(&x, &y); }by glouwbug - Well, C does give you the control when it matters, even if they feel bolted on for more modern features.
I actually believe Mojo is the only modern language not designed to pretend every computer is a PDP-11. C has been so successful that many succeeding languages just did C things as a matter of course.
In Mojo, everything is designed with the complexity of the modern computer in mind, and at every stage the programmer has complete control of outcomes. You decide what gets inlined, what gets passed in registers, what gets unrolled, etc. The language has excellent ... ney, probably the best portable SIMD support there is; all integers are built on top of SIMD, and the scalar integers are just SIMD with length of 1. You get complete control of what gets compiled as well due to powerful compile-time programming that is similar to, but more powerful than Zig's (imo, because you can supply a lot more information). While C and Rust allow inline asm, Mojo goes further by letting you supply inline MLIR and LLVM as well, so in situations that warrant it, you can tell the compiler to compile to a specific LLVM intrinsic. The language also does not assume you're compiling to run on just one machine; every modern computer is heterogeneous by nature and may contain multiple programmable units, so the compilation pipeline is designed to allow compiling certain parts of code for one target and other parts for other targets... as one compilation unit.
by melodyogonna - I’ve been a fan of this article for years, though it does often make me think that there really aren’t any true low level languages for our super scalar modern CPUs. Does anyone know of any?by legobmw99
- “Low level language” is one of those terms like “VLSI” (very large scale integration) where they defined it in the 70’s or something, so the academic definition is out-of-sync with what most people would expect.
This is fine, it’s a term of art and those don’t need to be immediately obvious.
I don’t like the title of this article for that reason, though. Really a better title would be something like “a modern x86 processor is not a PDP-11.” The subtitle is perfect basically.
Edit: also IMO it is not really fair to beat up on C for this, the problem is not really one of low-level-ness. A language that actually exposed the complexity of speculative execution and all that could be pretty high level. It would just be harder to read in a linear text editor, right? We’d be better off drawing the dependency graph or something.
by bee_rider - This is such a pedantic point IMO. C is low level because it makes it very easy to work with machine language/assembly and do stuff like this (LLM assisted example follows):
This is something "low level" programmers use very often to realize the benefits of a high-level language while exercising explicit control over using specific hardware instructions (vp2intersectd being an AVX-512 instruction used in highly optimized search algorithm impls).int main() { __m512i vecA = _mm512_setr_epi32(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15); __m512i vecB = _mm512_setr_epi32(0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75); unsigned short mask = 0; __asm__ ( "vp2intersectd %[B], %[A], %%k2" : "=@cck2" (mask) : [A] "v" (vecA), [B] "v" (vecB) : "k3" ); printf("Intersection Mask: 0x%04X\n", mask); return 0; }Obviously if you rely on implicit behavior from the compiler to optimize your code you are no longer "low level". But if you can quickly and easily drop into machine-level instructions to provide explicit implementation semantics, and the language indeed makes that relatively simple and easy to do, that sure seems "low level" to me
by weitendorf