Showing posts with label project: Dynamic Scoping. Show all posts
Showing posts with label project: Dynamic Scoping. Show all posts

Saturday, September 10, 2011

Dynamic scoping in C++

I've had ideas for dynamic scoping before. There are pros and cons with dynamic scoping, as is explained at the emacs wiki.

Last time I implemented it in Java, this time I'm trying to get something more primitive (compared to the Java implementation) working in C++ (it should be straight-forward to port to C).

The use-case I had in mind when implementing this was how to distribute loggers or hierarchical configurations to every part of an application. In such code is is usually required to pass a Logger or a Configuration around to basically every function. However, with the approach described here, there is no need to pass stuff around like that, instead one uses stack-searching technique.

This little demo demonstrates the idea:
int func1() {
  TaggedInt i1(1);
  printf("i1 = %d\n", findClosestTaggedInt());
}

int func0() {
  printf("i0 = %d\n", findClosestTaggedInt());
  func1();
}

int main() {
  TaggedInt i0(0);
  func0();
}
When run, the following is printed:
i0 = 0
i1 = 1

Ok, what happens here? It's pretty simple. The class TaggedInt is a class that holds two values. A tag and an int. The function findClosestTaggedInt searches backwards through the stack until it finds the tag of a TaggedInt object and returns the corresponding int of that object.

In a real application the int would probably be replaced by something else, like a pointer to a LogConfig object or something similar. Further more, the findClosestTaggedInt would be replaced by findClosestTaggedLogConfig and probably not be used explicitly like in this demo, but rather implicitly in a constructor of some other object such as Logger. For instance:
void func() {
  Logger logger; // findClosestTaggedLogConfig is called by the ctor.
  logger.warning("Something is happening!");
}

int main() {
  LogConfig config(std::cerr); // This is a tagged object.
  func();
}

Now, there is a problem with this approach. Searching through the stack is an expensive operation, and not something you should do often. That implies that findClosetsTaggedXYZ should only be rarely called, or when the program is not in a time-critical phase. However, since findClosestTaggedXYZ is only used when distributing an object throughout the application (not when the object is used) this can usually be done once at application start-up and never again.

To sum up, here's a the rest of the code for running the demo above:
#include <string.h>
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>

static const unsigned TAG_SIZE = 16;
static const char TAG[TAG_SIZE] = "my magic string";


// A tagged int is an magic tag followed by an int. The tag
// *must* be at zero  offset relative to the 'this' pointer.
class TaggedInt {
  char tag[TAG_SIZE + sizeof(void*)];
public:
  int variable;
  TaggedInt(int variable) : variable(variable) {
    // Setup the tag.
    memcpy(tag, TAG, TAG_SIZE);
    TaggedInt* self = this;
    memcpy(&tag[TAG_SIZE], &self, sizeof(self));
  }
};

// Find which direction the stack grows.
int stackDirection() {
  int first;
  int second;
  int diff = intptr_t(&second) - intptr_t(&first);
  return diff > 0 ? 1 : -1;
}

// The maximum number of bytes to search backwards through

// the stack for the  tagged int before giving up.
static const unsigned STACK_SIZE = 1024 * 1024;

// Search backwards through the stack for the first tag.
// Note: this might be possible to optimize by a large factor

// by knowing the  alignment of stack allocated variables.
int findClosestTaggedInt() {
  static const unsigned ALIGMENT = 1;
  int direction = stackDirection();
  char start;
  for (char* ptr = &start; ptr != &start - STACK_SIZE;

       ptr -= direction * ALIGMENT) {
    if (0 == strcmp(TAG, ptr)) {
      TaggedInt* tagged;
      memcpy(&tagged, &ptr[TAG_SIZE], sizeof(tagged));
      return tagged->variable;
    }
  }
  assert(false);
}

With this code you should have a fairly good start for implementing something more useful, such as a distributor of Loggers or Configurations.

One last thing, I would be really interested in hearing from any anyone that figures out how to compute the ALIGMENT constant in findClosestTaggedInt to increase performance while still making sure no tag is missed.

Sunday, April 6, 2008

Approximating other people and dynamic scoping

I have a theory (or rather a hypothesis) that you can approximate how other people react, think, do, etc, in a given situation by asking yourself: what would I have done in the same situation.

Yeah, I know its sound pretty stupid... because we're all different, right? But for small things like "It such nice weather. I really like an icecream. I wonder if I have to stand in a long queue to buy one" it work fairly well. In this example, I probably would have to wait a while to get an icecream, because if I want an icecream other people will as well.

To get to the point, when applying this "theory" on my latest micro-project I realized that having to call the done() method to close a dynamic scope annoy a lot of people. Why? Because it annoys me. Here are a few reasons for that:
  • it's an implementation detail that is irrelevant to the service the Scope class provides;
  • in some sense it exposes implementation;
  • it's a detail that is easy to forget;
  • forgetting to call done() will not break your code in all cases, thus, doing so is a hard-to-find bug.
In summary, the Scope class sucks. Let's make suck a bit less.

Instead of explicitly pushing and poping objects to the Stack<Object> that Scope contains I'm using the call stack of the current thread. That is, when the Scope.of method is called it looks at the current call stack and finds where a new scope was created. This makes the done() method redundant and fixes the problems with the Scope class that annoyed me.

Searching through the call-stack is heavier on the CPU, but it's easier on the programmer - a trade-off I'm willing to make. There is also a bit of memory overhead because Scope now contains a map that holds object that otherwise would not exist at all or be possible to garbage collect. Again, a trade-off I'm willing to make.

To conclude, with the new version of Scope it's now possible to do
new Scope(someObject) { {
  methodCallingMethodCallingMethodCallingMethodUsingThatObject();
} };

instead of
new Scope(someObject) { {
  methodCallingMethodCallingMethodCallingMethodUsingThatObject();
} }.done();

which is a Good Thing.

Friday, April 4, 2008

Dynamic scoping as alternative to Singletons

The Singleon pattern is one of the most misused design pattern. Singletons is basically gloryfied static methods and global data, which makes the code hard to test, hard to extend/inherit/reuse, hard to multi-thread, etc.

Most of the time singletons is not necessary since a single instance of the class can be created at start up and then passed to objects that need it. This has the downside that you have to pass the used-to-be-singleton-object to a class A just because it creates a class B which needs the used-to-be-singleton-object. Yuck!

Seriously, designing software properly takes enough time as it is, I don't need more tedious details to worry about. Just make it work! Just give class B an object that provides it with the services it needs.

So, what's the alternative then (hint: title)? Dynamic scoping in Java, of course!

I think a disclamer is in order: I don't consider dynamic scoping to be the best solution to the problem described above. If it is possible redesigning the code such that its maintanability is improved without usins dynamic scoping, then that is much better. If this is not possible, however, then dynamic scoping may be the solution you seek. Now, let's discuss how to implement this scoping business.

I would like a way to express "from now on, every time I ask for a class A, give me the instance of that class that is on the top of the stack", where stack means the stack where all the variable in the dynamic scope is stored. Also, I would like to express that an object is pushed to the dynamic scoping stack like this:

// place 'object' in the dynamic scope
scope (object) {
  // code calling code calling code calling code using 'object'.
}
// 'object' is not in the dynamic scope anymore

where scope is a new keyword I made up for the sake of the discussion. Allrighty then, how can that be done i simple Java? Simple answer: it can't, Java isn't close to expressive enough to let the programmer define new control structures and keywords. We have to do like this instead:

new Scope(object) { {
  // code calling code calling code calling code using 'object'.
} }.done();

Neat! But wait a minute... how do we get an object that is placed in the dynamic scope? It easy, like this:

ClassOfObject object = Scope.of(ClassOfObject.class);

As you can see there is no way to say "I want that (points with finger) instance of ClassOfObject", you can only say "yeah, whatever, give me something I can do X, Y, and Z with". This may appear to be a limitiation, but its actually a feature: it keeps encapsulation and its overridable (it's possible to push another instance of ClassOfObject to the dynamic scoping stack, which then will be returned whenever someone (inside that scope) calls Scope.of(ClassOfObject.class)).

And this is how the Scope class is implemented, and here are some simple test-cases.

The Scope class is, of course, not thread-safe, because it would be a mistake from my side to even try accomplish thread-safety...