Tim Martin's Blog http://blog.asymptotic.co.uk On the human side of software Wed, 12 Mar 2014 22:50:00 +0000 en-US hourly 1 http://wordpress.org/?v=4.2.3 The safe bool idiom in C++ http://blog.asymptotic.co.uk/2014/03/the-safe-bool-idiom-in-c/ http://blog.asymptotic.co.uk/2014/03/the-safe-bool-idiom-in-c/#comments Wed, 12 Mar 2014 22:50:00 +0000 http://blog.asymptotic.co.uk/?p=1026 I’m in the process of writing a series of articles on C++11, and a passing explanation of this idiom grew to become a whole article. There’s no original content here, but I learned something in writing it and I hope it might be useful to someone out there.

It’s idiomatic C++ to evaluate a variable in boolean context, even when it’s not a boolean variable, to detect whether that variable is “not a thing”. For example, with a pointer variable it checks whether the pointer is null or not:

if (my_pointer) {
   // my_pointer is not null
}

Exactly what this boolean conversion means varies by type, but experience shows that one’s intuitive sense of how this should work is pretty consistent and this can make code more expressive. Some would say this is bad practice, but for now I’ll assume that it’s desirable.

If you’re writing a user-defined class, you want to follow this kind of pattern if possible. If 0 is false, then surely the (0, 0, 0) point in a 3D space is false? Of course, C++ lets you make your user-defined type act pretty much however you want it to, so of course you can define an implicit conversion to bool:

struct TestResult {
   //...
 
   operator bool() const {
      return m_passed;
   }
};

The problem with this is that it’s not just a conversion to bool. It’s a conversion to a type that is part of a system of numeric types, and the types allow conversions between them that allow you do do silly things. For example, you can assign it to an integer:

TestResult test_result;
int i = test_result; // Should really be a compile error

More insidiously, things like the left-shift operator suddenly work on your objects in ways that you might not expect:

test_result << i;

As is the way with all C++ design issues, you can get around this by careful application of edge cases of language tools that were meant for something else. You can expose a conversion to any type you like. Void pointers are a reasonable thing to try, because there’s not a lot you can do with a void pointer:

struct TestResult {
   operator void *() {
      return m_passed ? this : 0;
   }
};

There’s no implicit conversion of void pointers in C++, so this seems reasonably safe. However, one thing you can do with a void pointer is call delete, and there’s no way to prevent that from compiling:

TestResult tr;
delete tr; // Gets converted to pointer, attempts to delete a stack variable!

You could try returning a pointer other than this, which could eat least mean that the code would crash horribly the moment delete was called:

struct TestResult {
   operator void *() {
      return m_passed ? (void *)1 : (void *)0;
   }
};

But this is horrible. Besides, there’s no guarantee that you won’t segfault just by referencing pointers to non-allocated portions of memory (i.e. segfault even in the good case where you’re just converting the result straight to boolean).

A common trick in C++ (which dates from an earlier related trick in C) is to give code an incomplete type to work with. If you have a class declaration in scope, but no definition, then you can handle pointers to the incomplete class but there are limits to what you can do. In particular, you can’t dereference or delete the pointer. So you can safely pass such a pointer back to the caller and allow them to compare it with NULL without worrying that they can delete it.

How can you get a pointer to a type that you can be sure won’t be defined? You define one for yourself. A nested class will do nicely:

struct TestResult {
  //...
 
  class never_defined;
 
  operator const never_defined*() {
    return m_passed ? reinterpret_cast<const never_defined *>(this) : 0;
  }
};

Unfortunately, while pointers to incomplete types can’t be dereferenced, you can still compare them:

TestResult x, y;
 
// later ..
 
if (x > y) // Really shouldn't compile
{
 // ...
}

Can we prevent this? Just one more dip into the junk draw of C++ will sort us out. One of the more overlooked features of C++: the pointer-to-member (in this case, a pointer to member function).

A pointer to member isn’t like a regular pointer. A regular pointer points to data of a particular type in the memory space. A pointer to member operates in the world of classes, not objects. The pointer to member identifies a member of a particular type on a particular class; if you have a int Foo::*, it can point to any integer member of the Foo class. When you set the value of your pointer-to-member, it points to that same member on every instance of Foo (or, equivalently, on no particular Foo instance at all).

Pointers to member can’t be compared to each other, so we can combine our conversion-to-pointer trick with a pointer-to-member and have (at last) a safe boolean conversion:

struct TestResult {
  //...
 
  typedef void (TestResult::*bool_type)() const;
  void do_nothing() const;
 
  operator bool_type() const {
    return m_passed ? &TestResult::do_nothing : 0;
  }
};

If you’re not used to unpacking these definitions, the line:

typedef void (TestResult::*bool_type)() const;

deserves some explanation. This is just like any other typedef, except that since it’s a function typedef the name of the type defined (bool_type) goes in the middle and not on the right hand side. The TestResult::* bit identifies that we’re defining a type that points to a member of TestResult, rather than a regular pointer. The remaining stuff just tells us that we’re talking about a const function that takes no arguments and returns void.

For an example of this being done in the wild, you can see the safe_bool class within Boost::Spirit.

]]>
http://blog.asymptotic.co.uk/2014/03/the-safe-bool-idiom-in-c/feed/ 1
Learning programming with stories http://blog.asymptotic.co.uk/2014/01/learning-programming-with-stories/ http://blog.asymptotic.co.uk/2014/01/learning-programming-with-stories/#comments Sun, 05 Jan 2014 12:50:58 +0000 http://blog.asymptotic.co.uk/?p=781 Over a year ago I came across Python Pals, a project to write stories that motivate young people to learn programming. I always intended to write about the project but forgot to do so.

The concept for the stories is inspired by the Bytes Brothers stories of old, and follows a similar format: in each story, the pair of young protagonists come across a problem (such as calculating the exact age difference between their parents) that gives rise to a simple solution that they work together to implement. The story contains code snippets that the reader can use to follow along for themselves.

I love the concept, and the stories are certainly a refreshing change from the status quo in teaching programming. Using female protagonists is a nice modernisation, though I found the trendy inclusion of a Raspberry Pi irritating: you don’t need a Raspberry Pi to learn to write command-line programs in Python. In fact, the Pi can only make the task harder and implies that special equipment is needed (laptops that are capable of running Python are still massively more ubiquitous than Raspberry Pi’s, despite the latter’s low price and status as a media darling).

My instinct is to worry that this story-based approach is solving the wrong problem: my own experience was that it was very easy to get started with simple command-line programs and much harder to get as far as making things that felt like “real” programs. The idea that computers could be made to do things came easily to me, but I felt that writing a tool or game that someone else would want to use was well out of my reach. I’d have been better cutting my teeth on something that made the installer and GUI easy, such as the Android platform (or even not-quite-programming environments like writing AVS presets).

But I don’t have a lot of experience teaching young people to program, and my experience was a long time ago and may be atypical, so I’m happy to be proven wrong here. I don’t think we need to be teaching all children to program, but we should be providing resources for all those who are interested. A diverse range of solutions has to be a good approach.

]]>
http://blog.asymptotic.co.uk/2014/01/learning-programming-with-stories/feed/ 2
Unused employee creativity http://blog.asymptotic.co.uk/2013/12/unused-employee-creativity-toyota-production-system/ http://blog.asymptotic.co.uk/2013/12/unused-employee-creativity-toyota-production-system/#comments Thu, 12 Dec 2013 22:57:26 +0000 http://blog.asymptotic.co.uk/?p=966 I’ve been reading about the Toyota Production System (TPS) recently. As everyone knows, one of its key principles is eliminating waste in the production system. Waste is defined much more broadly than you might first assume, but it makes sense: anything that doesn’t add value to the customer is waste.

As I looked down the list of eight sources of waste, one of them caught my attention:

  1. Overproduction
  2. Waiting (time on hand)
  3. Unnecessary transport of goods
  4. Over-processing or incorrect processing
  5. Excess inventory
  6. Unnecessary movement of staff
  7. Defects
  8. Unused employee creativity

I wasn’t expecting “unused employee creativity” to be considered, let alone to be given equal footing to the other types. There’s a tendency to think of Toyota and TPS as extremely conservative and valuing of strict procedures, and not at all open to creativity.

I think what brings these two concepts together is another Toyota principle:

“Make decisions slowly, considering all the possibilities. Act quickly.”

The decision process is conservative by virtue of taking its time and requiring evidence before something is changed, not by virtue of considering a small number of possibilities.

For a long time I’ve felt that there is a false dichotomy between the popular visions of small dynamic start-ups and conservative larger companies. Perhaps this example provides a useful model how companies can be exceptions to this rule.

]]>
http://blog.asymptotic.co.uk/2013/12/unused-employee-creativity-toyota-production-system/feed/ 0
The delusion of omnicompetence http://blog.asymptotic.co.uk/2013/12/the-delusion-of-omnicompetence/ http://blog.asymptotic.co.uk/2013/12/the-delusion-of-omnicompetence/#comments Wed, 04 Dec 2013 20:25:35 +0000 http://blog.asymptotic.co.uk/?p=977 In the context of the failure of the failure of the Affordable Care Act exchanges, Megan McArdle relates a fun anecdote about a user who expected too much from his speech recognition software:

“Hold on, please,” I said. “Can you show me exactly what’s not working?”

“It’s not doing what I want,” he said.

“What do you want?” I asked.

“I want it to be,” he replied, “like the computer on `Star Trek: The Next Generation.’”

“Sir, that’s an actor,” I replied evenly, despite being on the sleepless verge of hysteria. With even more heroic self-restraint, I did not add “We can get you an actor to sit under your desk. But we’d have to pay SAG rates.”

I’m sure we’ve all been there. But there’s a wider point made by the article, and you should read the whole thing. McArdle argues that there’s a more systematic problem with people who are smart in one domain assuming that they are equally able to handle any topic, “the delusion of omnicompetence”, as she puts it:

The technocratic idea is that you put a bunch of smart, competent people in government — folks who really want the thing to work — and they’ll make it happen. But “smart, competent people” are not a generic quantity; they’re incredibly domain-specific. Most academics couldn’t run a lemonade stand. Most successful entrepreneurs wouldn’t be able to muster the monomaniacal devotion needed to get a Ph.D. […]

Yet in my experience, the majority of people in these domains think that they could do everyone else’s job better, if they weren’t so busy with whatever it is they’re doing so well.

This is definitely consistent with my experience of software engineers, who often seem to feel that they are the most important people in the company. And I’ve certainly met academics who look down on anyone without a PhD.

An interesting thing to me is that in my experience (and I may be biased), the type of intelligence that good engineers have actually does transfer to other topics. I’ve had many a conversation about business strategy or marketing or history or politics with my fellow engineers, and I believe they are generally highly perceptive and rational.

What engineers often are, though, is ignorant. I believe one issue is that understanding of computers comes so easily to people like us that we tend to view with suspicion disciplines that require more study. It may seem like people who study history, say, are taking refuge in a subject where hours of grind can make up for lack of incisive brilliance. And that gives rise to a naive faith in perfectly logical solutions that somehow omit to deal with the real world. In other words, thinking we’re good gets in the way of being the best we can be.

This is a wild generalisation of course. But probably nearly all of us can stand to make some improvement in the degree of respect we accord to other professions, and absolutely everyone can improve themselves in some way or other. We shouldn’t let a (correct) sense of satisfaction in our achievements hold us back.

]]>
http://blog.asymptotic.co.uk/2013/12/the-delusion-of-omnicompetence/feed/ 0
Is remote work dystopian? http://blog.asymptotic.co.uk/2013/11/remote-work-dystopian/ http://blog.asymptotic.co.uk/2013/11/remote-work-dystopian/#comments Sat, 30 Nov 2013 21:42:34 +0000 http://blog.asymptotic.co.uk/?p=970 1484-office365-1

Microsoft has a new advert out, and David Heinemeier Hansson thinks it’s deplorable. He argues that Microsoft are pushing a dystopian idea of work that never stops, and busywork expands to fill the time wherever we are.

I’m not sure I agree, though I’ll definitely admit that Microsoft’s advertising people have done a poor job with the wording. One of the reasons I’m inclined to take their side is that I’ve suffered from the other extreme, when I’ve had to miss out on activities because I have to wait around in the office doing busywork just in case I’m needed while an important demo takes place or deal is signed.

The question is whether you work in a job that requires a high volume of routine work or one that intermittently requires skilled judgement for brief periods. Automation and outsourcing are killing off the former (aside from customer service, which can’t be done from a bar during happy hour anyway). Maybe I’m giving Microsoft too much credit, but it seems to me that they were aiming their pitch at the latter sort of work, in which case working (i.e. providing brief high-value responses) from your children’s sports match is liberating.

Ultimately it’s not Microsoft’s job to set boundaries in our work, we have to do it for ourselves. Technology isn’t the solution to managers who demand too much of us, but it isn’t the cause either.

]]>
http://blog.asymptotic.co.uk/2013/11/remote-work-dystopian/feed/ 0
Working a room http://blog.asymptotic.co.uk/2013/11/working-a-room/ http://blog.asymptotic.co.uk/2013/11/working-a-room/#comments Sat, 16 Nov 2013 17:45:10 +0000 http://blog.asymptotic.co.uk/?p=968 This week there was a good post about how to “work the room” at networking events, aimed at people who find this kind of thing unpleasant. You should read the whole thing, but here’s a spoiler of the main point:

Then one of my colleagues told me the trick he uses: When he walks into a room alone, he looks for pairs of people who are talking, and introduces himself to each person in the pair.

So if you see a pair of people, the chances are that they arrived together and know they should be mingling. Or else they’ve just met and are, in the back of their minds, worried that they’re going to end up talking to this one person all night.

I appreciated this post because introducing myself at networking events is something that I still don’t like doing, even though I’ve improved substantially over the years. I particularly like two things about the article: firstly, that it acknowledges that networking is a learnable skill that anyone can improve on, and secondly the point that other people hate introducing themselves too and you can use this to your advantage.

The only thing I’d add to this is to make a conscious effort to read body language. Pairs of people who are interested in meeting new people don’t face each other head-on but stand at an angle. This means they form a V shape, typically facing into the room. They’ll be giving each other less eye contact and looking at other people in the room. If you join such a group there’s a natural space for you to do it and you’re likely to be well received. If you see a pair of people squarely facing each other and not looking elsewhere in the room, the chances are greater that they aren’t ready to meet anyone new just yet.

]]>
http://blog.asymptotic.co.uk/2013/11/working-a-room/feed/ 0
Another new site http://blog.asymptotic.co.uk/2013/10/another-new-site/ http://blog.asymptotic.co.uk/2013/10/another-new-site/#comments Sun, 13 Oct 2013 08:02:49 +0000 http://blog.asymptotic.co.uk/?p=957 I didn’t get round to writing anything in September, not least because I was working on a new web site. It came about by coincidence, but since I started working on the first day of September I decided to give myself just a month to do it, from zero to usable product. Given my time budget for side projects, this is about 16 hours of work in total, so I’m quite pleased that I managed to get the project completed to a reasonable standard. Though I’m writing this in mid-October, I finished the project to schedule and then failed to write about it for a couple of weeks.

The site is called TaskMaster, and it’s a simple to-do list app. Unfortunately one of the things I didn’t fit into the month was work on documentation and usability, so it’s pretty much undocumented at the moment. One of the things I noticed in doing Anonymarks was how long the help text took to write: 2 hours wouldn’t be unreasonable for writing the copy, doing screenshots and basic layout work, and this is a substantial fraction of the time budget for the project as a whole. I don’t know whether this means I’m a good web developer or a poor copywriter, but it’s a lesson I’m going to take forward to the next project I do.

The TaskMaster concept is something I’ve used for some time, and I even had a web app that worked in much the same way a couple of years ago, written in Ruby on Rails. I had to ditch the web app when there was a Rails security scare and I couldn’t remember enough to make the dormant project safe. I’ve recreated it in Django, using Bootstrap to make the design less time-consuming.

The to-do list concept is something I’ve been refining for a while, very loosely inspired by ideas from Agile software development. It’s unusual in that every task on the list has to have a deadline, and once you’ve set it you can’t alter it in any way (except for a 1-hour cooling-off period). Tasks have importance weights added, which is intended to measure importance (impact of not doing the task) rather than urgency. Most unusually, the target isn’t to get every task completed by its deadline, but to get 90% (weighted by importance). The idea is that if you’re hitting 100% then you aren’t being ambitious enough with your goals, so 100% is regarded as a failure.

This isn’t an approach I’ve tested on anyone other than myself, but for me it works well. I like that it takes the pressure off having an enormous list of tasks to do and keeps the focus on honestly predicting what you’re going to achieve. The system rewards people who honestly appraise what they’re capable of and punishes people who load up the list with every conceivable task and then fail to complete many of them. It seems to me that people use to-do lists as if forgetting tasks was their biggest risk, when in fact I think that truly forgetting a task is rare. The real problem is that people procrastinate and use busywork to avoid unpleasant tasks, and traditional long to-do lists make this worse, not better.

]]>
http://blog.asymptotic.co.uk/2013/10/another-new-site/feed/ 0
I’ve made a new web site http://blog.asymptotic.co.uk/2013/09/ive-made-a-new-web-site/ http://blog.asymptotic.co.uk/2013/09/ive-made-a-new-web-site/#comments Sun, 01 Sep 2013 14:09:15 +0000 http://blog.asymptotic.co.uk/?p=941 For once, one of my side projects has been released to the public in a usable state. It’s a simple service that provides anonymous cloud bookmarks that you can access from any device, using only a passphrase.

I mainly came up with this as a way to try out using some Amazon web services, most notably DynamoDB. I’m pretty happy with the scalability story for DynamoDB, at least in simple cases like this where the model is a good fit for what I’m doing. The site seems pretty quick (I haven’t done any load testing yet), and the non-scalable Django portion of it is quite small. For moderate loads, it should just be a matter of cranking up the provisioned capacity in AWS. For larger loads, I could easily split across a couple of nodes and do some trivial load-balancing, because the only application state is in the DB.

I still don’t think I would be able to figure out how to do any more advanced modelling of data using DynamoDB. I’m used to thinking of data in terms of relationships between facts, and DynamoDB doesn’t make that easy at all.

As it stands, I’m suspending work on this project to do something else. I actually end up using it for myself, as something like a substitute for Delicious or Mozilla’s cloud bookmark service. There’s a lot more features I could put in to it, but I’m only going to put more work into it if people seem interested in using it. Contact me with any thoughts.

]]>
http://blog.asymptotic.co.uk/2013/09/ive-made-a-new-web-site/feed/ 0
Kid’s can’t use computers—and it doesn’t matter http://blog.asymptotic.co.uk/2013/08/kids-cant-use-computers-and-it-doesnt-matter/ http://blog.asymptotic.co.uk/2013/08/kids-cant-use-computers-and-it-doesnt-matter/#comments Sat, 24 Aug 2013 12:53:14 +0000 http://blog.asymptotic.co.uk/?p=930 This article by Marc Scott on the state of computer knowledge among young people got me angry. All the more angry because, among all the bits I disagree with, I think he has a point.

In summary, he is arguing that the widespread belief that the young people of today are knowledgeable about computers is wrong. In Scott’s view, which I largely share, there’s a mistaken conflation of being able to operate a computer with having an understanding of computers. Although the next generation of people are comfortable using computers in their daily lives, they are helpless when it comes to performing non-routine tasks or anything technical. Any abilities they do have are spoon-fed to them and they have no ability to self-teach.

The first thing that bothered me about the article was the arrogant tone. There’s nothing wrong with a good blog rant, especially on a site you own. I know I’ve done a few myself. But the article seems to aim to right some of these misunderstandings, and if so the tone is working against this by being dismissive.

Combined with the arrogance there was a vein of mind-reading being applied to the author’s opponents. It makes for good writing to tell a story involving emotional colour, but the inferred (or rather guessed-at) thoughts of one’s antagonists can’t be used as a part of your argument without further proof. In the anecdote that leads the article, Scott eviscerates the character of a young woman who asked for help with her computer, just because he didn’t like the look on her face. His characterisation may be true, but it would be a stronger argument without this.

Putting aside these reservations, I find myself agreeing with the content but somewhat disagreeing with the prescriptions. I certainly agree that there’s a lot of ignorance out there, but I don’t think there’s ever been a golden age where understanding of computers was any better than it is today.

I think things look worse than they used to for two reasons. Firstly, there’s more broad exposure to computers as thus more opportunities for people to reveal ignorance. When I was growing up, people who had no affinity for computers simply didn’t use them. Nowadays, school and jobs and so on force people constantly into situations where they have to fix WiFi problems or display a PowerPoint with the wrong version of the software.

The other problem is something that I think Scott pretty much nailed: there’s a complacency in the way older people judge the skills of younger people. If you’ve never deeply understood computers yourself, then someone who can change the WiFi password probably looks pretty similar to someone who can program a WiFi driver—hence the tedious requests to fix printers that all software developers receive. Again, while this is a problem (and a particular problem when the complacency lies in the teachers who should be educating our children), I don’t see a reason to suppose there’s a decline here.

As to the proposed solutions: clearly anything that spreads knowledge is a good thing. Parents should encourage their children to investigate the world around them and teach themselves, in computing as in anything. But I’d prefer to emphasise teaching everyone the basics rather than trying to produce a few more people with advanced skills while demotivating the rest.

A future where everyone can program is a theoretical possibility, but not with the current state of technology. If it can work at all, I think we’re missing some advance that will make it possible for people to build customised solutions with far lower cognitive load than it currently involves. And while we’re speculating about such future advances, we can probably equally well imagine that the whole concept of programming as an activity will become as outdated as scribes copying books by hand.

In lots of fields of human endeavour there are purists with deep expertise who decry the lack of knowledge among the amateurs. The same thing is true of cooking, tailoring, home repair and car maintenance. Realistically, we won’t all become experts in these things, and I don’t see why programming should be any different.

]]>
http://blog.asymptotic.co.uk/2013/08/kids-cant-use-computers-and-it-doesnt-matter/feed/ 0
Why you can’t write a good FizzBuzz implementation http://blog.asymptotic.co.uk/2013/08/why-you-cant-write-a-good-fizzbuzz-implementation/ http://blog.asymptotic.co.uk/2013/08/why-you-cant-write-a-good-fizzbuzz-implementation/#comments Mon, 19 Aug 2013 19:56:35 +0000 http://blog.asymptotic.co.uk/?p=923 At work the other day, conversation on a mailing list fell to the fact that most programmers can’t write FizzBuzz. For those of you who haven’t heard this discussed before, the point is that you set the most trivial possible programming task for interview candidates: Write an algorithm that prints numbers from 1 to 100, except that it should print “fizz” instead of multiples of 3, “buzz” instead of multiples of 5, and “fizzbuzz” for numbers that are both. A full implementation in the most straightforward way involves just two control structures: A for loop wrapping round an if condition.

Naturally, since we are all programmers and somewhat competitive, we had a go at solving the problem ourselves in the most “creative” way possible. I had a number theoretic solution (repeatedly sum the digits of the number until you have a single-digit number, then compare against 3, 6 and 9 to determine whether it is a multiple of 3) and a slightly more elegant solution involving itertools in Python: one iterator produced the “fizz”s, another iterator the “buzz”s, and an imap knitted them together into a single sequence.

My second solution was controversial: some thought it was elegant and idiomatic Python. Some thought that it was pretentious obfuscation. I’m going to argue that it’s impossible to tell which of these is true.

Good code is about the relationship between the problem domain and the representation in code. The problem domain is comprised of the stuff that is known by the person with a problem to solve. We can assume they’re intelligent, but they don’t (and shouldn’t need to) know anything about how the program is implemented. The best code preserves and makes accessible the relevant aspects of the problem domain, and minimises the interference of “accidental” details of programming that have no representation in the problem domain.

I maintain that the FizzBuzz problem domain is so badly under-specified that it’s impossible to know how a really good solution would look. There are lots of problems that are isomorphic to FizzBuzz but have different characteristics, that would (if the problem were not so trivial) ideally be approached in different ways. Perhaps “fizz” and “buzz” are two entirely different concepts that different parts of the business want to talk about, in which case my dual-iterator solution might help to make this plain. Or perhaps it’s going to be extended into some kind of number theoretic analysis, in which case we should write our code so that the mathematical properties are foremost (perhaps we introduce a prime factorisation concept from the start). Or maybe we’re writing single-use code for the accounting department to produce a report during the merger of two companies.

I hope it goes without saying that simplicity is also an important feature, and that in the case of something as trivial as FizzBuzz simplicity ought always to win out over other concerns. But sometimes when programmers talk across boundaries of industry and experience it’s necessary to treat toy problems as if they were a bit more than that, and I felt like there was some mileage in that this time.

]]>
http://blog.asymptotic.co.uk/2013/08/why-you-cant-write-a-good-fizzbuzz-implementation/feed/ 0