Archive for the ‘CodeClarity’ Category

Bye Bye mall##oc

No Comments »

Using malloc() and free() necessitates care; a lot of care. In fact, I can not remember seeing any non trivial C program, that would not have an extra memory management layer. Often a double linked list was involved and atexit() reporting of non free()ed memory. At the very least some simple reporting was going on usually redefining malloc() in terms of mall##oc(). I recently used the latter construct, to show off my superb arcane knowledge of the C pre processor, when I was met with skepticism; What was wrong with the LOC below?
redefinemalloc
To demonstrate (how little this PFY knew and) how cpp was going to balk at the recursive definition, I typed it in and, low and behold, the compiler accepted it and generated the right code. All I could do was grin. Of cause I had always realized that not adding a token to the symbol table before the whole definition was parsed would be better, but compilers just never did. Who changed this when? And would this open the door to recursive macro’s, does the pre processor do a multipass? So I ran the two snippets below through gcc -E to expand A(4).

Fail Redef
A(4)A(4 +1 +3) A(4)(4 +1 +3)

As you can see, there is some lazy expantion going on. If we RTFM, it shows that: Each macro is expanded when it appears in the definition of the other macro, but not when it indirectly appears in its own definition. Ok, I’ve learned never to trust things to stay the same, again.


Pointer To Pointer

2 Comments »

Some hold that pointers in a language like C are dangerous and hard to master. Both maybe true, but so are scalpels. Since you are reading this, you know that pointer practice makes pointer perfect. The same goes for pointers to pointers. I remember vividly when I first saw some elegant code that used a pointer to a pointer (I was working on Amoeba). It was a coding changing event. Before I would write like:
Picture 2
After I would write:
Picture 3
I’ve even used that last bit of code in job interviews. If some self proclaimed hardcore C coder could not explain those lines of code I would know they were no experts. Now that this trick is out of the bag, I will have to use an other one, next time we meet.


Fixed Width Coding

2 Comments »

No pro-programmer I know prefers a variable-width typeface to code. On first thought, a fixed-width typeface makes it easy to align statements and numbers. But one can get all that, and more, using tab-stops. So, on second thought, why do we prefer fixed-width typefaces to code? Well, in coding, things that are similar should look similar. Here are three similar lines of code, in fixed- and variable-width.

aap_noot[iii] := 4.1;
aap_noot[mmm] := 4.2;
aap_noot[jjj] := 4.3;
  aap_noot[iii] := 4.1;
aap_noot[mnm] := 4.2;
aap_noot[jjj] := 4.3;

The variable-with code, is more dense, but look how hard it is to spot the error in the variable-with code, where I hit the key left to the ‘M‘ by accident. This error would have been more obvious in the fixed-width typeface because it differentiates glyphs better. Non coders usually don’t understand why this is important. But than again, they never lost three days of work because the ‘I’ looked like an ‘l’. There are special coding-typefaces that provide good differentiation within the glyph groups 0Oo and 1liIL. There is much more to it, so if you are using whatever typeface came with your IDE, you might want to spend some time on this subject. For example read what Dan Benjamin has to say [Top 10 Programming Fonts].


Code Locality

2 Comments »

BlumaMost coders agree that non trivial [p]rograms [...] obey the principle of locality. (P.J. Denning and S.C. Schwartz) [Properties of the Working-Set Model] This principle is also known as the locality of reference and is divided in two types: temporal locality and spatial locality. However I postulate there is a third type: code locality. Ideally, source code consist of relative small blocks, each at their own level of abstraction, fully understandable in isolation. This makes sense if you realize that our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed. (E.W. Dijkstra) [Go To Statement Considered Harmful] This is why a goto needs a limited scope, a global variable needs to be constant, and multithreading needs queuing. Most agree that there exist severe limitations on the amount of information that we are able to receive, process, and remember. By organizing the stimulus input simultaneously into several dimensions [abstraction layers] and successively into a sequence or chunks [code blocks], we manage to break [...] this informational bottleneck." (G.A. Miller) [The Magical Number Seven] To prevent brain overload code locality is necessary. It will turn writing (or just understanding) code into a sequence of separate tasks where one task can be completed before the next is undertaken. "Completing the task means resolving the tension system [...] If a task is not completed, a state of tension remains". (Bluma Zeigernik) [On Finished and Unfinished Tasks] (Hint: click the photo.)


Premature Optimization

No Comments »

en_1212_upI have a confession to make. When I code, I feel like a deity. Honest I do. Rules don’t apply to me. In this domain, I make the rules. Especially, the severe penalties for premature optimization don’t apply to me, or so it feels. I don’t mean that in a big way, I mean that in a million small ways. Not premature optimizing is so medamn awful hard. I know Pareto, yet I just can not contain my self 20% of the time, so I get 80% of the penalties. I admit, I once wrote i += i < 0 ? -1 : 1; to save a boolean. But no more! We can learn to help each other. If you, after coding clean for a week, broke an abstraction layer, or if you, after coding clean for month, drop below the 1:3 remark:code ratio, or if you, after coding clean for a year, suddenly have a laps and spend six hundred and sixty six hours on my_malloc(), than join the POA.

Premature Optimization Anonymous® is a fellowship of men and women who share their experience, strength and hope with each other that they may solve their common problem and help others to recover from premature optimization. The only requirement for membership is a desire to stop premature optimizing. There are no dues or fees for POA membership; we are self-supporting through our own contributions. POA is not allied with any sect, denomination, politics, organization or institution; does not wish to engage in any controversy, neither endorses nor opposes any causes. Our primary purpose is to code clean and help other premature optimizers to achieve sobriety.

First meeting of the Dutch POA is in the RAI in Amsterdam, december 31st.


Names Should Constitute Knowledge

No Comments »

When you know all the names, in every language, of that bird, you know nothing but absolutely nothing about the bird. (Richard Feynman) This is mostly true for normal life, but not for solid code. In fact names constituting knowledge is the the basis of good code locality—meaning that code should consist of relative small blocks, each at their level of abstraction, fully understandable in separation.


Maligment Metaphor Mixing

No Comments »

source: Wikipedia

source: Wikipedia

Recently I was reading a book on algorithms and I had trouble understanding some example code. They were discussing breadth first traversal of a tree. Like the basic flood-fill algorithm, it is straightforward to implement with a FIFO queue. When it comes to linear ordered data there are at least three naming conventions for type and methodes: Vertical e.g. stack_t with push(), pop(); Horizontal e.g., queue_t with enqueue(), dequeue(); and Gyved e.g., list_t with putHead(), putTail(), getHead(), getTail(). You should not push down on a queue or dequeue from a stack, that is confusing. This was, however, exactly what happend in the book. It used a standard C++ library template called queue that has push() and pop() methods. To add insult to injury, the authors used the the name stack for their queue object. This made things far worse, because now there was one line of code that turned the whole interpretation 90°. I glossed over the code and started to wonder (wrongfully) why they were using a LIFO stack, turning the example in a depth first traversal. Only after re-reading some text and re-examining the code, did I spot the definition of stack as a queue: “queue<node> stack;.” Note that the C++ queue template uses push() and pop() but any underlying containers have to implement the oxymora push_back() and pop_front(). This was a very clear and short example. Imagine doing something like that in a real-life application.
So the lessons learned, again, were to never mix metaphors and to always refactor mixtures in given-code.


Failing Gracefully

No Comments »

Most languages have a mechanism to handle failure. For example, ADA has raisewith, C has setjmp(), longjmp(), Python has try:, except:, else:, finally:, and Perl has eval{die}. Despite this, a (library) function will often handle failure in an other way: by return-value. This is because failure comes in many guises.
Read the rest of this entry »