C++ Renaissance

Dynamic language developers who are concerned about performance end up writing pieces of their applications in C++. So if you’re going to write C++ anyway, why not write your entire application in C++?

Library writers develop in C++ so that their users won’t have to. That makes a lot of sense. But if you’re developing your own application, not a library, maybe it would be better to write everything in C++ instead of wrapping C++ in something else.

A few years ago an immediate objection would be that C++ is hard to use. But with the advent of C++ 11, that’s not as true as it once was. C++ has gained many of the conveniences traditionally associated with other languages.

Dynamic languages are designed for programmer productivity[1] at the expense of efficiency. If you can afford that trade-off, and quite often you can, then don’t worry about C++. But if you’re using a dynamic language and C++, maybe it would be easier to just stick to C++. Of course the decision depends on many factors — how much of the application needs to be efficient, the size and skill of your team, etc. — but I suspect more projects will decide to do everything in C++ because of its new features.

* * *

[1] “Productivity” implicitly assumes productivity at a certain set of tasks. If your tasks fall into the set of things a language was designed to support, great. But a “productivity” language may not improve your productivity if you don’t meet the language’s intended profile.

More C++ posts

Square root of people

How do you infer the economic well-being of individuals from household income? At one extreme, you could just divide household income by the number of people in the household. This is naive because there are some economies of scale. It doesn’t take twice as much energy to heat a house for two people as a house for one person, for example.

The other extreme is the two-can-live-as-cheaply-as-one philosophy. All that matters is household income; the number of people in the house is irrelevant. That’s too simplistic because while there are fixed costs to running a home, there are marginal costs per person.

So if you have a household of n people do you divide by the total income by n or by 1? Said another way, do you divide by n1 or n0? Some economists split the difference and use an exponent of 0.5, i.e. divide by the square root of n. This would say, for example, that the members of a family of four with a total income of $100,000 have roughly the same standard of living as a single person with an income of $50,000.

Dividing by √n is a crude solution. For one thing, it makes no distinction between adults and children. But for something so simple, it makes some sense. It makes more sense than dividing by n or not taking n into account.

Source: Burkhauser on the Middle Class

Classifier progress exaggerated?

Yesterday Simply Statistics linked to a paper with the provocative title Classifier Technology and the Illusion of Progress. I’ve only skimmed the article so far, but here are a few sentences that stood out.

In particular, simple methods typically yield performance almost as good as more sophisticated methods, to the extent that the difference in performance may be swamped by other sources of uncertainty that generally are not considered in the classical supervised classification paradigm. …

The situation to date thus appears to be one of very substantial theoretical progress … While all of these things are true, it is the contention of this paper that the practical impact of the developments has been inflated; that although progress has been made, it may well not be as great as has been suggested.

WinRT, Projections, and COM

Martyn Lovell gave a great talk on the new Windows Runtime at Lang.NEXT this week. You know it’s going to be a good talk when the speaker uses the word “soporific” four seconds into the presentation.

One of the ideas I found interesting was language projections, providing multiple programming languages idiomatic access to the lowest level system APIs. What’s new is that these projections are not hand-crafted interfaces but software to create interfaces. The operating system calls are described in metadata that the projections use to create language-specific interfaces. This prepares the way for future growth.

In years gone by, Microsoft would first make an API available to C++, then make it available to VB in a later release. But starting with Windows 8, all languages will have immediate access to new features as they are released. Microsoft is writing projections for .NET, JavaScript, and native code. Third parties will write projections for other languages. If an obscure language has a projection, it will gain access to new runtime features at the exact same time that C# does.

Another point I found interesting is that WinRT is reusing some ideas from COM. I thought the basic ideas of COM were brilliant, though in practice COM development was painful. Near the end of the video (42:17), Martyn Lowell explains how WinRT relates to COM.

Philosophically, COM was about taking a world of different languages and using interfaces to abstract them. And we’re about taking a world of different languages [and abstracting them] so in that sense the philosophy is similar. But if you worked with COM at the time, as I did quite a lot, there were a lot of pain points. … The piece of COM that is largely unchanged in Windows Runtime is IUnknown and the marshalling and proxy system. Beyond that, almost everything you can see about the Windows Runtime is about re-imagining an interface-based system …

If COM brings back bad memories, understand that Microsoft is not saying you need to go back to writing COM, only that they’re using ideas from COM to provide you higher-level interfaces.

Writing software for space probes

A few days ago I quoted Ron Garret on his experience debugging software running millions of miles away. Since then I discovered a video of a talk Garret gave at Google a few weeks ago. He talks about remote debugging toward the end of his presentation, but most of his talk is about how NASA developed software for space probes during his time there.

More NASA posts

Fractional integration

Define the integration operator I by

(I,f)(x) = \int_a^x f(t)\, dt

so I f is an antiderivative of f.

Define the second antiderivative I2 by applying I to f twice:

(I_2, f)(x) = \int_a^x \int_a^t f(t_1)\, dt_1\, dt

It turns out that

(I_2, f)(x) = \int_a^x (x - t) \, f(t)\, dt

To see this, notice that both expressions for I2 are equal when x = a, and they have the same derivative, so they must be equal everywhere.

Now define I3 by applying I to I2 and so forth defining In for all positive integers n. Then one can show that the nth antiderivative is given by

(I_n, f)(x) = \frac{1}{\Gamma(n)} \int_a^x (x - t)^{n-1} \, f(t)\, dt

The right side of this equation makes sense for non-integer values of n, and so we can take it as a definition of fractional integrals when n is not an integer.

Related post: Fractional derivatives

 

Users will tolerate a lot to get their work done

Suppose users have a choice of two software applications.

  • Application #1: Beautiful user interface, well documented, robust. It does 99% of what they need in order to get their work done, but they don’t know how to do the remaining 1%.
  • Application #2: Ugly, poorly documented, crashes routinely, but it does 100% of what they need.

Users will choose #2. If they have no other options, they may even be excited about it. This took me a while to understand. I was dumbfounded the first time I had the following conversation, but I’ve had it several times since.

User: This is a really great piece of software!

Me: But doesn’t it crash easily?

User: Yeah, but it does just what I need!

The key is the missing 1% in the first application. Developers may not realize that 1% is missing. Or they may over-estimate how willing/able the user is to fill in the last 1%.

Update: When I wrote this, I particularly had in mind the case where the buggy but complete program came first. Users may not choose it from scratch, but they will certainly stick with it if they’re already using it.

a < b < c

In Python, and in some other languages, the expression a < b < c is equivalent to a < b and b < c. For example, the following code outputs “not increasing.”

a, b, c = 3, 1, 2
if a < b < c:
    print "increasing"
else:
    print "not increasing"

Now consider the analogous C code.

int a = 3, b = 1, c = 2;
if (a < b < c)
    printf( "increasingn" );
else
    printf("not increasingn");

This outputs “increasing”!

If you don’t know C, you’d expect the output to be “not increasing.” If you do know C, you might expect the code not to compile.

Here’s what’s going on. The code first asks whether a < b. This evaluates to 0 because a < b is false. Then it asks whether 0 < c, which is true.

If the code above were part of a C++ program, it would still compile and still produce the same result. However, the compiler would generate a warning for implicitly casting Boolean result to an integer.