Earlier this week, Brent Schlender published selected Steve Jobs quote highlights from his interview tape archives.
Here’s one about us:
The difference between the best worker on computer hardware and the average may be 2 to 1, if you’re lucky. With automobiles, maybe 2 to 1. But in software, it’s at least 25 to 1. The difference between the average programmer and a great one is at least that.
This illustrates that there’s always lots of headroom to keep growing as a developer. We should always keep learning, and strive to become ever stronger at our craft.
You might also enjoy the history and observant commentary in Schlender’s other new article The Lost Steve Jobs Tapes, which focuses on “the wilderness years.”
Last week at the Lang.NEXT 2012 conference in Redmond, I gave a 40-minute C++ talk and participated on a native languages panel. Both are now online at Channel 9.
Here’s the 40-min C++ talk, taken from the C9 site:
(Not Your Father’s) C++
What makes ISO C++11 "feel like a new language"? What things that we know about past C++ do we need to unlearn? Why is C++ designed the way it is – historically, and in C++11? Finally, what is the difference between managed and native languages anyway, and when is each applicable? This talk gives an overview and motivation of modern C++ and why it’s clean, safe, and fast – as clean to code in and as type-safe as any modern language, and more than ever the king of "fast."
And the panel (my favorite highlight is at 24:00-28:00):
Lang.NEXT 2012 Expert Panel: Native Languages
Walter Bright, Robert Griesemer, Andrei Alexandrescu, Herb Sutter
Native programming languages panel hosted by Martyn Lovell.
I hope you enjoy them.
I’ve been meaning to post a link to Vincent Lextrait’s nice (and actively maintained) catalog of what languages are used to build what modern and major mainstream software:
This table contains a list of major software products or utilities, with details about the programming languages used to implement them. Information on this is difficult to find, and a few small mistakes might have escaped the author‘s attention. Corrections, suggestions for additions or even references are welcome. …
A nice data point to use to show that the world is built on C++ (and its C subset).
The table was compiled without bias on the part of the person who compiled it; he’s just trying to gather information. If you think a language is under-represented, send mail to Vincent with specific project data (make sure it’s something you know of first-hand or can point to an authoritative source) and I’m sure he’ll be glad to add it.
A nice talk by Mads Torgersen just went live on Channel 9 about C#’s non-blocking Task<T>.ContinueWith() library feature and await language feature, which are a big hit in C# (and Visual Basic) for writing highly concurrent code that looks pretty much just like sequential code. Mads is one of the designers of await.
If you’re a C++ programmer, you may be interested in this because I’ve worked to have these very features be offered as proposals for ISO C++, just with a few naming tweaks like renaming Task<T>.ContinueWith() to std::future<T>::then(). They were initially presented at the recent Kona meeting in February, and we’ll dig deeper next month at the special ISO C++ study group meeting on concurrency and parallelism.
Here’s the talk link and abstract:
Asynchronous programming is what the doctor usually orders for unresponsive client apps and for services with thread-scaling issues. This usually means a bleak departure from the imperative programming constructs we know and love into a spaghetti hell of callbacks and signups. C# and VB are putting an end to that, reinstating all your tried-and-true control structures on top of a future-based model of asynchrony.
While we were chatting after the talk, I managed to gently twist Mads’ arm and he has graciously agreed to come to the May 7-9 ISO C++ parallelism study group special meeting to present this to the committee members in detail and answer questions about await’s design and C# users’ experience with it in production code, which will help the committee decide whether or not this is something they want to pursue for ISO C++.
I hope you enjoy the talk. While at Lang.NEXT, I also participated in a panel and gave a C++ talk but those sessions aren’t live yet; I’ll post links once they are.
Trivia: If you noticed the Romanian accent in the first question from the audience, it’s because it came from Andrei Alexandrescu, who was sitting beside Walter Bright, both of whom were two of the other speakers at the conference. It was fun to be in a room full of language designers and implementers sharing notes about each other’s languages and experience.
Nicely put… Christian Lindholm:
Most companies (including web startups), he said, are looking to “wow” with their products, when in reality what they should be looking for is an “‘of course’ reaction from their users.”
Simple and obvious beats flashy. So many great designs are obvious in retrospect.
Hat tip to John Gruber.
@Alf, @Herb – I don’t quite get the [[noreturn]] example. While it may (not) compile on VC++, (as far as I understand) it does not carry any semantic meaning, and, what’s more, it is *perfectly* safe for any compiler that sees [[noreturn]] to just ignore it — the runtime behaviour vs. VC++ shouldn’t be changed at all.
So how is [[noreturn]] in the same camp as “restrict” ??? (I agree it may(?) be in the same camp as final and override.)
I will quote Bjarne: (http://www2.research.att.com/~bs/C++0xFAQ.html#attributes)
> There is a reasonable fear that attributes will be used to create language dialects.
> The recommendation is to use attributes to only control things that do not affect the meaning
> of a program but might help detect errors (e.g. [[noreturn]])
> or help optimizers (e.g. [[carries_dependency]]).
Yes, this argument was used. I’m (even) more conservative than Bjarne on this one.
People spoke up for two main different views on the question, “what does it mean to say [[attributes]] should not affect language semantics?” For convenience I’ll label these as the “weak” and “strong” views. Both views agree that if a program is valid both with and without the attribute, it should have exactly the same meaning both ways. Where the two views/camps differ is on whether it counts as “changing the meaning of the program” if a program that is valid if the attribute is ignored is rejected (fails to compile) if the attribute is observed:
- The “weak” view says that’s okay because it didn’t really change the meaning of code that could ever execute, it just caused it to fail to compile. (I know, [[noreturn]] seems like it’s doing that… but it actually doesn’t quite meet this definition in my opinion, see below.)
- The “strong” view, which I strongly support, says that calling a program illegal not only is the most dramatic semantic change possible, but also should be considered a nonconforming extension because it rejects code that is legal in the standard. (I know, [[noreturn]] in particular is standard… but it’s still problematic for this reason, see below.)
On principle, I do not like opening the door to let compiler writers use [[attributes]] as an excuse to not respect legal ISO C++ programs. And I say that as someone who works on a C++ compiler team and actively does C++ language extension design, and having the excuse of disabling part of ISO C++ that I don’t like by throwing in an [[attribute]] could be useful. Don’t get me wrong, there are corner cases of C++ I would like to turn off, but I try hard (and so far successfully) to refrain from doing such a thing without ISO C++’s blessing because it would break source code portability. Encouraging the view that nonstandard [[attributes]] can be a legitimate excuse to reject conforming C++ programs strikes me as putting a live grenade in a public square with a “pull me” tag on the pin. The whole point and primary benefit of having an ISO standard for C++ is to guarantee source portability; this weakens that, and for that reason I view it as a dangerous position to take.
However, in general the “weak” interpretation prevailed, and on those grounds [[noreturn]] and [[carries_dependency]] remained an attribute. I didn’t fight it because at least we got to remove [[final]], [[override]] and [[base_check]] as attributes, which was my primary concern since those would see far more use, and as long as we fixed those I was happy to say I could live with the others in order to get a consensus standard.
Post-Mortem: Assessing [[noreturn]]
Disclaimer: The following is an informational analytical exercise, not a public lobbying for a change. I support where we ended up as a whole to get C++11, it is probably too late to tweak [[noreturn]], and I consciously didn’t pursue making the following arguments at the time because [[noreturn]] (and [[carries_dependency]] are so rarely used that I can live with them, and you have to be willing to give some ground to get a consensus standard – the important thing was to get [[final]], [[override]], and [[base_check]] out and then stop while you’re ahead.
With that disclaimer in place, let me present counterarguments to show why I believe that in an ideal world [[noreturn]] shouldn’t be an attribute because it really is a keyword in [[attributes]] clothing and doesn’t actually meet either the weak or the strong view:
- I don’t think that [[noreturn]] meets the bar set by the weak view, because it does more than just cause programs to fail to compile. In my opinion, adding [[noreturn]] does change the meaning of a conforming program, because the C++11 standard says in 7.6.3/2: “If a function f is called where f was previously declared with the noreturn attribute and f eventually returns, the behavior is undefined. … [Note: Implementations are encouraged to issue a warning if a function marked [[noreturn]] might return. —end note ]” – Even if respecting a [[noreturn]] did cause a compiler to reject some code (which is not required by the standard, and is not even mentioned even in the non-normative note which just talks about maybe issuing a warning), that means that void f(); and [[noreturn]] void f(); do not have the same semantics – returning from the first is always defined behavior (if you do it), and returning from the second is undefined behavior. This isn’t just a language-lawyerly argument either – the reason the standard says “undefined behavior” here is because that’s how the standard explicitly gives latitude to optimizers – it’s saying that “a compiler optimizer may assume the function doesn’t return, and optimize the code in ways that could cause different execution (even catch-fire semantics) if f ever actually does return.” Telling the compiler it may rely on this attribute to have meaning is, to me, clearly giving the attribute a language meaning and so changes the program’s semantics if it is present. So I don’t think it’s actually true that the presence of [[noreturn]] doesn’t affect language semantics.
- It also doesn’t meet the strong view and discourages portability, by opening the door for using nonstandard attributes as a reason to reject conforming code. Now, it’s true that [[noreturn]] is in the standard itself, and so we might be tempted to say it’s not like a nonstandard attribute in this way that reduces portability, but it is – you cannot reliably write portable C++11 code under the assumption that [[noreturn]] has no semantic meaning and can be ignored. That’s because adding [[noreturn]] really does change the meaning of a function declaration (by adding guarantees that the optimizer can use, as described above) and so you really need to treat it as though it were a language keyword – because it is, just dressed in [[attributes]] clothing.
So in my view [[noreturn]] is a keyword dressed in [[attributes]] clothing.
Having said all that, experts do disagree, and the two camps have simply had to agree to disagree on this question – we got unanimous consensus on the standard, even though [[noreturn]] and [[carries_dependency]] are a bit of a sore point, because everyone was satisfied enough that we at least averted having [[final]], [[override]] and [[base_check]].