Death to C - <AUTHOR> http://techcrunch.com/2015/05/02/and-c-plus-plus-too/ <comment><USER2> I'm sorry, but as a user and hacker of UNIX, POSIX and all things GNU/Linux since 1996 I have to say this is just fruitless and counter-productive. Although, I will support the sentiment "Death to C++" :-)

The argument is over-simplified and rather than looking to the root of the problem tries to sweep it under the rug by also ignoring the fact that many new languages have their interpreters written in C. The root issue is that the C language needs an update, an overhaul, and that once the standard has been refreshed, C will continue to be the #1 language among programmers.

Sadly, nothing can be done for C++ and to lump C and C++ together is as upsetting as calling for programmers to cease the use of C! :-)

Last thought: There needs to also be more focus on teaching programmers how to write secure C programs. Every year new exploits are released that target insecure C programming styles, and the C community should make sure programmers are being educated on how to avoid these issues. Look to subsets like MISRA C as an example and a move in the right direction; advocating secure programming/language subsets rather than changing languages ultimately makes more sense.

<comment><USER3> MISRA is a bloated mess from the accounts I've seen, no doubt to encourage paying for it. If u remove all the filler and padding the substantial part may be 40 rules.

There should be a new C that obviates the substantial parts of MISRA.

<comment><USER4> In my experience, the major problem with standards like MISRA is that people read the rules, but rarely the rationale behind them, which makes every coding standard end up _encouraging_ cargo cult bug avoidance.

Case in point: MISRA C forbids goto statements primarily because it can mess up static analysis. Yet this rule is gratuitously followed even when no static analysis tools are used, thus yielding none of the gains that you trade off for occasionally writing ugly code.

<comment><USER2> The intent with standards like MISRA C is actually to be a reference point against which certifiable audits can cite companies for infractions. That is, the standard is no good as you note, unless a desired industry certification is only attainable for a company if an audit demonstrates the programmers are indeed following the rules.

Otherwise, you're right. The value goes out the window without enforcement, without compliance.

<comment><USER4> Absolutely. If you're audited for MISRA compliance, you need to follow it point by point.

The rules themselves are not meaningless or without a point, but there are a lot of companies that adopt MISRA without actually _having_ (in the sense of audit and certification) to be compliant. Instead of focusing on _the point_ of every provision, they rigidly follow them even when not applicable.

But it can be worse, really. The gem of a coding standard we have at $work forbids not only goto, but also break, without MISRA's exception of one break per loop. And forbidding the use of goto and continue is cited as being done for readability reasons, rather than static analysis tools.

</comment></comment></comment></comment></comment><comment><USER5> You're not going to convince C programmers simply by beseeching them. The article is missing an entire component: the argument for Rust. There needed to be examples of C programs that one may write that are actually unsafe and of how Rust addresses that. There needed to be a discussion on the performance of Rust, and of its ability to call into C without overhead (or to be called by C without overhead). Everyone already knows what the problems of C are, what they need to know is what the alternatives offer and how in the end you are not giving up too much.

<comment><USER6> I really like the promise of Rust. I mostly like its design.

But, for myself, I notice this: Writing Rust programs (vs. writing C programs) correctly is _hard_!

N.B. This might be an old dog new tricks thing.

I automatically structure my programs (be they rendering engines, or computation/numerical simulations or even agent-based simulations) where allocating and freeing memory from/to pools just isn't that hard. I don't really think about it. I just throw together my code, compile it and run it.

Of course, I make many (many!) silly/stupid mistakes during the course of development, but failing to free a pointer is rarely one of them.

Now I loop back to your point. (Sorry I took the long way)

> Everyone already knows what the problems of C are, what they need to know is > what the alternatives offer and how in the end you are not giving up too > much.

I know what the problems of C are. I am aware of the alternatives. But the problems of C don't seem to be overwhelming enough to bother throwing away and constructing an entirely new tool-chain and support system on whatever your platform is.

That was a pretty bold statement, and I would invite a response.

I would like to think that we, as an industry, are not just implementing new language ecosystems because we can't be bothered to free our pointers...

<comment><USER7> _> Writing Rust programs (vs. writing C programs) correctly is hard!_

To be clear: getting Rust programs past the compiler is much harder that C programs: C doesn't incorporate much type-system/static checking so a lot more gets past the compilers. But writing truly _correct_ C programs (i.e. don't crash horribly) is a harder task, as there's no computer assistance for avoiding large classes of possible bugs.

 _> failing to free a pointer is rarely one of them_

 _> we can't be bothered to free our pointers_

Solving this "problem" is not the goal of Rust. Rust aims to avoid undefined behaviour by default, e.g. derefencing invalid pointers, use-after-free, iterator invalidation are statically ensured to never happen, unless you opt- in at specific locations via `unsafe`. Cleaning up memory automatically is a nice feature, but the main draw card and the reason Rust might actually be interesting is that Rust offers memory safety without garbage collection.

In any case, I think you're being overly glib about the problems of C: it's so so easy to have a program that exhibits undefined behaviour, and so is theoretically operating with no restrictions.

<comment><USER6> > In any case, I think you're being overly glib about the problems of C:

In short form, here, without a doubt.

> it's so so easy to have a program that exhibits undefined behaviour, and so > is theoretically operating with no restrictions.

I've run into this. A lot! It was almost always my fault. One notable exception was back when I used to do a fair amount of with GP (Genetic Programming -- evolving large populations of small programs). The system was shockingly adept at finding/exploiting edge-cases and exploiting them for advantage.

</comment></comment></comment></comment><comment><USER8> Well, there's Go.

Java was supposed to fix all of these problems, but it's a mess in its own way. There's no perfect language.

Almost simultaneously with C the Pascal language was introduced, completely safe and easier to learn. It enjoyed a period of popularity, and for a while it was widely taught in high schools and universities. Some big systems were built in Pascal, but every big Pascal app I've ever seen relied on external code in C (or assembly language) because Pascal is hobbled to enforce safety (see Brian Kernighan's article "Why Pascal Is Not My Favorite Programming Language, [http://www.lysator.liu.se/c/bwk-on- pascal.html](http://www.lysator.liu.se/c/bwk-on-pascal.html)). Some of Pascal's faults were fixed in Modula and Oberon but those never got any traction.

To be absolutely safe the language is either crippled so it's missing important features, or it requires a runtime to sandbox everything, check pointer references, do garbage collection, etc. And that slows things down.

I don't see C going away any time soon in embedded software, which is where bugs and vulnerabilities can be most dangerous and where they are hardest to fix. It's not much of a disaster for a video game to crash, but it can be very bad if piece of hospital hardware or a flight control system has a latent bug.

There are tools that can analyze C code both statically and dynamically -- the language is not just old, it's mature.

I'm sure someone is already rewriting the Linux kernel and all of the Unix-y tools in Rust or Go or whatever. I won't hold my breath.

<comment><USER9> > _Well, there 's Go._

Not for the things C is good for. OS work, drivers, common libs like OpenSSL callable from other apps, infrastructure work, etc.

Besides Go is nothing new. There have been similar languages ever since 1970, and they are not replacing C.

<comment><USER10> Agree, better shout out would be Rust. Also referring the complete interview[1] which the TC article quotes, which seems to be favouring Rust.

[1]. [https://www.codementor.io/rust/tutorial/steve-klabnik- rust-v...](https://www.codementor.io/rust/tutorial/steve-klabnik-rust-vs-c-go- ocaml-erlang)

<comment><USER11> Two things: First, I'm on the core team, so I obviously have bias. I try to remain as objective as possible at these things, but still. Second, that interview was from October. Not a lot has changed, really, but it is an eternity in Rust-time.

<comment><USER12> Question for you, sir. When folks like you and the rest of the team set about making a new programming language, is it ever with the new programmer in mind? Or is your primary purpose to fix a shortcoming in another language, and as such, you're not really thinking of the beginners?

The reason I ask is because I went to look at the docs for Rust, and they still seem incomplete.

As someone on the outside looking in... I'd have a hard time recommending Rust over C, because the learning path isn't complete yet. C is extremely well- documented. I want to learn Rust, because it's the new hotness, but it seems difficult to do _right now_.

That said, I'm very curious to hear your thoughts on this.

Also, if you have advice on how best to learn Rust, I'd love to hear what you have to say on that. My professional experience has been almost entirely with scripting languages, and nothing more low-level than that.

<comment><USER11> > is it ever with the new programmer in mind?

New programming languages are almost never designed with the new programmer in mind. I've spent a _lot_ of time teaching people to program, and they all have really serious hurdles. There are some good projects in this space, but they're a very, very tiny minority. Don't underestimate how hard "Hello world" is, which is actually something that that PDF I linked points out.

> they still seem incomplete.

Can you elaborate on this, with specifics? It'd be really helpful.

<comment><USER12> I created a video with ScreenFlow.

[https://www.dropbox.com/s/vuax1ocki846llu/rust_example.mp4?d...](https://www.dropbox.com/s/vuax1ocki846llu/rust_example.mp4?dl=0)

Downloading and installing Rust, no problem. Then I tried doing the "Hello, World!" example. Pretty sure I had it typed right in vim. It didn't work.

Then, I typed it in Sublime Text, it still didn't work. Then I thought, I forgot to set +x on the file, and I remember I hadn't set anything on the shebang line in the file, so I went on in the docs.

As you can see... I got to the "Learn Rust" page, and it wasn't ready yet.

<comment><USER11> Thanks for making this! It was _very_ instructive.

First of all, I submitted a patch to remove that link to the old intro this morning, so that should go away.

Second, the issue was that you compiled the program, which worked just fine, but you never ran it! on [http://doc.rust-lang.org/nightly/book/hello- world.html](http://doc.rust-lang.org/nightly/book/hello-world.html) , the example shows:

        $ rustc main.rs
        $ ./main # or main.exe on Windows
        Hello, world!

You did the rustc, but not the ./!

As for "Learn Rust", that's one of two paths through the documentation, as the first page of the book mentions. I've been focused on the "Syntax and Semantics" section, which is the other path. "Learn Rust" is coming over the next two weeks.

<comment><USER12> Now I see that there was an "hw" file, now. I ran it and got the desired results. Should have paid better attention.

Hopefully, the instruction was more than, "Wow, this guy is a bonehead." :D

I think some mindset changes are needed here, in that I'm used to dealing with interpreted languages, rather than compiled ones.

<comment><USER11> It's all good! Seriously, I've taught tons of people to program, and the beginning is the hardest part.

Yeah, the two-step process is different. In the next setup section, when Cargo is introduced, you end up with a 'cargo run' command that does the build and runs your code in one step.

</comment></comment></comment></comment></comment></comment></comment></comment></comment></comment><comment><USER13> Rather than "death to C" a better viewpoint is: minimize our use of C _and anything that looks like it_. We don't need a better C, in which to write mega-projects.

There is a parallel here in assembly language. Once upon a time, programmers extended the viability of assembly language by building smarter assemblers with powerful macros and such. None of that is necessary if you minimize your use of assembly language, so that all you have in your system that is in assembly language is a few atomic instructions, some context saving/restoring code, interrupt dispatch, and a speedy memcpy and whatnot.

Going from C to Rust (or Go, or C++ or whatever) is kind of like trying to use a deluxe assembler to write large assembly language programs with better reliability.

If I'm going to leave C behind for some task, it's because I want to get away from _that sort of_ semantics---any version of that semantics.

</comment><comment><USER14> I personally don't see Rust as a good replacement for C - it's too complex a language, and it is especially easy to loose sight of what is happening at a low level due to all of the abstractions.

Even if you did decide to use Rust instead of C in C's typical domain - operating systems, drivers, and constrained resource devices - you would be forced into using "unsafe" blocks anytime you had to interact directly with the hardware, manually manage memory, or issue ASM commands; at which point you're as vulnerable to programming mistakes as C.

<comment><USER15> Not necessarily as the idea is to isolate those components into the unsafe blocks, and having locality on a bug is a pretty big component of fixing it.

<comment><USER16> Well, that's locality on what in theory could be causing a bug, but not on where it might manifest, i.e. a wild pointer trashing data maintained by purely safe code.

Still, in theory isolating the possible causes is a fantastic advantage.

</comment></comment></comment><comment><USER17> The C ecosystem has tools designed to compensate for its issues. There's valgrind, static analysis, debuggers, asan, tsan, etc.. With its immense popularity, its flexibility and portability, and its mature, comprehensive ecosystem behind it, there's no all-purpose programming language better than C (expect maybe C++).

</comment><comment><USER18> Rust people, please don't screw up. We desperately need a replacement for C. Rust could be it. But it's not too late for the Rust crowd to blow it. Rust may have too much cruft at version 1.0 for C programmers.

Things that worry me about Rust:

* Too much mandatory metaprogramming. Basic things such as I/O require generics, and even lambdas. Rust's cruft level in this area picks up where C++ with Boost left off.

* Error handling is too verbose. Wrapping things in "Result<>" and "Some<>", then unwrapping them with "match" is wordy. Wrapping that in generics makes it shorter but hides what's happening.

* The type system and type inference are very complex, and type errors induced from another module can be hard to diagnose.

* Too much language churn. Supposedly "stable" modules still keep changing. I'm surprised when I recompile a program after a few weeks and it still works. This needs to settle down very soon.

* Resource Allocation is Initialization. Initialization isn't that bad, but what do you do about an error discovered in a destructor? Destructors are always troublesome, and Rust doesn't seem to have that area under control. A "with" clause approach would have been cleaner. The recent discovery of a soundness problem in Rust destructors is being handled in a way that bears watching. First, the actual issue reporting the problem was closed without a fix.[1] The discussion was "moved to an RFC" so as not to block the release of Rust 1.0.[2] Related issues are now being discussed to death. A good discussion of the issue is at [3].

While Rust avoids complex run-time abstractions, it has very complex compile- time abstractions. Rust has all the cool abstraction ideas - closures, generics, templates, type inference, RAII, functional programming, etc. This may be too much for the C crowd. The basic libraries use all these features, so you can't restrict their use on a project.

[1] [https://github.com/rust-lang/rust/issues/24456](https://github.com/rust- lang/rust/issues/24456) [2] [https://github.com/rust- lang/rfcs/pull/1066](https://github.com/rust-lang/rfcs/pull/1066) [3] [http://smallcultfollowing.com/babysteps/blog/2015/04/29/on-r...](http://smallcultfollowing.com/babysteps/blog/2015/04/29/on- reference-counting-and-leaks/)

<comment><USER19> I understand your anxiety on the complexity of Rust. I wonder if there were a language that fixes exactly the pitfalls of C (e.g. sane string manipulation), without adding any high level concepts, but with memory safety.

However, at the same time I think the language researchers cannot help but add abstractions on today's languages. The unusual exception was Go, but it failed to target the same niche as C/C++ at the end. Actually I think there are more people who like abstractions than those who like the extreme simplicity of C. So unfortunately, a "direct" replacement of C will not happen in the foreseeable future, I think.

<comment><USER18> It's not bad that the language has those features. It's that their use is so deeply embedded in the libraries that all Rust users must understand them to do anything. It's a big jump in abstraction for C programmers.

<comment><USER19> Indeed! That's why I'm still not used to Haskell. While I can do simple things with the language, the abstractions made by the popular libraries written in Haskell require me to understand a certain concept to use them properly.

However, while the feature complexity can be avoided at least in the standard libraries, I think that's a more general (possibly cultural) problem, considering a Rust developer will have to use any libraries other than the standard libraries at the end.

I believe that's why the Go designers are so wary of adding new features to the language. If there's a feature, library writers _will_ use that feature. Nothing can prevent this.

</comment></comment></comment></comment><comment><USER20> Yeah. "Stop using PostgreSQL and Redis. And Linux." Then these people usually go on to describe a completely different problem domain, it used to be something-lisp and now it's ruby-whatever.

Problem is, sooner or later you need to be using the operating system for something more than just starting processes, be it controlling file handles or sandbox code or whatever. Then you need API compatibility and control over your mallocs. Which isn't impossible in non-systems PLs, but it isn't exactly a walk in the park either, as you're basically left calling wrappers for syscalls instead of doing it directly, which means you have master both your runtime _and_ your C-based operating system.

At least this time they have an answer that's at least worth listening to. The newest crop of languages with Rust and Go actually make an effort towards system programming. That excites me! Now all you have to do is make something as secure and robust as Redis or Postfix, and let's see how it fares in production. And if Servo grows to be a fully grown competitive web browser, applying binary deltas to itself, sandboxing GL code, and everything in between, that would be a great litmus test for Rust to actually compete with C++.

<comment><USER21>
       >  And if Servo grows to be a fully grown competitive web browser

From what I hear Servo is a research project. There exists a great chance it will never become a fully grown web browser.

It already started sandboxing some code, but I'm not sure what binary deltas have to do with massively parallel web brwoser.

</comment></comment><comment><USER22> So for a mission critical or safety critical system, what's the alternative? It looks like the options are:

        1, assembler
        2, C + validated compiler + static verification + coding standard (MISRA-C maybe)
        3, C++ + validated compiler + static verification + coding standard (MISRA-C++ maybe)
        4, Java + specialized VM with RTSJ + static verification + coding standard (RTSJ)
        5, Ada/SPARK + ???

So really, C/C++/Java/Ada aren't being used alone, it's the language + validated compiler + verification tools + a coding standard that are being used.

How are Haskell, Rust, Go, and whatever other nouveau language of interest to the HN crowd tenable options for serious work when they lack the ecosystem of a formal standard, validated compilers and verification tools, track record, etc.?

</comment><comment><USER23> I'll confess, I have looked ever-so-briefly at D and Go and I figured that Rust was probably similar to Go but I just didn't take the time to learn about it. I like the idea of D (especially design-by-contract), but I have difficulty convincing my colleagues (and myself) that a product with a garbage collector can perform consistently well enough.

Then I read this in TFA:

> Despite guaranteeing memory safety, Rust does not have a garbage collector > or runtime, and one of the benefits of this is that Rust code can be called > from C with no setup at all.

Maybe I should think about it as "you always enable ASan in your production binary"? That suits me just fine, if that's one of its major benefits. I will resolve today to follow up on Rust and try to learn more about it.

<comment><USER11> Most of Rust's safety guarantees are at compile time, not at runtime, and so have no runtime overhead. ASan's docs claim a 2x slowdown.

That said, defense in depth is always nice. kmc got AFL working with Rust recently, and it's uncovered some things. Using an ASan-like tool to do some of the runtime stuff would be great to have.

<comment><USER23> > uncovered some things

Those were problems with the rust compiler or the binaries it generates?

<comment><USER11> Three things so far. Two in the parser, one in generated code:

\- [https://github.com/rust-lang/rust/issues/24276](https://github.com/rust- lang/rust/issues/24276)

\- [https://github.com/rust-lang/rust/issues/24275](https://github.com/rust- lang/rust/issues/24275)

\- [https://github.com/rust-lang/rust/issues/21889](https://github.com/rust- lang/rust/issues/21889)

</comment></comment></comment></comment><comment><USER24> The whole fallacy with articles like this is that they all too often show why a language is unsuited for some subset of tasks and then proclaim "death to $LANGUAGE." There's a time and place for C, and while writing a web framework is probably not that place, I think for embedded C is going to be around for a while.

Sometimes you need to do things that could potentially cause problems (like every single pointer dereference) because there are deadlines for things to happen. If DMA had to check whether the place it's about to write the next 4 sample from the ADC is ok every single time, you might very well miss it

</comment><comment><USER25> I'm sure C will be still going for a while yet in embedded development ... microcontrollers, etc. There's usually no other option except assembler.

<comment><USER11> While this is true for many embedded platforms, if it's an architecture that LLVM knows about, you can use Rust on it. That said, many have just a proprietary C compiler, or something similar for a barrier to entry, it's true.

</comment></comment><comment><USER26> Hardware level approaches to making C more secure are in the works at Intel. Hardware assisted bounds checking and the like...[http://en.wikipedia.org/wiki/Intel_MPX](http://en.wikipedia.org/wiki/Intel_MPX)

The main thing that will finally convince people that a high-level of abstraction is OK for OS level programming is for someone to get off their a$$ and build one. (That's actually usable. It would have to be SO usable that people could quickly build out the new user code to make something like *nix or windows seem like more of a hassle in contrast. That's such an insanely tall order...not sure how you get there.)

I think that the best you'll ever be able to do is to build systems with frameworks that are safe(r). People won't give up C because it makes them feel smarter. The pile of code for C based systems will be with us forever. A new system would have to be able to do all that AND be safe.

<comment><USER3> You're missing a key point. What makes Linux usable is that it has numerous drivers written for it... written in C. An OS's core is not supremely difficult to write. But the drivers are... Much specialized knowledge is required.

</comment></comment><comment><USER4> My list of "things I hate about C" is about 4 pages long now, after many years in embedded development (and a few in scientific computing prior to that). As soon as a viable replacement for it comes, I'm going to get drunk, ritually burn K&R's "The C Programming Language" then get drunk again. But I've been waiting for that day for a long, long, long time, and there's still no sign of it, not even with Rust ( _maybe_ with Go but we'll have to see).

I cannot think of a single systems programming language that has not vowed to put an end to all this buffer overflow and dangling pointers mess. The ones I tried so far (I think there's a dozen...) failed because of at least of one of the following items:

* Some of them mainly achieve safety by forbidding any unsafe read or write -- and then when you _have_ to do a read or a write, they implement that by cleverly eschewing a protection mechanism or by isolating everything in an unsafe area. The former is disastrous because you can have bugs that eschew the protection mechanisms, too (see Heartbleed -- which can be _perfectly_ replicated in Rust or Go); the latter, while useful in most application software, is next to useless in my day to day activity, where I have entire _modules_ that consist of nothing other than unsafe reads or writes. At that point I might as well be using C.

* Others mainly achieve safety through a complicated system of annotations ("this parameter must not be NULL") or a type system that makes certain guarantees ("these parameter can never be NULL"). The end result is a system of annotations and/or types which you can describe in about as much space as The C Programming Languages takes to describe the whole language. Barring the fact that my memory is limited after ingesting C++, real life experience shows that "more complexity" is how bugs get introduced, rather than resolved. Except that the new problems don't arise because a pointer is pointing where it shouldn't, but rather because 1 == 1 returns False for certain types of 1 or something.

* Aaand some of them simply delude themselves through clever sandboxing and protected writes, ignoring the fact that the sandboxing back-end is C all the way and can be exploited. Except it's so mind-boggingly complex that fixing it is incredibly complicated.

Historically, there have been many instances of _operating systems_ written in high-level (ish) languages. Hell, there are operating systems written in Common Lisp. It can be done. People haven't flocked towards high-level languages despite 30 bloody years, if not more, of operating systems written in high-level languages because it turns out you usually can't do it unless you turn most of those fancy protection features off. At which point you end up with C, only with a more complicated syntax, and why the hell bother?

The key to writing secure software that doesn't crash _is still_ in correct programming. Tooling can help, but no language, no matter how fancy and hand- holding, is going to compensate for that.

</comment><comment><USER27> Newbie here. Can anyone share their experiences with Rust?

<comment><USER28> I mainly program in C and C++, but have recently started a side project in Rust. So these are thoughts from a Rust newbie (which I still think can be valuable):

Pros:

\- Pattern matching is beautiful, and is one of the things I miss most when not working in Racket.

\- I love their static typing. I think they hit a sweet spot with type inference inside of functions but required types to be specified as parameters (too much inference can make it hard to know exactly what type something is, too little inference means I spend all my time writing type signatures).

\- Borrowing and lifetimes are neat and have helped me avoid some lifetime- related bugs.

\- Being able to call Rust code from C is a huge win, and I think this world needs more "systems-level" languages than C and C++.

Cons:

\- Borrowing and lifetimes. This is actually is a huge pro, but sometimes the compiler can spot a lifetime issue that I don't understand (which makes fixing it hard). I'll get better with this with time, but associating lifetimes with object types is a bit confusing and hard to do if you want to do anything nontrivial. Again, I'm sure this is mostly because I'm a newbie, but it's also reality.

\- Verbosity. Rust is actually concise for the most part, but if you want to pass a &str to a function, but have a String, (which, FYI, is fairly common in my experience, as most string-related functions take a &str), you've got to either call as_str() (which is unstable) or dereference-reference (i.e. &*) the String. There are a few simple things that require you to be more verbose than some other languages do.

Overall I like Rust. I think it's worth experimenting with, but I wouldn't start a really serious project with it right now (because it's so young and volatile). If someone wants to use it for a really serious project, I'd suggest checking out Rust in another year or two when it's a little more mature.

<comment><USER11> Glad you're having a good time with Rust. :) One small note:

> if you want to pass a &str to a function, but have a String

You can just add a & to your String. &String coerces to &str. Deref coercions are one of the few places where Rust does an implicit coercion: [http://doc.rust-lang.org/nightly/book/deref-coercions.html](http://doc.rust- lang.org/nightly/book/deref-coercions.html)

<comment><USER28> Ah, cool, that's much better! Is that relatively new? I swear you had to do &* if you had a String and & __if you had a &String.

Edit: Ah, here: [https://github.com/rust- lang/rfcs/blob/master/text/0241-dere...](https://github.com/rust- lang/rfcs/blob/master/text/0241-deref-conversions.md#benefits-of-the-design)

<comment><USER11> It's not only new, but there wasn't any user-facing documentation until a few weeks ago. I'd been waiting to make changes to the book until after beta, and the re-organization of the TOC I did made me realize that I was missing a few things, this and UFCS being the primary two.

</comment></comment></comment></comment></comment><comment> a-saleh Can anybody point me to a good 'modern c programming' book?

I liked the approach of Learn C the Hard Way, (i.e. lesson 1: "Now compile the hello.c with -Wall", lesson 2: "Lets learn to write simple makefiles",..., lesson 4: "Lets use Valgrind", ...)

But the latest revision of the last chapter that I remember had quite a good critique of K&R's C writing style, now contains just a rant on internet trolls (?). [http://c.learncodethehardway.org/book/krcritique.html](http://c.learncodethehardway.org/book/krcritique.html)

</comment><comment><USER29> In order for a language to replace C, it _has_ to do two things: 1) be able to write an OS kernel competitive with Linux in this language. 2) get its compiler(s) ported to new architectures, including the Top500 supercomputers, where I work. Note that these two help each other: you make a new architecture, you either code a custom OS in C or port Linux, both of which start with a port of a C compiler. If your language can't do the OS thing, C will remain out of necessity, and be too tempting and stable an alternative.

<comment><USER3> Someone to come up with a list of 10 reforms for C, nail it to Kernighan's or Ritchie's front door, and start a new language sect.

</comment></comment><comment><USER30> I think the article points out the real problem: overly complex code. If you make the effort to write sensible, simple, easy to understand code, it's definitely possible to review every line of code to ensure there are no memory management bugs.

</comment><comment><USER31> There is no way that any language can truly replace C at this point, C will still be around for the foreseeable future. We should learn to coexist with it not replace it.

<comment><USER11> This is generally the position of the Rust team as well. It's also why the zero-overhead interop is important to us.

</comment></comment><comment><USER32> And here's hoping for the death of sensationalist articles with zero substance.

<comment><USER9> Or sensationalist comments with zero substance.

Perhaps there should be this unwritten rule, that if a post has made it to the front page of HN, it means enough HN users voted it, and it's interesting to them, so it's counter-productive to dismiss it as uninteresting...

<comment><USER32> An article can be up voted for many reasons, including mockery. I was not dismissing the post here, but the article itself. Also, it is already off of the front page.

</comment></comment></comment><comment><USER33> Safe programming is bogus programming.

</comment><comment><USER34> Terrible title. A more useful dialogue would be along the lines of "Death to C where it is inappropriate", but C isn't used much these days where it's the wrong tool for the job. Mostly, C is used for the things that C does very well. Maybe we'd agree on "Death to C++ where it's inappropriate", because C++ is much more often used (than C) where it isn't appropriate. Then we have to go down the rabbit hole of _why_ C++ often sucks, and we realize that it's not even that it's a bad language itself (not that it's great, but it doesn't have to be horrible) so much as object-oriented programming (OOP) has been bastardized by business, and misused by reactively-writing programmers under tight deadlines, to create obfuscation. Then we realize that this problem is even more severe in Java codebases. Then we wonder if a new language can really fix a problem (code quality) that is partially sociological and political...

The counterexample to the "C is unsafe" argument is that C is what people use for extremely high-reliability programming. I prefer Haskell, and Rust is promising, but the fact is that JPL uses C. The Mars Rover is probably running C code. While C is insecure as hell under typical corporate use (tight deadlines, unskilled programmers) it can be pretty damn reliable in the right hands.

<comment><USER35> Do you think that avionics software is an appropriate application of C?

Boeing does...

[http://www.engadget.com/2015/05/01/boeing-787-dreamliner- sof...](http://www.engadget.com/2015/05/01/boeing-787-dreamliner-software- bug/)

</comment></comment><comment><USER3> Jon Evans, master complainer. C could be improved, but the amount of important C code out there (Linux...) militates against adopting a new C. Is someone going to pay to switch over the code base?

Ultimately if a newer, tighter, safer C is going to arise it must come fron the GCC or LLVM people.

Go: owned by google so it's a no-go.

<comment><USER36> > Go: owned by google so it's a no-go.

It's actually an open source project, and many of the core contributors don't work for Google. Just thought I'd point this out as it seems to be a common misconception.

<comment><USER3> And are people expected to download the compiler executable from Google's website?

Given that the CIA recently bragged that they were able to put spyware in iOS apps because they have somehow exploited Xcode on developers' machines, one has to think about the implications of downloading executables from companies that are complicit in spying.

Just because I do something safe e.g. I compiled the compiler myself, it is the larger implication of everyone else not doing it right that is the concern.

<comment><USER36> Or you could compile it yourself from the github repo.</comment></comment></comment></comment>


The bar for being labeled a gang member is low. The consequences are serious - <AUTHOR> https://www.nytimes.com/2020/02/03/opinion/los-angeles-gang-database.html <comment><USER2> In the federal prison system, an inmate can get a gang member label added to their record by staff. Once it is added, it will never be removed from the person's record.

I thought I'd share an anecdotal experience I had in the federal prison system.

Whenever inmates are transferred into a new prison, they are taken aside to a private room individually and interviewed by "SIS", the internal police at each prison. One of the things they screen for is gang affiliation, so they can have an idea the kind of trouble that might brew up with the new transfers.

I transferred to a USP that had recently been recommissioned as a medium security facility. The staff there were used to the really violent guys of the high security, and were very stern and commanding with processing the busload of guys I came in with. As we had all transferred in from another medium, we were not used to the brusque treatment. When I was taken back for my intake interview by SIS, I thought I'd have some fun.

The officer asked me to sit next to his desk and then said, "Alright, are you in a gang?", to which I replied, "Have you ever heard of DND?"

Reaching for his pen and pad, he said, "No. Have they been around long?" I replied, "About 30 years."

He stopped writing and raised his eyebrows at me. "Really?" His surprise was probably due to him learning of a long established gang that the federal government didn't know about.

I asked him, "Do you have any DNDers here?" He said, "No."

I looked him straight in the eyes and deadpanned in a low voice, "Well, you're gonna."

We held eye contact for about 10 seconds before he said I could go.

It took about a month longer for Property to release my personal property to me than it did for the guys I came in with. I assume that SIS officer wanted to read through all my Dungeons and Dragons books.</comment>


Github: Latest commit per directory - <AUTHOR> https://github.com/blog/1301-latest-commit-per-directory

<comment><USER2> The wording is slightly ambiguous: You could read it as if it would display both the repository global latest commit and the current directory latest commit.

This is not the case. It only shows the directory latest commit.

Which is awesome!</comment>


Fundraiser: OpenBSD fork to remove non-free firmware - <AUTHOR> http://www.libertybsd.net

<comment><USER2> What a waste of time and resources. If you feel like donating you'd be better off donating to OpenBSD or the FSF

<comment><AUTHOR> The OpenBSD Foundation will get 10% of the money raised.

<comment><USER3> It's still creating a niche of a niche. It's a waste of resources; OpenBSD needs every active contributor it can get.

<comment><AUTHOR> Perhaps so, but since it's already made, releasing it shouldn't do any harm.</comment></comment></comment></comment>


Tom Duff on Duff's device (1988) - <AUTHOR> https://www.lysator.liu.se/c/duffs-device.html <comment><USER2> _In fact, the example in the message is not implementable as memcpy, nor is any computer likely to have an memcpy-like idiom that implements it_

REP OUTSW.

Reading a lot of literature from this period in computing, it seems that the majority of "serious programmers" were focused mostly on mainframes/minicomputers, and there was a divide between those people and the ones who were focused almost exclusively on the PC/microcomputers. No one thought x86 would become as commonplace as it is today.

 _Be careful when you use this thing that you don 't unwind the loop so much that you overflow your machine's instruction cache._

Saving cache has become more important with the growing gap between core and memory latency, and processors have gotten much better at predicting and executing "around" loops (especially for superscalar/OoO), so much that in my experience loop unrolling is very seldom beneficial to a great extent today. You may still see improvements if you microbenchmark, but the extra code has displaced something else from the cache and made the overall result slower.

<comment><USER3> REP OUTSW writes to an I/O port. Duff's device writes to memory-mapped I/O. It's not the same thing.

<comment><USER4> x86 can still do this. It has STOS (read next byte/word), LODS (memset), and MOVS (memcpy).

</comment></comment></comment><comment><USER5> Cool to look at the original work on this from 1988, and see just how little it's changed in the nearly 3 decades since.

Go for instance makes use of Duff's devices generated for each architecture in its core runtime. You can see the code to generate the devices here - [https://golang.org/src/runtime/mkduff.go](https://golang.org/src/runtime/mkduff.go)

</comment><comment><USER6> It's always worth rereading this when it comes up just for the last line:

"Many people (even bwk?) have said that the worst feature of C is that switches don't break automatically before each case label. This code forms some sort of argument in that debate, but I'm not sure whether it's for or against."

I crack up every time.

</comment><comment><USER7> > Actually, I have another revolting way to use switches to implement > interrupt driven state machines but it's too horrid to go into.

Does anyone have any insight into what he was talking about here?

<comment><USER8> Yeah, I think he's referring to what's described in more detail here: [https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html](https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html)

<comment><USER9> Been there, done that :) It's a neat trick, but the issue for me is that you still need to pass a separate struct for state which breaks the illusion enough that you might as well just write an ordinary iterator.

<comment><USER8> I agree. If you want user-level threading, just use a stack swapping library like libpth.

</comment></comment></comment></comment><comment><USER10> I really like td's style of writing C. You can find some of his code here: [http://www.iq0.com/duffgram/index.html](http://www.iq0.com/duffgram/index.html)

<comment><USER11> Very odd to see it without blank lines. I wonder what inspired this style?

</comment></comment><comment><USER12> Duff's Device was one of those "light bulb" moments, where my understanding of computers and programming really expanded.

<comment><USER13> Allow me to dramatise:

[Studies Duff's device]

"What... Oh, no, C! What are you doing?!"

<comment><USER14> Always followed by wild laughter, when I've seen people get the light.

</comment></comment></comment><comment><USER15> LLVM seems to have this as a test case: [https://github.com/llvm-mirror/test- suite/blob/master/Single...](https://github.com/llvm-mirror/test- suite/blob/master/SingleSource/Regression/C/DuffsDevice.c)

</comment><comment><USER16> NeWS had some spectacular abuses of C preprocessor macros with nested switch statement, loops and gotos.

Especially the conic splines code by Vaughan Pratt and James Gosling, which "flattens" Bezier curves into conic splines (unlike straight lines like most PostScript renderer implementations), which Vaughan Pratt's conix package can draw really fast.

[http://www.chilton- computing.org.uk/inf/literature/books/wm/...](http://www.chilton- computing.org.uk/inf/literature/books/wm/p005.htm)

SunDew - A Distributed and Extensible Window System

[...] Two pieces of work were done at SUN which provide other key components of the solution to the imaging problems. One is Vaughan Pratt's Conix [53], a package for quickly manipulating curve bounded regions, and the other is Craig Taylor's Pixscene [63], a package for performing graphics operations in overlapped layers of bitmaps. [...]

[...] Pixscene is based on a shape algebra package. The ability, provided by Conix, to do algebra very rapidly on curves should make non-rectangular windows perform well. [...]

[53] Pratt, V., Techniques for Conic Splines, Computer Graphics 19(3), pp.151159 (1985).

[63] Taylor, C. and Pratt, V., A Technique for Representing Layered Images. SUN Microsystems Inc., 2550 Garcia Avenue, Mountain View, CA94043.

Direct Least-Squares Fitting of Algebraic Surfaces: Vaughan Pratt, Sun Microsystems Inc. and Stanford University. April 30, 1987.

[http://boole.stanford.edu/pub/fit.pdf](http://boole.stanford.edu/pub/fit.pdf)

[http://donhopkins.com/home/code/NeWS/SUN/src/server/graphics...](http://donhopkins.com/home/code/NeWS/SUN/src/server/graphics/pathtoarc.c)

        /*-
            Convert a PostScript style path to an arclist
            pathtoarc.c, Thu Sep 19 15:45:44 1985
         */

[http://donhopkins.com/home/code/NeWS/SUN/src/server/graphics...](http://donhopkins.com/home/code/NeWS/SUN/src/server/graphics/arctochain.c)

        /*-
            Convert a conic arc to a curve
            arctochain.c, Tue Jun 11 14:23:17 1985
            "Elegance and truth are inversely related." -- Becker's Razor
                Vaughan Pratt
                Sun Microsystems
                This code is a version of the conix package that has been
                heavily massaged by James Gosling.
         */

[...]

        /* macros for the conic machines */
        #define out(b) {		\
            if (b)			\
            xpos += dir;		\
            else			\
            *ypos++ = xpos;		\
        }

        #define across(rel,q1) {						\
                out(1);							\
                Fx += Fxx, Fy += Fyx;					\
                if ((F += Fx) rel 0)					\
                    goto q1;					\
            }

        #define down(rel,q1) {							\
                out(0);							\
                if (--rem0 < 0)						\
                    goto final;					\
                Fx -= Fxy, Fy -= Fyy;					\
                if ((F -= Fy) rel 0)					\
                    goto q1;					\
            }

        #define trans1(axis, q1)						\
            for (;;)							\
                axis(>=, q1);

        #define trans2(axis, q1, rel, q2)					\
            for (;;) {							\
                axis(<, q1);						\
                if (Fx rel Fx_err)					\
                    goto q2;					\
            }

[...]

            /* enter conic machine at appropriate state */
            rem0 = size.y;
            if ((size.x > 0) == (side < 0))
            goto EOD;
            else
            goto OED;
            /* OE state machine */
        ODE:trans1(across, OED);
        DOE:trans2(across, ODE, >, OED);
        OED:trans2(down, ODE, <, DOE);
            /* EO state machine */
        EDO:trans1(down, DEO);
        DEO:trans2(across, EDO, >, EOD);
        EOD:trans2(down, EDO, <, DEO);
        final:;
            /*-	clearasil(buf0+1, bitlen); 	/* clean out 0011/1100 pimples */
            assert(ypos <= curve->x + (curve->y1 - curve->y0 + 1));

The main loop of the NeWS PostScript interpreter itself is the realization of Duff's dire warning "Actually, I have another revolting way to use switches to implement interrupt driven state machines but it's too horrid to go into."

[http://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus/...](http://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus/PostScript.c)

        /*
         * This is the PostScript interpreter.  Its implementation breaks almost every
         * rule of structured programming.  This is a result of needing to support
         * multiple PostScript processes and a paranoia about performance. There are a
         * couple of #includes that you should think of as procedure calls.  Life is
         * tough in the trenches.
         *
         */

        /*
         * The PostScript interpreter has a fairly simple basic structure:
         *
         * while (1) { 1. Pick up an object to interpret 2. Execute it }
         *
         * Part 1, picking up an object to interpret is handled by the statement that
         * starts "switch (es->type)".  es points to the top of the execution stack: a
         * stack of sources of executable objects.  The switch determines what kind of
         * thing the object is being fetched from: an array, a string, ...
         *
         * Part 2, executing an object, is handled by the code that starts with the label
         * "execute_top".  It does some tests and switches on the type of the object
         * being executed.
         *
         * All of this is complicated by the mechanism for blocking.  If the process
         * needs to block, say by needing to read a new buffer from a socket or by
         * needing to wait for a message, then the interpreter needs to stop working
         * on this process and leave information around that lets it restart.  This is
         * the "restart_state" variable: it is used as the index to a switch statement
         * that is executed when the interpreter starts up, so it won't necessarily be
         * intering the main loop of the interpreter at the top. There are cleaner
         * ways of doing this, but they can't be written in C!
         */

[...]

            /*
             * Restart the interpreter where it left off last
             */
            switch (ee->restart_state) {
            case 1:
            goto read_1;

[...]

            case 24:
            goto read_24;
            }

            /* The main loop of the interpreter */
            while (1) {
            struct object new;

[...]

        /* Pick up an object to execute */
            switch (es->type) {

[...]

            case file_execution:{
                register PSFILE *f = es->env.file.file;
                /* be charitable and think of this as a procedure call */
        #ifdef GPROF_HOOKS
        /* gP_GetFile defined in parse_file.h */
        #endif
        #include    "parse_file.h"
                break;
                }

[http://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus/...](http://donhopkins.com/home/code/NeWS/SUN/src/server/nucleus/parse_file.h)

        /*-
         * 	Parse a PostScript object from a PSFILE
         *
         * 	parse_file.h, Mon Dec 31 09:36:02 1984
         *
         * 		James Gosling,
         * 		Sun Microsystems
         */

        /*
         * This is a version of getc that pauses if the buffer is empty and suspends
         * the process
         */</comment>


What are the dark corners of Vim your mom never told you about? - <AUTHOR> http://stackoverflow.com/questions/726894/what-are-the-dark-corners-of-vim-your-mom-never-told-you-about <comment><USER2> Mom was into IBM mainframes. She never used vim.</comment>


The Kember Identity  - <AUTHOR> http://www.elliottkember.com/kember_identity.html

<comment><USER2> All of the programs there have a _fatal_ flaw in their logic.

If any of them come across a collision - where 2 strings hash to the same value - then it will just go into a "loop".

The chances of that happening in that key space is probably fairly high (based on my experience).

EDIT: also I have 80 billion hashes a few clicks away and none of the 32bit string ones in there (estimate: between 5 and 10 billion ) that I have run a quick test against (so far about 100 million or so) proved negative. Should be done by tomorrow... I doubt there will be match.</comment>


Why Republican Voters Decided on Trump – Nate Silver - <AUTHOR> http://fivethirtyeight.com/features/why-republican-voters-decided-on-trump/ <comment><USER2> The rise of Trump and Sanders, much to the chagrin of "experts", is succinctly explained here: [http://www.nytimes.com/2016/04/29/opinion/if-not-trump- what....](http://www.nytimes.com/2016/04/29/opinion/if-not-trump- what.html?_r=0)

</comment><comment><USER3> "Usually a party picks a nominee who is both reasonably "electable" and who upholds its traditional policy positions. In Trump, the Republican Party may have a candidate who fails on both counts."

this kid throws around a lot of loose garbage language for a statistician. he clearly let his emotions and feelings distract his analysis (and still is). trump is electable -- for sure -- and this presidential race is going to be very very interesting.

<comment><USER4> Huge bias against Trump from Silver

[http://imgur.com/r/The_Donald/LwZ9JwW](http://imgur.com/r/The_Donald/LwZ9JwW)

<comment><USER5> That's true, and the writers of FiveThirtyEight publish a weekly transcript of a Slack chat in which they discuss those things.

Some of the writers were very optimistic about Trump, and Nate was notably not optimistic.

It's impossible for journalists to be unbiased or to be right all the time. Good journalists will "show their work" (the data they're basing their analysis on), explain areas where they _could_ be wrong, admit their biases, and (ultimately) admit when they're wrong. Silver has done all these things.

Maybe you don't like his site or his writing, but "unbiased" journalism is a fantasy peddled by low-brow entertainment channels like CNN. When people study facts, they form conclusions, and we should want to know both the facts and the conclusions.

It's better to know the biases and be able to take the work with a grain of salt.

<comment><USER4> >It's impossible for journalists to be unbiased or to be right all the time.

Of course, the thing is Silver is 100% wrong in all his predictions regarding Trump.

You can't take him seriously when he talks about him.

<comment><USER6> I think a big problem is that intelligent people tend to be naive about the level of sophistication of voters.

<comment><USER4> Those poor and stupid people amirite?</comment></comment></comment></comment></comment></comment>


Rails 4 Postgres UUID Primary Key Guide  - <AUTHOR> http://labria.github.io/2013/04/28/rails-4-postgres-uuid-pk-guide/

<comment><USER2> This news pleases me enough to consider pitching into help complete the missing features.</comment>


How 'Snowball Earth' volcanoes altered oceans to help kickstart animal life - <AUTHOR> https://theconversation.com/how-snowball-earth-volcanoes-altered-oceans-to-help-kickstart-animal-life-53280 <comment><USER2> "The resulting continents were clustered near the equator where there are higher temperatures – resulting in increased evaporation of water from the oceans"

What am I missing here? This makes no sense to me. If the continents are clustered closer to the equator, then the oceans are at disproportionately _higher_ latitudes, resulting in _less_ solar radiation reaching them and making for _less_ evaporation.

Also, the link for "flush dissolved minerals via rivers into the oceans" doesn't work.</comment>


How Much Money Do You Save by Cooking at Home? - <AUTHOR> https://priceonomics.com/how-much-money-do-you-save-by-cooking-at-home/ <comment><USER2> I assumed that a website like "priceonomics" would factor time spent on shopping and prep. I'm a reasonably good cook, but "eating in" means losing about 90 minutes to shopping, prep, and cleanup, that could otherwise be spent on work, side projects, or reading (mix recreational and vocational).

I suppose it varies based on career and lifestyle, but I believe that most of the readers of this site, at least, feel more of a crunch on time than cash.

<comment><USER3> Food preparation and shopping, like a lot of skills, becomes a bit more efficient the more you do them. Eventually you become better at using your time.

And, you can cook more at once. Nothing says you have to start from scratch every day of the week; in my case I often cook Sunday nights and make 2 or 3 dishes. If you read through recipes a bit, you can find ways to reuse the same preheated oven, etc.

And, home cooked meals tend to be healthier. This is a form of time saving; while pretty hard to prove unfortunately, I strongly suspect that "losing about 90 minutes" now and having a healthier life will buy years down the road.

</comment></comment><comment><USER4> In which the cost of labor is apparently excluded.

Also excluded: food wasted at home.

<comment><USER5> I honestly waste a lot more food when I ordered take out or eat at a restaurant.

While I once used to eat everything that's on my plate because it's a pity to waste food, I've then learnt to just stop eating when I'm full.

On one hand this alone made me lose some weight, on the other hand I can't always save excess food for the next meal (example: restaurant or delivered things like french fries and things like that).

<comment><USER6> > I can't always save excess food for the next meal (example: restaurant or > delivered things like french fries and things like that).

This doesn't quite make sense to me. Although there are certainly items that don't keep particularly long, say, more than a day, I have trouble coming up with a common restaurant food that can't be saved at _all_ , with proper refrigeration.

Fully cooked potatos, such as french fries, I've never had trouble with, and they even reheat well and easily in a convection toaster oven.

<comment><USER7> I've never been able to do anything with day-old rice.

<comment><USER6> What happens to it after 24 hours in your refrigerator that makes it inedible? What temperature is your refrigerator? (Yes, I know few fridges have actual thermometers, but it's remarkably important both for food safety and, in many cases, palatability)

My go-to suspicion would be drying out, but I've never had a problem with that, even in an incompletely sealed takeout container kept refrigerated for a couple days. With the most-moisture-permeable container, I just sprinkle some extra water onto the rice when reheating in the microwave, and that makes up for it.</comment></comment></comment></comment></comment>


Ethereum Network Status - <AUTHOR> https://stats.ethdev.com/

<comment><USER2> The UI is rather reminiscent of Teenage Engineering synth UIs: [https://www.teenageengineering.com/products/op-1/modules](https://www.teenageengineering.com/products/op-1/modules)

Nice looking, overall

<comment><USER3> Very similar. I used to own an OP-1 and loved the visuals. On a different note, does anyone else have a massive slowdown of their browser while viewing [https://stats.ethdev.com/](https://stats.ethdev.com/) ? I'm on firefox 38.1.0.

</comment></comment><comment><USER4> Is this a custom dashboard or was it built with some kind of framework?

I'd like to build something like this for my own projects!

edit: Looks like a custom project, here: [https://github.com/cubedro/eth- netstats](https://github.com/cubedro/eth-netstats)

<comment><USER5> Custom. It's meteor and Ethereum's javascript interface to their network.

</comment></comment><comment><USER6> Can someone explain what all these charts mean, for the layman?

<comment><USER7> "Uncles" are blocks from miners who were "too slow" to broadcast their block to the network- They still earn some reward, but aren't parents of new blocks, just... well, uncles. (Uncles help ethereum have 12s block times, far shorter than most other cryptocurrencies)

The "Average block time" is around 11s which is what you want to see. It is very close to the optimal time of 12s. (Correction: optimal time is now targeted at 15s)

The Network Hash Rate of 52.4 GH/s means that maybe 3000 or so computers worldwide have appeared in the last 24 hours to join the network and mine for blocks. (probably many more have joined without mining, but that number cannot be determined from this dashboard)

The "difficulty" right now is relatively plateaued, which suggests blocks are traveling efficiently on the network and miners are successfully connecting to the network and not fluctuating too much in number.

The transaction graph is flat, because transactions are disabled until the final safety switch on Monday/Tuesday is removed.

"Active Nodes" are just the number of nodes linked to the Stats program, so that number doesn't mean much.

"Gas Price" is, roughly speaking, the cost of an opcode instruction for transactions/contracts, which miners get to decide on for each block they mine (within limits)

BOTTOM LINE: These network stats are super boring, and the ethereum launch yesterday was totally uneventful, which is EFFING AWESOME.

<comment><USER8> 52.4 GH/s is a lot slower than I would expect for a coin with such a large following. Is the hashing algorithm not ASIC/GPU friendly?

<comment><USER7> nemo1618: The proof of work algo for ethereum is MUCH more difficult than in most other cryptocurrencies, leading to far lower aggregate hash numbers- If you want to compare it against BTC/LTC/etc you first need to correct for the average hash rate on a single mining PC for the given currency.

</comment></comment></comment></comment><comment><USER9> That is a _really_ pretty dashboard.

</comment><comment><USER10> Anyone else not seeing any data when viewing on mobile (iPad, Safari)?

<comment><USER11> Make sure you wait a while - the data loads fairly slowly.

</comment></comment><comment><USER11> The data takes long enough to load that it would be better to say "loading..." in place of 0/0\. I thought it was a project with no interest.

</comment><comment><USER12> Beautiful</comment>


Java 14 GA - <AUTHOR> https://jdk.java.net/14/ <comment><AUTHOR> New features already discussed in [https://news.ycombinator.com/item?id=22477629](https://news.ycombinator.com/item?id=22477629), but now it's GA.

</comment><comment><USER2> > Remove the Concurrent Mark Sweep (CMS) Garbage Collector

pour one out for the legend

</comment><comment><USER3> I have done much Java since I moved to full time Python/Node/Go. Guess I should give a try now. The Helpful NullPointerException is certainly a exciting feature.

</comment><comment><USER4> Wow, I'm still using JDK 1.8. I thought I was way behind until I looked up the release schedule: apparently they're pushing out two (major) releases a year now.

<comment><USER5> They're not major releases; in fact, the last major Java release _ever_ was 9.

The way releases used to work for the past ten years or so was that after a major release, every couple of months there would be a bugfix/security patch, and every six months (for a year or more) there would be a feature release (that used to be called "limited update") with major new features (new GCs, new monitoring mechanisms etc.) but without spec changes to the language and libraries. This meant that all the changes that required changing the spec had to wait for the major release. This had several bad implications. Most if not all of the spec changes were no more disruptive than the changes in the feature releases, but they had to wait for the next major release -- a lot of changes delivered at once created an overall fairly large disruption. Also the major release had to wait for the large features, and people couldn't enjoy smaller ones. Finally, people wanted to get their changes into the next major release so they wouldn't have to wait another three years or more, so features were merged before they were fully tested, which meant that the .0 major release was noticeably less stable.

So, to make the upgrade process easier and cheaper, Java got rid of the major releases, allowed making spec changes in the feature releases, and, with the major releases gone, every feature release gets a new integer name. The result is a much more gradual process. Every feature release is about as big and only slightly more disruptive than the old feature releases. The releases are now much more stable because features are merged only when they're mature enough; there's no rush because if you miss a release, there's another in six months.

The ecosystem will take some years to adjust, but those who've made the transition to running in production on the current release (many still can't, as some tools haven't yet adjusted) report a smooth process.

<comment><USER6> You make it sound like the upgrading process is something to be savoured when for many it's the opposite.

Upgrading a code base because of language evolution is pure cost for most people. It's a relatively risky and almost zero-reward exercise for mature applications.

You've got 3rd party library/dependency drag, tooling drag (everything from IDEs to CI/CD pipelines), development effort for code changes or QA and testing resources. Your engineers have to invest time in learning about the language and library changes. Never mind that unless you do a total rewrite, you end up with an incoherent code base which mixes old and new styles.

All this busy work/effort could instead be applied to adding features, eliminating bugs, improving performance, etc. - changes that end-users actually appreciate or that add business value.

Java conquered the enterprise precisely because it was slow moving and stable and offered unparalleled backward compatibility. Pretty much, the very same reasons Microsoft windows conquered the business world. This is (was) Java's strength not the weakness you portray.

Let's face it, at this stage Java is never going to be "cool" again the way it was in the 90s. Trying to join the "move fast and break things" school of language evolution just makes it look like a middle aged person (I'm one btw) trying to be "hip" by emulating young teenagers in dress and speech. At the same time you're alienating your existing users.

<comment><USER7> I totally agree with this. I have worked in stable, long term, revenue generating projects that relied on java and its slow stable releases. I now cherish that we could focus on features and not have a "Migrate to Java x.x" story looming upon us.

With NodeJs, its a semi-annual affair to move and migrate or face unexpected broken 'npm install' commands. Fix the tooling, fix CI/CD, ignore warnings, application upgrades now require installing newer Node versions, no backward compatibility guarantees of any kind. Its a fool's errand.

I hate to see Java go this route. I don't think this will end well for the Java ecosystem.

<comment><USER5> Java has had the six-monthly feature releases (which were called "limited update" releases, as opposed to major and patch releases) for many years, with names like 7u4 or 8u20. They also had a support period of 6 months. For example, the 8u20 feature release got two patches, names 8u25 and 8u31, and then 8u40 came out and 8u20 no longer got patches. But people are confused by the choice to give those releases a new integer name now that major releases are gone.

It is an extreme misunderstanding to think that Java does not have "backward compatibility guarantees of any kind." Backward compatibility is of the utmost importance (Java has never made breaking changes as big as Python or .NET have), but it is not absolute. It's never been absolute; it's just that while breaking changes were mostly accidental before (or to implementation details), Java now admits some changes to the spec. But note that those aren't the changes that people have noticed (the biggest ones were removing methods that no one used). The breaking changes that people notice are implementation changes that some libraries, due to technical debt, relied on. As more investment is being put into the JDK and it's changing more quickly, that technical debt is showing, but it's not because of breaking spec changes.

</comment></comment></comment></comment></comment><comment><USER8> When are the Alpine builds getting GA status? The last release of Java to include a build for Alpine was Java 8. Ever since then the Alpine builds have been restricted to early access releases. In the meantime Microsoft has started providing officially supported Alpine builds for .NET Core.

<comment><USER9> At least, Azul provides Alpine builds. Maybe other OpenJDK distribs too, i don't know ?

</comment></comment><comment><USER10> Great news, although I know it's gonna be a while before it's a smooth transition to this version - definitely going to push for atleast one of our systems. Some features we needed in this one. e.g. helpful NPE messages</comment>