opensource.google.com

Menu

Introducing InFact library

Thursday, January 16, 2014

Have you ever heard of Greenspun’s Tenth Rule?  It says
Any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
This is remarkably true in practice, especially when it comes to configuring a large system at run-time. For programming languages like Java that have full reflection capabilities, one can use the language itself as a way to execute code on the fly, as is done by the BeanShell library. In C++, there is no equivalent mechanism.

Today we announce a new, lightweight library called InFact that serves as an interpreter and factory for C++ objects.  Since C++ does not have reflection, we require a tiny bit of help from the programmer, but we have kept that burden very low. InFact can interpret a set of assignment statements at run-time, then the programmer can access variables from the interpreter’s environment. The language is small and formally specified, and intentionally bears close similarity to C++ itself. The interpreter is also lightweight.

The language supports the most common primitive types (bool, int, double and string), objects that are constructed via a Factory class, as well as arrays of primitives or objects, and it can construct objects that wrap other objects.  Here’s a brief example:
// Construct a cow with a required argument, its name.
Cow c1 = Cow(name("Bessie"));

// Construct a second cow with a different name, and an optional age.
// Also, specifying a type is optional, since InFact does type
// inference.
c2 = Cow(name("Lani Moo"), age(2));

// Construct a human pet owner with the two cows as pets.
PetOwner p = HumanPetOwner(pets({c1, c2}));

InFact evolved from the Reranker Framework open source project, which uses it as its configuration mechanism.  InFact is available today from Google Code at http://infact.googlecode.com/

By Dan Bikel, Senior Research Scientist

.