.. post:: Oct 27, 2023 :tags: programming :author: Philipp Beisel Data Oriented Programming Practice - 0 ================================================== Recently I developed the desire to think about *how* we program. An activity that you spend a lot of your lifetime on, you want to make it an enjoyable one! As a happy programmer, I am a good programmer. I want to have an easy time programming. I want to produce source code that I like. I don't want to write code that will hinder me from proceeding some time in the future. Or to put it another way, I don't want to encounter roadblocks I created myself earlier. I've had this situation so many times and I started to call it *hangover*, because it felt like waking up and finding myself in a situation where reworking the whole thing felt like an inhumane task, a total defeat. But at the same time proceeding in the same manner was not responsible, it would cause pain. Mostly the solution was some workaround or ugly hack that questioned the whole architecture so far. Then I treated it as a blind spot from then on, or kept saying 'Yeah that needs some rework some point down the line' at best. I want to refine my practice, to avoid the mentioned situation in the future. I think a key aspect is to incorporate the topics *iteration* and *refactor* into the process naturally. To review and iterate over a piece of code should not feel like destroying and rebuilding it. Another desired property of my source code shall be *inclusiveness*: to use or to work with the code should not impose any behaviour to the user, i.e., the source code should be compatible to other programming styles and practices. So here I start presenting my current programming practice! I think it is a very simple one, and I enjoy performing it. Imagine we are working in an already existing codebase and want to add a certain functionality. At first we forget all entry points and places the code should later be plugged into etc. and just open a scope: .. code-block:: c++ { //... } and ask 1. What data do we operate on? 2. What are the core lines of code that solve the problem? and then we write down these lines of code at an adequate level of quality, including some necessary input and output example data. Then, if not yet possible, we arrange it so that we can compile and run this code snippet in isolation! In my case, this often means i just put the code snippet temporarily at the first uppermost location in the main function of my program and then compile and run as usual. Before I finish this first post on programming practice, I want to provide an example. We want to print some intensity image to the console using ASCII characters. So let the input data be a two-dimensional array of intensities (float) and the output data a two-dimensional array of ASCII characters: .. code-block:: c++ #include #include #include int main() { { //input data size_t width = 50; size_t height = 20; std::vector inputMem(width * height); //fill with some values for(int hI = 0; hI < height; hI++) { for (int wI = 0; wI < width; wI++) { inputMem[hI * width + wI] = std::sin(10.0f * 3.1415f * (float)wI / (float) width) * std::sin(12.0f * 3.1415f * (float)hI / (float) height); } } float * input = inputMem.data(); //output data size_t outputSize = width * height + height; std::vector outputMem(outputSize); char * output = outputMem.data(); //map to ascii art const size_t mpN = 6; std::array mapping = {' ','.',':','o','=','@'}; for(int hI = 0; hI < height; hI++) { for(int wI = 0; wI < width; wI++) { auto inputIdx = hI * width + wI; auto outputIdx = hI * (width + 1) + wI; output[outputIdx] = mapping[ ( std::max(0.0f, std::min(1.0f, input[inputIdx])) + 0.05f ) * (mpN - 1) ]; } output[hI * (width + 1) + width] = '\n'; } //print fwrite(output, sizeof(char), outputSize, stdout); } return 0; //... } when run this produces :: o==o o==o o==o o==o o==o .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. o==o o==o o==o o==o o==o o==o o==o o==o o==o o==o .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. o==o o==o o==o o==o o==o o==o o==o o==o o==o o==o .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. o==o o==o o==o o==o o==o o==o o==o o==o o==o o==o .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. .oo. o==o o==o o==o o==o o==o This is our first prototype to solve the given problem, but how do we plug that into our existing code base? See the next post!