Journal Articles
Browse in : |
All
> Journals
> CVu
> 126
(17)
|
Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.
Title: In Defense of the Normal Programmer
Author: Administrator
Date: 03 December 2000 13:15:40 +00:00 or Sun, 03 December 2000 13:15:40 +00:00
Summary:
Body:
It seems to be the season for change. I noticed in the last edition of Overload that John Merrells has a new job, and I am sure I recall other such departures for new challenges of late. Far be it from me to shun the bandwagon, I too have been looking for a new job, and my search for work furnished me with a couple of surprises.
My first surprise was more of an epiphany; I found increasingly that I was vetting prospective employers for suitability, rather than the other way around. This issue was brought home to me hard by one (very) senior C++ programmer who insisted that pure virtual functions cannot have a function body. Luckily I was given the opportunity to discuss my practical "test" with the interviewers, which included the senior programmer. It raises the question of what one should do when one has a better grasp of the language than the senior technical interviewer.
But I digress. My second surprise was the number of employers (including software houses, development divisions of large corporations, and small development teams in larger companies) who stated, quite categorically, that they do not use STL because it is too complex for normal programmers.
The first time I heard this, I was astonished and disappointed. My hard-earned skills in Standard Library techniques had been wasted! It occurred to me, however, that if I am not a "normal" programmer, what am I? (Please note - this is a rhetorical question). I do not consider myself a superstar, or a dullard, merely competent, and yet I am familiar with the C++ Standard Library, and know how to make good use of much of it. I would not say I know how to use all the STL functionality, but I am comfortable with the concepts.
STL's detractors commonly point first to its syntax, which is generally described as both contorted and verbose. I understand that, at first glance, the STL does indeed appear complex and unintuitive. I also recall that I found pointers in C to have complex issues and an unintuitive notation. With a little diligence and learning from mistakes, I became familiar with C pointers in much the same way as I have with STL. In both cases, I had a "Eureka!" moment when suddenly the clouds before me lifted (revealing some nasty terrain ahead to be sure) and I understood - even grokked - a good deal of the issues and solutions.
An example, I think.
Oooh - nasty. Yet, with some knowledge of STL, there are not many things we cannot deduce from just this snippet of code. It is reasonable, for example, to assume that a prod (as contained by a vector prices) is a structure of some kind from the use of the -> dereference operator. The named pricemap is a giveaway, but even without this clue, we could guess that it is a map, where the value type is another container - probably a vector. From just this information, it is possible to see that we have a collection of products, each of which has a minimum price, and an associated collection of possible prices for each product. We are removing all prices that are less than the stated minimum for that product, and displaying the results for each product.
Including as it does the use of function objects, function adapters and a standard algorithm that might not do exactly as you would expect[1], this is a fairly complex use of STL; yet I think it reasonably representative of the kind of thing for which STL is commonly used. The adept might even factor the call of remove_if into the call to copy, but I think that would be gratuitous. C++, as C before it, and legion other programming languages, can be made really obscure if you try hard enough.
Having said that, I believe that the problem stems simply from the matter of notation. It is an over-used example, I know, but I think people who were unfamiliar with C or C++ would struggle over the meaning of this simple idiom:
while(*d++ = *s++) As I already mentioned, the pointer notation in C++ as in C can be odd, to put it mildly. I think I am safe enough in saying it is the single most problematic area for beginners in C. STL, specifically its use of iterators, is designed to support such syntax as
copy (prices.begin(), remove_if (prices.begin(), prices.end(), bind2nd (less<int>(), i->min_price)), ostream_iterator<int>(cout, "\t"));
STL is a new notation for basic Computer Science concepts. I find it hard to believe that "normal" C++ programmers are unfamiliar with linked lists, stacks, queues and balanced trees (OK, the terminology changes in some cases). These are data structures that form the core of our industry. I remember all too well implementing a Binary Search Tree in C, using void * for the container. I welcome the news that I will never have to do it again! I actually think that the new notation is more intuitive. I will never again prefer item = item->next; over ++item;
The biggest boon I think for C++ programmers is that STL containers are value based. Specifically, when an item is removed from a container, it is automatically deleted. I mean "automatically" in the programming sense of automatic variables. Correspondingly, when the container itself goes out of scope, all of its contents are automatically deleted. Using the C version with void *, it does not make sense for the container to take any responsibility for memory. It cannot allocate space for an item, because it does not know its type. It cannot therefore sensibly free that memory, because it did not allocate it. All memory management is the responsibility of the user of the container. This is a source of errors and resource leaks.
It is much better that the container itself takes this responsibility. I think this is the behaviour most would want and expect. If for some reason it is not the behaviour required, then it can be changed. A vector<thing> can easily be made into a vector<thing *>. This is particularly useful when items are frequently moved between containers. An example that springs to mind is the concept of a Process in a real-time system, where the item representing a process will often move between a Ready-To-Run list and one of possibly several Stopped lists.
As I have already mentioned, I am no programming superstar. Yet I learned STL from Austern's "Generic Programming and the STL", which is by no means a simple introduction. Given my time again, I know there are many better introductions to STL. So this is a note to all "normal" programmers: take the time to learn basic STL concepts, and use it even for simple things like choosing vector<> instead of a C array. You will be rewarded with a simpler, not a more complex, programming life.
[1] remove_if causes removed items to be placed at the end of the container, and returns one past the end position of items not matching the predicate. It does not actually delete those items from the container. Hence newend as the returned iterator.
Notes:
More fields may be available via dynamicdata ..