Categories
Uncategorized

The Humble Programmer

In 1972, Edsger W. Dijkstra published a paper titled The Humble Programmer. Dijkstra was trained in math and physics and was a university professor for much of his life. This paper is an interesting reflection on the history of computers and contains thoughts for the future. A few quotes are included below:

Categories
Uncategorized

Why are Go applications so reliable?

Go does a lot of things well (good performance, easy to learn, very productive, extensive stdlib, excellent tooling, etc), but after programming with Go for three years (both embedded Linux and cloud applications), stability is the characteristic that really stands out.

Categories
Uncategorized

C++ callbacks to member functions

How to properly do callbacks to C++ member functions is something that has intrigued me for some time now.  There are a number of solutions, none of which I really liked.  But now with the std::tr1::function and std::tr1::bind functions, there appears to be a clean solution.

In the past, if you wanted a callback to a C++ member function a typical approach was to create a static function wrapper as described here.  However, this is ugly, and a step backwards from the capabilities of plain old C.

std::tr1::function is a function wrapper that can be used to create function objects for a number of scenarios.  We are interested in representing class member functions.

#include <tr1/functional>

struct X {
	int foo(int);
};

std::tr1::function<int (X*, int)> f;

f = &X::foo;

X x;
f(&x, 6);

f() is now a simple function representation that can be passed around, etc.  However, what we don’t like is the reference to the struct X type, which makes it much less generic.  This is where the std::tr1::bind function comes in.  With bind, we can dynamically bind one function to another, and re-arrange the arguments, etc.  So to make a generic portable function that points to X::foo(), we can do something like the following.

#include <tr1/functional>

struct X {
	int foo(int);
};

std::tr1::function<int (int)> f;

X x;
f = std::tr1::bind(&X::foo, &x, _1);

f(6);

Now, f() is a very generic function that could be used in various interfaces without specifically referencing struct X.

A more complete example of how callbacks might work is given below:

#include <iostream>
#include <tr1/functional> 

struct B
{
  std::tr1::function <void ()> _callback;

  void reg_callback(std::tr1::function <void ()> callback)
  {
    _callback = callback;
  }

  void unreg_callback()
  {
    _callback = NULL;
  }

  void process() {
    // simply calls callback
    if (_callback)
      _callback();
  }
};

struct A
{
  B * _b;

  A(B * b) :
    _b(b)
  {
    std::tr1::function<void()> callback;
    callback = std::tr1::bind(&A::callback, this);
    b->reg_callback(callback);
  }

  ~A()
  {
    _b->unreg_callback();
  }

  void callback() {
    std::cout << "A::callback called\n";
  }

  void process() {
    _b->process();
  }
}; 

int main()
{
  B * b = new B();
  A * a = new A(b); 

  // the following is example where object b calls
  // back into a method
  // in object a
  a->process();

  // now delete object a, and verify the callback
  // in B does not crash or still get called
  delete a;

  // now b should not execute the callback
  b->process();
}

In the above example, the callback in the object a will be called once.

Categories
Uncategorized

Specialization or not

I have often wondered about specialization.  We can often find ourselves in ruts if we specialize too much.  But on the other hand, specialization can lead efficiencies in some cases.  In my work as a consultant, I often find myself in new situations where I have to learn fast.  As one of my associates states — problem solving is the key skill.  Kevin Barnes article Three theories on how to use developers efficiently is a good read about the subject.