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, you’re 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 can’t clearly remember when I stopped doing so. And…looking back, I don’t think it was in this century.

That’s a helluva thing to have sneak up on me when “C expert” is one of the things you’d 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 C’s 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. I’d put that transition between about 1982 and 1985. Before that, there were multiple compiled languages vying for a working programmer’s 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 C’s 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 librarian’s 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 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 shouldn’t have. Because what was happening in the background was that the relentless cycling of Moore’s 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 didn’t suck! Python didn’t 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 C’s 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 Python’s 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 programmer’s 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; Moore’s law hadn’t 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 I’m not here to talk about Python today. It didn’t 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. There’s probably a nearby alternate timeline where I write a lot of Java.

I’m writing this reminiscence in part because I don’t think I’m 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 and doclifter, 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.

Again, though I’m 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 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, here’s 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 aren’t 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. It’s not just my judgment saying this – Go only exists because Google, then Python’s major backer, hit the same wall.

So Go is designed for the C-like jobs Python can’t handle. It’s too bad we don’t actually have an automatic code lifter, but the thought of doing all my systems stuff in Go doesn’t scare me. In fact I’m quite happy with the idea. My C chops are still largely applicable and I get garbage collection and really sweet concurrency primitives too, what’s not to like?

(There’s more about my first Go experience here.)

I’d like to include Rust under “reasons C is growing obsolete”, but having studied and tried to code in the language I find it’s just not ready yet.. 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 C’s application range (I’ll be more precise about that in a bit) and an awkward youngster that might complete successfully in a few years.

That’s 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 won’t name him so he doesn’t get stuck in a situation where he might be overpromising, but the approach looks sound to me and I’m trying to get him more funding.

So, now I can see three plausible paths out of C. Two years ago I couldn’t 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.

What’s 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, C’s hold is slipping. Like, if I were clean-starting an NTP implementation today, I’d do it in Go without any hesitation at all.

305 comments

  1. Sorry, I can’t resist. “Imminent death of C predicted.”

    I think C will still reign supreme in the embedded space until an automated lifter can be built, and that job is *hard* once you get away from well behaved Linux programs. I’m having a hard time imagining how a lifter could deal with the code I work on daily and handle the sneaky underhanded tricks we do that work, but aren’t exactly what one would call good C practice. (For example, we do one hell of a lot of pointer casting.) We understand the code because the two of us who work on it are old assembler hands, but…

    And I really can’t imagine our code ever being ported to Rust.

    IIRC, one reason for the rejection of your Linux kernel configurator rewrite was that it required Python. When do you think that consideration became no longer a serious roadblock for that kind of tool?

    1. In going from language to language or even host to host, the leaf nodes change a lot and the interior nodes quite a bit less. A tool that extracts the parameters and return values can do a lot. Even going from COBOL to lisp (;-))

    1. Can I ask what bothers you about Java logs? SLF4J? Log4j? Or something in general? Or am I maybe totally misreading you somehow?

      1. CPython is a very good example of how leaky internals can force an entire language to be eternally condemned to slowness.

        Exposing sys.__getframe() was a mistake. Because of it, CPython will never be fast. Meanwhile, fast Python VM’s like PyPy languish in obscurity because so much of the Python code we use is platform-specific.

        1. Yes. Leaky internals suck big time.

          I find it extremely funny that the C-interoperability that was used to make the code fast, now is one of the main reasons why PyPy and others can’t write a fast JIT for Python.

  2. There seems to be a lot of stuff written in Go these days that would have used C not so long ago. For example the people trying to replace the various extremely opaque firmware sorta OSes (UEFI etc.) are using it – http://u-root.tk/

    I suspect someone will write a full go based OS fairly soon. golinux? gonix? It would seem to be a classic PhD thesis

    1. I would *really* like to see a two prong attack on the IoT security issue:

      1) Take something like https://pdos.csail.mit.edu/6.828/2017/xv6.html, something small and simple and KEEP IT THAT WAY (This might mean maintaining a X86, MIPS and ARM ports) and then come out with a IoT distribution that provides just enough stuff by default to get you going but minimizes the attack surface.

      2) Build a GO and a RUST OS, or whatever else is out there competing, then build a IoT distribution that provides just enough stuff while minimizing attack surfaces.

      1. To be honest many embedded devices are little more than linux kernel + busybox + web server + “dedicated code to do what the thing is supposed to do” these days.

        I’m pretty sure a go webserver exists (if not it’s trivial) and it looks like u-root can provide some kind of basic shell and gnulike utils to run the above without any problems. The only issue is the replacement kernel.

        1. There have been way too many compromises of IoT devices for that to be the majority of the case.

          To many people in the appliance/smart-device (Refrigerator, Thermostat, car etc.) space have NFC about security.

          1. Look they are insecure as f*. Everything runs as root. The web pages frequently have gaping vulnerabilities due to lack of input validation etc.

            But that doesn’t stop me being basically right about what they are. I’ve looked at NAS boxes, cameras, routers and a bunch of other stuff. Just about all of them are MIPS or ARM CPUs running a cutdown linux kernel, busybox and (usually mongoose) webserver.

            1. An unsafe programmer using a safe language is forced to become a safe programmer, as otherwise their code is flat out rejected by the compiler. Try out Rust to see what I mean. Say hi to the borrow checker, affectionately known as borrowck.

        2. “I’m pretty sure a go webserver exists (if not it’s trivial)”

          It’s trivial; the one that ships with the standard library is production-grade with just a few tweaks.

          1. Actually, the one in the standard library is majorly flawed in a number of ways, so Go is facing the same issue that Python is with having inadequate solutions shipped in it’s “batteries included” standard library, and superior solutions provided as third party libraries.

        3. Heh, there’s no way a linux kernel would fit in the vast majority of the embedded projects I work on. I’ve got a few that have only 32K bytes of RAM. Over the last 15 years, I’ve had 1 project that had the storage capability and processor (AMD x86 SOC) to run Linux. In the small embedded world, C/C++ is still the king.

          Plus the only high level language that has been available on every single embedded processor I’ve worked with is C.

          1. I inherited a number of embedded 8051 designs originally written for 12 MHz MCPs.
            Since the hardware was getting a redesign (needed to replace an unavailable chip) I migrated them all to 24 MHz 8052-clones using FLASH rather than EEPROM.

            W00t!

            Assembler, BTW.

            Anything in an 8 bit or 4 bit MCU/MCP embedded design will likely be C or assembly.

            N.B., original architecture was set by someone else, when resources were MUCH more constrained

            http://www.scribd.com/doc/30709227/CSC2-87-ASM-DOC
            http://www.scribd.com/doc/30709231/CSC2-DFL-ASM-DOC
            http://www.scribd.com/doc/30709237/CSC2-HE-ASM-DOC
            http://www.scribd.com/doc/30709245/CSC2-HM-ASM-DOC
            http://www.scribd.com/doc/30709258/CSC2-MAG-ASM-doc

        1. Looks like a good start. Although since it currently only supports intel CPUs it’s not going to work in embedded as it currently stands.

          1. There is also Tock OS, designed explicitly for embedded. Seems it supports two ARM Cortex-M4 boards atm.

          2. Adding support for other processors isn’t difficult though. There’s just no need to do that at this time. Any platform supported by LLVM will be a possibly target with minor effort.

            Personally, I don’t see the merit of Go, especially not in the space of writing kernels and systems software. It comes with a rather expensive runtime garbage collector, and a very inefficient cgo translator.

            It’s also really lacking in all the necessary areas for writing complex software, and incredibly unsafe to use for writing software that interacts with mutexes/rwlocks/etc.

            1. You must not be familiar with the newer versions of Go. The garbage collection is quite fast… There are many die hard Rust lovers, honestly I don’t see the merit of Rust. It’s not always faster than C and it can be equally unreadable and unmaintainable as C. I might as well use C.

              1. >[Rust is] not always faster than C and it can be equally unreadable and unmaintainable as C. I might as well use C.

                I don’t agree. Rust’s memory safety guarantees are a really significant advance over C. There are deployments where that kind of provable correctness is so important that it is worth putting up with the language’s higher difficulty and extremely immature libraries.

                That said, I think Rust’s future is limited. It entered the competition too late, and now is still struggling to get a standard-library binding that is both stable and reasonably complete while Go (which has that job done) is succeeding in large-scale deployments as a C replacement. I see a future for Rust in kernels and firmware, but not in applications.

                1. What are you talking about? Rust’s standard library is stable. Software that I wrote back in the 1.0 days and haven’t touch still compiles today with the latest Nightly; and both the standard library and accompanying officially blessed crates are more comprehensive than what Go has to offer.

                2. Go’s standard library is much less complete than Rust’s, and it has an absolutely terrible regular expression implementation. I code in both Rust and Go, and find Rust to be the far more expressive and far more safe language with a far better library ecosystem. The only thing Go has going for it is that you can teach a below average programmer to code in it in a day.

                  1. I’m one of those below average programmers. :-) I find Rust to be a fascinating language, but I also find it to be the hardest language I have ever tried to learn. I can’t see Rust ever becoming mainstream due its difficult syntax and the amount of extra work it imposes on the programmer. On the other hand, I think that a language like Swift might be able to replace C in the long term. It is fast enough and it has many modern language constructs unlike Go. Its use of reference counting for garbage collecting avoids the delays of a Go-style garbage collector. The real problem is that it is tied to Apple, and many will avoid it because they distrust Apple. If Apple would put the language into an independent foundation and get other IT companies to share in the development, I think Swift would take over.

  3. Great writeup.

    “Any suitably creative backdoor is indistinguishable from a C programming bug”.

    C had a great run and we all loved her in her time. But that time has long passed. Let’s let her go and not look back. Adios.

    Hope you’ll keep us posted on the progress of ‘Cx’.

  4. There are several significant things I see as critical here.

    First is Moore’s Law. Hardware got steadily smaller, faster, and cheaper. We are at the point where you can write mostly in what is technically a scripting language because you’ll get adequate performance and won’t have to go to a language that compiles to native code.

    Second is a side effect of that – scripting languages tend by nature to be portable and cross-platform. Java is the pertinent example. Java code compiles to a tokenized binary form targeted at a virtual CPU implemented by the Java Runtime. The critical point is that the compiled code is the same regardless of where you compile it. I have IBM’s Eclipse IDE here. It’s written in Java. I have it under Windows and Linux using the same binary. I believe similar things are true for Python. You can write portable code in C, but it’s a lot harder, and requires detailed knowledge of the architectures under which it might run.

    And now we are seeing languages like go and rust that are in striking distance of being competitive with C. We can assume that hardware will continue to improve as well. Whether it gets faster is less important than that it will get still cheaper. I look at the current buzz over “the Internet of Things”, and see hardware cheap enough to use for all manner of embedded systems, but powerful enough to run a full TCP-IP stack. The default embedded processor these days seems to be at least a multi-core ARM variant that can run Linux given enough memory and storage, in a package about the size of a pact of cigarettes.

    C isn’t going away any time soon, but the effect of the stuff above will be far reaching. For example, we are seeing what may be the beginning of the end for Linux. When you have things like go and rust mature enough, something else becomes a possibility.

    As an example, OS/X used a modified BSD kernel. I believe the original intent was to use the Carnegie-Mellon Mach micro-kernel, and the BSD kernel got the nod because of performance issues context switching between Mach and user space. What if those issues go away?

    Linux is monolithic, and Andrew Tannenbaum once stated that Linus would flunk his course on writing OSes if he submitted a monolithic design. What if someone uses go or rust to implement something based on a micro-kernel like Mach, but designed to look and act like Linux to applications? It would implement the same legacy system calls and behave like Linux but wouldn’t be Linux, and might be easier to maintain and extend than Linux is due to better modularity.

    I don’t expect to see it any time soon, but I’d be a bit startled if there weren’t people thinking in that direction.

    >Dennis

    1. No OSX does not use a modified BSD kernel, it uses a modified Mach kernel (modified to be monolithic for performance reasons). It had BSD subsystems to provide networking and a virtual file system but these have been mostly rewritten since the 10.0 release and the device driver subsystem was entirely new, written by Apple (in a restricted version of C++).

      There’s already a Rust microkernel called Redox, but I can’t see a successful OS kernel being written in any language that uses non deterministic garbage collection, which I think discounts Go.

    2. The end of the free lunch with Moore’s Law may be old news by now, but what’s new is the storage and network shock. 3GB/sec sequential throughput on commodity nvme drives today, with microsecond or less network latency. Next year storage class memory.. That upsets a fundamental assumption of computing that’s held since the beginning according to an ACAM paper. We are no longer CPU bound if dealing with larger data sets. And data sets grow at 30% annualised.

  5. Obviously Apple has a higher opinion of it than others, but do see any value in the Swift programing language, as a possible replacement for C like they’re aiming for? Or do you think despite being available outside that Apple platform it will remain a language only for Apple products, in the way Objective-C is?

    1. Looking at the mailing lists at Swift.org, it’s pretty clear that not only Apple, but all of their developer community intend to make Swift replace everything from C in the kernel to the shader languages in the image processing systems.

      There are a lot of people contributing to Swift, since the whole thing is open-sourced, *and* it’s the way forward for iOS development, I could see it eventually being the implementation language of a new core OS when Apple transitions off of Intel.

      1. Basically, you have two camps at the moment: the Apple camp touting Swift as the de facto solution for everything; and everyone else who is pushing for Rust. And if you ask me, history tells us that it’s likely to be Rust that ultimately wins, while Swift remains as an Apple niche.

      2. I heard there is a plan to add Rust like memory management to Swift to allow programmer to optionally disable ARC. That might be a better solution than GC?

  6. > 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, here’s an automated translator that lifts C to the new language, now get all your usual work done – and the old hand would smile happily.

    You probably won’t actually be smiling, but I think it’s going to be JavaScript (or some subset thereof, such as WebAssembly). The “lifting old C code” part is already done (see, e.g., emscripten), and the ecosystem — the okay-if-not-great portable GUI with HTML, the massively scalable and relatively painless distribution mechanisms, the vast army of programmers… I don’t really see any competitor being able to catch up.

    Like I said, you probably don’t like that idea. Heck, *I* don’t much like that idea. But I think it’s going to happen.

    Languages like Rust are the modern equivalent of Algol. JavaScript is the modern C.

    1. WebAssembly is not a subset of JavaScript; you’re thinking of asm.js.

      WebAssembly is a portable bytecode designed to run in-browser Web applications. (Now where have I heard this before?)

      1. > WebAssembly is not a subset of JavaScript; you’re thinking of asm.js.

        WebAssembly is a bytecode *representation of asm.js*. So yes, it’s still a limited subset of JavaScript semantics-wise, just in a different representation (think tokenized BASIC).

        1. P.S.
          > (Now where have I heard this before?)

          You’ve heard it before many times, but only JavaScript (not Java or any of the others) has ever come close to delivering on the promise.

    2. emscripten doesn’t _lift_ C to JavaScript, it compiles to it. The difference is that the resulting JavaScript is less comfortable to work with than the source C. Lifting a C program to Rust, Go, or Cx should make it easier to work with not less.

      I do have high hopes for WebAssembly, but that is because I hope that it will make JavaScript less dominant.

      1. > Lifting a C program to Rust, Go, or Cx should make it easier to work with not less.

        Can you give an example of “lifting” in the sense you’re using the term?

          1. > https://github.com/jameysharp/corrode

            Umm… “Because the project is still in its early phases, it is not yet possible to translate most real C programs or libraries.”

            On its face, I would guess that it would be far easier to do auto-translation of C to JavaScript than C to Rust, if only because the syntax matches better. And, of course, there’s the existence proof in that emscripten *actually works* (albeit generating ugly code), while corrode apparently does not.

            1. Matching syntax is not really important. A lifter would compile the code down to an AST. What is important is sematics. A lifter will have to recognize memory operations and do the right thing in removing/replacing them.

    3. >You probably won’t actually be smiling, but I think it’s going to be JavaScript (or some subset thereof, such as WebAssembly).

      No, that’s silly. If I couldn’t write NTPsec or GPSD in it, it’s not a systems language.

      1. Not even within the node.js ecosystem?

        Not that I’m advocating such lunacy…but it seems plausible at least.

        1. Javascript qua Javascript is a non-starter. It is a common delusion that Javascript is as fast as C, but it is not. At the best of times you’re still looking at a roughly 10x penalty, and getting that performance requires you to write in a constantly-shifting subset of Javascript that the JITs can correctly optimize. As JITs do, it eats a lot of memory to obtain these speedups, like most or all of the scripting languages it hasn’t got a great story on dealing with memmapped spans, it offers you no control over memory locality, and honestly the problems with it being a C replacement go on and on. As a final existence proof, I’d submit that if Javascript could replace C, Python would already have done so, as Python is basically better than Javascript in every relevant way. (Almost every feature that Javascript has been slowly and laboriously adding over the past several years are features that were taken from Python. That’s a good thing, not a bad thing.)

          To address Doctor Locketopus above, WebAssembly has the twofold problem that A: it doesn’t actually exist yet, whereas Go and Rust do and B: as the name implies, it isn’t a language, it’s an “Assembly” language. Rust compiled into WebAssembly is still a great deal more Rust than Javascript. I don’t think Javascript is going to eat the world; I think WebAssembly will crowbar Javascript off of its browser platform, from which it has lorded over the lesser languages from its unassailable position for a long time, and what will happen is that people will find that only the most dedicated Javascript fans will find they miss it.

          1. > It is a common delusion that Javascript is as fast as C, but it is not.

            Odd that I’ve never heard anyone state this “common delusion”. Ever. Are you sure you’re not thinking of Java? Do you have a link to someone with actual credibility making that statement?

            > A: it doesn’t actually exist yet, whereas Go and Rust do

            The WebAssembly spec is every bit as finalized as that of Rust. Arguably, more so… the initial release will asm.js compatible (and that certainly *does* exist), while the Rust spec appears to be still evolving in very fundamental ways.

            > Python is basically better than Javascript in every relevant way.

            No, it is not. Python sucks ass when it comes to functional programming, to name just one area.
            While Javascript wouldn’t be my first choice for doing functional programming, it is absolutely superior to Python for that paradigm.

            I’m not actually here to defend Javascript, but I don’t think anyone is served by making obviously false statements about it.

            1. “Odd that I’ve never heard anyone state this “common delusion”. Ever.”

              I apologize for skipping down the argument chain a bit then. To claim that Javascript is a suitable replacement for C would require that Javascript has a performance profile that would allow it to replace C. I find that many people grotesquely overestimate the performance of Javascript, presumably as a result of listening to a whole bunch of news releases from the JIT projects about how this benchmark is 400% faster and that benchmark is 600% faster, without realizing the way performance numbers compose together is not what intuition leads you to believe. It is far too slow to be a replacement for C, even before its many other manifold issues.

              “The WebAssembly spec is every bit as finalized as that of Rust.”

              I apologize for skipping down the argument chain again. WebAssembly is, as near as I can tell, totally nonexistant on the system. You can’t implement “ls” in WebAssembly right now, and in fact the idea itself is a bit silly. As a system replacement, that’s a non-starter. I’m sure it’ll happen someday, but it’s years away. Rust is here now, and Go has a reputation for good command-line clients right now.

              “Python sucks ass when it comes to functional programming, to name just one area.”

              First, I don’t see that as a requirement for a C replacement anyhow.

              Second, from my perspective I’d also say it’s a popular delusion that Javascript is “good” at functional programming, too. I don’t see a lot of difference between Python and Javascript because they’re both terrible, once you’ve used a language actually designed for functional programming. Javascript’s “functional programming” wasn’t even bodged on at the last minute, it was desperately turned to by people to address the other manifold shortcomings in the language, and it’s horrid at it because it’s just a set of things sort of discovered to work without a lot of intent. It’s got weird issues with “this”, it has historically been very verbose, and it interacts very poorly with the need to slice everything up around the fact that Javascript can’t handle events without throwing the entire stack away.

              Now, I know how you are going to want to defend Javascript against that charge, and I’d point out that everything or nearly everything you’re about to say, Python has had for over a decade. Once you get past matters of syntax taste, on a feature-by-feature case, Python has had it for longer and to the extent that JS is progressing lately, it’s doing so by basically copying features from Python. Which is generally good, except when arguing that JS is better than Python. (Then why is it taking so many features from it, to wide acclaim?)

              1. > To claim that Javascript is a suitable replacement for C would require that Javascript has a performance profile that would allow it to replace C.

                No. C replaced asm, even though it wasn’t as fast as hand-written asm for many years (decades, really). Modern C compilers are better than all but the best hand-written and optimized asm, but that sure wasn’t the case when it took over.

                I take it, then, that you’re retracting your claim that it’s a “common delusion” that JavaScript is as fast as C.

                > I don’t see a lot of difference between Python and Javascript because they’re both terrible

                Sorry, that’s sheer nonsense. JavaScript lets you put anything you want in an anonymous function (a “lambda”). Multiple statements, function calls, whatever. Unless it has changed very recently, Python limits you to a single expression in a lambda.

                You really don’t “see a lot of difference” there?

                1. > JavaScript lets you put anything you want in an anonymous function (a “lambda”). Multiple statements, function calls, whatever. Unless it has changed very recently, Python limits you to a single expression in a lambda.

                  Anonymous functions are not a requirement for functional programming.

                  def x():
                  body
                  y(x)

                  is equivalent to:

                  y( function() { body } );

                  1. > Anonymous functions are not a requirement for functional programming.

                    So what? Nothing beyond a Turing Machine is a requirement for *any* kind of programming.

                    That doesn’t mean I’m going to start writing all my code for TMs, though. Neither are you, nor is anyone else.

                    Theory and practice: not the same thing.

      2. I believe the only language compiling to WebAssembly currently is C++.

        Which amuses me greatly.

      3. Node basically is JavaScript as a systems language. I don’t know if you could write gpsd or NTPsec in it, but you could certainly write e.g., reposurgeon in it. In fact it’s become a serious contender to displace Python and Ruby as the go-to application and network language because it means that one language can be used for Web development across the entire stack and even the tooling.

        1. >Node basically is JavaScript as a systems language.

          Not going there. Too many serious mistakes in the design of JavaScript.

          1. I agree. Node is a non-starter because it is based on JavaScript, which is in dire need of replacement.

            It’s a hodgepodge of patches and added-later objects and so on, without ever addressing its real limitations as a general-purpose language.

            A couple of people have tried to get me to work on projects based on Node. I took a look at them and said “no”. It’s an attempt to re-do things that are already done better elsewhere.

            The concept of client-side of computing is not all bad, and never was. But Node isn’t the way to do it.

        2. Who are you and what have you done with Jeff Read?

          We all know Jeff loves bondage-and-discipline languages that don’t trust the programmer to wipe his own ass correctly. JavaScript is about as freeform as it gets.

          1. But it doesn’t have the “intelligent” parts that make “free form” scripting languages so easy to use while avoiding simple mistakes.

            And despite all the efforts in recent years, it’s still rotten to debug.

            You want a free-form language that lets you do what you want but does the job right? Try Ruby.

            PLUS it has easy-as-pie interface with C libraries.

            1. “And despite all the efforts in recent years, it’s still rotten to debug.”

              You’re kidding, right? The developer tools in Chrome kick gdb’s ass so hard that it’s not even funny.

              Microsoft’s debug tools are great, but there’s nothing in the FOSS world that compares, IMO. As for Ruby…. well, I like Ruby a lot, but I certainly wouldn’t hold it up as a shining example of excellence in the debugging area.

              To go further afield, Allegro (Franz) Lisp is good, and some of the Smalltalk environments are excellent, but when it comes to C debuggers, only the M$ tools are even on the same page as modern JS environments.

              1. Eclipse’s debug environment is spectacular if you’re running on the JVM, but it’s limited outside of that. CDT’s is okay, no idea how it compares to modern Microsoft.

                1. Good point. I haven’t used Eclipse (or Java) in quite a while, but yeah, that environment was pretty decent for debugging (if annoying in many other ways).

      4. Sure you could. Node has general-purpose sockets.

        Now, I’m not saying that it would be a *good idea* to do that, but it could be done.

  7. > Obviously Apple has a higher opinion of it than others, but do see any value in the Swift programing language, as a possible replacement for C like they’re aiming for?

    I haven’t done a *huge* amount of programming in Swift yet, but in my experience it’s quite a pleasant language to use, and relatively quick to learn. The non-eye-bleedy syntax compared to Objective-C is a big plus.

  8. C will live on in embedded programming for a while. And people will continue to develop basic tools in C. But I think its days as a tool for writing end user software on full desktop or mobile platforms are in the past.

    1. After not having done anything serious in C for about 15 years, I’m now getting up to speed on C++ specifically for embedded. With insanely cheap ARM controllers (you can get a Cortex M4 with integrated Bluetooth for $3), this sort of gadgetry is going to become even more of a thing. It would be interesting to see something like Rust be able to take over, but it’s nowhere near yet.

      1. C++ is woefully inefficient compared to C, without adding a whole lot of benefit other than hand-holding in some of the more troubling aspects of C, and objects. Which add to the inefficiency.

        While the hardware has evolved to be capable of running it sufficiently, I don’t think I’d ever try to develop embedded software in C++.

        You’re better off going whole-hog rather than compromising. You can get a Rasperry Pi Zero W for about $10, and it runs Linux, with 1080p HDMI graphics, USB, micro SD, lots of built-in I/O, Bluetooth, and WiFi. The size of the board is roughly 1 in. x 2 in.

        Article is nearly a year old; price has come down since and availability has improved.

        http://www.wired.co.uk/article/wireless-raspberry-pi-zero-price-specs

        Oh… and for about another $25 you can get a very decent camera for it. It is capable of at least 720p 30fps WiFi streaming and even OSS libraries for face recognition are available.

        1. “While the hardware has evolved to be capable of running it sufficiently, I don’t think I’d ever try to develop embedded software in C++.”

          My boss wants us to shift to C++ in the next generation of the controllers I program for. I’m not looking forward to it.

            1. Not unless you’re interested in moving to middle-of-nowhere, southern Minnesota.

              But what I know of C++ I’ve learned on the fly from the 1.2MLOC monstrosity. Mainly, what I’ve learned is to hate it.

              If I’m going to be doing C++ in the embedded space – with no dynamic memory allocation at all, no heap, no malloc(), nothing – what would you suggest I study to learn the right approach?

        2. Hm, that’s funny since I’ve been writing embedded code in C++ for years. It’s object based coding as opposed to object oriented though so some C++ features are not used (polymorphism and inheritance for instance).

        3. “C++ is woefully inefficient compared to C, without adding a whole lot of benefit other than hand-holding in some of the more troubling aspects of C, and objects. Which add to the inefficiency.

          While the hardware has evolved to be capable of running it sufficiently, I don’t think I’d ever try to develop embedded software in C++.”

          Agree 100%. I use C++ compilers, but only make use a limited subset of the language. The biggest issue for embedded in my experience is limited variable memory space combined with systems that statistically never get rebooted.

          A memory leak is a firing offense in my industry. And buffer overruns are impossible if you design your input buffers properly.

          1. That’s because it’s the language most people are familiar with. It was the first language to be supported on their hardware, and immediately followed thereafter with official Rust support. They went to some Rust conferences to display their hardware and how simple it is to program it with Rust using their official crates.

  9. What is your opinion on Dlang? As far as Golang is concerned, I use it without hesitation and without the generics allergy.

  10. Have you taken a look at the D language ?

    https://dlang.org/

    It’s here since 2001, it’s well documented, and fast like C.

    Regarding memory management, citing wikipedia :
    https://en.wikipedia.org/wiki/D_(programming_language)#Memory_management

    “Memory is usually managed with garbage collection, but specific objects may be finalized immediately when they go out of scope. Explicit memory management is possible using the overloaded operators new and delete, and by simply calling C’s malloc and free directly. Garbage collection can be controlled: programmers may add and exclude memory ranges from being observed by the collector, can disable and enable the collector and force either a generational or full collection cycle.[12] The manual gives many examples of how to implement different highly optimized memory management schemes for when garbage collection is inadequate in a program.[13]”

    1. >Have you taken a look at the D language ?

      Years ago, and not very seriously because it was proprietary.

      I undetstand that has changed. It may deserve another look.

      1. I tried it some time back, after OSS implementations were available. At the time I was looking for a language with automatic memory management and native (not library) strings/resizable arrays/dictionaries; and which was compiled rather than interpreted. For some reason that combination was hard to find.

        D fit the bill and I liked the language a lot, but the available OSS linux tools were…somewhat short of adequate. Debugging in particular was difficult (although that may have been because I didn’t really understand debuggers at the time). Perhaps the D-on-linux situation has improved since then. I see at least one D compiler (LDC) in apt on my machine, although it appears to be out of date. Wikipedia says D is included in GCC as of sometime this year.

        If you do try it again, I can vouch for Alexandrescu’s book on the subject. Dunno if the online documentation is decent (it wasn’t when I last looked but that may have changed). The search term ‘dlang’ will do the right thing on Google.

        I for one would enjoy a review.

        1. Debugging in particular was difficult (although that may have been because I didn’t really understand debuggers at the time).

          Its not just D. Debugging in general is shit under Linux because no one can be bothered to even attempt to displace gdb — only wrap it with a UI that doesn’t fix the underlying deficiencies. Visual Studio is the gold standard for debuggers, and nothing on Linux comes anywhere close.

          1. I dunno, I haven’t had issues using pdb effectively. Though I don’t think I’ve tried to do anything too complicated with it.

            (Unrelated: I like that with a bit of magic I can make a command line switch for a program that will cause it to invoke PDB on crash.)

  11. Assuming you’re not annoyed by all the “What’s your opinion on language X” questions yet – and feel free to say so if you are – Jonathon Blow has been working on a language called Jai that I’ve been loosely following. Have you heard of it?

    Assuming you haven’t, he’s made several videos showing it in action as he continues developing it (though he still hasn’t released a compiler yet): https://www.youtube.com/user/jblow888/playlists

    Of course, you’re probably too busy to watch a bunch of videos. If you just want something written, I found a quick primer: https://github.com/BSVino/JaiPrimer/blob/master/JaiPrimer.md

    Also, Shamus Young (a programmer/gamer whose blog I read regularly) watched the first video and did an annotated commentary on it (follow the links at the top and bottom of the post to the other parts): http://www.shamusyoung.com/twentysidedtale/?p=26011

    1. >Jonathon Blow has been working on a language called Jai that I’ve been loosely following. Have you heard of it?

      Not at all.

      1. Ah. Well, I suppose there’s not much more to say until he releases a compiler and we can tinker with it. But it is being designed as a high-performance replacement for C and has some promising-sounding ideas, so I thought it might interest you.

  12. On my 2011 ThinkPad, Python does not respond at human speed.


    $ \time -f '%es' pip3 --version >/dev/null
    1.82s
    $ \time -f '%es' ipython3 -c exit >/dev/null
    2.64s

    When I use a command-line program and nothing happens for more than a second, it’s usually written in Python (3, Python 2 starts faster). That’s annoying enough for me to try avoiding having to use Python programs in interactive shells.

    P.S. I don’t know how to prevent the code in this comment from getting mangled (edit: actually seems fine; I guess that only happened in the preview).

  13. I guess I’m a real dinosaur (I do environmental supercomputing — things like coupled meteorology/atmospheric-chemistry models); in the last six months I’ve only written about 1000 lines of C — but 40,000 of Fortran (which has turned into a fairly nice structured language, for which strings and multi-dimensional arrays are first class citizens, by the way).

    FWIW

    1. While trying to get some weather forecasting code to run on a MacBook I was shocked to find I could install GNU Fortran, compile all this stuff from national labs, and It Just Worked. No continuation punches in column 70 like the last time I used it. Lots of new Fortran out there which is pretty scary.

      But I wouldn’t call Fortran a live language using esr’s definition, it’s more a lucrative zombie like COBOL. If Fortran is any example, C’s legacy will remain lucrative for a long, long time.

      1. COBOL is a real zombie, limited basically to legacy systems for compatibility reasons. No one sane would do a new payroll system in it, free from concerns about interoperation. Fortran, on the other hand, is still king of its original domain — hardware-pushing scientific/numeric computing.

        I mean, if you don’t need to squeeze performance, you can use Python for scientific/numeric computing, sure. NumPy/SciPy give you the necessary tools (largely an interface to numeric libraries implemented in Fortran). But when performance becomes critical, the obvious move is implementing in Fortran.

        Now, that might change — Julia, released in 2012, is hitting 1.0 soon. But it’s not clear yet that it will.

        1. Not R? I know a bunch of people who have moved stuff from Fortran to R. Since number bashing isn’t my thing I’ve no idea how the two compare in performance. I do know that R seems more (modern) user friendly

          1. R is slow. By (rough) analogy to ESR’s original post, in the domain of number-bashing, Fortran is C, R is Python, and Julia looks like a candidate for Go.

            1. I was going to say the same thing.

              R may be (relatively) easy to learn, but it is slow, I find its syntax to be quite tedious, and its forte is really statistics, not necessarily general math or science.

        2. Well, these days C++ is also used for that kind of stuff often enough that calling Fortran “the obvious move” seems excessive. (I’m a computational physicist and I haven’t used Fortran for 6 years as far as I can remember.)

    2. To paraphrase Tony Hoare, I don’t know what the numerical modeling language of the future will look like, but I know it’ll be called “Fortran”.

  14. What is your opinion on Dlang?

    D has been around for a long time and hasn’t achieved much in terms of popularity or notoriety. If it hasn’t done so by now it probably never will. But it’s a nice language and should have been a strong contender.

  15. I’m the other way around. I find myself doing more in C/whatever-else that is basically C/Fortran as I work with scientific computing libraries and learn GPU programming and firmware programming. If you want to control what a processor is doing, you need a language that is pretty bare metal. In many cases I don’t want a garbage collector: I want memory to allocate when I want it to, and I need it to deallocate when I want it to.

    I recently wrote a bunch of data-parsers in C. I needed the speed: Python and Matlab could take 10 hours to do what these programs did in 10 minutes. (I was processing tens-of-gigabyte binary files.)

    But I’ll look into these new languages. I use python for some things, and I’d consider using it for the display aspects of an application, but for the heavy number crunching I’m not sure that I’d want a non-compiled language.

  16. I once joked with a friend that the real computer-apocalypse will destroy civilization when people keep piling higher-level things on top of lower-level layers that they don’t want to deal with, forget how to work with the lower level layers, then have something down there break.

    Someone’s got to make the bare-metal-layer and understand how that stuff works on a mechanical level.

    1. The bare-metal layer can be implemented in Rust, and thus, with 100% memory safety except in those cases where violating memory safety is strictly necessary (handled with unsafe blocks in Rust).

    2. There is a original Star Trek episode about this situation. Was very influencing on my personality.

      1. There was a sf story many years ago about a “universal filing system” that ran into this problem. I can’t recall the name of the story, but it was almost certainly before Star Trek.

    3. There’s an increasing resurgence of interest in working at the lower levels, but with new systems languages. Primarily Rust, which has made working at the bare metal layer comfortably simple. It’s ridiculously easy to write your own kernel from scratch in Rust, or any kind of software, for that matter. Just take a gander at how far Redox OS has come along in two years, with largely a single lead developer, and a few regular contributors.

      Theo de Raadt is trembling at the idea of memory safe languages like Rust dethroning his OpenBSD project[1]. He’s currently on the first (partially second) stage of the five stages of rewriting your software in Rust[2].

      [1] https://www.youtube.com/watch?v=fYgG0ds2_UQ&feature=youtu.be&t=2112
      [2] https://imgur.com/a/kC0WU

  17. Consider the ESP8266-based dev boards out there; for about $5 you get a couple hundred kilobytes of RAM, wifi, a 80-Mhz RISC CPU and your choice of arduino/C or a built-in lua programming environment. (Checking now, apparently subsets of python or VB (!) are available if you reflash). High-level languages on ultra-low-end environments like this are new but I suspect the future.

    It’s interesting that Java, though, didn’t have full POSIX capabilities when it first came out (in particular, IIRC, it wasn’t possible to create temporary files security on a shared system). But enterprise developers were desperate for a cross-platform solution supported by a major IT vendor…

  18. Fix?

    > “Python didn’t drive C out of my toolkit,”
    Should be “Python didn’t drove C out of my toolkit”?

    I had a similar experience but much earlier. Having written a bunch of C and Lisp in the late 80’s I discovered Tcl in the early 90s. No GC, super simple to extend the language by writing new commands in C, and you could embed it in other programs or use it as the top level event loop. It was a huge win to write entire programs in Tcl and then identify the 10% performance critical section and implement new language primitives in C. Example – the built in lsort command had an option to sort numerically but it was an order of magnitude faster to write lsortn in C.

    Now I’ve discovered and am exploiting the same pattern using SQL in SQL Server and writing CLR functions on C#.

        1. Correction correction:

          > “Python didn’t drove C out of my toolkit,”
          Should be “Python didn’t drive C out of my toolkit”?

  19. esr may be horrified to learn what goes on outside the realm of professional software engineering. When I was in grad school in the US in 2009-2011, C was routinely used for brand new projects. I started a couple myself before I quickly wised up and switched to Matlab. Imagine people neither experienced with nor inclined toward software engineering trying to write numerically rigorous C code, usually to grind away on bulk data. Since I had C experience before then, I became a go-to guy for C problems, and got to see all the ugliness. This code delivered results that fed into scientific papers and PhD dissertations that would never withstand real scrutiny. The Climategate scandal broke around that time, but sadly didn’t lead to any change in practices.

    1. None of the CRU code I saw was in C, but fortran or cobol if I remember correctly. None of the revealed issues were related to programming language.

  20. @esr I’d be curious to know what your opinion of Wirth’s Oberon language is (in general), and whether or not you see it influencing other languages in a similar fashion to how it informed Go’s approach to type extension.

    1. Oberon-2 was one of my favorite things to play with when I was a teenager. I haven’t gone back to look at it in ages though. It’s crazy that he’s now made an entire computer based on his language and operating system, that runs on an FPGA.

  21. I’ve started applications in C more recently than you have, but only because they were written for 20mhz-40mhz controllers.

    And the biggest one is now being ported to Python. Even the embedded hardware has caught up to where C just doesn’t make much sense.

  22. Almost everything I’ve started in this century has been C/C++, because a few of the things I do involve enough number-crunching that I need the performance and because (not being primarily a coder) I don’t want to develop or maintain more skillsets than necessary. And almost everything I do is either by and for myself alone, or for very small teams / user groups, so the weaknesses of C aren’t as significant.

    Languages like Python that can do 80% of what I need are like electric cars that can take me 80% of the places I need to go. Nice idea, but I’ll wait for the next generation. Something like Cx, from the description, sounds like it would do very nicely and I hope to hear more about it.

    1. If “Cx” is this Cx, then it is explicitly not based on C semantics though it shares some syntax similarities; and lifting C to it may be trickier than you or Eric anticipate.

      Best stick with Rust. That language has already accreted the necessary critical mass to make it a viable C replacement.

      1. >If “Cx” is this Cx, then it is explicitly not based on C semantics

        No. Different languages,

        >Best stick with Rust.

        I think I could start a serious Go port of NTPsec today and have it done in three months or so, with milestones and problems both rather predictable. I have no such confidence about Rust.

        This means Rust has already lost its fight in userland – Go crossed the chasm first and is going to be climbing towards majority status while Rust is still trying to finalize its standard library. Go making the TIOBE top 20 was a leading indicator.

        Rust may yet have a good story in kernels and deep firmware, but the future in which it takes over most of C’s historic application range is no longer plausible. I might have bought it six months ago; I don’t now, because Go is winning bigger than I expected.

        1. Go isn’t rising to popularity because it’s replacing C. It’s rising to popularity because it’s replacing Python.

          Meanwhile, Rust is already making userland inroads; fd and ripgrep are highly regarded replacements for find and grep, respectively. Both are written in Rust.

          1. Hey! I implemented the parallel command execution logic in `find`. Gained a lot of parallel exec experience with Parallel[1] and Concurr[2]. I’d also recommend looking into the Ion shell[3] I’ve been developing over the last year. We aren’t just making inroads with CLI applications, but GUI applications as well[4]. I’ve written three GTK3 applications with Rust so far.

            [1] https://github.com/mmstick/parallel/
            [2] https://github.com/mmstick/concurr
            [3] https://github.com/redox-os/ion/
            [4] https://github.com/mmstick/fontfinder/

        2. I’d recommend Ada to you, but I know you won’t touch that. I don’t think Ada’s safety guarantees are as extensive as Rust’s, but until Rust came along Ada was the best bet for writing safe code. It even has standard POSIX bindings (though not part of the standard library) an implementation of which, called Florist, is readily available for the GNAT compiler.

        3. I have two years with Go, and now going on two and a half years with Rust. In hindsight, I can tell you that while starting a project in Go might initially progress faster than Rust for a short period of time, Rust ultimately wins in productivity in the long run, especially the more complex the application becomes. I’ve long found that Go is no match for Rust in the productivity department, as a result.

  23. > As little as three years later, I would have not have hesitated before writing SNG in Python rather than C.

    There is something about the way old Unix-heads think that I don’t fully understand. If you write it in Python, then everybody who runs it needs to have a Python interpreter installed, and it should be the correct version, and if there are multiple version then ensure the program is executed with the correct interpreter. This sounds a lot harder than just downloading a compiled binary.

    I know, the idea is that someone will wrap that into a package which will have the proper Python package as a prerequisite and if you have two incompatible versions of Python installed then apt-get will install the third one and configure it so that your program will run with that one. If everything works well. If not, then it will be some manual configuration and the user will get more proficient in the most important language programmers learn: cussing.

    My point is: how is it possible that the ease of installation is _not even on the list of considerations_ for old Unix-heads? One thing you guys never invented nor put it ever on the long list of things to copy from Windows was the Next/Next/OK installer file downloadable from some website. Presumably, because it can be expected that if the software is any good someone will make a package. Or even build it into a distro. Still… until that?

    What were the reasons of not putting ease of installation on the list of considerations?

    Besides, systems programming often means applications that are crucial parts of the distribution, of the generic functioning of the user’s environment (the things the user considers parts of the OS, even when it is not strictly so), and a compiled C program usually just depends on itself and maybe a config file. Even if the Python interpreter is preinstalled in the distro, can really mission-critical apps depend on the user not removing an old version of the interpreter, considering it outdated?

    There are probably good answers to these questions. My question is rather: why are they not even really asked in old Unix-head circles, why do you think the most important thing is to develop good software quickly and efficiently, and let others worry about whatever exotic environment the user requires to run it?

    1. >What were the reasons of not putting ease of installation on the list of considerations?

      It’s not so much an old Unix thing as it is an adaptation to a world in which we assume an equivalent of apt-get with dependency tracking is always available.

      Before that, I think Unix guys were more casual about this than you’re used to be because we developed the idea of a shared infrastructure through open source well before “open source” was formalized as an idea. That meant the overhead of assuming – say – Perl, back in the day was relatively low (though not nearly as low as today).

      Also, Python is a bit special here. It’s been so popular for so long that the idea of a modern desktop or server Unix system without it now seems really odd and why-would-you-do-that? It’s ubiquitous as scripting glue in vendor-installed stuff, too. (Embedded is different, python’s footprint is a little heavy for those systems.)

      1. It’s not so much an old Unix thing as it is an adaptation to a world in which we assume an equivalent of apt-get with dependency tracking is always available.

        apt-get has made a pig’s ear of things because it cannot handle conflicting versions of things correctly. The new hotness is to containerize all the things, give each app its own root namespace with all the dependencies it needs, and ship the app as an entire filesystem image with Docker or similar.

        Note that DLL hell is a solved problem under Windows (and has been since at least Windows XP), yet continues to plague Linux to the extent that a binary you download today is not guaranteed to work on next year’s Linux system. For mission-critical apps, binaries must be guaranteed to work forever.

          1. Docker solves it by brute force — bundling an entire OS (minus kernel) along with the app. And Docker does nothing to solve the underlying problem — I can’t find a piece of Linux software I want, double click on its installer, hit next a couple of times and have the program ready to go. So it falls flat on its face from an ease-of-use perspective.

            Under Windows, these are non-issues because Microsoft cares about its installed user base.

            1. There’s an effort being made to fix that for the desktop use case which is getting a lot of traction. It’s a Freedesktop.org-originated project that began under the name xdg-app and is now called Flatpak.

              http://flatpak.org/

              It’s sort of a hybrid of Android APK design and traditional linux package management in that:

              1. You CAN treat it like a Docker container and bundle the world, but supporting shared dependencies is also a goal.
              2. You CAN configure it to “allow all” for easy distribution of legacy applications, but it also provides a sandboxing mechanism and “portals” (APIs to punch holes in the sandbox in a safe fashion) that GTK+ and Qt integrate with so things like the built in Open/Save dialogs are transparently proxied and result in the selected file/folder being mounted into the application’s namespace.

              (It also means we’ll FINALLY have unified common dialogs across GTK+ and Qt applications, which is reason enough to run all legacy GUI applications inside Flatpak in “allow all” mode.)

              Here are some links about what the portals cover and progress made to support them:

              http://flatpak.org/xdg-desktop-portal/portal-docs.html
              https://blogs.gnome.org/mclasen/2016/07/08/portals-using-gtk-in-a-flatpak/
              http://www.jgrulich.cz/2017/01/18/kde-flatpak-portals-introduction/

            2. I find that for most software, installing / uninstalling on Linux is much less hassle than on Windows. I can tick off a whole bunch of mixed installs, uninstalls, and upgrades together in Synaptic, and in just a few clicks get the whole batch started, as opposed to doing everything one at a time on Windows. The big difference is the behavior of small time developers. Such developers on Windows tend to provide a zip file with prebuilt binaries, and either use static binaries or provide the needed DLLs in their zip file. Equivalent Linux developers provide sources, and maybe an *.rpm and/or *.deb. The package files are as dead simple as installing through your package manager if the current release of your distro has the right library versions. If that’s not the case, that’s when things start to get hairy. But it’s a *cultural* thing. DLL hell on Windows can still be quite infuriating if a developer doesn’t include the needed libraries (and obtaining them from a safe source can skeins be difficult), but Windows developers tend to be a lot more conscientious about avoiding those issues *even when it’s the same developer working on Windows and Linux releases of a package*.

        1. The assertion that “DLL Hell is a solved problem… since… XP” is just plain ludicrous. It sure as hell was NOT solved in XP. And it was as big a problem in Vista as it had ever been.

          There may be fewer problems today, but they come at a huge performance and resource cost. If you want to call that a “solution”, go ahead, but Windows 10 is a resource-hogging behemoth and even with a relatively new top-of-the-line i7 processor, I find it runs sluggishly. OS X is enormously faster on the same bare hardware, and Linux screams hypersonically in comparison.

          A decent compromise is Windows 7.

          Regardless, I can compile a program for Windows XP or even 98, and have seldom had problems. Because it took / takes some intelligent DLL management rather than “compile with defaults”.

      2. There will be python for sure, but which python?

        The whole 2.7 -> 3.x transition did not exactly cover the python ecosystem with glory. Writing code which works on both flavors in all the cases (and does not fail obscurely on one of them when given incorrectly encoded inputs) is not easy – it certainly requires testing with both flavors. And it’s even harder when some distribution include 2.6/3.2 which were even less compatible.

    2. One thing you guys never invented nor put it ever on the long list of things to copy from Windows was the Next/Next/OK installer file downloadable from some website.

      Uh?! Sharchives would like a word; these are still used in distributions of some proprietary software. Some of them even boot graphical installers, but usually this is considered to be in poor taste (since “mission critical” systems running Unix may not even have an X server to talk to).

      You can build the case, however, that making it a doddle to install and give administrative privileges to any random program from any random web site has been at the heart of many of the perennial security problems with Windows. This is why most post-desktop operating systems have adopted the apt-style officially blessed distribution package model in the form of app stores.

      In short, what you’re looking for has existed for decades, but it withered on the vine in Unix culture because its drawbacks are, for good or ill, perceived to be greater than its advantages within that culture.

      My question is rather: why are they not even really asked in old Unix-head circles, why do you think the most important thing is to develop good software quickly and efficiently, and let others worry about whatever exotic environment the user requires to run it?

      Because old Unix heads, and open source folks in general, have no concept of customers — people who are not developers, who must be pleased or else it’s your ass. Without customers they have no concept of products either, and thus everything in open source is never finished, and developers never take responsibility for things that don’t immediately interest them.

      In the meantime, there is Anaconda, a package manager that lets you locally deploy and manage interpreters and other dependencies for different Python versions — in similar fashion to nvm for Node or rvm for Ruby. Comes in an easy-install sharchive, too.

    3. Here again, the JavaScript story is far better than that of traditional languages. Using <script src=”https://foo.bar.com/baz.js”><script> is so much easier than wanking around with apt-get, install scripts, and all their friends that it’s not even funny. The user doesn’t have to do *anything* to download and run the code. Upgrades happen automatically. The ability to run random code from random sites without (usually) getting your box pwned is a Big Deal. The scalability infrastructure (CDNs, etc.) is also a Big Deal. What do you suppose would happen if a Python package suddenly achieved the download traffic demand of (say) jQuery? Ugly things, I reckon.

      By contrast, it seems like I run into versioning and package installer issues just about every time I try to run something new (and non-trivial) that’s been written in Python. Yeah, I *can* sort that stuff out. By the time I get it done, though, my enthusiasm level has declined significantly.

      1. By contrast, it seems like I run into versioning and package installer issues just about every time I try to run something new (and non-trivial) that’s been written in Python

        Seconded, but I blame a lot of this on pip and python developer culture. Or at least, I think I do.

        Python developers mostly seem to ship only pip packages. pip packages can and (usually) do define appropriate dependencies on other pip packages. But there will always be some additional dependency on system packages, even if it’s just a minimum interpreter version. There’s no way to represent those dependencies in pip, as far as I know. Making sure they’re satisfied is up to the user.

        The problem is inherent in using two interdependent package systems with separate dependency trees. I would be surprised if it didn’t exist for other language-specific repos as well. Developers should ship OS packages for the most common distributions instead, with pip used as a fallback for less common ones. See also: Why Developers Should Care About System Packages.

        I can sort of understand this when the developer doesn’t know how to do packaging, knows they don’t know, and is willing to punt to the distros or the users. But I don’t like it. Double malus points if a cross platform project ships a windows installer (which shows that they can package), no rpm/deb, and then complains that the distro repos are always out of date. Of course they are. It’s your itch, you scratch it.

        (Context: sysadmin background. Complaints above represent many dreams of kzzzzzrting, often of my own devs.)

    4. Python programmers are not “old Unix-heads”.

      They are “relatively new Unix-heads”.

      And yes, I agree, a non-compiled language is not very suitable for standalone, distributable runtimes. I don’t know anybody with half a brain who thinks otherwise.

      (I kind of expect to hear from a few, now.)

      1. >And yes, I agree, a non-compiled language is not very suitable for standalone, distributable runtimes. I don’t know anybody with half a brain who thinks otherwise.

        It depends. Distributable is important, of course, but you don’t always need standalone.

        I have done a couple of large applications in Python. Having it as a prerequisite was not a problem because Python is ubiquitous on the systems where I expected them to be used – and, indeed, nobody has ever said to me “Gee, I want to run reposurgeon or doclifter but I can’t because I don’t have Python.

        I’m now thinking about moving from Python to Go, but that would be for performance reasons rather than because the Python dependency is an actual deployment problem.

        1. I actually rewrote a Python application in Rust[1] precisely because of how difficult it was to get it packaged with all of it’s dependency problems, and that the upstream developer and others commenting on the project were gearing up to ship it in a Snap/Flatpak to solve the packaging problems.

          With Python applications, you have multiple runtime dependencies that are pinned to specific versions of Python, which your distribution may not ship; and where your distribution may not even ship the required dependencies at all, so you’re forced to tell your users to manually Pip everything themselves.

          In the end, only took me three days to complete the project, and the final result is much more powerful than the original, with half the lines of code.

          [1] https://github.com/mmstick/fontfinder

  24. I, too, have given up on C. Before C, I liked Pascal. But after installing Unix in 1975, I made the switch to C. Now I use a language I developed myself, Embedded System Language (ESL):
    https://github.com/bagel99/esl.

    It is a low level system programming language that inter-operates with C. It has no reserved words and so can easily be extended. The compiler is written in itself and uses LLVM as the backend code generator. A project written is C can be transitioned to ESL incrementally, top-down.

    For examples of system code, including IPv4 and IPv6 stacks, see:
    https://github.com/bagel99/blocks-os

  25. Very nice, Brian. Was wanting to do something similar with a LISP (syntax) front end. I like the way LISP 1.5 and earlier included inline assembly, and the data representations in memory were as easy to munge as they are in C.

  26. A long time ago I made the calculation about the combined run time of deploying my programs/scripts and the time needed to write and debug the code. When I found out that it took me much much longer to write and debug a C program than it would ever run in total time, I decided to switch to scripting languages. These might be an order of magnitude slower in run-time, but the reduction in writing time would still make them faster. And this holds for any application except for mass use.

    Nowadays, the problem is neither run-time nor developing time, but distribution. When I write code for random users, it has to run on Linux, OSX, Android, iOS, and Windows. Most of these systems are locked down and will not install or execute my code unless I jump through hoops.

    So I have moved to Javascript. I hate it, but it will run in any web browser window on any computer or mobile gadget directly from a Github (ghpages) account. This works great, except for iOS.

    Apple browsers will NOT do record sound from Javascript. But then, why should I care about Apple?

    So, now I only have to find out how to connect my emscripten asm.js code to the rest of the Javascript code I use it in. And I totally agree that the output of emscripten is hideous. The first massive application I tried with emscripten resulted in 100M lines of incomprehensible asm.js. Node simply balked and stopped loading it.

    1. Why JavaScript instead of Rust? I know some people who write JavaScript[1] professionally, whom have told me that Rust is much easier to learn and develop solutions with than JavaScript, which is incredibly difficult to debug due to it’s complete lack of static type checking.

      As for packaging, all users have to do if it’s not packaged yet for their distribution, is to to type `cargo install package`, or `cargo install –git `. You may even distribute static binaries yourself. Rust uses Cargo for building and managing dependencies for a project, and pulls dependencies from Crates.io automatically. When compiling, these dependencies are statically-linked into the final binary, so there are no runtime dependencies at all.

      [1] https://plus.google.com/+WorldofGnomeOrg

  27. @Francist
    “Not R? I know a bunch of people who have moved stuff from Fortran to R. Since number bashing isn’t my thing I’ve no idea how the two compare in performance. I do know that R seems more (modern) user friendly”

    Fortran is optimized for manipulating large multidimensional matrices. Examples are the atmosphere or sand transport by sea currents. I know at least one signal processing application that is written in C but uses the Fortran lapack libraries for matrix manipulations.

    When I install R packages, I remember seeing Fortran compiler messages. So I think the opposition between R and Fortran is not real. R function often are implemented in Fortran.

  28. One thing that I’ve noticed that I like in languages is having a very small syntactic universe from which everything else is built. Needing to know some gigantic vocabulary to get simple things done (and knowing where all that stuff is squirreled away) like in Java makes it infinitely harder for me. It’s absolutely horrifying if you *have* to know all this junk because you *can’t* do it naturally within the language.

    C and Fortran work out very nicely by that criterion: There are only a few things you have to be aware of to start writing code.

    I’ll often study a language up until I have the bare minimum set of commands needed to make anything else (base data types, loops and control structures, terminal IO, file IO, memory allocation (and, though I need to be better about this, how to invoke other object files and dlls)), and then start cranking out code. I don’t necessarily need or want to know about some deep hierarchy of syntactic sugar designed to save me from myself.

    1. C and Fortran work out very nicely by that criterion: There are only a few things you have to be aware of to start writing code.

      In C’s case, there are a lot of semantic “gotchas” you have to be aware of to write good code. You may be able to easily write “Hello, world” and other simple problems without issue, but that breeds a false sense of confidence when you go on to build more complex systems and run into snags that won’t be caught by the compiler or even the runtime, but will result instead in fandango on core or other serious vulnerabilities.

  29. Apparently you don’t know C or pretend to do so even after 35 years of programming in C. The pain in software development is in most cases not debugging or dealing with hard bugs, but to layout the architecture in such a way so it can be done in a sensible way. This is hard for every programming language. C just does very little to hide that fact. So depending on what types of project you are working on, you have different levels of sensibility requirement, sometimes you can getaway with some fuzzy logic using an “automatic” language, but some cases you can not. Then some language that forces you to do this is a must. And such a language just happens to be C.

    1. Then some language that forces you to do this is a must. And such a language just happens to be C.

      Being a minefield of safety issues and “undefined behavior” is not a feature. Rust also requires you to structure your program sensibly, and its compiler will catch you out if you fail to do so. The same cannot be said for most C compilers…

    2. > but to layout the architecture in such a way so it can be done in a sensible way

      With almost three years of experience in writing software in Rust, I can say that this is not really a concern with Rust. The compiler already takes care of ensuring that you construct your software with a good architecture. The type system and generics are also incredibly helpful when employing modern techniques like entity-component systems. C doesn’t help at all with anything of the sort. It doesn’t encourage good software architectures.

  30. go has a gc. it’s worthless for systems programming, mcus and iot.
    if anything comes even close to replacing c, it’s rust. but as you succinctly put it: maybe in five years. or maybe when there’s c->rust llvm-based transpiler, so ten-ish years.
    meanwhile c is evolving too. and its ubiquitous, so external tools and solidly tested libraries dealing with its problems are widely available. c won’t go away in my lifetime.

  31. Interesting opinion. Wake me when the Linux kernel is ported to something other than C or C++. Till then, I think it’s here to stay.

  32. I don’t know systems programming, but in the world of deep learning, people mostly write in Python for readability with the heavy numerical work being done in C or C++ under the hood. I don’t know of any new language with a blas/lapack equivalent that performs as well as C’s. (I had a friend who was working on a Haskell version, but that doesn’t seem to have materialized.)

    1. I’ve actually proven to a number of people in the Python crowd that Rust is more readable than Python, and just as performant (if not more performant) than C. This was my most recent project which rewrote a Python application and drastically expanded it[1]. Only three days of effort. And an accompanying remark from a user on Reddit that did not believe that it could be done, but then admitted to the level of conciseness of the code after I released it[2].

      [1] https://github.com/mmstick/fontfinder
      [2] https://www.reddit.com/r/programming/comments/7blaey/learning_go_by_porting_a_mediumsized_web_backend/dpn2vqe/?context=3

        1. If you disable Nim’s GC you will encounter places where it is impossible to free memory. Just one example, try to free memory associated with a closure. It isn’t possible since the language completely abstracts closures away so you have zero access to the memory resources. Even with GC off, Nim is perfectly happy to allocate memory without giving you any indication it did so and is perfectly content with making it impossible to free that memory through abstraction.

          Those to write Nim’s compiler claim that you can disable the GC without issue but this is simply false. I don’t know why this claim is being spread. It seems not one person has sat down and looked at what places Nim allocates memory and made sure that for each place you can 1) alloc manually 2) dealloc manually

          1. > disable the GC without issue

            I didn’t say “without issue”, I said you can disable the GC. It will warn you if you use constructs that automatically allocate memory, so you don’t use those, except for really short-running programs. It’s a different style of programming of course, but the exciting part is that you can do it with the same toolchain. This is arguably the same thing that made C so successful- you can write big apps or you can write device drivers- but to a much more comprehensive extent.

  33. After several years of using python I’ve come to the conclusion that it’s not a good language for anything other than small throw-away scripts that only need to run on my machine.

    The moment I need the script to become bigger or to share it with other people, python becomes an unreasonable choice.

  34. I was disappointed at syntax and object sizes of golang ;-) See https://snag.gy/ZoULBl.jpg

    As for choice of a programming languages is concerned, it all depends on the environment where or for whom you work.

    OTOH, nobody can stop you creating a new world of your own. But, but, please, please don’t distract others from using whatever they want.

    1. Dunno about the syntax (yet), but the object size is because the Go compiler produces a static binary, while GCC produces a dynamic library.

      I suspect the Go app starts working faster and has roughly the same memory footprint. Then again, with Hello World it’s going to be a close race anyway.

  35. C++ is obviously the ornamental proboscidea…

    I don’t see any point in pursuing yet another language that can reach down to that level when there is one that is ubiquitous from multiple sources and is now on a well managed development path.

    Paul

    1. >C++ is obviously the ornamental proboscidea…

      Same problems as C, obviously. I didn’t consider it worth the bother to call out separately.

      1. I disagree, C++ avoids the memory management and core dumping of C while allowing low level code to have a higher level of abstraction. You should never see an allocation from new to a bare pointer. New itself should be extraordinarily rare. People should be writing Linux kernel and driver components in C++, there would be fewer exploits left for the finding.

        Anyway Go is interesting and Rust not so. C++ reaches up, Go reaches down. Substantial overlap. The problem with C++ has always been that you can write C in it, but perhaps that’s why it has endured. It’s an imperfect world.

        It’s interesting that TensorFlow is C++, but you would probably use it from Python.

        Paul

        1. If C++ is so wonderful and does such a great job of memory management, then why does the one C++ program I’m invilved with, a 1.2MLOC monstrosity that’s been hacked over for 13 or 14 years by literally a thousand pairs of hands, have such a major problem with memory leaks, despite the two major efforts to go through it and eradicate them?

          No. C++ is a crawling horror, a large language from which a good small language is struggling to get out.

          1. I don’t know. Perhaps it was conceived by C non-experts…. There are penalties from being more or less capable of compiling C programs.

            My thoughts really flow from the note by Eric about ‘Cx’ and from other comments about enhancing C with methods. It all exists, along with other good stuff, pretty much everywhere that has a C compiler already. So there’s no excuse for the monstrosity C creations that are still extant spewing exploits across the net.

            For example the other week there were reports of significant bugs being found in the driver code for a particular Wifi hardware found in some phones. 600000 lines of C. If that had been properly engineered using C++ then the bugs reported would have been avoided by design, and the result wouldn’t have paid any performance penalty. And it would be possible, whereas doing it in Rust wouldn’t be, as of now.

            If you see C++ code, and the programmer has written ‘new’ allocated to a smart pointer, raise a query, if there’s a raw pointer then reject it. Code review was never so easy.

            Paul

              1. I think it’s possible in principle, (to create substantial Linux kernel components in Rust) but nobody’s doing it, as far as I can find, so it’s not a practical decision for a hardware supplier. Yet.

                Paul

                1. You should probably have a look at Redox to get a better understanding of what is actually being done with Rust. I’ve been exploring the Rust ecosystem, and the deeper I look, the more I feel, based on my 25 years of software development across many languages and paradigms, that they are on the right track.

                2. Nobody’s doing it? Err…. we have a complete kernel, a system shell, a display server and UI toolkit, a packaging utility, and an associated userspace that has been developed from scratch with Rust. An entire OS, without any C. Even the drivers are written in Rust. It’s been done[1].

                  [1] https://redox-os.org/

                    1. Dude, careful. He’s got that look in his eye. Just smile and nod.

                    2. I think it’s you that’s missed the context. I don’t see what relevance that Android has in relation to your claims that Rust is unable to be used for writing substantial kernel components and that there is no one doing it today, despite the fact that Redox already has and is doing this right now.

                    3. Michael, go up and read again. Context is a driver for a Wifi chip used in phones.

                      Your Rust fanboiism is a bit over the top. Are you posting from Redox? Building your projects?

                      Paul

                    4. Where was Android part of the context? It wasn’t. I just searched again, and nowhere is Android mentioned in this context until your comment. “Android is based on Redox”. So, it seems that you are confusing what was said. Not the other way around.

                    5. The context was Linux drivers. The response was that you can write a whole OS in Rust. Completely nonresponsive. You should spend more time reading the entire thread, rather than writing it out to prove to everybody else how their understanding is wrong.

            1. If you see C++ code, and the programmer has written ‘new’ allocated to a smart pointer, raise a query, if there’s a raw pointer then reject it.

              …and you’re on a desktop-class machine. I’ve been trying to get reacquainted with “modern” C++ after doing Java and other high-level languages for 15 years, and it seems like about half of the best practices just don’t apply to embedded development.

              1. There need not be any overhead. We just want the compiler to write code that we would otherwise get bogged down in. But the embedded world beyond the Raspberry Pi is another country to me. And the Pi is a full fat place.

                Paul

            2. Bad C++ programmers can do even more damage than bad C programmers.

              Good C++ programmers don’t have memory leaks, period. Even when there are exceptions thrown.

              Of course this requires using RAII properly, which in turn requires understanding how to do polymorphism without exposing pointers to the application layer.

              But it can be done. I know because I have done it.

              1. C++11 introduced shared_ptr, which finally solved a single problem with a single solution that was obvious (if limited in performance and applicability) since long before C++98.

                RAII and exceptions can get a single programmer down to somewhere near one crashing bug per year. I’m not sure where polymorphism fits into that…I guess if you use polymorphism in your C++ code, you should avoid breaking the other stuff with it?

                Plenty of other problems remain in C++ though, even after agreeing (and manually policing all source code ever written by anyone we ever work with) to abstain from using parts of the standard language.

                “Iterator validity issues” are the C++ name for what C calls “pointer bugs.” Just because you can’t see the pointers doesn’t mean they’re not still there, or that you can’t still dereference them after the referenced object has been freed.

        2. C++’s RAII is incomplete, and it does not have move semantics by default, or a borrowing and ownership model. It does not solve the issue of aliased pointers, and pointer management in C++ is just as dangerous and incredibly-error prone as C. So no, memory management in C++ is a complete failure.

          Rust is the only language that solves all of these problems, without having to introduce a runtime garbage collector. And that’s just a small piece of the puzzle that Rust solves where C++ fails.

          1. “pointer management in C++ is just as dangerous and incredibly-error prone as C”?

            This proves that you know nothing about C++. Stick to topics where you have some knowledge.

            1. The funny thing about your counter-argument is that you didn’t argue any of the valid statements that I made, which supported that statement. You just simply copped out a “stick to topics where you have some knowledge”, which proves that you have no legs to stand upon.

              1. The fact that you said “pointer management in C++ is just as dangerous and incredibly-error prone as C” demonstrates that you know nothing about C++. Automatic memory management via RAII is one of the MAJOR improvements of C++ over C. The fact that you have to know how to use RAII to gain these advantages does not mean that they don’t exist. Many people, including myself, do know how to do this.

                Thus, I can dismiss any further claims you make as being made by someone totally ignorant of the topic.

                Get it?

                1. As I said, RAII is incomplete. It is only part of a larger story that is required to enable safe memory management. Case in point, where is your lifetime syntax to assign lifetimes to references in order to ensure, at compile time, that the references will always point to valid memory? Fact of the matter is, you have no such parallel in C++. You have to resort to very unsafe pointers with zero aid from a static code analysis tool.

                  And as I mentioned before, why does C++ not have move semantics by default, and a borrowing and ownership model? RAII is pretty much useless without also being accompanied with that.

                  And more evidence to support how flawed C++ is at developing highly parallel, complex software.

                  https://blog.rust-lang.org/2017/11/14/Fearless-Concurrency-In-Firefox-Quantum.html

                  “Personally, my “aha, I now fully understand the power of Rust” moment was when thread safety issues cropped up on the C++ side. Browsers are complex beings, and despite Stylo being Rust code, it needs to call back into Firefox’s C++ code a lot. Firefox has a single “main thread” per process, and while it does use other threads they are relatively limited in what they do. Stylo, being quite parallel, occasionally calls into C++ code off the main thread. That was usually fine, but would regularly surface thread safety bugs in the C++ code when there was a cache or global mutable state involved, things which basically never were a problem on the Rust side.”

                  “These bugs were not easy to notice, and were often very tricky to debug. And that was with only the occasional call into C++ code off the main thread; It feels like if we had tried this project in pure C++ we’d be dealing with this far too much to be able to get anything useful done. And indeed, bugs like these have thwarted multiple attempts to parallelize styling in the past, both in Firefox and other browsers.”

                  “Firefox developers had a great time learning and using Rust. People really enjoyed being able to aggressively write code without having to worry about safety, and many mentioned that Rust’s ownership model was close to how they implicitly reason about memory within Firefox’s large C++ codebase. It was refreshing to have fuzzers catch mostly explicit panics in Rust code, which are much easier to debug and fix than segfaults and other memory safety issues on the C++ side.”

                  1. Oh now I see! So it is not like the C++ memory management was a complete failure. Or that C++ references were broken. It is that they do not what you want — what Rust does.
                    Yes, borrow-checking in C++ would be nice. However C++ is a language to replace C, it is not supposed to replace high-level languages (unless you really want performance).

          2. The reason pointer management is just is bad as in C, is because C++ is a superset of C, and therefore you can do whatever bad horrible C pointer thing you want in C++ as well.

            1. The fact that you CAN write bad code in C++ does not mean that you MUST write bad code in C++.

              I have written several large C++ programs that have no, repeat NO, memory leaks or allocation errors. That is possible in C++ by using the language properly.

              C does not have the facilities to make this feasible, as you must use raw pointers to refer to dynamically-allocated memory. Thus, C is inferior to C++ in (at least) this regard.

              1. Just because you can write “Hello World” without memory errors doesn’t mean that you can write Firefox or a video game without memory errors. It requires a monumental effort to develop complex software with C++, and along the way you are certain to come across many instances of undefined behavior and memory safety violations. It’s not a matter of if, but when.

                Rust prevents that at compile-time and then further enables the ability to design and implement features that you wouldn’t dare to do with C++, because of how difficult it would be to pull off. Case in point is Firefox’s new Stylo engine. First web browser to feature a parallel CSS processor, which will soon be further enhanced by shipping a fully parallel GPU-accelerated web renderer. Something that was too difficult to achieve with C++.

                Also, there’s this from game developers, Chucklefish: https://www.reddit.com/r/rust/comments/78bowa/hey_this_is_kyren_from_chucklefish_we_make_and/

                1. Please try to read what I wrote, not something you imagine.

                  I have written large programs, not “Hello, World”, in C++. These same large programs have no memory allocation errors or undefined behavior.

                  The fact that others don’t know how to do this just means (as I have said elsewhere on this thread) that most programmers, including most C++ programmers, suck.

                  It is not an indictment of C++.

                  1. The problem is that you are attributing flaws in the language to the developer, and not the language. When we have a language that exists today (Rust) that can push that burden entirely upon the language and it’s compiler, and thereby no longer making it possible for the developer to be the problem, then you have no reason to stand behind and in support of C++. You’re basically coddling the language against criticism with an irrational defense.

                    See the following writeup from the Firefox developers who just replaced 160,000 lines of C++ with 85,000 lines of Rust. Firefox is now the first web browser to have a parallel CSS engine. Not even Google devs have been able to do this with C++. Firefox achieved this with Rust, and they do mark that Rust is the reason why they are able to achieve it, and that while there have been many attempts to parallelize CSS parsing in web browsers in the past, all attempts have failed because C++ made it too difficult to accomplish, due to memory unsafety.

                    https://blog.rust-lang.org/2017/11/14/Fearless-Concurrency-In-Firefox-Quantum.html

  36. If you have a piece of hardware you want to enable others to use, you might want to write example source code that doubles as a library.

    C is the only answer. Every respectable language has a FFI that will interface with C. Every respectable system has a C compiler. Every real customer who could buy significant quantities of your hardware has an employee who can at least read C well enough to interface to it. Every real system that your hardware might be slotted into already has at least some preexisting C code running in it.

    An embedded system your product might go into might not have enough available RAM for an interpreter or JIT. The processor it uses might be oddball enough there is no port of go. The programmers may be too crotchety and jealous of performance to allow something too high level. The C example code/library shows you are sensitive to all these concerns, and serious about your product — especially if it works well, and the API is orthogonal and easy to interface from other languages.

    There may be external reasons to use another language. Showing you are trendy to capture the millennials. A quick time-to-market for a product that you can’t yet produce in sufficient quantities to service the TAM.

    But if you’re serious about building a good product and capturing a large part of the TAM, you’ll eventually wind up writing that C library anyway. Or if you get really lucky, maybe one of your good customers will do it for you.

    Bottom line: new programs might or might not get started in C very often; new libraries get started in C daily.

    1. >Bottom line: new programs might or might not get started in C very often; new libraries get started in C daily.

      I have not started a new library in C in this century, either.

      That said, I think you have a point. One is somewhat more likely to be able to avoid complex memory-management issues in libraries, and they run small compared to whole programs. Thus, the scale pressure towards a language with GC is less.

    2. Redox can run on real hardware, and it does not involve C at all! It’s written in Rust from scratch, so the first bits of assembly that boot the system immediately hook into a Rust kernel and run a Rust userspace.

      Rust does support some embedded devices, and there’s actually some IoT hardware out there that only supports Rust, not C! And many C libraries are being rewritten in Rust today!

      In addition, Rust kernel modules have been writing for Linux, so that can be done as well. Reported benefits of writing kernels, drivers, etc. in Rust are the significantly-reduced surface area of mistakes. It’s very easy to construct complex solutions in Rust, and have all the corner cases accounted for.

      The compiler then ensures that you correctly use your memory, so there’s no double frees, or use after free. The generics proves to be incredibly useful for designing interfaces shared across the code base, and the vast array of capabilities in the core language with it’s traits and iterators make it trivial to reduce the lines of code required by a significant gap.

      The move semantics, borrowing and ownership mechanisms, traits and attributes then combine to make multi-threaded software incredibly easy to develop. Hence Firefox’s Quantum project making major strides with Servo (Stylo + WebRender + Etc.), which is why Firefox Beta is so much faster now (even though it only has Stylo integrated at the moment).

      1. Good advertising; wrong comment to respond to, though.

        If I have to write a C library for my largest, most conservative customer, I’m not going to bother writing a rust library in addition to that until some other large customer tells me it would be really nice to have.

        1. Why would you bother to write a C library to begin with, when you already have a Rust library? Rust libraries can export a C ABI, and there is a lot of infrastructure in place to make it trivial to work across the FFI boundary. In fact, if you are using a GNOME-powered Linux desktop today, then you are already using a Rust library that is exporting a C interface. One of GNOME’s first forray’s into their inevitable rewrite of GNOME and it’s ecosystem in Rust was to rewrite librsvg in Rust.

          librsvg is used by a lot of C software in GNOME, and was previously written in C. The Rust rewrite was able to uncover a number of vulnerabilities and bugs in the original C implementation, because the compiler caught them. It also managed to decrease memory use and increase performance. But to all the C software out there that relies heavily upon it? They are none the wiser that they are interfacing with a Rust library, because it exports the same C ABI! It is simply re-using the same exact C header as it was using before the rewrite.

          1. You’re not doing your chosen language any good with your poor reading comprehension and used-car salesman tactics.

              1. There wouldn’t be any childish retorts if you paid attention and addressed my points, but you haven’t. If I’m writing libraries for others, a C compiler is assumable. A rust compiler isn’t; at least not yet. C programmers are assumable. Rust programmers aren’t; at least not yet. I’m talking about customers who are more apt to read the C and transliterate it into assembler for their tiny embedded systems than they are to link rust into their systems.

                This could certainly change in a few years (as per esr’s post and other comments here). It’s not my job to push your language by sending out libraries in a language that none of my customers grok, and if it’s your job, you are seriously doing a terrible job of it by your argumentative stance. Communication is not a one-way street. I understood everything you said, but you didn’t address a single thing I said, so yeah, poor reading comprehension and used-car salesman tactics.

                1. You say that I didn’t address your points, and yet I did. It is assumable that everyone has access to a Rust compiler. It is cross-platform, and easily installed on any OS for many different architectures, even without root

                  Most distributions provide Cargo + Rustc already packaged, and for developers, we have the official Rustup toolchain manager[1], which does not require root to be installed on any development platform. Simply open a terminal and enter the following:

                  curl https://sh.rustup.rs -sSf | sh

                  Once finished, you will have the latest stable version of Rust installed. Switching to nightly is just a matter of running:

                  rustup default nightly

                  Updating your toolchains is also simple:

                  rustup update

                  So no, I don’t buy that you, or anyone else, would not have access to a Rust compiler to use within their build system. And they’d be much better off using it to begin with, given Rust’s quality and safety guarantees.

                  > C programmers are assumable. Rust programmers aren’t

                  I have been able to personally pick someone that has never programmed in their life, and within two weeks they were writing masterfully-crafted Rust. If you come with an experience in programming, then it should be all the easier.

                  > I’m talking about customers who are more apt to read the C and transliterate it into assembler for their tiny embedded systems than they are to link rust into their systems

                  I have read comment after comment, post after post, from people who have just picked up Rust, and this is on their first day with the language, stating how readable, concise, and simple the language is compared to C or C++.

                  Fact is, Rust chose early on that the language should be explicit in intent, so it is much easier to ‘read and transliterate’ Rust than it is to do the same for the ambiguous C. This explicitness is both helpful to the reader, as code will be read for more often than it is written; and helpful to the compiler which can use the extra compiler information to enact more aggressive compiler optimizations.

                  Rust has clear rules on access patterns, whereas C has no rules at all! Thus, where someone would have to carefully read your function’s implementation to decipher the access pattern, you can get that information from just reading the function declaration in Rust. These rules provide for a large degree of guarantees about the code.

                  [1] https://rustup.rs/

                  1. You say that I didn’t address your points, and yet I did.

                    You do realize that people can read what you wrote, right? It’s still there.

                    It is assumable that everyone has access to a Rust compiler.

                    You obviously have internalized this assumption, and you’re entitled to your own opinion, but not your own facts. Assumption fail. 8051, AVR, RISC-V.

                    Sure, people are working on some of those things (such as RISC-V), but they’re not really there yet. There are a lot of platforms that have had production C compilers for years that don’t have production-quality rust compilers.

                    Most distributions…

                    Doesn’t address the problem, and the part of your post that really belongs in a user manual is completely irrelevant.

                    So no, I don’t buy that you, or anyone else, would not have access to a Rust compiler to use within their build system.

                    Doesn’t matter. You’re not the one buying — you’re the one trying to sell, and not doing a very good job of it.

                    I have been able to personally pick someone that has never programmed in their life, and within two weeks they were writing masterfully-crafted Rust.

                    That still doesn’t address my point that it’s not my job to convince my customers to try your language.

                    I have read comment after comment, post after post, from people who have just picked up Rust,

                    That statement can be completely true, and still not make it the right business decision to complicate a simple sale by saying “oh, and all our libraries are in rust. Your programmers will love them.”

  37. @esr If python and C are your favourites and you’ve given a GC language a go (pun intended) why waste your time on reviewing rust instead of going straight to Nim?

    It’s a no brainer, really.

      1. To be perfectly honest, unless you’ve been living under a rock, Nim is one of the more popular languages that consistently gets mentioned within your usual online programming communities. I’d find it hard to believe that a programmer who still programs today would be unaware of Nim.

        Do you not follow programming communities on Reddit, HackerNews, Google+, and other such sites? Next you’ll tell me you’ve never heard of Crystal, Elixir, and Jai.

        1. I don’t spend my time looking around at all the weird and wonderful new languages people come up with. I spend my time writing code. In good old-fashioned C, at work, and in C++ and Python at home. That’s because I work within existing ecosystems, not haring off on my own looking for wheels to reinvent.

          And no, I have never heard of Crystal, Elixir, or Jai.

          1. >And no, I have never heard of Crystal, Elixir, or Jai.

            I think another regular here would describe these as languages of, by, and for skinny-jeans hipsters. They’re cute, precious, not entirely devoid of good ideas, and self-consciously serving niche tastes. The designers tend to be from web-dev or games and boy does it show.

            I haven’t used any of them, but I think I know how it would go; pleasantly when you’re inside the specific use cases the designer had in mind and really, really badly the second you step outside ’em.

            1. I did a quick Google. Whee. Have any of them – especially Jai – been used for anything besides their own compiler?

          2. Following programming news doesn’t mean that you aren’t writing code. In fact, following programming news can open the door to writing better code, or to try out new technologies and libraries. Less re-inventing the wheel, and more collaboration across the globe.

            I’ve written a lot of open source software, and it has been very beneficial to keep up to date with what the rest of my community are doing. Person A makes an announcement regarding a new crate they’ve released, and I immediately try it out in a project and possibly provide feedback or PRs to enhance their software. Or there may be announcements about an established library having a major release, then pointing out all the new routines and capabilities, or whether there’s any critical changes to be aware of.

            There are over 250,000 programmers in the Google+ community, and another 250,000 in the Reddit community. There are many people in language-specific and domain-specific communities as well. News regarding software libraries, new concepts and ideas, critical vulnerabilities, and more are regularly reported in these avenues. It is ridiculous to not stay in touch with what’s happening.

            You’re not helping yourself by building a wall between yourself and all the advancements that the rest of the world are making. Probably why you’re using Python and C++ at home, whereas everyone else is moving away from both and moving towards Rust.

            1. Everything I’ve heard about Rust leads me to believe it’s the programming equivalent of Blender. Blender doesn’t have a learning curve, it has a learning cliff. It’s also the most user-hostile program I’ve ever inflicted on myself. (And I say that as a former IBM mainframe systems programmer!)

              I learned Blender because there were jobs I wanted to do that could be done no other way. So far, there is no equivalent use case for Rust for me: I can get everything I need to do done in C++ or Python. I’m not about to beat myself about the head with a Louisville Slugger full of splinters and nails just because some rabid Rust fanboy thinks I should.

              My C++ is limited to working on that 1.2MLOC monstrosity I mentioned earlier. I don’t even use it for new programs. The kind of programming I do at home, I do in Python. It works well and gets the job done. If you don’t like that…well, that’s just too fucking bad.

              1. It’s much easier to learn Rust than C or C++, so I don’t get your point. It’s not a ‘learning cliff’. Everything’s clean cut and straightforward, so you can pick someone off the street and teach them Rust within two weeks of training.

                1. “It’s easier to learn Rust than C or C++”…

                  I’ll happily give you C++. That’s not a language for beginners either.

                  But C? People can pick up Arduinos and be writing sketches in a few hours. If they’re ahveing to fumble around to invoke the exactly correct incantation to convince the compiler that their code somehow passes all of the rules, then it will deign to spit out a running program for them.

                  Sorry. Everything I’ve ever read bout Rust is that the learning curve is very high.

                  1. >Everything I’ve ever read bout Rust is that the learning curve is very high.

                    I confirm.

                    I’ve written code in more odd languages and language-like markups than most people know exist. I normally eat new ones like candy – production code in less than a day, fluency usually in two to four days, mastery in not more than a month or so (and that’s for the hard ones). It’s not magic – each one gets easier and once you’re past 20 or so you know the patterns, it’s unusual for anything to surprise you any more. I mean, often I can read the first quarter of the docs for something like Nym or Crystal and start making accurate predictions about the design choices I’ll see next.

                    Seriously, throw your Dart or Swift or C# or Erlang or whatever at me. I don’t know any of these languages, but if you bet against me to hit the ground running within a week you are begging to lose.

                    It’s pretty rare for a new language to make me more than break stride these days. Haskell was the last one before Rust, but I got it – if you know enough formal logic going in the only big deal about it is monads, and those are actually a lot simpler than the (arguably misapplied) mathematical terminology around them makes it sound.

                    Compared to Rust, Haskell is a walk in the park. Rust is brutal. I spent six days grinding at it and getting almost nowhere, which is crazy – normally by day six I’d be writing production code almost as fast as I can type (admittedly I’m a slow typist) with stops mostly to absorb more chunks of the standard-library documentation.

                    Instead, I found myself asking why I was putting up with this shit. Everything is difficult, all the time, and basic stuff like select(2) is inexplicably just missing! Bailed out, taught myself enough Go to do the same exercise in it (all of an IRC server except the protocol machine itself), polished that off in less time than it had taken me to read the Rust book twice over (and I’m a fast reader).

                    And I’m, like, What. The. Actual. Fuck? This is supposed to be some sort of great white hope to replace C and it makes me want to kick it out of bed? Me, with 35 years of C experience? Me, the implementer of INTERCAL-90? Me, a harder-core new-language junkie than just about anybody? (OK, I never use most of them for a lot, but I like to learn them.)

                    This is the basic reason I don’t buy the Rust hype. With all my advantages and experience, given I bounced that hard there is no fscking way the language is going to be a comfortable or even usable tool for most C programmers. It is therefore not a practical replacement.

  38. Any replacement for C has to be designed so that you can have an outer-loop for your binary in which there is no garbage collection, and you do need to be able to do pointer arithmetic – though it should be probably disabled/warned-off by default. Go has quite low latency garbage collection. Go also has unsafe access. But as far as I can tell, writing Go for something like an Arduino would not yet yield the kind of tight code you can get in C. But for writing “userland” code, there is way too much of it written in C for no good reason at all.

    1. You should take a closer look at Rust. It’s not built on top of a garbage collector, and pointers are part of the language. Embedded development comes up pretty often in the community. For example, you can disable the standard library if you don’t want it.

      I agree that it’s not quite ready for broad scale deployment, but it’s moving fast, and has already come a long way since that blog post in January.

      1. >I agree that it’s not quite ready for broad scale deployment, but it’s moving fast, and has already come a long way since that blog post in January.

        Perhaps, but my interest in it has also decreased since then – Go looks like a better fit for the work I’m doing. Poke we when it’s no longer “moving fast”, e,g,. the API seems both complete and stable. Remember, for my infrastructure projects I need stability on the scale of decades.

        1. Of course. I completely agree with your article, and think that 5 years is a reasonable estimate of a stability horizon. I intended the reply for Rob Fielding above, since Rust does cover the concerns he was expressing (i.e. no GC, pointer arithmetic, high performance etc.), and there are people doing projects on Arduino.

          In my work, I tend to view Go as a contender for replacing Python, and Rust as a needed-5-years-ago replacement for C++.

  39. I proposed a type-safe C compiler for my bachelor’s thesis but my advisor wanted me to write the first multi-connection TCP for the IBM PC instead (PC/IP). I think a type-safe C compiler would have had more impact on the world, but I almost certainly would have never graduated on time with a task that large …

  40. Luckily a whole lot of embedded projects are NOT just bits of Linux and GNU pasted together. It is true that processing speeds have made it possible to write many applications in programming languages that are not C. But when the pedal hits the metal and you need screaming performance in a resource-limited form-factor there is still no real competitor – apart from native assembly language. Even if the resources are not so limited but the processing load is still at the edge of possibility e.g. digital signal processing, AI, ever-more-realistic graphics then C takes the chequered flag. CUDA I hear you say ? Just C but not so flexible. If you are happy just stringing together libraries of code someone else had the fun of writing and you make a living at it, good for you. But there is great satisfaction in wrangling state-of-the-art hardware into submission and breaking new code to make it happen and only C can hold the ring at this.

  41. I haven’t written a new C program since 1993.

    That’s when I started to use C++.

    For the past three years I’ve been working on my first-ever significant GUI program.

    It is written in C++.

    I’ve also developed a library that I started working on 40(!) years ago and it is finally getting pretty close to optimal.

    It is written in C++.

    I have had no mysterious crashes due to incorrect pointer use since the mid 90’s when I learned how to use C++ properly.

    That’s because C++, when used properly, isn’t subject to such errors. Of course I’m not saying I don’t have bugs in my programs. But I don’t use raw pointers except inside functions that manage them, and there are very few of those. The fact that you can do that in C++ is one of its biggest advantages over C.

    So to get back to the original topic, my prediction is that C++ will remain the premier performance-oriented language for the next 25 years as it has been for the last 25.

    1. >So to get back to the original topic, my prediction is that C++ will remain the premier performance-oriented language for the next 25 years as it has been for the last 25.

      Wow, there’s a blast from my past! It’s good to hear from you again, Steve.

      (For the rest of you, Steve Heller and worked together around 1980-1981 and remained friends for some years afterwards. I don’t remember how we lost touch, exactly…might have been when I moved out of Philly.)

      So, Steve, you never heard my why-I-stopped-coding-in-C++ story. I started to write a long comment about this, and decided it needs to be a post. Which will probably be up by the time you read this.

      1. Sounds good.

        Of course I realize that you can’t write kernel code in C++, at least with the Windows (and I assume the Linux) kernel.

        I don’t know what the issue is with Linux (other than that Linus doesn’t like C++).

        But I do know what the issue is with Windows, namely that Microsoft’s C++ compiler doesn’t (or at least didn’t in the 2010 time frame) allow the programmer to say “put compiler-generated code in this type of memory page”, and that is obviously a necessity to write kernel code.

        However, the REASON that the compiler doesn’t have that facility is more interesting. It is not because it is intrinsically impossible or even necessarily that difficult. The compiler maintainers would be happy to add that facility but no one wants to pay for it.

        That is because the Windows OS designer (Dave Cutler) hates C++. I wrote to him and asked him what the problems were in writing kernel code in C++ and he wrote back saying essentially “C++ programmers suck”, although not in those precise words.

        Which of course is true, because programmers in general suck. But I’m not sure that problem is any worse in C++, other than Bjarne’s famous comment (paraphrasing) “It’s harder to shoot yourself in the foot in C++ than it is in many other languages. But when you do, you blow your whole leg off.”

        1. On a minor point it has been possible to write Windows drivers in C++ for ever. There’s even a compiler flag to configure it appropriately, so no exceptions, RTTI or default new or delete. etc.

          It’s in the documentation…

          Paul

        2. You can write kernel code with C++ and Rust. Both have been used to write entire kernels from scratch, as well. Redox OS, for example, is entirely written in Rust. People have written Linux kernel modules in Rust as well, but you’re not going to see it get merged in the mainline kernel simply because you’d have to convince upstream to accept Rust pull requests.

  42. And do drive home the point, these high-level features are almost all zero runtime cost abstractions (and even if they are not 100% zero-cost yet, like some formulations of iteration, that is the goal and they have a solid story of how they are going to get there).

  43. Hmmm… interesting. I’m still not sold on Rust: somehow it’s not nasty enough – a little too sanitized for proper straight-to-the-metal programming. I think C still has some life in it: you need to be able to break the rules to be able to do proper machine-level programming. Of course, I speak as an old machine code programmer, so perhaps I’m biased… but I just don’t see getting around the idiosyncrasies of hardware with a “safe” language.

      1. If we have to use unsafe blocks in Rust, why would we switch away from the C+Python layered combo?

        1. 1) Rust runs circles around Python even in safe code. Unsafe blocks are infrequently used in practice, only in cases where you absolutely MUST break Rust’s ownership constraints. This means the vast bulk of your code is safe and fast.

          2) Strong, static typing. Static types —
          particularly algebraic data types with some form of generics — are a must in any serious programming language for building large systems. Which means yes, Go doesn’t cut it, and Python certainly doesn’t, unless you like encrusting your code with tests to make sure you don’t accidentally the wrong type in production.

          In general, the stronger the type system, the more invariants you can encode which are checked at compile time. And checking them at compile time is cheaper than checking them at run time, so save your employer money and learn to love static types.

        2. No one has to use unsafe blocks to build anything. Effectively every kind of software can be built without unsafe, and instead using the safe collections and abstractions in the standard library, or through other existing crates.

          Even Redox OS and it’s kernel makes very little usage of unsafe. Where it does pull out unsafe, it makes perfect sense. And if there’s ever a serious issue to track down, a quick ripgrep for the unsafe keyword will quickly point out exactly where a problem might arise.

    1. You’re definitely biased and heavily-outdated on proper machine-level programming in modern times. You can achieve ‘straight-to-the-metal’ programming in Rust the same as you do with C.

      If you want to work with raw pointers, this is how it’s done:

      let ptr = &data as *const T;
      let mut_ptr = &mut data as *mut T;

      The above is equivalent to the following in C:

      const T *ptr = &data;
      T *mut_ptr = &data;

      Raw pointers avoid all of the borrowing and ownership rules of other safe types in Rust (but they can’t be sent across thread boundaries). Yet you’ll have to come up with some serious reasons for using raw pointers instead of using mutable and immutable references. Not even kernel development with Rust has much need for raw pointers over references.

      The reason being is that Rust has a lifetimes mechanism which can be used to designate the lifetime of a reference to ensure, at compile-time, that the data that the reference points to will exist for as long as the reference is in use. In C or C++, there is no such method of assigning a lifetime to a reference, and thus the only tools they have at their disposal are raw pointers.

        1. C++ does not have the ability to assign lifetimes to references. The only other language than Rust which demonstrated lifetime assignments was the Cyclone C experiment. They referred to their feature as ‘region-based memory management’. Their research paper on this technique was majorly influential in the design of Rust and it’s lifetimes syntax, which is a mirror image of what Cyclone did.

        2. In C++ it is very easy to have an object execute code at the end of its lifetime, and that feature can be used to communicate with other objects (e.g. a container object can notify a reference object that its reference is no longer valid); however, as far as I know, these approaches all have run-time costs in C++.

          Rust, from what I hear, does not. It can catch iterator invalidity bugs at build time. The cost is that the developer now has to model their code in terms of ownership constraints. C++ developers pay that cost and more already, because they have to do the verification work manually (or force the machine to do it all the time).

          It might be possible to import ownership and borrowing concepts into C++ through type_traits-style extensions like std::is_trivially_copyable but I have no idea what that would look like.

  44. To be clear, you can write a rust library that exposes a C-FFI interface that can be linked to and consumed by anything that can link to and consume a normal C-library (with zero overhead). So, you can “today” build a Rust lib that can be a drop-in replacement for a c library that has all the safety advantages of Rust (internally) while exposing itself to the rest of the system as if it were a normal C library.

  45. What I’ve seen of Rust impresses me. I’d be interested to learn what is “unbaked” enough for the “wait 5 years” judgment, not as a springboard for argument, but out of genuine curiosity. Those are the places I would watch and study.

    There is no one C++ you can generalize about. The C++ I wrote up through about 2003 used the idiom I learned in the early-to-mid 90s that was already becoming very dated then. I would have to learn proper usage from scratch now because the additions since ‘03 have introduced idioms that make it a potentially safer language. Getting a whole team of C++ devs with different histories working consistently in a common idiom? Not easy.

    My first reaction to Go was kind of a visceral rejection. It feels aesthetically ugly to me in a way that Rust doesn’t. My initial reaction to Python was also negative — it parses the shape of whitespace? really? — but it is now my “go to” language for explorations and glue because the compact syntax (including how it uses whitespace) makes for a fast solve. So I’ll have to spend a little more time with Go before I say “no way”. :) My gut can be very wrong.

    Meanwhile, most of my present work is complex browser SPAs doing complex GUI, EE math, and visualization in ES6+ JavaScript, challenging in its own way – idioms again – but pretty far from the soft-real-time call control for which I wish I had Rust at hand a decade or more ago.

    1. >I’d be interested to learn what is “unbaked” enough for the “wait 5 years” judgment

      Use the search box on my blog to find my Rust posts. I think they’re pretty clear.

      1. Okay, “it’s a fair cop”. Rust is a wise language but the Rust folks haven’t taken ownership of their ecosystem yet. They’ve made a very nice building and waited for foot traffic to guide where to pave the sidewalks. Meanwhile the cost of entry is muddy shoes and uncertainty whether someone will eventually plant a shrub where you got accustomed to walking.

        When there is some notion of “standard crates” that provide “the normal way” to do commonplace things, the language documentation can show usage with these crates. The trade press and YouTube tutorials will parrot it, the stampede of newbies will use it, and code won’t need to “stay current” with library fashions.

        Based on last November’s roadmap, the “will to pave” has become real. One, maybe two years now? But then you did this experiment a couple of years ago. Five years from then isn’t that far off. And Tokio, for example, is still in a zero-dot version and undergoing fundamental structural change. So, Rust gets commercial around 2020… as eager as I am for a safe-by-design GC-free ecosystem for writing infrastructural bedrock code, you’re probably right. :(

        1. Regarding “gets commercial” I’d like to point any future readers (as well as the original author) at https://www.rust-lang.org/en-US/friends.html (a bunch of companies employing Rust – which I also linked to in my own comment below).
          Seems to me to contradict the point (at least for the most part).

          1. I did find it amusing that, after responding here and spending a longish evening or two revisiting the Rust site and related areas to catch up on the state of its developmental growth, I opened my office browser the following morning to find it’s been upgraded to Firefox Quantum. :) Last night, I reinstalled the toolchain and started re-reading the manual.

        2. Having dug further, with “lexical lifetimes” for the borrow checker, borrow scope can overreach what it protects, which you must then insert additional scopes or rearrange code to narrow. This is not exactly obvious from the documentation, and you can trip over it in an apparently trivial function – visibly safe code that won’t compile. (Everything in the NLL RFC seems like the kind of early-encounter tiger trap that the language manual should cover in some detail.)

          Is this the sort of repeating frustrating encounter you ran into when coding, Eric? Would narrowing borrow lifetimes based on the control flow graph (NLL), which more precisely delineates the real boundary of safety, have improved the experience by much?

          This is the only major issue at the raw _language_ level that I see so far.

      2. Wait, so you post follow up posts where you (at least to an extent) revise you’re original judgement, but when someone asks what exactly is the reason for “wait 5 years”, you point them back at your original posts. Hmm ….
        I wrote below that I don’t think this blog post has much relevance, but seeing that people will read, and then base there judgement upon it, I guess it makes sense to “beg to differ”…

        1. Oh it has relevance. Especially enlightening are the comments. They convince me that I should probably stay away from Rust for any serious project. And I mean the comments of Rust’s *supporters*.

          Up until this month I thought maybe I should invest some time in studying the language. And maybe it will give me some new insight into what I might like in a language, so I will take a look at it anyway. But no way am I going to base something on an infrastructure with such *passionate* supporters.

          When you use a language for your project you expect a stable foundation.

          1. The commentator Andy Rooney once said “I am often embarrassed by the people who agree with me.” Any technology with merits (and admittedly any technology with few if any merits) tends to collect a coterie of people around it who style themselves as evangelists, who will use any edge they identify to promote the technology.

            If I were to let the antics of salesmen dissuade me from studying a technology, I’d miss too many things of real value. So study Rust’s ideas, use it if it suits you, and ignore its promoters. If the technology is any good, somewhere behind the circus are a bunch of people actually building something, and it will show.

            At the very least, a detailed worked example of applying immutability and ownership will probably improve the way one codes in any language, even if the language doesn’t enforce the design. At the very least, Rust will contribute this to history, just as Eiffel was a worked example of defining preconditions, post-conditions, and invariants.

            1. To EFRaim’s point, it’s not about people who gush about Rust. It’s about people who gush about Rust who might be in a position to affect the development of the language.

              For example, Python is exceedingly mature and well-managed. Yet, somehow, in the 2-to-3 transition, the zealots managed to do a lot of damage by removing a bunch of stuff that was useful for library developers. 3.0-3.2 were basically unusable from my POV. Much of the broken compatibility got sheepishly re-added; it’s now not unreasonable to target 2.6, 2.7, and 3.3 and above with a library. But the fact that b” != ” is still completely fucking broken, and apparently unfixable at this point.

              And look at the perl fiascoes.

              Now extrapolate this sort of problem to a newer language with fewer developers. Maybe rust isn’t comparable, but who has the time to figure out the politics? With a more mature language, hey, if the developers go off in the weeds, you still have an old, supported, debugged, widely ported version that you can use until they get back on track.

          2. I’d like to address this and similar sentiments. I went back an reviewed all the comments on this blog post and I find that the overwhelming amount of negative comments that lack useful argumentative rationale are not by Rust supports, but, in fact, the opposite.

            I am not part of the Rust project and until recently I have only been reading up, researching, and trying to understand it in my free time. I’ve decided I would like to pursue it further, but, I don’t think that makes me anything of a Fanboi or whatever nonsense gets espoused. Here are comments from this thread classified with some responses and some of my own commentary about what I think about the tone and usefulness of the comments.

            If anything I say offends anyone, I apologize in advance. It is not my intent to offend or call anyone out other than to point out where I feel the comments have not been constructive. I leave it to you to judge for yourself which camp is being constructive and which is not.

            EFraim on 2017-11-16 at 10:07:42 said:

            Oh it has relevance. Especially enlightening are the comments. They convince me that I should probably stay away from Rust for any serious project. And I mean the comments of Rust’s *supporters*.

            Anti-Rust
            ———

            Jerry on 2017-11-10 at 21:18:31 said:

            In my opinion there are no unsafe languages, only unsafe programmers.

            >>>> Blaming the user rather than having an honest and objective evaluation of the facts. Not very useful.

            Jay Maynard on 2017-11-09 at 13:25:00 said:

            Who are you and what have you done with Jeff Read?

            We all know Jeff loves bondage-and-discipline languages that don’t trust the programmer to wipe his own ass correctly.

            >>>> I’m willing to believe this is a joke meant in a friendly way, but, comments like this don’t lend credence to the assertion that Rust supporters are making lots of negative/unfounded comments. If anything, it supports the opposite.

            esr on 2017-11-08 at 21:45:13 said:

            >If “Cx” is this Cx, then it is explicitly not based on C semantics

            No. Different languages,

            >Best stick with Rust.

            …[sic] I have no such confidence about Rust. This means Rust has already lost its fight in userland – Go crossed the chasm first and is going to be climbing towards majority status while Rust is still trying to finalize its standard library.

            >>>> This assertion boils down to nothing more than, I like Go better than Rust without recognizing that Go has garbage collection and so will never be as close the the metal as Rust and so will remain unusable for things like writing Browsers, Kernels, Low-Level Libraries while at the same time ignoring the fact that Rust has superior ergonmics, higher-level zero-runtime cost abstractions, and a focus on safety, security, and speed that will definitely out-compete Go in the long run. Being “First” doesn’t make you the best (see C# vs Java).

            William O. B’Livion on 2017-11-14 at 13:28:44 said:

            Dude, careful. He’s got that look in his eye. Just smile and nod.

            >>>> What is this supposed to mean? It’s useless comment that adds nothing, defends nothing, responds to nothing.

            steve heller on 2017-11-13 at 11:28:23 said:

            “pointer management in C++ is just as dangerous and incredibly-error prone as C”?

            This proves that you know nothing about C++. Stick to topics where you have some knowledge.

            steve heller on 2017-11-13 at 20:51:14 said:

            The fact that you said “pointer management in C++ is just as dangerous and incredibly-error prone as C” demonstrates that you know nothing about C++. Automatic memory management via RAII is one of the MAJOR improvements of C++ over C. The fact that you have to know how to use RAII to gain these advantages does not mean that they don’t exist. Many people, including myself, do know how to do this.

            Thus, I can dismiss any further claims you make as being made by someone totally ignorant of the topic.

            Get it?

            Patrick Maupin on 2017-11-14 at 10:01:09 said:

            You’re not doing your chosen language any good with your poor reading comprehension and used-car salesman tactics.

            Gary Arnold on 2017-11-14 at 15:55:19 said:

            There is no replacing C for real time embedded development. Languages like Go and Rust have garbage collection which disqualifies them. C will live forever and will be used on nearly all new embedded projects and certainly all real time embedded projects (or C++).

            Questioning/Doubting Rust
            ————————-

            FrancisT on 2017-11-09 at 19:05:00 said:

            Looks like a good start. Although since it currently only supports intel CPUs it’s not going to work in embedded as it currently stands.

            >>>> Yeah, because things just “Stand-Still”. Again, this is assertion made from ignorance (in the truest meaning of that word) – that is, you are just misinformed because you haven’t bothered to research (as the below repsonse show)

            DEFENSE:

            silmeth on 2017-11-10 at 18:22:17 said:

            There is also Tock OS, designed explicitly for embedded. Seems it supports two ARM Cortex-M4 boards atm.

            Michael Aaron Murphy on 2017-11-11 at 21:13:06 said:

            Adding support for other processors isn’t difficult though. There’s just no need to do that at this time. Any platform supported by LLVM will be a possibly target with minor effort.

            Paul R on 2017-11-11 at 16:13:47 said:

            I disagree, C++ avoids the memory management and core dumping of C while allowing low level code to have a higher level of abstraction.

            >>>> So, C++ programs never have buffer overflows, pointer invalidation, stack breaking, never core dumps/segfaults? I think not. C++ suffer from the same kind of security issues due to a broken memory enforcement as C programs routinely do. C++ is definitely an improvement, but, it hasn’t solved the issue. Rust aims to solve the issue and they have made SUBSTANTIAL progress to doing just that.

            You should never see an allocation from new to a bare pointer.

            >>>> And yet, you see it in C++ code-bases all the time.

            New itself should be extraordinarily rare.

            >>>> Should be and IS are two entirely different things.

            People should be writing Linux kernel and driver components in C++, there would be fewer exploits left for the finding.

            >>>> This has been shown to be false by those who have tried.

            Anyway Go is interesting and Rust not so. C++ reaches up, Go reaches down.

            >>>> This statement says nothing meaningful or useful. It’s like the saying, “C++ is C on steroids”. Completely useless statement.

            The problem with C++ has always been that you can write C in it, but perhaps that’s why it has endured. It’s an imperfect world.

            >>>> Rust aims to make the imperfect world safer to operate in and make it a little more perfect.

            Questioning/Doubting C/C++ Alternatives (like Rust)
            —————————————————

            Stephen M Hernandez on 2017-11-10 at 14:54:06 said:

            Interesting opinion. Wake me when the Linux kernel is ported to something other than C or C++. Till then, I think it’s here to stay.
            Reply ?

            >>>> So this statement is immediately refuted with solid counter-examples – are you awake now?

            DEFENSE:

            Gerald E Butler on 2017-11-12 at 18:25:04 said:

            See “Redox”.
            Reply ?
            Michael Aaron Murphy on 2017-11-13 at 10:56:40 said:

            Yeah, Redox has already been done with Rust, so I guess C and C++ are not here to stay…

            Jay Maynard on 2017-11-14 at 01:08:09 said:

            I don’t spend my time looking around at all the weird and wonderful new languages people come up with. I spend my time writing code.

            >>> I hear ya brother! We’re all just trying to make a living, but, if we fail to consider new ideas and adapt, we become obsolete.

            esr on 2017-11-14 at 02:54:43 said:

            >And no, I have never heard of Crystal, Elixir, or Jai.

            I think another regular here would describe these as languages of, by, and for skinny-jeans hipsters. They’re cute, precious, not entirely devoid of good ideas, and self-consciously serving niche tastes. The designers tend to be from web-dev or games and boy does it show.

            >>> Yeah, I know it’s all the vogue to shank on the millenials and hipsters (“Get Off My Lawn!”), this kind of comment is useless and adds nothing of value to the discourse. Frankly, for someone of your stature I’d call it fairly pathetic and the only thing it shows is that you have aged into a position where you no longer adhere to the scientific method and instead fall back to criticizing the “Young’ans” because you have become intellectually lazy in your twilight. A little more introspection would be useful.

            Jay Maynard on 2017-11-14 at 21:13:57 said:

            Everything I’ve heard about Rust leads me to believe it’s the programming equivalent of Blender.

            >>>> What specifically have your heard? Have you read the docs? Have your followed the RFC’s and read the reasoning that has gone into things? What is it that your know? Saying you’re too busy writing code to research is fine, but, then really you KNOW nothing and if you were intellectually honest you’d admit that your lack of knowledge on the subject prevents you from make a rational evaluation.

            ADVOCATING C/C++
            —————-

            ams on 2017-11-10 at 08:28:30 said:

            One thing that I’ve noticed that I like in languages is having a very small syntactic universe from which everything else is built. Needing to know some gigantic vocabulary to get simple things done (and knowing where all that stuff is squirreled away) like in Java makes it infinitely harder for me. It’s absolutely horrifying if you *have* to know all this junk because you *can’t* do it naturally within the language.

            >>>> This is laughable. Java is an EXTREMLY small language. Few keywords. Minimal syntax. Everything is a LIBRARY. Java goes to pains to not add new features to the core language prefering everything to be a library as much as possible. NOTE: This is a similar philosophy to what Rust is doing. They are going to great pains to evaluate features critically to ensure the core language remains small while pushing as much functionality as possible to libraries. If you don’t understand this, you don’t understand the difference between language complexity and library complexity.

            Pingkai Liu on 2017-11-10 at 09:55:04 said:

            Apparently you don’t know C or pretend to do so even after 35 years of programming in C. The pain in software development is in most cases not debugging or dealing with hard bugs, but to layout the architecture in such a way so it can be done in a sensible way. This is hard for every programming language. C just does very little to hide that fact.

            >>> So, you admit that C does almost nothing to make the life of the programmer easier or more secure or reliable. The below responses pretty well answer your ill-formed conclusions.

            DEFENSE:

            Jeff Read on 2017-11-11 at 04:24:19 said:

            Then some language that forces you to do this is a must. And such a language just happens to be C.

            Being a minefield of safety issues and “undefined behavior” is not a feature. Rust also requires you to structure your program sensibly, and its compiler will catch you out if you fail to do so. The same cannot be said for most C compilers…

            Michael Aaron Murphy on 2017-11-13 at 10:55:31 said:

            > but to layout the architecture in such a way so it can be done in a sensible way

            With almost three years of experience in writing software in Rust, I can say that this is not really a concern with Rust. The compiler already takes care of ensuring that you construct your software with a good architecture. The type system and generics are also incredibly helpful when employing modern techniques like entity-component systems. C doesn’t help at all with anything of the sort. It doesn’t encourage good software architectures.

            SarahC on 2

            steve heller on 2017-11-13 at 11:27:20 said:

            Bad C++ programmers can do even more damage than bad C programmers.

            Good C++ programmers don’t have memory leaks, period. Even when there are exceptions thrown.

            Of course this requires using RAII properly, which in turn requires understanding how to do polymorphism without exposing pointers to the application layer.

            But it can be done. I know because I have done it.

            >>>> You statements boil down to, “I’m competent and can do stuff right, even though the language provides little in the ways of protections for me, but, everyone else who fails is dumb. I never fail.” The responses clearly demonstrate how your thinking on the matter could use a more objective and honest evaluation of the situation.

            COUNTER:

            Zygo on 2017-11-14 at 16:41:22 said:

            C++11 introduced shared_ptr, which finally solved a single problem with a single solution that was obvious (if limited in performance and applicability) since long before C++98.

            RAII and exceptions can get a single programmer down to somewhere near one crashing bug per year. I’m not sure where polymorphism fits into that…I guess if you use polymorphism in your C++ code, you should avoid breaking the other stuff with it?

            Plenty of other problems remain in C++ though, even after agreeing (and manually policing all source code ever written by anyone we ever work with) to abstain from using parts of the standard language.

            “Iterator validity issues” are the C++ name for what C calls “pointer bugs.” Just because you can’t see the pointers doesn’t mean they’re not still there, or that you can’t still dereference them after the referenced object has been freed.

            steve heller on 2017-11-13 at 20:40:49 said:

            In C++ it is very easy to assign a lifetime to an object, which is what people who understand C++ do.

            C != C++.

            >>>> C++ does not track “life-times” of objects beyond the local scope in the useful sense that Rust does. For some comparisons, see the following:

            https://www.youtube.com/watch?v=WQbg6ZMQJvQ
            https://www.youtube.com/watch?v=lO1z-7cuRYI
            https://www.youtube.com/watch?v=wXoY91w4Agk
            https://www.youtube.com/watch?v=9ev3xTDEhtw
            https://www.youtube.com/watch?v=oAZ7F7bqT-o
            https://www.youtube.com/watch?v=imtejBNbm0o
            https://www.youtube.com/watch?v=9wOzjbgRoNU

            Pro-Rust
            ——–

            Charles on 2017-11-08 at 16:52:44 said:

            Check out Redox OS.

            >>>> Nothing negative or offensive hear.

            Michael Aaron Murphy on 2017-11-13 at 14:28:53 said:

            Actually, the one in the standard library is majorly flawed in a number of ways, so Go is facing the same issue that Python is with having inadequate solutions shipped in it’s “batteries included” standard library, and superior solutions provided as third party libraries.

            >>>> Someone speaking from experience with all 3 languages. Not someone speaking from zero experience with the language being criticized. A useful and thoughtful comment.

            Michael Aaron Murphy on 2017-11-13 at 10:38:25 said:

            What are you talking about? Rust’s standard library is stable. Software that I wrote back in the 1.0 days and haven’t touch still compiles today with the latest Nightly; and both the standard library and accompanying officially blessed crates are more comprehensive than what Go has to offer.

            >>>> Rust’s standard library is in fact stable. The large ecosystem of crates isn’t necessarily stable, but, show me any language with a “stable” ecosystem of libraries that never changes and I’ll show you a dinosaur.

            Jeff Read on 2017-11-08 at 19:47:11 said:

            The bare-metal layer can be implemented in Rust, and thus, with 100% memory safety except in those cases where violating memory safety is strictly necessary (handled with unsafe blocks in Rust).

            >>>> Clearly, politely, and factually demonstrates that the misinformation around “Bare Metal” is false and that those who keep saying it are effectively sticking their fingers in their ears and going, “Nah, nah, nah, nah, nah….”

            Michael Aaron Murphy on 2017-11-11 at 21:48:21 said:

            There’s an increasing resurgence of interest in working at the lower levels, but with new systems languages. Primarily Rust, which has made working at the bare metal layer comfortably simple. It’s ridiculously easy to write your own kernel from scratch in Rust, or any kind of software, for that matter. Just take a gander at how far Redox OS has come along in two years, with largely a single lead developer, and a few regular contributors.

            >>>> Another POSITIVE comment, lacking attack on anyone or anything, that explains WHY you might want to consider Rust

            Michael Aaron Murphy on 2017-11-13 at 10:46:12 said:

            I actually rewrote a Python application in Rust[1] precisely because of how difficult it was to get it packaged with all of it’s dependency problems, and that the upstream developer and others commenting on the project were gearing up to ship it in a Snap/Flatpak to solve the packaging problems.

            With Python applications, you have multiple runtime dependencies that are pinned to specific versions of Python, which your distribution may not ship; and where your distribution may not even ship the required dependencies at all, so you’re forced to tell your users to manually Pip everything themselves.

            In the end, only took me three days to complete the project, and the final result is much more powerful than the original, with half the lines of code.

            >>>> Again, someone speaking from personal experience who has tried, used, and implemented in both. Useful comment.

            Michael Aaron Murphy on 2017-11-13 at 10:51:56 said:

            Why JavaScript instead of Rust? I know some people who write JavaScript[1] professionally, whom have told me that Rust is much easier to learn and develop solutions with than JavaScript, which is incredibly difficult to debug due to it’s complete lack of static type checking.

            As for packaging, all users have to do if it’s not packaged yet for their distribution, is to to type `cargo install package`, or `cargo install –git `. You may even distribute static binaries yourself. Rust uses Cargo for building and managing dependencies for a project, and pulls dependencies from Crates.io automatically. When compiling, these dependencies are statically-linked into the final binary, so there are no runtime dependencies at all.

            >>>> Clearly refutes the notion of distributing Rust software is more complicated than anything else. In fact, it demonstrates clearly that the opposite is true.

            Gerald E Butler on 2017-11-12 at 18:28:10 said:

            Why do you believe it couldn’t be done in Rust? What specifically prevents it?

            >>>> Nothing negative here. Just asking a question.

            COUNTER:

            Paul R on 2017-11-13 at 08:55:57 said:

            I think it’s possible in principle, (to create substantial Linux kernel components in Rust) but nobody’s doing it, as far as I can find, so it’s not a practical decision for a hardware supplier. Yet.

            COUNTER-COUNTER:

            Gerald E Butler on 2017-11-13 at 09:15:55 said:

            You should probably have a look at Redox to get a better understanding of what is actually being done with Rust. I’ve been exploring the Rust ecosystem, and the deeper I look, the more I feel, based on my 25 years of software development across many languages and paradigms, that they are on the right track.

            Gerald E Butler on 2017-11-13 at 12:24:13 said:

            And do drive home the point, these high-level features are almost all zero runtime cost abstractions (and even if they are not 100% zero-cost yet, like some formulations of iteration, that is the goal and they have a solid story of how they are going to get there).

            >>>> Nothing attacking or negative. Just pointing out the objective facts.

            Gerald E Butler on 2017-11-13 at 17:35:07 said:

            To be clear, you can write a rust library that exposes a C-FFI interface that can be linked to and consumed by anything that can link to and consume a normal C-library (with zero overhead). So, you can “today” build a Rust lib that can be a drop-in replacement for a c library that has all the safety advantages of Rust (internally) while exposing itself to the rest of the system as if it were a normal C library.

            >>>> Nothing attacking or negative. Just pointing out the objective facts.

            Ralph on 2017-11-15 at 15:20:23 said:

            I did find it amusing that, after responding here and spending a longish evening or two revisiting the Rust site and related areas to catch up on the state of its developmental growth, I opened my office browser the following morning to find it’s been upgraded to Firefox Quantum. :) Last night, I reinstalled the toolchain and started re-reading the manual.

            >>>> OK, so, here someone recognizes that there might be something worth looking into due to the OBJECTIVE FACT that Rust is being used in a security conscience application that has a large attack surface, is a huge target, and requires extreme performance, cross-platform (hugely), and extremely complex.

            Gerald E Butler on 2017-11-14 at 16:08:47 said:

            Repeat after me, “Rust DOES NOT have garbage collection. Rust has compile-time life-time tracking that has ZERO run-time cost.” If you aren’t going to bother reading up on and understanding Rust, you shouldn’t keep spreading complete misinformation. It really does make you look rather ….. (as they used to say in the military, “If the shoe fits, wear it!”)

            >>>> OK, here I may have been a little over-the-top. I could’ve probably left off the 3rd sentence. That being said, I think we all need to “Own our ignorance”.

            1. tl;dr — your protestations make it less likely, not more, that others here will seriously consider rust, because you also don’t understand the underlying concerns.

              When I said “You’re not doing your chosen language any good with your poor reading comprehension and used-car salesman tactics” that was because, in response to me, and after I explained that the sales job didn’t address my concerns, there were still “solutions” presented that still didn’t address my stated concerns.

              And it’s still that way. Your comment didn’t help either. Quantity is not quality. All you have done is muddied the water by cherry-picking crap you think supports your side and making it harder to figure out who said what when by grepping through the post.

              As far as everybody else’s comments, there were similar issues. The “look in his eye” comment was made after it was apparent that my concerns were being ignored, etc.

              If I were esr, I’d consider deleting your comment and the thread it rode in on, just to make it easier for everybody to follow what’s going on.

              1. To be perfectly honest though, if someone reading these comments decides to not invest in Rust, it’s not because of the comments, but that they were already snarling their nose at the idea to begin with. They were a lost cause to begin with.

                And in all honesty, we’d be better off without them causing drama in our community. Rust has already reached critical mass, regardless of what the naysayers in here have stated, and they aren’t going to stop it from it’s ambitions, either. We don’t need them for Rust to succeed.

                1. Let me get this straight: I was being very interested in Rust.

                  Then I read here and elsewhere that some people surrounding the language core/documentation are pushing some pretty out-there political ideas. (for instance referenced in earlier comment threads on this very blog)

                  But still I thought to myself: if I can expect professional behavior from those people I don’t have to pay any attention to their personal beliefs, because that’s what people in professional environment do.

                  And then I come and see all this drama. *Now* I am snarling my nose at the idea. No way I am going to invest significant chunk of my life mastering an ecosystem (and mastering C++ has been a significant chunk of my life) which seems to be overrun with drama queens. Companies/organizations led by perfectly logical business considerations are often led astray when those considerations turn out to be incorrectly weighted. (Nokia seems to be the most prominent recent example. But see also some recent decisions in Microsoft’s ecosystem; What’s going on with the WPF which has been a very large investment to learn?)
                  And if a not-insignificant part of the core is a cult? (what you said in your last paragraph is essentially “if you are not with us, you are against us”) Well that risk has just grown unacceptable in my opinion.

                  There are lots of things to learn and explore in this world and very little time indeed. If it is not immediately needed for my work, I am not going to study another WPF or a Perl5.

                  P.S. I actually want some language like Rust to succeed. I think C++ is overgrown abomination with some bright spots and a modern system language is sorely needed. But at this point my heuristic tells me studying Rust is not a worthwhile investment of my time. This thread actually lowered that estimate somewhat.

                  1. Replying to myself just to explain why I consider passionate drama + politics to be a bad combination in a technical community: They seem to foster ideal conditions for witch hunts, and while it’s fun to watch, it’s much less fun to be on the receiving end of one. Also they are usually destructive to the community as a whole. I think you’ll find plenty of examples in technical community as of late, even very close to home.

                    1. I fail to see where there is any drama in this thread from Rust supporters. The opposite is in fact the case. As your post demonstrates. Your post is nothing but a huge stinking pile of “Drama Queen”. For christs-sake, look in the friggin’ mirror! The tone of the anti-Rust crowd is abominable. No, I am not part of Rust. I’m just interested in it. I pointed out above all the unfounded, negative, Ad Hominem crap that has been posted (not by the Rust supporters). Your post is more of the same. You are attacking what you perceive as some sort of threatening philosophy instead of debating the merits. I would never in a million years want to work with you in any professional capacity if this is the way you approach a debate. It truly is pathetic.

                    2. @Gerald E Butler: replying to myself since apparently this exceeds WordPress’s threading limit.

                      >> Your post is nothing but a huge stinking pile of “Drama Queen”. For christs-sake, look in the friggin’ mirror!

                      Cute. Posting after that the claim that it is *I* who invoke ad-hominem attacks, that is.

                      >> I pointed out above all the unfounded, negative, Ad Hominem crap that has been posted (not by the Rust supporters). Your post is more of the same.

                      So where is the Ad Hominem crap in my post? Care to look in the mirror yourself? That’s called projection.

                      >> I would never in a million years want to work with you in any professional capacity if this is the way you approach a debate. It truly is pathetic.

                      More ad hominem. Here is one for you – you sure are a sunshine to work around.

                  2. You and Murphy both ignore context, make inflated claims, and then get snarked. If you consider that the drama starts at the snark, you’re right. Some of us consider that the drama starts when the conversation goes off the rails because of the ignored context. E.g., in your case, conflating linux driver development with redox systems-programming.

                    Some of us also feel that if somebody spends the time to make a really long-winded comment that mainly consists of previous comments, and that new comment doesn’t show to everybody else what the commenter believes it does, perhaps the commenter should have used that time instead to reflect on what the other commenters were thinking when they posted, instead of just blindly cutting and pasting so he can shout “See! We’re not the problem! You’re the problem.”

                    But that’s obviously unlikely to happen here. I think we can all agree on that.

    2. People harking that Rust is not ready haven’t truly given Rust a good look. There is no software that you cannot already create with Rust today. The only things happening at the moment are things like NLL that make Rust easier for newcomers to learn, or the stdsimd project which is about to make SIMD available in stable Rust. Changes made to Rust at this time are made in a backwards-compatible manner, and are purely done for convenience reasons.

      I think you’ll find Rust leads to much more compact, concise, readable code than Python, so you should certainly enjoy using it as a replacement to Python, in addition to C/C++. I’ve rewritten some Python projects in Rust, and have been able to make significant LOC reductions and QoL improvements over the Python counterparts. A 1500 line Python project can easily be shortened to about 300-600 lines of Rust.

  46. There is no replacing C for real time embedded development. Languages like Go and Rust have garbage collection which disqualifies them. C will live forever and will be used on nearly all new embedded projects and certainly all real time embedded projects (or C++).

    1. Rust doesn’t use garbage collection. It uses static analysis and there is no additional runtime overhead.

    2. Rust uses compile-time reference counting, similar to what C++ is doing, only much more sophisticated in additionally providing lifetime annotations, move semantics by default, and a borrowing and ownership system that makes a distinction between immutable and mutable references. It does not have a runtime garbage collector, nor a runtime in general.

      Rust is just as low level as C, and can actually produce more optimized machine code than C, due to a greater volume of compiler information. The compiler backend doesn’t currently take advantage of all of this information as of yet though. Namely, due to the borrowing and ownership model, Rust can eliminate pointer aliasing. A future LLVM update will finally enable this optimization soon.

      Rust also offers generic types like Arc and Rc, which offer the capability to wrap types within atomic reference counters, or simply reference counting in general. Useful in areas where it’s not possible to determine, at compile-time, when a value should be dropped. You’d use similar tools with C and C++, only their solutions aren’t quite as easy to use.

  47. Repeat after me, “Rust DOES NOT have garbage collection. Rust has compile-time life-time tracking that has ZERO run-time cost.” If you aren’t going to bother reading up on and understanding Rust, you shouldn’t keep spreading complete misinformation. It really does make you look rather ….. (as they used to say in the military, “If the shoe fits, wear it!”)

  48. Aha, haha. Sorry, but I read this a few days ago, thought “hmm, seems pretty slanted / misrepresenting Rust”. I then read the older blog posts on the topic, started writing a reply, but on rereading this post before sending off mine, saw how the picture drawn of Rust had mellowed, and so I mellowed as well.
    But today I landed at the “friends of Rust page” (companies using Rust) – https://www.rust-lang.org/en-US/friends.html
    And after browsing through that, the statement “an awkward youngster that might complete successfully in a few years” came across as a total joke (honest, I was chuckling about it :P). But I guess its really hard to admit you’re wrong.
    ——————-
    P.S. I like to note that I didn’t read all the comments above. And maybe I shouldn’t have bothered either, seeing that in effect its adding attention to what, in the end, is a totally irrelevant blog post…

  49. poor you. you have been working in C for the half of your life and never even liked C.
    nobody’s stopping you, say goodbye.

  50. How did you find error handling of Go? I guess it is similar to C (return codes), but I personally, was surprised that they didn’t go with exceptions or something similar.

    Now error handling in Go seems to be very verbose and redundant (printf returns an error!).

    Anyway, what’s your take on this?

    1. >Anyway, what’s your take on this?

      Initially rather negative – I was used to Python and wanted my try/except back. I’m making my peace with it now, because Pike’s grumpy-old-man arguments against nonlocal returns are (alas) quite sound. As I get used to Go’s idioms I’m less and less bothered by it.

    2. Go’s double returns have to allocate for two types when returning, rather than just one. It’s completely disregarding sum types, pattern matching, and tuples that everyone else is doing to solve the problem. You are forced to have your return type as a tuple pair.

      And it very much completely annihilates code readability by introducing a massive degree of verbosity which cannot be abstracted cleanly. What Rust is doing with the early return operator (?) and the Result enum is fantastic in comparison.

      1. > And it very much completely annihilates code readability by introducing a massive degree of verbosity which cannot be abstracted cleanly. What Rust is doing with the early return operator (?) and the Result enum is fantastic in comparison.

        A matter of taste. I like Go precisely because error handling is done via big honking if blocks. It’s nice having your returns, especially error returns, be as visually explicit as reasonable. Exceptions are the worst in this regard, but Rust’s teensy weensy question mark operator is only slightly better.

        1. Java had (still has…) Checked Exceptions but after some time community has learned that it is cumbersome and doesn’t provide any guarantees that they were supposed to (no unexpected returns). In the end, everybody seemed to use some GeneralException type or just RuntimeException to avoid either breaking APIs or doing plenty of try {} catch to pass it up.

          I was surprised that after this, somebody decided to reintroduce basically the same mechanism.

          1. Aren’t checked exceptions orthogonal to the problem? They provide (compile-time) guarantees about the ways a function can fail (and that such failures eventually get handled), but no visual indication of where it might fail. “throws SomeException” in a function’s signature doesn’t tell you where (or even if) the function actually throws it.

            The charge of reintroducing checked exceptions applies better to Rust: as its errors are concrete types, you need to enumerate all the ways your function can fail in its signature. (It does dodge the worst irritant of checked exceptions – that new error types ripple up into the signatures of calling functions – by the ability to encapsulate error type sets behind enums, however.)

            1. >guarantees about the ways a function can fail (and that such failures eventually get handled), but no visual indication of where it might fail

              For me, it looks like the same holds true for Go – you know that function can return an error but where it actually happened, you can’t know (when each statement has “if err != nil”, it might have been just passed up from somewhere way below).

              Actually, with exceptions you have at least a stack trace and you can track down the actual source of the problem.

              1. >(when each statement has “if err != nil”, it might have been just passed up from somewhere way below).

                If that actually happens to you, you are writing very un-idiomatic Go. If a function gives you an err, doctrine is to do something visible with it right away. The point of that part of the design is to make it natural to do something that is not passing the error up the stack.

              2. The topic was code readability, so I was just concerned with the ability of a reviewer to quickly and easily identify the potential exit paths from a function. Exceptions hide them. But I acknowledge that you get easy and free context to aid in debugging in exchange.

  51. Python has one brilliant idea. if the code is not formatted properly it does not work. you can understand Python procedural code without any experience. it’s a good tool. the rest of it is so so.

    as Doctor Locketopus pointed out, JavaScript is superior for functional programming.

    C does not benefit you to program in object oriented of functional fashion but it does not stop you either. you can structure you code and modules to follow any fashion, even functional programming. remember that in C passing by value is default. Dennis Ritchie made it that way, no matter how many “experts” were doing passing by reference in the past years.

    compare that to programming languages that force you to do it object oriented or functional. Java, Haskell…

    sure it’s pain to do run-time polymorphism via pointer tables in C, but if you want to solve a problem in that fashion you’d better use C++ or do it in C some other way. any given problem can be solved even in FORTRAN 77 or COBOL.

    you can mix C and assembly, that’s a plus. doing it with Lua is easy.

    what to say of the number of additions and new versions those cool languages had to go through just to be capable of something? if that’s not duct taping i don’t know what it is.

    i constantly hear it, “we cannot do it in Python 2.5 we need Python 2.7”, so Python 2.5 was a joke?

    why is that so? because C gives you the alphabet so you can construct any sentence, languages like Java give you pre-baked phrases and words. with each new version, more and more of it so you can express your self, but never say freely what you want.

    in the past 30 years in C i only missed compound literals and even without you can do it without a problem.

    and if… only if, the C preprocessor could have been made to support some of the LISP constructs, C would have been the language to end all languages.

    ask your self’s just one thing. in all those people who made those beautiful languages (Nim, Jim, Shim… you name it. Phython, Ruby, Java… ) how many are on the same level of intellect with Dennis Ritchie??

    1. >>> any given problem can be solved even in FORTRAN 77 or COBOL.
      Worth remembering that any given problem can be solved in any language that can implement a Turing machine. A single instruction is sufficient. Think of the language wars that avoids.

      There’s an enormously long post up thread that quotes me and appears to make unsupported assertions. But I can’t be arsed.

  52. >(if you know enough formal logic going in the only big deal about it is monads, and those are actually a lot simpler than the (arguably misapplied) mathematical terminology around them makes it sound.)

    Interesting. All of monads’ explanations I’ve read so far were written using such mathematical terminology. (actually, I don’t know if other explanations have been written in the last year or so…) Would you write someday a sort of monads’ tutorial using another, simpler terminology?

    1. >Would you write someday a sort of monads’ tutorial using another, simpler terminology?

      Not a bad idea…after I get about a kerjillion other things done.

      1. Best definition I’ve seen so far… And I’ve read a lot of them.

        “So what is a monad? Well, it’s a design pattern. It says that whenever you have a class of functions that accept one type of thing and return another type of thing, there are two functions that can be applied across this class to make them composable:”
        – There is a bind function that transforms any function so that accepts the same type as it returns, making it composable

        – There is a unit function that wraps a value in the type accepted by the composable functions.

        From here -> https://blog.jcoglan.com/2011/03/05/translation-from-haskell-to-javascript-of-selected-portions-of-the-best-introduction-to-monads-ive-ever-read/

  53. Arduino programming is technically C++, not C. Most Arduino developers don’t use any of the object-oriented features although a few libraries do.

  54. I only just recently heard of Rust, but I have been writing Rust in C++11 for years, ever since C++11 came out. But I have been doing it manually, which is mistake prone, while rust does it for me.

    Rust is C++11 with correct use of C++11 enforced and made automatic. If Eric found Rust strange and alien, he has not been using C++11 correctly. Or perhaps not been using C++11 at all. The gcc and g++ compiler defaults to C++98, which breaks everything I write.

    Of course if someone has code that writes around the C++98 bugs, missing features, and misfeatures,I suppose that C++11 will break everything he writes.

  55. from Firefox 57: Some of the rebuilt portions are even using Mozilla’s new Rust programming language, which is designed to offer improved security compared to C++.

    well some of it… maybe it needs time. if was inventor of programming lang X i would do all my coding in X.

    never trust a bald barber.

  56. @vasko: “from Firefox 57: Some of the rebuilt portions are even using Mozilla’s new Rust programming language, which is designed to offer improved security compared to C++.”

    well some of it… maybe it needs time. if was inventor of programming lang X i would do all my coding in X.

    “Some of it” is not a surprise. There’s an enormous C++ code base. Mozilla is rewriting in Rust, one part at a time. If they waited till everything had been rewritten in Rust what is currently FF v57 likely wouldn’t be released till sometime late next year.

    What is now in Rust is a good chunk of the new Quantum rendering engine. About 160,000 lines of C++ got replaced by about 85,000 lines of Rust. Mozilla is claiming major speed increases, based on benchmarks. I have both Firefox ESR as production browser and Firefox Developer’s Edition with a test profile to track progress on Quantum and other things like Add-ons. FDE seems a bit faster, but the differences here are not dramatic. (As a rule, you are as fast as what you connect to. Folks like me with relatively fast broadband are more likely to notice speedups than folks still on DSL or satellite. It may render faster, but it needs to have pages to render.)

    I have mixed feelings about Mozilla throwing out the baby with the bathwater, and writing a brand new rendering engine in a brand new language, but they are doing it a piece at a time.

    >Dennis

    1. I would like to see about 160,000 lines of C++ replaced by about 85,000 lines of C, but better Rust than nothing.

  57. So after taking some time to read through this thread, instead of blurting out the first thing that comes to mind (which I did, and do not regret) … :)

    It seems that there are a lot of different people with a lot of different opinions on what features of C are important to have in some next-generation systems programming language. And everyone has a different opinion.

    I can think of one language which covers 100% of the C use cases. It’s called C.

  58. 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 C’s will fail. CS history is littered with the corpses of academic languages whose authors did not grasp this necessity.

    I love Perl dearly, and resent that due to its slow demise I am being forced into Python. I would love to read a post titled “The Harsh Lesson of Perl” that expands on this.

    1. What do you see as the signs of its slow demise? I only use it for small (< 2000 lines) personal projects, not as part of a development team, so I might not have a very good view of the big picture. But the occasional bug I find gets addressed quickly, and I can pretty easily get questions answered in robust perl forums, which are the main things I care about. If new releases aren’t coming out as fast as they used to, that suits me, because the language as it stands pretty much does what I need it to do. (I admit I gnash my teeth every time I get rebuked about variable-length lookbehind, but I do understand why it’s a hard problem to solve and why perl provides different ways to achieve similar functionality rather than implementing the idiom I tend to write first.)

  59. What about Ada programming language, why doesn’t that get more used?
    Is the main reason over-verbosity?
    If yes, why doesn’t someone create a language with same semantics as Ada, but much less verbose?

Leave a comment

Your email address will not be published. Required fields are marked *