[Translated]The Long Goodbye to C

This commit is contained in:
name1e5s 2017-11-15 22:23:24 +08:00
parent 91e04f7ded
commit 63c728c6e1
2 changed files with 86 additions and 86 deletions

View File

@ -1,86 +0,0 @@
Translating By name1e5s
The long goodbye to C
============================================================
I was thinking a couple of days ago about the new wave of systems languages now challenging C for its place at the top of the systems-programming heap Go and Rust, in particular. I reached a startling realization I have 35 years of experience in C. I write C code pretty much every week, but I can no longer remember when I last  _started a new project_  in C!
If this seems completely un-startling to you, youre not a systems programmer. Yes, I know there are a lot of you out there beavering away at much higher-level languages. But I spend most of my time down in the guts of things like NTPsec and GPSD and giflib. Mastery of C has been one of the defining skills of my specialty for decades. And now, not only do I not use C for new code, I cant clearly remember when I stopped doing so. And…looking back, I dont think it was in this century.
Thats a helluva thing to have sneak up on me when “C expert” is one of the things youd be most likely to hear if you asked me for my five most central software technical skills. It prompts some thought, it does. What future does C have? Could we already be living in a COBOL-like aftermath of Cs greatest days?
I started to program just a few years before the explosive spread of C swamped assembler and pretty much every other compiled language out of mainstream existence. Id put that transition between about 1982 and 1985\. Before that, there were multiple compiled languages vying for a working programmers attention, with no clear leader among them; after, most of the minor ones were simply wiped out. The majors (FORTRAN, Pascal, COBOL) were either confined to legacy code, retreated to single-platform fortresses, or simply ran on inertia under increasing pressure from C around the edges of their domains.
Then it stayed that way for nearly thirty years. Yes, there was motion in applications programming; Java, Perl, Python, and various less successful contenders. Early on these affected what I did very little, in large part because their runtime overhead was too high for practicality on the hardware of the time. Then, of course, there was the lock-in effect of Cs success; to link to any of the vast mass of pre-existing C you had to write new code in C (several scripting languages tried to break that barrier, but only Python would have significant success at it).
In retrospect I should have been alert to the larger implications when I first found myself, in 1997, writing a significant application in a scripting language. It was a librarians assistant for an early source-code distribution hub called Sunsite; the language was Perl.
This application was all text-bashing that only needed to respond at human speed (on the close order of 0.1s), and so was obviously silly to do in C or any other language without dynamic allocation and a real string type. But I thought of it as an experiment and would not have predicted at the time that almost never again would I type “int main(int argc, char **argv)” into the first file of a new project.
I say “almost” mainly because of [SNG][3] in 1999\. I think that was my last fresh start in C; all the new C I wrote after that was for projects with a 20th-century history in C that I was contributing to or became the maintainer of like GPSD or NTPsec.
By the time I wrote SNG in C I really shouldnt have. Because what was happening in the background was that the relentless cycling of Moores Law had driven the cost of compute cycles cheap enough to make the runtime overhead of a language like Perl a non-issue. As little as three years later, I would have not have hesitated before writing SNG in Python rather than C.
Learning Python in 1997 was quite the watershed event for me. It was wonderful like having the Lisp of my earliest years back, but with good libraries! And a full POSIX binding! And an object system that didnt suck! Python didnt drove C out of my toolkit, but I quickly learned to write Python when I could and C only when I must.
(It was after this that I began to feature what I called “the harsh lesson of Perl” in my talks that is, any new language that ships without a full POSIX binding semantically equivalent to Cs  _will fail._ . CS history is littered with the corpses of academic languages whose authors did not grasp this necessity.)
It might be too obvious to need saying, but a major part of Pythons pull was simply that when writing in it I never had to worry about the memory-management problems and core-dump crashes that are such wearying regular a part of a C programmers life. The unobvious thing is the timing in the late 1990s the cost-vs.risk tradeoff in applications and the kind of non-kernel system-service code I usually write definitively tilted towards paying the overhead of a language with automatic management in order to eliminate that class of defects. Not long before that (certainly as late as 1990) that overhead was very often unaffordable; Moores law hadnt cranked enough cycles yet.
Preferring Python over C and migrating C code to Python whenever I could get away with it was a spectacularly successful complexity-reduction strategy. I began to apply it in GPSD and did it systematically in NTPsec. This was a significant part of how we were able to cut the bulk of the NTP codebase by a factor of four.
But Im not here to talk about Python today. It didnt have to be Python that ended my use of C in new programs by 2000; while I still think it beats its competition like a dusty carpet, any of the new-school dynamic languages of the time could have pulled me away from C. Theres probably a nearby alternate timeline where I write a lot of Java.
Im writing this reminiscence in part because I dont think Im anything like unique. I think the same transition was probably changing the coding habits of a lot of old C hands near the turn of the century, and very likely most of us were as unaware of it at the time as I was.
The fact is that after 2000, though I did still the bulk of my work in C/C++ on projects like GPSD and Battle for Wesnoth and NTPsec, all my new program starts were in Python.
Often these were projects that might well have been completely impractical in C. I speak of projects like [reposurgeon][4] and [doclifter][5], in particular; trying to do these in C, with its limited data-type ontology and its extreme vulnerability to low-level data-management issues, would have been horrifying and probably doomed.
But even for smaller stuff things that might have been practical in C I reached for Python, because why work harder and deal with more core-dump bugs than you have to? Until near the end of last year, when I tried to start a project in Rust and wrote my [first successful small project in Go.][6]
Again, though Im talking about my personal experience here, I think it reflects larger trends pretty well, more anticipating than following them. I was an early Python adopter back in 98, and statistics from [TIOBE][7] tell me I did my first Go project within months of when it broke out from being a niche language used mainly at the corporate shop that originated it.
More generally: Only now are the first languages that directly challenge C for its traditional turf looking viable. My filter for that is pretty simple a C challenger is only “viable” if you could propose to a old C hand like me that C programming is No Longer Allowed, heres an automated translator that lifts C to the new language, now get  _all your usual work done_   and the old hand would smile happily.
Python and its kin arent good enough for that. Trying to implement (for example) NTPsec on Python would be a disaster, undone by high runtime overhead and latency variations due to GC. Python is good enough for code that only has to respond to a single user at human speed, but not usually for code that has to respond at  _machine speed_   especially under heavy multiuser loads. Its not just my judgment saying this Go only  _exists_  because Google, then Pythons major backer, hit the same wall.
So Go is designed for the C-like jobs Python cant handle. Its too bad we dont actually have an automatic code lifter, but the thought of doing all my systems stuff in Go doesnt scare me. In fact Im quite happy with the idea. My C chops are still largely applicable and I get garbage collection and really sweet concurrency primitives too, whats not to like?
(Theres more about my first Go experience [here][8].)
Id like to include Rust under “reasons C is growing obsolete”, but having studied and tried to code in the language I find [its just not ready yet.][9]. Maybe in five years.
As 2017 is drawing to a close, we have one relatively mature language that looks like a plausible C successor over most of Cs application range (Ill be more precise about that in a bit) and an awkward youngster that might complete successfully in a few years.
Thats actually huge. Though it may be hard to see just how huge until you lift your head out of current events and take a longer perspective. We went  _thirty years_   most of my time in the field without any plausible C successor, nor any real vision of what a post-C technology platform for systems programming might look like. Now we have two such visions…
…and there is another. I have a friend working on a language he calls “Cx” which is C with minimal changes for type safety; the goal of his project is explicitly to produce a code lifter that, with minimal human assistance, can pull up legacy C codebases. I wont name him so he doesnt get stuck in a situation where he might be overpromising, but the approach looks sound to me and Im trying to get him more funding.
So, now I can see three plausible paths out of C. Two years ago I couldnt see any. I repeat: this is huge.
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.
Whats opening up now is the space just above that that I usually play in projects like GPSD and NTPsec, system services and daemons that would historically have been written in C as a matter of course. Other good examples of the sort of thing I mean are DNS servers and mail transport agents system programs that need to communicate and handle transactions at at machine speed, not human speed.
It is now possible to glimpse a future in which all that code is written in specific C replacements with strong memory-safety properties. Go, or Rust, or Cx any way you slice it, Cs hold is slipping. Like, if I were clean-starting an NTP implementation today, Id do it in Go without any hesitation at all.
--------------------------------------------------------------------------------
via: http://esr.ibiblio.org/?p=7711
作者:[Eric Raymond][a]
译者:[译者ID](https://github.com/译者ID)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://esr.ibiblio.org/?author=2
[1]:http://esr.ibiblio.org/?author=2
[2]:http://esr.ibiblio.org/?p=7711
[3]:http://sng.sourceforge.net/
[4]:http://www.catb.org/esr/reposurgeon/
[5]:http://www.catb.org/esr/doclifter/
[6]:http://www.catb.org/esr/loccount/
[7]:https://www.tiobe.com/tiobe-index/
[8]:https://blog.ntpsec.org/2017/02/07/grappling-with-go.html
[9]:http://esr.ibiblio.org/?p=7303

View File

@ -0,0 +1,86 @@
对 C 的漫长的告别
==========================================
这几天来,我就在思考那些能够挑战 C 语言作为系统编程语言堆中的根节点的地位的新潮语言,尤其是 Go 和 Rust。我发现了一个让我震惊的事实 —— 我有着 35 年的 C 语言经验。每周我都要写很多 C 代码,但是我已经忘了我上一次是在什么时候 _创建新的 C 语言项目_ 了。
如果你认为这件事情不够震惊,那你可能不是一个系统程序员。我知道有很多程序员使用更高级的语言工作。但是我把大部分时间都花在了深入打磨像 NTPsec GPSD 以及 giflib 这些东西上。熟练使用 C 语言在这几十年里一直就是我的专长。但是,现在我不仅是不再使用 C 语言写新的项目,而且我都记不清我什么时候开始这样做的了。而且...回望历史,我不认为这是本世纪发生的事情。
当你问到我我的五个核心软件开发技能“C 语言专家” 一定是你最有可能听到的这件事情对我来说很好。这也激起了我的思考。C 的未来会怎样 C 是否正像当年的 COBOL 一样,在辉煌之后,走向落幕?
我恰好是在 C 语言迅猛发展并把汇编语言以及其他许多编译型语言挤出主流存在的前几年开始编程的。那场过渡大约是在 1982 到 1985 年之间。在那之前有很多编译型语言来争相吸引程序员的注意力那些语言中还没有明确的领导者但是在那之后小众的语言直接毫无声息的退出舞台。主流的FORTRAN,PascalCOBOL语言则要么只限于老代码要么就是固守单一领域再就是在 C 语言的边缘领域顶着愈来愈大的压力苟延残喘。
在那以后,这种情形持续了近 30 年。尽管在应用程序开发上出现了新的动向: Java, Perl, Python, 以及许许多多不是很成功的竞争者。起初我很少关注这些语言,这很大一部是是因为在它们的运行时的开销对于当时的实际硬件来说太大。因此,这就使得 C 的成功无可撼动;为了使用之前存在的 C 语言代码,你得使用 C 语言写新代码(一部分脚本语言尝试过大伯这个限制,但是只有 Python 做到了)
回想起来,我在 1997 年使用脚本语言写应用时本应该注意到这些语言的更重要的意义的。当时我写的是一个帮助图书管理员使用一款叫做 SunSITE 的源码分发式软件,我使用的那个语言,叫做 Perl。
这个应用完全是基于文本的,而且只需要以人类能反应过来的速度运行(大概 0.1 秒),因此使用 C 或者别的没有动态内存分配以及字符串类型的语言来写就会显得很傻。但是在当时,我仅仅是把其视为一个试验,我在那时没想到我几乎再也不会在一个新项目的第一个文件里敲下 “int main(int argc, char **argv)” 了。
我说“几乎”,主要是因为 1999 年的 [SNG][3].我像那是我最后一个从头开始写的项目。在那之后我的所有新的 C 代码都是为我贡献代码,或者成为维护者的项目而写 —— 比如 GPSD 以及 NTPsec。
当年我本不应该使用 C 语言写 SNG 的。因为在那个年代,摩尔定律的快速循环使得硬件愈加便宜,像 Perl 这样的语言的运行也不再是问题。仅仅三年以后,我可能就会毫不犹豫地使用 Python 而不是 C 语言来写 SNG。
在 1997 年学习了 Python 这件事对我来说是一道分水岭。这个语言很完美 —— 就像我早年使用的 Lisp 一样,而且 Python 还有很酷的库!还完全绑定了 POSIX还有一个绝不完犊子的对象系统Python 没有把 C 语言挤出我的工具箱,但是我很快就习惯了在只要能用 Python 时就写 Python ,而只在必须使用 C 时写 C .
(在此之后,我开始在我的访谈中指出我所谓的 “Perl 的教训” ,也就是任何一个没有和 C 语言语义等价的 POSIX 绑定的语言_都得失败_。在计算机科学的发展史上作者没有意识到这一点的学术语言的骨骸俯拾皆是。
显然对我来说Python 的主要优势之一就是它很简单,当我写 Python 时,我不再需要担心内存管理问题或者会导致吐核的程序崩溃 —— 对于 C 程序员来说,处理这些问题烦的要命。而不那么明显的优势恰好在我更改语言时显现,我在 90 年代末写应用程序和非核心系统服务的代码时为了平衡成本与风险都会倾向于选择具有自动内存管理但是开销更大的语言,以抵消之前提到的 C 语言的缺陷。而在仅仅几年之前(甚至是 1990 年),那些语言的开销还是大到无法承受的;那时摩尔定律还没让硬件产业迅猛发展。
与 C 相比更喜欢 Python —— 然后只要是能的话我就会从 C 语言转移到 Python ,这让我的工作的复杂程度降了不少。我开始在 GPSD 以及 NTPsec 里面加入 Python。这就是我们能把 NTP 的代码库大小削减四分之一的原因。
但是今天我不是来讲 Python 的。尽管我觉得它在竞争中脱颖而出Python 也不是在 2000 年之前彻底结束我在新项目上使用 C 语言的原因,在当时任何一个新的学院派的动态语言都可以让我不写 C 语言代码。那件事可能是在我写了很多 Java 之后发生的,这就是另一段时间线了。
我写这个回忆录部分原因是我觉得我不特殊,我像在世纪之交,同样的事件也改变了不少 C 语言老手的编码习惯。他们也会和我之前一样,没有发现这一转变。
在 2000 年以后,尽管我还在使用 C/C++ 写之前的项目,比如 GPSD ,游戏韦诺之战以及 NTPsec但是我的所有新项目都是使用 Python 的。
有很多程序是在完全无法在 C 语言下写出来的,尤其是 [reposurgeon][4] 以及 [doclifter][5] 这样的项目。由于 C 语言的有限的数据本体以及其脆弱的底层管理,尝试用 C 写的话可能会很恐怖,并注定失败。
甚至是对于更小的项目 —— 那些可以在 C 中实现的东西 —— 我也使用 Python 写,因为我不想花不必要的时间以及精力去处理内核转储问题。这种情况一直持续到去年年底,持续到我创建我的第一个 Rust 项目,以及成功写出第一个[使用 Go 语言的项目][6]。
如前文所述,尽管我是在讨论我的个人经历,但是我想我的经历体现了时代的趋势。我期待新潮流的出现,而不是仅仅跟随潮流。在 98 年,我是 Python 的早期使用者。来自 [TIOBE][7] 的数据让我在 Go 语言脱胎于公司的实验项目从小众语言火爆的几个月内开始写自己的第一个 Go 语言项目。
总而言之:直到现在第一批有可能挑战 C 语言的传统地位的语言才出现。我判断这个的标砖很简单 —— 只要这个语言能让我等 C 语言老手接受不再写 C 的 事实,这个语言才 “有可能” 挑战到 C 语言的地位 —— 来看啊,这有个新编译器,能把 C 转换到新语言现在你可以让他完成你的_全部工作_了 —— 这样 C 语言的老手就会开心起来。
Python 以及和其类似的语言对此做的并不够好。使用 Python 实现 NTPsec以此举例可能是个灾难最终会由于过高的运行时开销以及由于垃圾回收机制导致的延迟变化而烂尾。当写单用户且只需要以人类能接受的速度运行的程序时使用 Python 很好,但是对于以 _机器的速度_ 运行的程序来说就不总是如此了 —— 尤其是在很高的多用户负载之下。这不只是我自己的判断,起初 Go 存在的主要原因就是 Google ,然后 Python 的众多支持者也来支持这款语言 ——— 他们遭遇了同样的痛点。
Go 语言就是为了处理 Python 处理不了的类 C 语言工作而设计的。尽管没有一个全自动语言转换软件让我很是不爽,但是使用 Go 语言来写系统程序对我来说不算麻烦,我发现我写 Go 写的还挺开心的。我的 很多 C 编码技能还可以继续使用,我还收获了垃圾回收机制以及并发编程机制,这何乐而不为?
[这里][8]有关于我第一次写 Go 的经验的更多信息)
本来我像把 Rust 也视为 “C 语言要过时了” 的例子,但是在学习这们语言并尝试使用这门语言编程之后,我觉得[这语言现在还不行][9]。也许 5 年以后,它才会成为 C 语言的对手。
随着 2017 的临近,我们已经发现了一个相对成熟的语言,其和 C 类似,能够胜任 C 语言的大部分工作场景(我在下面会准确描述),在几年以后,这个语言届的新星可能就会取得成功。
这件事意义重大。如果你不长远地回顾历史你可能看不出来这件事情的伟大性。_三十年了_ —— 这几乎就是我写代码的时间,我们都没有等到 C 语言的继任者。也无法体验在前 C 语言时代的系统编程是什么模样。但是现在我们可以使用两种视角来看待系统编程...
...另一个视角就是下面这个语言。我的一个朋友正在开发一个他称之为 "Cx" 的语言,这个语言在 C 语言上做了很少的改动,使得其能够支持类型安全;他的项目的目的就是要创建一个能够在最少人力参与的情况下把古典 C 语言修改为新语言的程序。我不会指出这位朋友的名字,免得给他太多压力,让他给我做出不切实际的保证,他的实现方法真的很是有意思,我会尽量给他募集资金。
现在,除了 C 语言之外,我看到了三种不同的道路。在两年之前,我一种都不会发现。我重复一遍:这件事情意义重大。
我是说 C 语言将要灭绝吗没有在可预见的未来里C 语言还会在操作系统的内核以及设备固件的编程的主流语言,在那里,尽力压榨硬件性能的古老命令还在奏效,尽管它可能不是那么安全。
现在被攻破的领域就是我之前提到的我经常出没的领域 —— 比如 GPSD 以及 NTPsec ,系统服务以及那些因为历史原因而使用 C 语言写的进程。还有就是以 DNS 服务器以及邮箱 —— 那些得以机器而不是人类的速度运行的系统程序。
现在我们可以预见,未来大多数代码都是由具有强大内存安全特性的 C 语言的替代者实现。Go , Rust 或者 Cx ,无论是哪个, C 的存在都将被弱化。如果我现在来实现 NTP ,我可能就会毫不犹豫的使用 Go 语言来实现。
--------------------------------------------------------------------------------
via: http://esr.ibiblio.org/?p=7711
作者:[Eric Raymond][a]
译者:[name1e5s](https://github.com/name1e5s)
校对:[校对者ID](https://github.com/校对者ID)
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
[a]:http://esr.ibiblio.org/?author=2
[1]:http://esr.ibiblio.org/?author=2
[2]:http://esr.ibiblio.org/?p=7711
[3]:http://sng.sourceforge.net/
[4]:http://www.catb.org/esr/reposurgeon/
[5]:http://www.catb.org/esr/doclifter/
[6]:http://www.catb.org/esr/loccount/
[7]:https://www.tiobe.com/tiobe-index/
[8]:https://blog.ntpsec.org/2017/02/07/grappling-with-go.html
[9]:http://esr.ibiblio.org/?p=7303