Tabular-C++ Guide
Introduction
Most of us remember when we first started to program, that we should be fighting with our language of choice for it to do something we know fully well we could do ourselves. For me, those days are quite far behind me, but that hardly makes me a programming savant.
When working on anything larger than a toy project, one often struggles less with getting basic functionality, but rather with the design of tha application as a whole. There are number of goals we tend to keep when writing our programs:
- To make our code easy to understand, both for ourselves, as well as other developers.
- To segment our code into differnt modules or source files, so that we know where to insert additions and changes
- To make code reusable
The quest to meet these goals, is what spawned the adoption of the commonly used object-oriented style of programming. In this style (using C++ or Java as an example), much of our data is encapsulated in classes, which are also host to methods which deal with that data.
This style allows for a fairly intuitive workflow while writing software, since as humans we tend to think of data (positions, colours, etc.) as belonging to an object. We also think of most actions as being performed by objects, often on other objects.
Object-ortiented programming is not however without its problems. There are some actions for which it is difficult to decide whose responsibilty it is to perform (i.e. which class a method should go in). Considering classes as existing in some sort of hierarchy, it is also not difficult to see that sibling interactions can be rather challenging. Even if we figure out a way to do this, our arrangement would be unstable to data refactoring.
And there, is the clincher. In order to sensibly develop an application in the object-oriented style, it important for us to have a solid idea of both the data and logic structure from the get-go. Maybe we don't need to be 100% sure, however any mistakes we make in our initial conception will be paid for in a painful bout of refactoring.
For some it may be different, but for me this requirement of a solid conception from day one, is in outright denial of the nature of software development. My first language was Java, the quitessential object-oriented language. Whenever I felt ambitious and tried to make something big, I always ran into this refactoring issue. Each time I would work on a project, there would be a change I wanted to make which would require a fundamental change in the program's structure.
What was I to do? Well that is something I failed to address for many years. Something I could have done, is to learn the infamouse design patterns that progressional programmers study. I am still yet to do this properly, but from what I understand now, the necessity to study such formal patterns is simply an indicator that something better must exist. I had heard about data-oriented programming, and was enchanted by its philosophy:
The Basic Principle of Data-Oriented Programming (DOP)
Data is data, and logic is logic.
Logic operates on data, but data does not own logic.
- Data is easily accessed wherever it's needed, and can be recontextualised without too much effort
- Data which are used together occupy contiguous memory
Implementing a table-based model is easier in some languages than others. In Python a table might be constructed as collection of arrays, and all the important table update functions can be written quite generally due to Python's non-static typing. In C++ however, things are not so simple (or at least as far as I can tell). Created by yours truly, Tabular-C++ aims to help developers construct and use tables in C++ via:
- A general class to represent tables and member functions for the most common operations.
- A set of macros to construct the class code which represent a particular table
- A Python script which can covert a Python module into the necessary macros to construct a table.