Introducing InFact library
January 16th, 2014 | Published in Google Open Source
Have you ever heard of Greenspun’s Tenth Rule? It says
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:
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