
The long goodbye to C - jgrahamc
http://esr.ibiblio.org/?p=7711
======
tptacek
I'm not sure there's really much to learn from this post.

Raymond is not in fact in a good vantage point to judge the suitability of Go
or Rust as "systems languages". His claims to authority in this post are
"NTPsec" and GPSD†, but Raymond neither designed nor implemented either of
those programs: NTPsec is a hostile fork of ntpd, and GPSD --- which is
probably not a good example of a program that makes particularly strenuous
demands on its programming language runtime --- was _maintained_ by Russell
Nelson, after being written by a different team --- before Raymond claimed it
for his resume.

In this middle of this article, Raymond claims that Python is suitable largely
for single-user applications operating "at human speed". This is so far
outside the reality of how Python is used in industry as to call pretty much
everything else Raymond writes in the article into question.

Surely, somebody else has to have written something better on the trend
towards next-generation systems languages.

† _These are the examples he provides, in this article, by the way._

~~~
Nokinside
I predict that C++ will lose more ground to Rust and Go than C.

It's hard to find programming language that will cover as much low level
programming needs as C. If some aspiring hacker turns 14 today and wants to
get into the low level systems programming/embedded programmer career learning
C well is a must. They may use some other language more, but they need to know
C unless they want to limit themselves.

Some processors have stack size just 2-8 and memory available can be something
like 128B - 8KB. Any replacement must have programing model that is very low
level. Any replacement for C must have very low level and simple programming
model.

~~~
digitalzombie
Go... isn't really a system programming language. I don't get why people group
Rust and Go together.

C++ may lose some ground to Rust but it may just end up saturated like Ruby,
PHP did. Ruby is basically in steady state now. NodeJS jump in on a crowded
market and got no where let alone it's crazy threadless model.

C++ btw have been pumping out new versions, C++17 was just completed by GCC
and Clang is almost done. C++ is really trying to modernize.

Google whole backend is most likely C++... it ain't going no where.

Rust is a beautiful language but it still have a long way to go. And also
resources such as books to help people jump on board not just general books
either but books in different domain (scientific computing, data structure,
web dev, etc.. whatever).

~~~
emodendroket
Plenty of people are working in node, for whatever reason. Just yesterday I
was reading someone on HN saying backend JavaScript is the only way to make
any money. Not that I think he's right, but if there are people out there
thinking that I figure it has to have healthy enough marketshare.

------
fhood
Oddly enough C never bothered me. It has its purpose, and despite its flaws it
still feels elegant. C++ however should be illegal. When do we get to say
goodbye to it?

Edit/Continuation: I feel like the freedom offered by C works because of it's
simplicity, and as a language for embedded systems I still enjoy developing in
C. As someone who recently started working primarily in C++ though I am
frequently astounded by the choices that were made. And to make things worse,
offering C style controllability in a complex OO language doesn't work well. I
shouldn't have to feel like I need to read the designers minds to predict how
a language will act.

~~~
rwbt
After programming in C++ for nearly a decade, I too came to the same
conclusion. I was always told to avoid C (because dangling pointers and what
not) but now even though C++ has some things I like, overall I think C is a
lot easier to 'think' in. Even though dangling pointers etc are an issue,
you'll pick up good habits over time and avoid many usual C issues.

I think what replaces C should be something like Nim, which compiles to C and
also has great C interop. C++ is definitely not it.

~~~
Nokinside
>dangling pointers etc are an issue

In the safety critical programming we use subset of C or (C++) with static
code analysis. It's possible to prove that there is no dangling pointers,
divisions by zero, floating point exceptions (with assertions), out of bounds
array access. It's called verification.

Programming is limited into MISRA C and then it's run trough static code
analysis tool like Astree to prove that there is no run­time errors. There are
still bugs, but they are not "typical C errors". Waiting for new systems
programming candidates to get their toolchain to match the task.

[https://www.absint.com/astree/index.htm](https://www.absint.com/astree/index.htm)

~~~
pjmlp
> Waiting for new systems programming candidates to get their toolchain to
> match the task.

Ada, doing it since 1983.

------
throwaway2016a
I think it is easy to overestimate the importance of a managed language.
Having to manage memory yourself is not that big a burden in many
applications. In many cases it is a help.

For instance, I had a ETL program I was writing to process 100+ GB files. I
pre-allocated all the memory I needed for exactly one row of data and
immediately printed out the data when it finished that row (stream style).

The entire program processed 100 GB with lightning speed in less than 1K of
memory. Maxing out the performance of the disk.

Best of all, I only had to free my memory at the end. Completely safe. No
danger of double freeing and no extra memory allocation at all. Literally a
dozen mallocs at the start and a dozen frees at the end.

Could I do that in Go? Sure. Would it have as optimized memory access?
Maybe... but probably not. And C my entire program was 200 lines of code and
absurdly fast.

Don't get me wrong, I love Go. I write programs in Go often. But for simple
apps where the code can fit in a single file nothing can beat C. No bloat, no
extra memory operations, and a code optimizer that has been being optimized
for 30+ years. Go's code optimizer is not even close yet from what I can tell.

~~~
isaiahg
Just out of curiosity from someone who started with languages like JavaScript
and other languages. But what makes C special for this case? For instance
couldn't I achieve the same thing with typed arrays in JavaScript?

Sorry if it's a naive question. My experience with C is limited.

~~~
vvanders
Nope, the main advantage of C/Rust/D/etc is explicit control of memory
allocation and placement.

90% of your program performance is going to be dominated by cache usage(unless
you're doing something really dumb). With C you can place things next to each
other explicitly so that your prefetcher/etc is automatically pulling in the
data you need to the L1 cache.

Any ref'd/GC'd language is going to make that _really_ hard(not impossible,
but you have to jump through a million hoops like sun.misc.unsafe in Java).

Look up Data Oriented Design if you're interested in this stuff, Mike Acton
does a great job covering it.

~~~
pjmlp
> Any ref'd/GC'd language is going to make that really hard(

Not true at all.

Oberon, Active Oberon, Component Pascal, Modula-2+, Modula-3, D, System C#,
Nim all offer ways to manually control memory outside GC control, just like C
and C++.

Glad to provide Modula-3 examples to any C tricks you might want to do, or in
D if you prefer something more modern.

~~~
vvanders
Yet not a single one of those examples is a mainstream language. So when you
finish the project and move on to bigger things I've got a codebase that no
one can maintain.

Note that I didn't say that it was impossible, just that the ergonomics of
GC'd languages don't tend to focus on performance in the ways that languages
with explicit memory control do.

~~~
pjmlp
Most of those languages died due to political reasons and company
acquisitions, not because of lack of technical features.

GC systems programming languages offer exactly the same explicit control as C
does, in unsafe memory blocks.

Do you want to shot yourself like C in Modula-3? Declare a variable as
_UNTRACED REF_ , 100% like a C pointer.

Do you want a C union? Declare a tagged _RECORD_ type.

Do you want a packed record to fill you cache line? Compiler alignment
pragmas.

Allocation of value types on the stack or global memory section? Great, it is
the default allocation type.

Bit fiddling to prepare a statically allocated buffer for a DMA transfer?
_UNSAFE_ code section.

~~~
vvanders
> Most of those languages died due to political reasons and company
> acquisitions, not because of lack of technical features.

Yet you just talked past my point to give some sort of soliloquy about
Modula-3.

It doesn't matter how those languages died, it just matters that they did. The
ecosystem and number of people who know how to write a language is almost, if
not more important than the language when it comes to shipping software.

~~~
pjmlp
No, my point was that these languages have 100% the same ergonomics as C in
what concerns explicit memory management, with the additional productivity of
having a GC around when those requirements aren't a must.

We should not think of Java when comparing system programming languages with
GC against C.

~~~
vvanders
Yet you _still_ keep talking past my point(while also nicely moving the
goalpost).

Yes, the languages you mention meet all the technical requirements(congrats,
here's your 10 internet points) it doesn't matter if I can't find people who
know how to write it.

Since you seem to want to avoid talking about anything I raise I don't think
it's productive to continue this conversation.

~~~
pjmlp
Just because these languages died, doesn't mean we cannot take those lessons
into GC languages where you can find people who know how to write it.

For example, all the work with System C# done in Midori has been being applied
to C#, with .NET Native, ref returns, local ref variables, value tuples,
regions with disabled GC, memory slices, with a few more down the roadmap,
like effectively manual memory management presented at OOPSLA 2017.

Or the ongoing @nogc and BetterC improvements in D, Wallmart, EBay, Netflix,
Remedy Games among many others, seem to be able to find people that know how
to write it.

------
moxious
It's going to be a loooooooooooooooong goodbye. COBOL is still around for what
it's worth. The dominant OS (Linux) is written in C. I'd assert that any
language used to implement a widely deployed operating system has at least
that operating system's lifetime + 20 years, assuming the OS isn't rewritten.

"Re-write Linux in Go" I think would be a massive but classic folly

~~~
pjmlp
Which is why, although I deslike C, I am also very realist than until we get
rid of UNIX clones, C will stick around.

~~~
greenhouse_gas
What does C have to do with Unix? You can write a Unix-like OS in Rust and a
Non-Unix like OS in C (or C++[1], like Windows).

It happens to be a trope that C would have died if not for Unix[2], but to the
best of my memory of reading programming books of the eighties, C's un-safety
was a _feature_, not a bug (I remember Java books were _so_ apologetic that
Java didn't have points arithmetic).

In the days before optimizing compilers and slow computers, the ability to
write unsafely manipulate arrays was actually useful when one needed speed
(and if one wanted to be a "real hacker", one needed to optimize every byte
and instruction.) Now it's true that not every program needed that speed, and
quite a few would be willing to trade speed for safety, but no "self
respecting real programmer" would allow himself to write in _anything_ that
wouldn't let him be that "uber-hacker" (sounds familiar? I guess Resume
oriented programming is an old problem).

[1]. Before I get the pedants that C++ isn't C, I'd like to remind them that
the Windows NT codebase started in the late eighties and early nineties, when
C++ _was_ almost like C with classes.

[2]. In reality, quite a few languages took off which were not the same
language as their OS (for example, Java, Python, C#). If anything, I'd say
it's more important that the compiler vendor be the same company as the OS
vendor (see Borland's history), but even that seems like a more modern problem
(again, see Borland's history)

~~~
pjmlp
Using C++ with Turbo Vision, OWL, VCL, MFC was hardly C with Classes.

I never did manually resource management with them. RAII was already a thing
in MS-DOS.

Java and C# were pushed by OS vendors.

------
ravingraven
This showing up next to "LibHTTP: Open Source HTTP Library in C" on the HN
front page made me giggle. Someone should start a website a-la
bitcoinobituaries for C.

C will be around for as long as everything under the sun has a C compiler. If
you ask yourself when was the last time you started a C project, ask yourself
when was the last time you wanted to write something truly ( _truly_ ,
including embedded) portable instead and there is your answer.

~~~
pjmlp
To kill C, we need to kill UNIX.

So until we get to replace POSIX across the board, C will be around.

It will take generations.

~~~
greenhouse_gas
Kill Unix?

Bell Labs tried to kill their child and supplant it with plan-9 and inferno.

It failed.

Not because they were bad OSs, but because once you have market domination and
code, things _must_ be backwards compatible.

If Linux/GNU didn't imitate POSIX, it wouldn't be any more popular than Haiku.

~~~
pjmlp
And so C use grew instead of dying, as Apple and Microsoft systems were
already focusing on C++.

------
bachmeier
"Am I predicting the imminent extinction of C? No. For the foreseeable future
I think it will retain a pretty firm grip on OS kernels and device firmware.
There, the old imperative to squeeze out maximum performance even if it means
using an unsafe language still has force."

Maybe, but there are projects like D's betterC[1] that are designed to remove
that reason to use C as well.

[1] [https://dlang.org/blog/2017/08/23/d-as-a-
better-c/](https://dlang.org/blog/2017/08/23/d-as-a-better-c/)

~~~
krylon
D is a sweet language, but there are lots of CPUs/Microcontrollers for which C
compilers are available, but not much else (except assembly).

~~~
pjmlp
Once upon a time, C was only available in expensive UNIX workstations.

~~~
krylon
I do not work in embedded systems, so take anything I say with a grain of salt
(or more!).

If D became available in all of those embedded platforms, I am sure lots of
people would rejoice. Or maybe they would just shrug because they would not
know what hit them. But it would be their loss, because D is, in many ways,
C++ "done right". Which IMHO is a remarkable achievement.

Either way, I would not hold my breath for C becoming obsolete in the sense of
"no one is using it any more". It is not happy, but for now it is all we've
got.

~~~
scruple
> I am sure lots of people would rejoice

I'm one of those people and I spent ~6 years in embedded and I still write C
today (though it's no longer my primary language). Of my former co-workers,
probably 50 people in total across 4 teams, exactly 0 of them were at all
interested in any sort of C alternative. I'd wager less than 6 of them even
knew what C alternatives were even picking up steam. If it wasn't talked about
by folks like Michael Barr or Embedded magazine, they simply wouldn't have any
way of finding out.

> Either way, I would not hold my breath for C becoming obsolete

I wouldn't either. Call it the old guard, call them greybeards, it really
doesn't matter. They're the ones buying chips from vendors that supply C
toolchains and compilers. Until that is addressed, none of this talk matters.

~~~
pjmlp
Which is why there is the saying that progress can only be achieved by
replacing generations.

------
shmerl
I agree with the sentiment, but not with the idea that Go is a suitable
general replacement for C. Rust on the other hand fits that role.

~~~
stmw
And the issue is mostly the garbage collector, not any other language features
or compiler optimization improvements. You just can't have GC in a systems
language.

~~~
shmerl
Mostly. Rust also tends to provide explicit control, which makes it more
complicated, but aligns more with the approach of C to that.

As someone explained to me, it's the reason Rust doesn't have a nice
initializer syntax like C++11 for example[1].

1\.
[http://en.cppreference.com/w/cpp/language/list_initializatio...](http://en.cppreference.com/w/cpp/language/list_initialization)

~~~
slavik81
I'm not sure I would call it a nice syntax. std::initializer_list was a
questionable addition to C++ because its syntax clashes with other forms of
initialization. It ends up creating special cases and complicating generic
code. They fixed some of its problems in C++14, and we might see more
improvements in C++20, but the entire idea of that syntax creating a special
object feels like a mistake.

------
sytelus
Go isn't systems programming language. As soon as you enforce gc built-in to
language, it seizes to be systems programming language.

~~~
pjmlp
Tell that to Niklaus Wirth, Alan Kay, Joe Duffy, Luca Cardelli and quite a few
other industry luminaries.

~~~
sytelus
Go being paddled by industry hot shots doesn't change the facts. A language
designed for systems programming must have precise control on everything that
goes on. When you are dealing with thousand threads on 100s of cores, every
microsecond counts. When you are designing control software for aerial
vehicles on embedded devices doing stuff in ISRs, every thing needs to be
predictable. No one in their right mind will rely on gc in that kind of
systems programming world.

~~~
abiox
this is a narrow and arbitrary definition of "systems programming". you seem
to be describing something closer to hard realtime computing, which is not the
same thing.

~~~
dboreham
Seriously? He's using the term in exactly the way everyone uses it, even
Wikipedia :
[https://en.wikipedia.org/wiki/System_programming](https://en.wikipedia.org/wiki/System_programming)

~~~
abiox
if you read your link, even the wikipedia article authors do not restrict the
notion to hard realtime computing.

it's not really how "everyone" uses it. it's a narrowing that a subset of
vocal people have been trying to push, i can only presume for ideological
purposes.

------
Santosh83
> Am I predicting the imminent extinction of C? No. For the foreseeable future
> I think it will retain a pretty firm grip on OS kernels and device firmware.
> There, the old imperative to squeeze out maximum performance even if it
> means using an unsafe language still has force.

Rust is well suited for OS code if not for the inertia that most OS devs are
experts at C and not so in Rust and compiler support. Those two factors are
going to become less important going forward, so Rust (with generous 'unsafe')
could replace C in its last stronghold too.

~~~
muricula
I don’t believe Rust is ready for OS kernels yet. People have written OS
kernels but they really stretch the language to do it. For instance, the
default heap allocation API panics on failure, which isn’t something I want my
kernel to do. There’s work on a new API which doesn’t do this in nightly rust,
but they could completely change all that tomorrow.

Additionally, alignment constraints are also really important at that level,
but rust doesn’t have a mature way to align structures or arrays.

Rust isn’t ready for this space yet.

~~~
steveklabnik
When you're writing a kernel in Rust, you aren't using the default heap
allocation API; you aren't using the allocation API at all. You could then
build any sort of allocation strategy you want. You don't need to wait for the
new traits, though of course, using them eventually helps with
interoperability.

You're certainly right about "mature way" wrt alignment, but it's something
that can be worked around until then.

------
chx
There's another thing slowly but inexorably gaining ground: you need to write
concurrent code. From your CPU to your cloud, parallel is the new king, much
more than before. Any language where two parallel running pieces of code can
alter the same variable is not usable for parallel purposes as debugging
becomes a special hell.

Hail to Erlang and even more, Elixir.

~~~
AstralStorm
The "unsafe" threading has to be available though. Simone primitives like
barriers as well.

Otherwise you pay the cost when you really do not need to. Just ask people
involved in actual places where microseconds matter, such as real time control
or high frequency trading.

Erlang does not provide these primitives enforcing unnecessary copies in a
bunch of places.

------
Aloha
I strongly suspect that even in 50 years, we will still be writing systems and
software in a dialect of C - so long as UNIX lives on, C will too.

There will probably always be a need in computering for 'Portable Assembly'
too, which is another reason C (or C like languages) will never disappear.

------
baybal2
Death of C is like a commercial fusion power. Every 5 years, some specialist
comes forward and predicts that C will be obsoleted in the next 5 years.

And I think it is even more true for FORTRAN

------
clw8
I went to a "Public Ivy" about ten years ago and at the time both CE and CS
students started with C, CE students sticking with it and CS students moving
on to Java. Is this still true for the average public school? Learning C and
various Assembly languages and using them to program micros is where
everything finally clicked for me. Rust is lovely but I don't ever see it
being the CS101 language because of elegant but difficult concepts like
lifetimes.

~~~
loeg
UW does Java for both CS and CE and has done since the 00's. There was one
optional C and unix class while I was there. Also one mandatory "programming
languages" class that introduced functional languages and lisp.

------
DmitryOlshansky
You should absolutely checkout D language (dlang.org).

It’s less stringent compared to Rust’s borrow checker, but also has meta
programming capabilities of similar power to macroses. The default is GC
manged memory like in Go.

However it’s super flexible in that you can go from 100% simple GC-based
programming with dynamic arrays and maps to hardcore low-level stuff with
manual memory or anything in between (e.g. Ref-Counting as in C++).

------
vortico
C is really great for writing format encoders/decoders that easily bind with
any scripting or compiled language in existence. The ease of compiling it on
all platforms and producing binaries that export simple "function_name"
symbols make it still the best choice for delivering a format implementation
as widely as possible.

~~~
erik_seaberg
Most decoders are in a position to be attacked with malicious input, which
makes C a disastrous choice.

~~~
vortico
In my experience, most applications of C libraries are used in places where
security is irrelevant, but even if it mattered, there are of course ways to
write C without carelessly throwing around pointers. For example, an AIFF to
WAV converter likely doesn't need to allocate any memory at all, it just takes
a buffer with a length and writes to a buffer with a length. It's very easy to
prove correctness of a large number of library decoders/encoders, but of
course there are others which may be difficult.

------
AndyKelley
Go has a garbage collector and writing code in Rust can be extremely
difficult. A third competitor is Zig, which does not guarantee safety, but is
designed to make safety much easier. This is explained in more detail in this
wiki article, "Why Zig When There is Already C++, D, and Rust?":
[https://github.com/zig-lang/zig/wiki/Why-Zig-When-There-
is-A...](https://github.com/zig-lang/zig/wiki/Why-Zig-When-There-is-Already-
CPP%2C-D%2C-and-Rust%3F)

------
nice_byte
C++ >= 11 is your answer

------
gpvos
Not sure why he promotes Cx instead of D.

