“Managed” languages’ closed-world top-down design assumption makes interoperability difficult and slow.
C’s main advantage is not performance, as often assumed, but its assumption of flatter, open-world interoperability in the context of a larger system.
C’s safety disadvantages are implementation artifacts that can be addressed without changing languages—but because of the emphasis on numerical performance, implementations are going in the opposite direction.
Without an equally good open-world language (Rust?) you couldn’t rewrite a lot of C anyway.
For better or worse, C won; that’s the difference.
I would say for better. Not because the C model was better, but because one of the risks was not to have a common calling convention. And that would have been a nightmare.
The greatest trick C ever pulled was convincing the world it doesn’t have a VM or runtime.
This is rarely debated but completely right. Lack of VM or heavy runtime was so influential that almost no one remembers other ways of working, except in almost dead or niche languages.
Due to this, almost all new languages are boringly close to C and this has created a huge gap in language innovation.
“C’s safety disadvantages are implementation artifacts that can be addressed without changing languages—but because of the emphasis on numerical performance, implementations are going in the opposite direction.”
I countered the concept of just implementing C safer elsewhere with the following:
The problem is that it isn’t a new idea. People keep trying it as shown below. Unfortunately, C wasn’t designed so much as a modified version of something (BCPL) that was the only collection of features Richards could get to compile on his crappy hardware. It’s not designed for easy analysis or safety. So, all the attempts are going to hit problems in what legacy code they can support, their performance, or even effectiveness if about reliability/security in a pointer-heavy language. Compare that to Ada, Wirth’s stuff, or Modula-3 to find they don’t have that problem or have much less of it because they were carefully designed balancing the various tradeoffs. Ada even meets author’s criteria for safe language with explicit memory representation despite him saying safe languages don’t have that.
To back that up with references, first is a bunch of attempts at safer C’s or C-like languages with performance issues. The next two are among most recent and practical at memory safety for C apps far as CompSci goes. The last one is an Ada book that lists by chapter each technique its designer used to systematically mitigate bugs or vulnerabilities in systems code.
Ada basically proves his point that you can have a safe, unmanaged, integrative systems language, if you provide good enough facilities for describing the “alien” memory you got from other modules.
I think he’s mainly responding to the widespread assumption that that’s not possible: that only a language that assumes its runtime “owns” the entire address space and allows direct memory access only through a narrow API can ever be safe. Presumably Ada users know that’s not true, but they’re too busy to write blogs…
I like that perspective. With that one, we start with what can be done with current languages then can argue tradeoffs each method offers. Far as Ada users, they seem to be apathetic to or suck at community efforts more than most groups using a language. I think the ones doing solid writing almost exclusively do it in Ada-specific forums, conferences, etc. It might be a pragmatic choice based on how many people in general forums ignore such languages. Nonetheless, it hurts them in adoption since the benefits aren’t widely seen.
If I had a pressing need for some high assurance C code, I’d probably start with something like that. Their results were pretty good with minimal annotations. If you commit to using something like that, you’d increase annotations over time to improve performance.
I agree completely, and reading this paper echoes a lot of my own thoughts about not just the C ecosystem but the surrounds of UNIX in which many of us are constructing the building blocks of our even broader distributed systems. A variety of more-constrained runtime environments with various degrees of memory safety exist, most or all of which are to some degree willfully ignorant of, or even actively hostile to, existing operating system primitives and libraries of code written in other languages.
One example is of how difficult it is to use something like doors when your language implies and enforces a model of parallelism that precludes direct control of operating system threads. Another is SQLite – how likely is it that a de novo implementation to fit into a language-specific world view will have seen as much real-world use and extensive testing?
Also, it should be noted that this is an essay for Onward!, which “is not looking for research-as-usual papers with rigorous development or validation”. It’s looking for insight more than anything else.
…sharing the theme that we need to think less about languages as discrete abstractions, less hierarchically in general, and more about the systems which embody languages—seeing language implementations as parts of those systems, and not shying away from contextual details associated with implementation…
I’m not done reading it and so far I don’t find it to be a convincing case for C or anything, but I think this point is a good one.
It was painful to try to read this one. I eventually opened HN where I saw it just to see if someone summarized it. Fortunately, jasode had a nice one here:
That lets me get right to the points to acknowledge or counter in other threads. Other than response to wrs, I’ll also note the author is incorrect about safe languages not representing memory. Ada lets you describe data types in a high-level, compiler-checkable way plus tell the compiler how to lay them out in memory. Many of these languages also have an UNSAFE mode. One can also output C like Galois does with Ivory language if using compilers for portability or performance. PreScheme also did that with the added benefit one was then system programming in a semi-functional language with real macros! :) Far as communication and system-wide integration, both Ada and Wirth’s stuff were way more effective on that while being low-level enough for OS’s.
The author is correct that people wanting C gone are better off trying to understand why people use it in the first place. I’ve often listed reasons where C is a good choice for a specific team or project. However, authors like this also need to do their research on system languages that are safer or more expressive to see why one might use them. Then, carefully assess how much of those capabilities could be moved to a C-like language to improve it. One of the people who did that a few years ago came up with Cyclone whose safety concepts got iterated into Rust’s.
First time I’ve seen a good synthesis of:
“Interoperability?!” Ha! At least I remember battling calling conventions.
For better or worse, C won; that’s the difference.
The greatest trick C ever pulled was convincing the world it doesn’t have a VM or runtime.
I would say for better. Not because the C model was better, but because one of the risks was not to have a common calling convention. And that would have been a nightmare.
This is rarely debated but completely right. Lack of VM or heavy runtime was so influential that almost no one remembers other ways of working, except in almost dead or niche languages.
Due to this, almost all new languages are boringly close to C and this has created a huge gap in language innovation.
How so? I’m trying to follow this comment here but am not sure what you mean.
“C’s safety disadvantages are implementation artifacts that can be addressed without changing languages—but because of the emphasis on numerical performance, implementations are going in the opposite direction.”
I countered the concept of just implementing C safer elsewhere with the following:
The problem is that it isn’t a new idea. People keep trying it as shown below. Unfortunately, C wasn’t designed so much as a modified version of something (BCPL) that was the only collection of features Richards could get to compile on his crappy hardware. It’s not designed for easy analysis or safety. So, all the attempts are going to hit problems in what legacy code they can support, their performance, or even effectiveness if about reliability/security in a pointer-heavy language. Compare that to Ada, Wirth’s stuff, or Modula-3 to find they don’t have that problem or have much less of it because they were carefully designed balancing the various tradeoffs. Ada even meets author’s criteria for safe language with explicit memory representation despite him saying safe languages don’t have that.
To back that up with references, first is a bunch of attempts at safer C’s or C-like languages with performance issues. The next two are among most recent and practical at memory safety for C apps far as CompSci goes. The last one is an Ada book that lists by chapter each technique its designer used to systematically mitigate bugs or vulnerabilities in systems code.
https://pdfs.semanticscholar.org/a890/a850dc78e65e26f8f4def435b17094ce08cf.pdf
https://llvm.org/pubs/2006-06-12-PLDI-SAFECode.html
https://www.cs.rutgers.edu/~santosh.nagarakatte/softbound/
http://www.adacore.com/uploads/technical-papers/SafeSecureAdav2015-covered.pdf
EDIT: Removed this comment from main thread and posted it here as a reply. Clicked the wrong one at first apparently.
Ada basically proves his point that you can have a safe, unmanaged, integrative systems language, if you provide good enough facilities for describing the “alien” memory you got from other modules.
I think he’s mainly responding to the widespread assumption that that’s not possible: that only a language that assumes its runtime “owns” the entire address space and allows direct memory access only through a narrow API can ever be safe. Presumably Ada users know that’s not true, but they’re too busy to write blogs…
I like that perspective. With that one, we start with what can be done with current languages then can argue tradeoffs each method offers. Far as Ada users, they seem to be apathetic to or suck at community efforts more than most groups using a language. I think the ones doing solid writing almost exclusively do it in Ada-specific forums, conferences, etc. It might be a pragmatic choice based on how many people in general forums ignore such languages. Nonetheless, it hurts them in adoption since the benefits aren’t widely seen.
Link to CCured paper: https://www.cs.virginia.edu/~weimer/p/p477-necula.pdf
If I had a pressing need for some high assurance C code, I’d probably start with something like that. Their results were pretty good with minimal annotations. If you commit to using something like that, you’d increase annotations over time to improve performance.
I agree completely, and reading this paper echoes a lot of my own thoughts about not just the C ecosystem but the surrounds of UNIX in which many of us are constructing the building blocks of our even broader distributed systems. A variety of more-constrained runtime environments with various degrees of memory safety exist, most or all of which are to some degree willfully ignorant of, or even actively hostile to, existing operating system primitives and libraries of code written in other languages.
One example is of how difficult it is to use something like doors when your language implies and enforces a model of parallelism that precludes direct control of operating system threads. Another is SQLite – how likely is it that a de novo implementation to fit into a language-specific world view will have seen as much real-world use and extensive testing?
It was hard wading through that…. but D looks like a closer fit to addressing all the concerns listed in that doc.
Also, it should be noted that this is an essay for Onward!, which “is not looking for research-as-usual papers with rigorous development or validation”. It’s looking for insight more than anything else.
I’m not done reading it and so far I don’t find it to be a convincing case for C or anything, but I think this point is a good one.
Proof that if you wrap drivel in academic packaging people will fall for it.
It was painful to try to read this one. I eventually opened HN where I saw it just to see if someone summarized it. Fortunately, jasode had a nice one here:
https://news.ycombinator.com/item?id=15179700
That lets me get right to the points to acknowledge or counter in other threads. Other than response to wrs, I’ll also note the author is incorrect about safe languages not representing memory. Ada lets you describe data types in a high-level, compiler-checkable way plus tell the compiler how to lay them out in memory. Many of these languages also have an UNSAFE mode. One can also output C like Galois does with Ivory language if using compilers for portability or performance. PreScheme also did that with the added benefit one was then system programming in a semi-functional language with real macros! :) Far as communication and system-wide integration, both Ada and Wirth’s stuff were way more effective on that while being low-level enough for OS’s.
The author is correct that people wanting C gone are better off trying to understand why people use it in the first place. I’ve often listed reasons where C is a good choice for a specific team or project. However, authors like this also need to do their research on system languages that are safer or more expressive to see why one might use them. Then, carefully assess how much of those capabilities could be moved to a C-like language to improve it. One of the people who did that a few years ago came up with Cyclone whose safety concepts got iterated into Rust’s.
[Comment from banned user removed]