Code Reviews - the rules

2015-08-05, , , Comments

The rule is: no code gets checked in without a review.

It’s not always easy to get a reviewer to sign off a changelist. Does the code build? In all configurations and on all platforms? Do the tests pass? Are all new code paths covered? Does the commit message describe the change? Does the formatting match the style guide? Does the code match its surroundings? How about documentation, compiler warnings, license requirements?

Is the change really necessary? Could it have been realised more simply?

Certainly the reviewer’s task is easier if the task has been paired on. Small and self-contained changelists are more straightforward. Removing code, too, should be less contentious.

Depending on infrastructure, some checklist items can be automated. Ideally the changelist has already been though CI, for example, ticking the builds-cleanly and passes-its-tests boxes.

So far, so what? (So obvious!)

Here’s another rule, and one I’ve not seen written down before.

When I review code I might well consider how I would have made the change. That doesn’t mean I’ll insist the submitter does things my way. In the absence of automated formatters there will be more than one acceptable way to lay out the code. Sometimes there’s little reason to prefer an explicit loop over an algorithm + lambda combination, or vice-versa. Short names work for me but not for everyone. It’s hard to argue against test coverage, but is more always better?

In such cases I won’t try to impose my own style on the changelist. Instead, the question becomes: does the code match the standards we, as a team, have set? Or, do these changes merit a place in our codebase?

It’s a simple principle but not an obvious one. It helps me review fairly and also to learn from others on my team.

There is more than one way to do it!

Programming Paired and Shared

2015-05-27, , Comments

We pair program where I work. Two people, one desk. It can get intense.

Floor cleaner Emacs

Editor wars claim few casualties — until an emacs and a vim user are forced to share a keyboard and screen, that is. Anyone for notepad?

Sharing the typing isn’t why we pair. Where I work we also do code reviews. Whilst pair programming is encouraged, code reviews are mandated: code cannot be checked in until approved by a reviewer. That reviewer could be the person you paired with, and it soon becomes apparent that reviews conducted with a pair go more smoothly than ones where the reviewer is new to the task. It’s hard for someone to review a tricky changeset without the context of its development.

The context of its development turns out to be paramount for understanding a codebase, not just a changeset. Pair programming helps provide that context.

The term pairing serves better than pair programming. The former suggests sharing; the latter, typing. The benefits come from sharing all aspects of the work: decisions and responsibility; research, design, development; how to test; where to cut corners and where to go beyond the immediate requirement; when to take a break. Anyone for table football?

Edd and Bridget vs Bridget and Edd

Jokey Code?

2015-05-11, Comments

Choose Talks

I usually leave it as late as possible before deciding which sessions to attend at the ACCU conference. There’s ample time to study the schedule when you’re there and anyway, it’s subject to change.

This year I stuck with this policy with a couple of notable exceptions. First, there was my own talk, where I noted that computer programmers are writers who impose formal constraints on their texts, and who can learn from other writers who practice the same discipline. Second, there was Peter Hilton’s talk, “How to name things — the hardest problem in programming”, in which he argued more generally that programmers had much to learn from writers.

I had to see Peter Hilton’s talk and it did not disappoint. It engaged me at the time, in discussions afterwards, and it continues to make me think. I won’t post a full response here but I do want to consider one aspect: humour.

Tell Jokes

Peter Hilton argued we should pay attention to tips from the likes of George Orwell and Stephen King because their advice is better written and also because it’s funnier. Why does this humourous aspect matter? Well, perhaps we’re more likely to listen to someone who makes us laugh. Witty advice sounds less pompous.

It goes deeper than this, though. Another point from the talk:

Improve your general vocabulary. Read books, especially funny novels.

Why funny novels? At this point in the talk Peter Hilton disingenously suggested such books were easier to read. A point he made later goes deeper:

Tell jokes … Puns are important for naming, because they rely on double-meanings. Spotting double-meanings is the essential skill for avoiding ambiguous names.

Interesting! I agree that word play and word power are linked: but do you need to be a punster to avoid ambiguity? I’m not sure. In the words of Chris Oldwood:

I’ve been writing more functional code lately. I recently tried a few numerical recipes with currying functions, but all I got was a NaN.

all I got was a NaN

Laughable Code

Is there a place for humour in code? Rarely, I’d say. Code is read, re-read and then read again: most jokes become tired and then irritating under such scrutiny. Peter Hilton, though, described his amusement on discovering this function, which configures and starts Apache Camel:

/** Configure and start Apache Camel */
def mountCamel() {
    Logger.info("Starting Camel...")
    val context = new DefaultCamelContext()
    configuredRoutes foreach { route =>
        context.addRoutes(route)
    }
    context.start()
}

The obvious alternative, startCamel(), just isn’t funny enough, apparently. I’m glad the author resisted the temptation to call it humpCamel().

I’m reminded of a colleague with a fondness for franglais who would, for example, check in a graphics routine called do_le_render(). Mildly amusing first time round, maybe, but less so each time it got revisited to fix les bugs.

Ark of Desert - Camel

I don’t see many jokes in the code I read and I don’t think it’s because the authors lack a sense of humour. Just as good documentation should inform rather than entertain, good code should express complex ideas as plainly as possible: humour doesn’t get a look in.

There are exceptions. We’ve already seen the name “camel” used for something which isn’t a camel: libraries, products and projects can benefit from short, memorable and quirky names. In unit tests, too, code is less complex, which can leave space for quips and in-jokes. When an integer is expected it often turns out to be 42. Binary input data is laid out to form strange messages when viewed as hexadecimal. If some text — any old text — is needed, lorem ipsum would indicate a lack of imagination. Even so, well-chosen names and values from the domain under test would probably be more helpful when a failing test needs fixing.

Charming code

I’m down on jokes in code but I do think code can be a pleasure to read and that well written programs can delight. Whilst I agree with Peter Hilton’s recommendation to read widely and well, I was surprised he didn’t recommend reading code, and when I discussed this with him afterwards he asked, where is it? Where is it! That will be the subject of another article, but off the top of my head, freetype, ffmpeg, llvm, the Go and Python standard libraries. If you read through any of these you’ll enjoy their clarity and internal consistency — their style; and should you code against them, these same attributes show through their interfaces.

I haven’t found any jokes in the SQLite source but if you decide to integrate it in your application, when you check the license you’ll find, instead, a blessing. This may seem funny — unusual, certainly — but it’s actually quite serious.

May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.

We may not issue blessings with our own code but maybe we can find other ways to surprise and delight.

Election Manifesto - a timely activity for agile retrospectives

2015-04-29, Comments

Did I mention that I’ve become scrum master for my team? I have now. It’s a new thing for me (and for this blog) but I enjoy it, especially running the retrospective meetings. You have to keep these fresh and one way of doing this is to connect them with what’s going on in the world outside: the Oscars, the eclipse, the general election

With a week to go, my vote has been posted. So, here’s an activity I devised for a recent retrospective. We were focusing on infrastructure issues and trying to come with improvements. For this, it worked well.

Ask the team to split into three or four “political” parties. Each party must come up with a manifesto for change. What isn’t working? How would they improve things, given the chance? After 20 minutes of discussion, reconvene and ask the party leaders to present their manifesto to the electorate. Be prepared for tough questions and heckling!

Now it’s time to plan a brighter future. Summarise the key points of each manifesto and write them up on sticky notes, using different colours for the different parties. What do the parties agree on? Which promises are unrealistic and which can be delivered?

For more retrospective ideas, I recommend Retromat by Corinna Baldauf. You can find another suggestion of mine, #tweetmysprint, on the Retromat and I’ve submitted this one too.

Speaking at the ACCU Conference 2015

2015-04-28, , Comments

This time last week I was on my way to the ACCU 2015 conference in Bristol. The past couple of years I’ve been, but for one day only. This year, as a presenter of a full length (90 minute!) session I got to go to the whole thing.

Being a speaker made all the difference. Having the chance to attend plenty of sessions meant I was more relaxed about choosing which ones to pick — each slot during the day offered 5 options — and less upset if I thought, 10 minutes into a presentation, that I could have picked something else. Perhaps as a consequence of this, I was happy with all my choices. That said, I’d love the whole thing to run again so I could take a second route through the schedule.

I’d run a couple of practice versions of my talk at ACCU local groups in Bristol and then in Oxford, which meant I was comfortable with the material and convinced it would hold an audience’s interest.

Some things to consider for next year:

  • I’m going to submit another talk proposal, and if it’s accepted
  • I’ll practise it twice, at least and
  • I’ll get a remote control.
  • My laptop is too bulky for comfort. Dirk Haun ran his talk from a tablet. Could a phone be used?

My lightning talk ☞ Life A User’s Manual.

Slides for my main talk ☞ Lessons from the OuLiPo.

I would like to thank all the organisers of the conference, everyone who presented, and everyone who attended. Especial mention to Jon Jagger who announced that this would be his last year as conference chair. Let’s hope that in future years the mail bag continues to be inundated with letters! Pete Goodliffe too deserves a special mention for setting up three excellent lightning talk sessions. Controlled anarchy — he’s good at it!

2147483647

2015-02-12, Comments

Magic!

When software developers refer to “magic numbers” they mean those numeric literals which appear in a program without explanation — as if by magic. Consider the mysterious figures in this incantation:

int cigarettes()
{
    return 365 * 20 * 10 + 2 * 20 + 17;
}

Why is the 20 repeated? Does the first 20 mean the same as the second one? Could 365 be the number of days in a year? Named constants would make the code easier to read and maintain.

Some numbers truly are magical though.

2147483647

The number 2147483647 is special and terrible.

It’s a substantial number, far greater than the number of goals Lionel Messi has scored or the number of hot dinners I’ve eaten, and comparable with the number of heart beats in a lifetime or the number of instructions a processor executes in a second; but it’s not that large. You’ll need more than 2147483647 bytes to install a modern operating system, let alone store your video collection. And shuffling a pack of just 52 cards has 80658175170943878571660636856403766975289505440883277824000000000000 possible outcomes.

If 2147483647 isn’t remarkable for its size it certainly has a noteworthy history. In 1772 the Swiss mathematician Leonhard Euler proved it a prime. I’m guessing it was the largest known prime at the time. Euler didn’t have a computer to hunt for primes so he narrowed the field by focusing on Mersenne numbers — numbers one less than a power of two — a strategy which remains a winner even today, when computers are networked to search.

Actually, 2147483647 is a double Mersenne prime, which is to say it takes the form 2m - 1, where m itself takes the form 2n - 1.

>>> 2**(2**5 - 1) - 1
2147483647

Magic!

Dragons!

2147483647 has a special significance for C programmers, who know it by the name INT_MAX, and for C++ programmers, who demystify the digits as std::numeric_limits<int>::max().

Remember, 2147483647 is Mersenne(Mersenne(5)), which is Mersenne(31), or 2 to the power 31 minus 1. In binary arithmetic you add a zero on the right to multiply by 2 so 2 to the 31 is 1 followed by 31 zeros; and subtracting 1 leaves 31 1’s. It’s the largest signed value you can fit in a 32 bit register.

>>> mersenne31 = 2**31-1
>>> bin(mersenne31)
'0b1111111111111111111111111111111'
>>> hex(mersenne31)
'0x7fffffffL'
>>> mersenne31
2147483647L

It’s quite possible to inadvertantly increment an int which has reached INT_MAX. The result is undefined behaviour: anything could happen.

Gangnam Style

We never thought a video would be watched in numbers greater than a 32-bit integer (=2,147,483,647 views), but that was before we met PSY. Gangnam Style has been viewed so many times we had to upgrade to a 64-bit integer (9,223,372,036,854,775,808)!

youtube developers

Psy

Exactly what undefined behaviour was provoked when PSY’s popularity broke the magic limit isn’t disclosed. Maybe a server leaked account details to North Korean hackers. Or maybe the video’s viewing figures were wrong for a while.

Note that the new limit of 9,223,372,036,854,775,808 is an unsigned value, which is exempt from this flavour of undefined behaviour and wraps to zero when you bump it up.

Bugwards compatibility

There’s another reason for preferring INT_MAX to the magical 2147483647: the two values might be different. 2147483647 is 2147483647 but INT_MAX depends on the implementation.

A modern computer probably has 64 bit registers making a 64 bit int a more natural choice. However, for compatibility reasons, ints may intentionally be limited to 32 bits!

Lessons from the OuLiPo

2015-01-12, , , Comments

I’m delighted to announce that my talk, Lessons from the OuLiPo, has been accepted for the ACCU 2015 conference.

Slide 1

The talk follows up on a lightning talk I gave at my employer’s last year about Georges Perec’s masterpiece, Life A User’s Manual. Click the graphic below to play the animation and read the transcript.

Knights tour

I’ll be giving a preview of the full version here in Bristol in a couple of weeks. I hope you can come along. More details on Meetup.

In the meanwhile, the next section of this page introduces the ideas I’ll be exploring in my talk.

§

As software developers we often ponder what it is we do: are we architects, engineers, or scientists? Are we — gasp! — rock stars or ninjas? Which metaphors best fit? Tending a code base is like gardening. Through the seasons we encourage new growth, whilst pruning back dead code and squashing bugs. Programming is like carpentry, maybe. Select the right tool from a set kept sharp and ready for action. Programming is like cooking. Source the finest ingredients and follow the recipe.

I think there’s a more obvious metaphor. Actually there’s nothing meta- about it. It is what we do.

We’re writers.

We write to communicate and to instruct. We write for fun and profit. We edit and adapt. We rewrite. We borrow text from other writers. The languages we think we write in — C++, Python, Javascript — are actually just highly stylised dialects of our native tongue. Like poets we’re particular about punctuation and space. We have strange ideas about spelling. The texts we write, programs, are subject to formal constraints.

We’re writers bound by mathematical rules.

November, 1960. Paris. The poet Raymond Queneau organises the first meeting of a group which will become known as OuLiPo. A dozen turn up: writers, mathematicians, pataphysicians and surrealists. Their mission: to explore the literary potential of applying mathematical constraints to texts.

Of course constrained writing is nothing new — consider the haiku: 17 syllables, arranged as 3 phrases of 5, 7 and 5 syllables, a Japanese form many centuries old — and one strand of the OuLiPo’s efforts is devoted to researching past experiments and structures; but I claim it’s no coincidence the OuLiPo emerged at much the same time as our own novel form of constrained writing: computer programming.

In this talk I’ll discuss the OuLiPo in more depth, investigating the parallels between their work and ours. We’ll focus on Georges Perec, whose book Life A User’s Manual is an Oulipian tour de force. There will be some code, as well as quines, easter eggs and — as you’d expect — bugs.

Why zip when you can map?

2014-12-16Comments

Why zip? when you can map?

You’ve got a couple of parallel lists you’d like to combine and output, a line for each pair. Here’s one way to do it: use zip to do the combining.

>>> times = [42.12, 42.28, 42.34, 42.40, 42.45]
>>> names = ['Hickman', 'Guest', 'Burns', 'Williams']
>>> fmt = '{:20} {:.2f}'.format
>>> print('\n'.join(fmt(n, t) for n, t in zip(names, times)))
Hickman              42.12
Guest                42.28
Burns                42.34
Williams             42.40

Slightly more succinctly:

>>> print('\n'.join(fmt(*nt) for nt in zip(names, times)))
...

If you look at the generator expression passed into str.join, you can see we’re just mapping fmt to the zipped names and times lists.

Well, sort of.

>>> print('\n'.join(map(fmt, zip(names, times))))
Traceback (most recent call last):
...
IndexError: tuple index out of range

To fix this, we could use itertools.starmap which effectively unpacks the zipped pairs.

>>> from itertools import starmap
>>> print('\n'.join(starmap(fmt, zip(names, times))))
Hickman              42.12
Guest                42.28
Burns                42.34
Williams             42.40

This latest version looks clean enough but there’s something odd about zipping two lists together only to unpack the resulting 2-tuples for consumption by the format function.

Don’t forget, map happily accepts more than one sequence! There’s no need to zip after all.

Don’t zip, map!
>>> print('\n'.join(map(fmt, names, times)))
...

Find the average of a collection of tuples or dicts using Python

2014-12-03Comments

You’ve been running some tests, each of which returns a 3-tuple of numerical results — (real, user, sys) times, maybe — and you’d like to combine these into a single 3-tuple, the average result.

Easy!

def average(times):
    N = float(len(times))
    return (sum(t[0] for t in times)/N,
            sum(t[1] for t in times)/N,
            sum(t[2] for t in times)/N)

If you want a more generic solution, one which works when the tuples might have any number of elements, you could do this:

def average(xs):
    N = float(len(xs))
    R = len(xs[0])
    return tuple(sum(x[i] for x in xs)/N for i in range(R))

or this:

def average(xs):
    N = float(len(xs))
    return tuple(sum(col)/N for col in zip(*xs))

The second generic variant uses zip to transpose its inputs.

Now suppose we have keyed collections of results which we want to average:

>>> times = [{'real': 34.4, 'user': 26.2, 'sys': 7.3},
             {'real': 28.7, 'user': 21.5, 'sys': 6.4},
             {'real': 29.3, 'user': 22.0, 'sys': 6.9}]

If, as in the example above, each result has the same set of keys, the average result could be calculated like this:

>>> N = float(len(times))
>>> { k : sum(t[k] for t in times)/N for k in times[0] }
{'real': 30.8, 'sys': 6.9, 'user': 23.2}

What if the inputs don’t have the same keys? Consider the contents of four fridges.

>>> fridges = [
    { 'egg': 5, 'milk': 1.700, 'sausage': 6 },
    { 'beer': 6, 'milk': 0.568, 'egg': 1 },
    { 'egg': 3, 'sausage': 4, 'milk': 0.125, 'lettuce': 1 },
    { 'carrot': 4 }]

A Counter can collect and calculate the average fridge contents.

>>> from collections import Counter
>>> total = sum(map(Counter, fridges), Counter())
>>> N = float(len(fridges))
>>> { k: v/N for k, v in total.items() }
{'sausage': 2.5, 'lettuce': 0.25, 'beer': 1.5, 'carrot': 1.0, 
 'egg': 2.25, 'milk': 0.59825}

Note that although Counters were primarily designed to work with positive integers to represent counts, there’s nothing stopping us from using floating point numbers (amount of milk in our example) in the values field.

Group When

2014-07-16, , Comments

Phil Nash’s recent tweet intrigued me.

He later clarified what he was after — and had now found — linking to a solution posted a couple of years ago by Tomas Petricek. The function groupWhen splits a sequence into groups, starting a new group whenever the predicate returns true.

 module Seq =
   /// Iterates over elements of the input sequence and groups adjacent elements.
   /// A new group is started when the specified predicate holds about the element
   /// of the sequence (and at the beginning of the iteration).
   ///
   /// For example: 
   ///    Seq.groupWhen isOdd [3;3;2;4;1;2] = seq [[3]; [3; 2; 4]; [1; 2]]
   let groupWhen f (input:seq<_>) = seq {
     use en = input.GetEnumerator()
     let running = ref true
     
     // Generate a group starting with the current element. Stops generating
     // when it founds element such that 'f en.Current' is 'true'
     let rec group() = 
       [ yield en.Current
         if en.MoveNext() then
           if not (f en.Current) then yield! group() 
         else running := false ]
     
     if en.MoveNext() then
       // While there are still elements, start a new group
       while running.Value do
         yield group() |> Seq.ofList }

Here’s a nice Haskell version coded up by @sdarlington.

Maybe takewhile and dropwhile could power a Python solution, but my first choice would be itertools.groupby. Groupby chops a sequence into subsequences, where the elements of each subsequence have the same key value. A suitable key function, in this case, must change its return value every time the sequence yields an element for which the predicate holds. It could toggle between a pair of values, for example. Or it could just count the number of times the predicate holds.

class count_p:
    ''' Return a value which increments every time the predicate holds.
    '''
    def __init__(self, pred):
        self._n = 0
        self._pred = pred
    
    def __call__(self, v):
        self._n += self._pred(v)
        return self._n

def group_when(pred, xs):
    return (gp for _, gp in groupby(xs, count_p(pred)))

Here, group_when accepts an iterable and returns an iterable sequence of iterable groups. Clients choose how to consume the results.

>>> def odd(v): return v % 2
>>> xs = group_when(odd, [3, 3, 2, 4, 1, 2])
>>> print([list(g) for g in xs])
[[3], [3, 2, 4], [1, 2]]

Note that count_p does something very like itertools.accumulate. Here’s another version of group_when which takes advantage of this.

def group_when(pred, xs):
    xs, ys = tee(xs)
    accu = accumulate(map(pred, ys))
    return (gp for _, gp in groupby(xs, lambda _: next(accu)))

§

After a short break, here’s a third version of group_when. This is the first time I’ve found a use for takewhile and dropwhile. Beware: as the teed streams xs and ys diverge, the amount of backing storage required will grow … only for the stored values to then be dropped!

from itertools import *
 
def group_when(p, xs):
    def notp(x): return not p(x)
    xs = iter(xs)
    while True:
        x = next(xs)
        xs, ys = tee(xs)
        yield chain([x], takewhile(notp, xs))
        xs = dropwhile(notp, ys)
 
def odd(x):
    return x % 2
 
[list(g) for g in group_when(odd, [3, 3, 2, 4, 1, 2])] # [[3], [3, 2, 4], [1, 2]]

Word Aligned, hosted by Github

2014-03-13Comments

To anyone who subscribes to this site’s feed, my apologies if your reader recently got filled with items you’d already seen. I can explain.

About seven years ago, I signed up for a great deal on hosting for life with a company called TextDrive. For most of the time since then, this service was actually provided by Joyent — who took over TextDrive. Then they, Joyent, said the hosting for life deal was being “sunsetted”, i.e. canned. Happily TextDrive’s original founder, Dean Allen, stepped in to revive his company and honour the original offer, which has indeed happened, though it’s been all too clear that he’s been hard to get hold of whilst the operations staff have been over-stretched.

Last week, a tweet from one of these hardworking ops tipped me off that TextDrive would soon be gone.

Tomorrow!

What to do?

After some googling I’ve chosen Github pages as the new host for Word Aligned. I’ve had to relinquish a little control over URLs to make the site truly static. (A side-effect being old content appearing with new identifiers in the RSS feed). I also won’t be configuring a web server or rooting around in rotating log files. The experts at Github can take care of that.

I do get to keep my own domain, which was paramount. I don’t have to pay anything, which is nice.

Previously, I used version control to track my site’s contents and rsync over SSH to publish. Now I simply use version control: pushing a change to github is publication.

It’s early days yet, but I’m happy with the change. The feed should settle down now, so stay subscribed. Please let me know if you spot any problems with the site.

Go for short variable names

2014-03-06Comments

Recently Brad Fitzpatrick promoted the Go style guide on twitter, which prompted Tim Penhey to take issue with its advice on variable naming.

A brief and inconclusive exchange followed. Twitter’s fine for opinions and one-liners but flawed for discussions — even when the subject happens to be brevity.

I’m not going to tweet about it, but I like Go and I like its style. I’d rather read code which uses short variable names. Long descriptive names, which may appear to provide more information, often obscure the structure and flow of the code. The narrower the scope, the shorter names can be; so the style guide implicitly sanctions short functions and shuns globals. All good.

How short is short?

Those variables are certainly short rather than descriptive but they aren’t scary: c could be a character; ch for channel, maybe, or another character; d for data, difference or distance; m, midpoint; s string; st state. All guesses, of course, but in context I’d expect to see — in the space of just a few lines of code — where each variable lives and how it’s used, a more clear and correct indication of what it means than a lengthy name could ever be.

Single character variables are just fine, says the style guide:

Prefer c to lineCount. Prefer i to sliceIndex.

Some languages allow you to go further. Omit a variable in Perl and it defaults to being what you’d like it to be. Usually.

A single character variable name is an extreme form of abbreviation. It works nicely for small things, like pixels and characters.

Pixel pixel, pel, px, p;
Character character, char, ch, c;

Some less terse abbreviations hurt my ear: mngr, svr, cnt.

The style guide is, after all, a guide, and common sense applies. Some abbreviations are ugly and others save so little space they aren’t worth it.

Go’s advice on naming tips a hat to the language’s C heritage and to C’s great application, UNIX, which is unsurprising when you realise one of Go’s prominent contributors, Ken Thompson, had a hand in both. When Thompson was asked what he would do differently if he were redesigning UNIX he replied:

I’d spell creat with an “e”.

So, working on Go, he did.

You wait all day for a bus…

2013-10-02, Comments

Any and all didn’t appear in Python until version 2.5, released in 2006, when the language was already well into its teens.

Why the delay in offering such fundamental functions? An oversight? Or simply that they’re so easy to implement they weren’t thought necessary. Either way, they’re here now.

The functions are closely related and complementary. We can define any in terms of all and vice-versa.

def any_(xs):
    return not all(map(operator.not_, xs))

def all_(xs):
    return not any(map(operator.not_, xs))

C++ reached its 30s before introducing its own versions of these logical algorithms, any_of and all_of, but made up for lost time by finding room for a third, none_of, which is not any_of.

template <class Iter, class Pred>
bool none_of_(Iter b, Iter e, Pred p)
{
    return std::find_if(b, e, p) == e;
}

template <class Iter, class Pred>
bool any_of_(Iter b, Iter e, Pred p)
{
    return !none_of_(b, e, p);
}

template <class Iter, class Pred>
bool all_of_(Iter b, Iter e, Pred p)
{
    return !any_of_(b, e, std::not1(p));
}

Reverse, Esrever

2013-09-27, Comments

Reverse is a member of the C++ standard library, but its reverse, esrever, isn’t. Similarly keep isn’t but peek is.

Can anyone think of a C++ standard library member whose reverse is also a member?

Answers in the comments below.

Go!

Clown, Flee, Jump

2013-09-11Comments

The clown is running away from the circus. The contortionist wants nothing more to do with him. She’s confessed everything to her husband, the strongman, who’s after the clown’s blood. The clown has no time to pack. Hurrying from the big top he snatches up his most treasured possessions and some refreshments:

  • a makeup case
  • a box camera, with tripod attached
  • a cactus
  • a roasted goose
  • a magnum of champagne

Each item weighs exactly 3kg.

Soon he reaches the edge of a ravine. A rope bridge connected to the other side has a sign in front of it.

WARNING
UNSTABLE STRUCTURE
SAFE TO A MAXIMUM OF 75KG

The bridge is 100m long. The clown weighs 70kg. The strongman, who’s closing in, weighs considerably more. The clown must cross the bridge at once to effect his escape. How can he do so without abandoning any of his baggage?

?

Elsewhere, it’s school sports day. Conditions are perfect for the high jump — warm, sunny, still — and a talented young athlete has raised the bar to 1.85m, which happens to be his own height. On the first two attempts he fails. On the third attempt he succeeds.

High Jump

“Chapeau!” says the French teacher.

“Awesome!” says the Chaplain.

“Unbelievable!” says the head of Mathematics.

“Actually,” the sports coach says, “it’s quite simple: a combination of talent, training, and technique. He cleared his own height but his centre of gravity didn’t.”

“What nonsense!” says the mathematician.

??

Grimaldi

The clown barely breaks stride. Juggling with mismatched objects is part of his act and quick as a flash case, camera, cactus, fowl and fizz are in the air. At no point does he have more than one object in either hand so his weight never exceeds 73kg. The bridge holds. The clown gets away.

“Grrrr!” says the strongman, shaking his fists.

???