We’ve gone from working with the same data types that the CPU processes to an elaborate stack of layer after layer of artifice and illusion. If C is a punk band, blaring out the two or three basic types that the CPU understands, this new style of programming is Rick Wakeman hiring the London Symphony Orchestra to play backup for his synthesizer.
There are some good zingers in there, to be sure:
I especially like that one, because my current go-to for bludgeoning problems into submission is JS.
Half the fun of C and JS is figuring out how to write them in a “highbrow” manner, with the expectation that when the end of the night comes and the lights go down you can drop down into the dirty tricks and win on low animal cunning.
If you like that I can recommend Common Lisp as well (which is my go-to). A very practical, high-level, batteries included language that allows for some pretty good optimizations when needed:
This is a fun read, but the author stretches the “ownership” idea pretty thin. And what isn’t punk about the FSF? That whole licensing thing is merely a weapon of opportunity, like a found brick. That Stallman is so unbending in its use is merely the method by which he chose to throw it–to great effect, I might point out!
C remains a simple and small language, translatable with simple and small compilers.
And if you find one being used, let me know!
"hello" / 2
I don’t think of C as punk rock. Writing assembly because it’s cool/retro might be steampunk, but plenty of people still write assembly for work and do very careful, methodical work with it.
To me, C is the dominant mid-level language, and probably dominates that space like no other language dominates an abstraction level. In high-level languages, we have the very real set of trade-offs between dynamic and static typing. I happen to like one side (ML/Haskell-style static typing) better but I also recognize that most people will never pick up a language where you need monads to perform side effects. At the low level, we still have different kinds of processing units and varying capabilities: vector instructions, conditional moves, GPUs and DSPs and so on.
The middle level of abstraction seems to be “solved”– not perfectly, but good enough for many purposes– in a way that higher and lower levels still haven’t been. That, I think, is C’s appeal.
The middle level of abstraction seems to be “solved”
For now. C has been fairly robust to small architectural changes - vectorizers mostly work well enough to utilize SIMD - but it’s not good at adapting to larger shifts. Case in point: look at GPU computing, where C’s best solutions are sorta-kinda-C kept as strings (OpenCL) or preprocessors that cut up your source (CUDA). Contrast this with something like Haskell, where for example GPipe gives a nice EDSL without any funny separation from the rest of your code. C has the same problem even with parallel processors, where interfaces like transactional memory can’t be implemented sanely in straight C so compilers added language extensions to handle it instead. Again, better languages allow this to be handled cleanly as a library.
This problem will come to a head when FPGAs or similar very-parallel architectures start being commonplace, which they will, as we’ll need to find our speed boosts somewhere with free die shrinkages tapering off. C is a bad fit for this setting, as attempts at C-to-Verilog translators continue to demonstrate. Something Rust-like might be a good fit for it’s ability to at least write EDSLs, but I think functional languages like Haskell are really the right way forward. Lack of side effects allow for fine-grained parallelism, which is exactly what an FPGA setting gives you, so functional languages can adapt to circuitry in a way that sequential procedural languages can’t.
C has enjoyed being the “language of the machine” for decades, but it probably only has one more in that capacity.
Is Bourne shell punk rock? It’s not really owned by anyone anymore, and some code I’ve seen written in it is… Of low aesthetic value.