All roads lead to Rome

Published: January 20, 2015

Is there such a thing as ideomatic C? I'm not sure: I hear Python people talk about ideomatic Python a lot (although I'm probably still very unpythonic most of the time), and I'm convinced that functional programming in languages like Haskell and Lisp approaches the task of programming with fundamentally different ideoms than an imperative language like C. But I haven't really witnessed many conversations about the concept of ideomatic C.

Why am I asking this? This semester of EE264, the advanced C programming course for undergraduate electrical engineers at Purdue (where I am the TA), is being taught by a Lisp hacker. Which is awesome, because the Lisp-y way of problem solving is sometimes quite different from the way I would approach a simple problem.

One issue that came up during class was the problem of counting the number of letters in a string (It's week 2 of the semester). Recall that in C, strings are represented as arrays of characters, terminated with a zero delimiter. In memory, the string "Hello World!" would look something like this:

'H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd' '!' '\0'

To be a valid C string, every string has to be terminated by the zero delimiter '\0'. Now if I were to be tasked with the problem of counting all the letters in a string, I'd do something along the lines of this:

size_t my_strlen(const char * str)
{
  int len =0;
  while (str[len] != '\0') {
    len++;
  }
  return (size_t) len;
}

Loop over the whole string, exit the loop when you hit the zero delimiter, and keep a count as you go. Sounds perfectly simple and clear to me. Why would I do such a simple task any other way?

To teach the concept of a callstack, the instructor presented this very Lisp-y solution to the letter-counting problem:

size_t my_strlen(const char * str)
{
  if (*str == '\0')
    return 0;
  else return 1 + my_strlen(str+1);
}

Recursion! To count letters in a string. It is perfectly clear to me that this works, but I also know that I personally approached the problem from a completely different viewpoint. If there is such a thing as ideomatic C, the first way is probably it, but that does not mean that the recursive approach is wrong.

I doubt that there are any significant differences in performance between the two solutions (although I did not test this), but the interesting thing to me is the fundamental difference in the way how the same problem was approached. There are probably many other ways of doing this, some more elegant and some less, and in teaching C, I will inevitably be exposed to all of them.

Apart from programming, little things like these teach me another lesson: When trying to solve a problem, one should try to 'think outside the box' as much as possible and consider input and opinions from a variety of sources and a variety of people.

Let's hope that I follow my own advice and use as many sources of knowledge as possible to solve the problem in my next blog post, which will be a lot more mathematical than this one.

Dennis