<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jalf.dk &#187; stl</title>
	<atom:link href="http://jalf.dk/blog/tag/stl/feed/" rel="self" type="application/rss+xml" />
	<link>http://jalf.dk/blog</link>
	<description>Musings and thoughts on programming and other geeky stuff</description>
	<lastBuildDate>Sun, 25 Mar 2012 09:51:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Hating that which you don’t understand</title>
		<link>http://jalf.dk/blog/2011/01/hating-that-which-you-dont-understand/</link>
		<comments>http://jalf.dk/blog/2011/01/hating-that-which-you-dont-understand/#comments</comments>
		<pubDate>Tue, 18 Jan 2011 23:03:25 +0000</pubDate>
		<dc:creator>jalf</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[stl]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://jalf.dk/blog/?p=719</guid>
		<description><![CDATA[A few days ago, I came across an interesting rant about “Why C++ Templates (and STL) Are Bad”. As any C++ programmer who reads my blog likely knows, I’m quite fond of both templates and the STL — I feel those are largely what transforms C++ from a clumsy and outmoded language that should’ve died [...]]]></description>
			<content:encoded><![CDATA[<p>A few days ago, I came across an interesting rant about <a href="http://www.ski-epic.com/templates_stl_rant/index.html">“Why C++ Templates (and STL) Are Bad”</a>.</p>

<p>As any C++ programmer who reads my blog likely knows, I’m quite fond of both templates and the STL — I feel those are largely what transforms C++ from a clumsy and outmoded language that should’ve died 10 years ago, into a modern, expressive, high-performance and yes, even elegant language that I <em>enjoy</em> using.<span id="more-719"></span></p>

<p>This isn’t the first time I come across a rant such as this. Templates are a fairly complex language feature, and they are infamous for causing certain problems (in particular, they can make compiler error messages very verbose, and very hard to understand, and they can hurt compilation time if used carelessly). And the STL is an unusual library, and as such it has a certain learning curve. It doesn’t behave the way you’d typically expect.</p>

<p>But this rant isn’t about these <em>real</em> shortcomings of the two language features. Instead, it is about all the things the author himself doesn’t quite understand about them. And because he doesn’t understand them, he doesn’t like them. (I should mention, in fairness, that this article is around 5 years old. Since then, compilers have gotten better, and the author himself might have changed his mind as well. I know plenty of my opinions about programming, programming languages, libraries and frameworks have changed quite a bit since 2005. So while I have no way of knowing how the author actually feels about the topic today, the best I can do is to read it at face value, and comment on it as it is written. )</p>

<p>In the following, I’ll go through the arguments presented in that rant, and offer my take on each one. Hopefully, at the end, I’ll have shown that templates and the STL aren’t “bad” — that in fact, they enable so major improvements in the way we write C++ code.</p>

<h1>1. STL is Poorly Supported By Developer Tools</h1>

<p>The author shows two screenshots from Visual Studio, where its built-in Intellisense shows the function signatures for the built-in <code>std::string::compare</code> function as well as the string comparison function from their proprietary string class, <code>MlfString::Equals</code>.</p>

<p>As he correctly points out, the <code>std::string</code> version has a much more complex signature. There are two problems here, though, and he doesn’t distinguish between them:</p>

<ol>
<li>the standard library string class offers five different overloads of the function, where their own class has only three. This means that even if every overload is just as simple as the ones in <code>MflString</code>, there’d still be 66% more information to be presented. </li>
<li>the standard library string class is an instantiation of a class template, with a lot of “hidden” default parameters. Intellisense shows all of them, so that instead of simply saying <code>std::string</code>, it says <code>std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;</code>, and when we have a <code>std::string</code> member function which takes a second string as its parameter, all this has to be duplicated.</li>
</ol>

<p>Of course, there are good reasons for both of these differences, and yes, they add up to the unavoidable fact that more information has to be conveyed if we want to accurately display the type of, say, a string member function.</p>

<p>But this is missing one fairly important point: <em>you shouldn’t need to look at this at all</em>. The <code>std::string</code> class offers a much simpler way to determine string equality.</p>

<p>Where the author uses this code:</p>

<pre><code>tag-&gt;path.compare("/config/analyzer/server/real") == 0
</code></pre>

<p>which involves looking up the member function <code>compare</code> to check how it behaves, and involves determining what the not-very-obvious <code>int</code> return value means, <code>std::string</code> offers a simpler solution:</p>

<pre><code>tag-&gt;path == "/config/analyzer/server/real"
</code></pre>

<p>here, we don’t really need to look up any member functions, and we don’t need to remember what they return. The string just <em>does what we expect</em>. Of course, if you look up the signature of <code>operator==</code>, that’s pretty much as complex as the <code>compare</code> function, but</p>

<ol>
<li>we don’t <em>need</em> to look it up,</li>
<li>there are fewer overloads of it, and the overloads that exist have more uniform signatures (they all take two strings in <em>some</em> form or shape, and return a <code>bool</code>) , so even if we do look it up, it is much simpler to read.</li>
</ol>

<p>And yes, I’ll admit that one of the properties of the STL is that it ends up looking very complex <em>when used incorrectly</em>.
But when used correctly, we get code that is simpler to read than his own string class.</p>

<h1>2. STL API Syntax is Unclear, the Designers Had No Taste</h1>

<p>Here, the author first objects to the terminology of “input” and “output” iterators, saying they should’ve been called “read only” and “write only” iterators instead. And yes, that makes a certain amount of sense, but his next complaint doesn’t:</p>

<blockquote>
  <p>The very words “Input” and “Output” are even reversed from what might make sense in this case!</p>
</blockquote>

<p>The words are chosen for the same reason that we have input and output streams. An input stream is one we can read from, and likewise, an input iterator is one we can read from. An output stream is one we can write to, and just like we can write to an output iterator.</p>

<p>That’s hardly surprising, and in fact, it is only consistent with the standard library stream classes, <code>std::istream</code> and <code>std::ostream</code>, or with the nearly universal concepts of standard input and output (often named <code>stdin</code> and <code>stdout</code>), which are shared between pretty much any language. I don’t often hear people say that “The standard output stream should really be called <code>stdin</code>”. It is an output stream because I can use it to output data. Why should iterators not use the same convention?</p>

<p>Then he returns to beating on <code>std::string</code>, this time, for unknown reasons, comparing it to Java’s string class. This in itself seems quite a stretch, because so far, his point has been that “Instead of C++ with the STL, we should prefer C++ without the STL”. So how is a comparison to Java at all relevant? At the same time, he conveniently leaves out the thing that <em>would</em> be relevant: a comparison with the same code expressed without the STL.</p>

<p>So let’s see if we can remedy that:</p>

<p>For reference, the problem we wish to solve is that of determining if a string begins and ends with certain other strings.</p>

<p>here’s his Java code:</p>

<pre><code>String filePath = "/tmp/downloaded.exe";
if ((filePath.startsWith("/tmp")  &amp;&amp; (filePath.endsWith(".exe")))
    // fits the pattern.
</code></pre>

<p>and here’s his C++ code:</p>

<pre><code>std::string filePath = "/tmp/downloaded.exe";
std::string::size_type startPos = filePath.find("/tmp", 0);   // the "zero" means start from beginning
std::string::size_type endPos = filePath.rfind(".exe", filePath.size() - 1);  // search from back to see if it ends in ".exe"
if ((startPos == 0) &amp;&amp; (endPos == filePath.size() - 4))
    // fits the pattern.
</code></pre>

<p>Well, yes, that looks a lot more cluttered. Let’s see if we can fix that if we know what we’re doing. Here’s my attempt:</p>

<pre><code>std::string filePath = "/tmp/downloaded.exe";
if (filePath.find("/tmp") == 0 &amp;&amp; filePath.rfind(".exe") == filePath.size() - 4)
    // fits the pattern.
</code></pre>

<p>Is this so much worse than the Java version?</p>

<p>As a STL afficionado, it does feel iffy to use integer indices to represent string positions, instead of actual iterators. A simple remedy for this would be to use <code>std::search</code> instead. If we did that, we could write the prefix test as follows:</p>

<pre><code>std::string filePath = "/tmp/downloaded.exe";
std::string prefix = "/tmp/";
if (std::search(filePath.begin(), filePath.end(),
  prefix.begin(), prefix.end()) == filePath.begin())
    // fits the pattern.
</code></pre>

<p>Choose whichever you find more readable. The only major flaw we still haven’t dealt with is that I have to compute where the “end” string <em>should</em> begin if it is a suffix of <code>filePath</code> (and at the moment, I hardcode the length as 4. I could (and should) of course have taken the length of the actual string instead.</p>

<p>Alternatively, I could of course have gotten creative with string reversal: We could have said “when reading the string in reverse, do we find the reverse of <code>".exe"</code> at the beginning?”, which could be implemented as follows:</p>

<pre><code>std::string filePath = "/tmp/downloaded.exe";
std::string suffix = ".exe";
if (std::search(filePath.rbegin(), filePath.rend(),
  suffix.rbegin(), suffix.rend()) == filePath.rbegin())
    // fits the pattern.
</code></pre>

<p>Ok, perhaps that’s not more readable, but it avoids the need to determine the length of the <code>".exe"</code> string, and when reading over it, the code <em>is</em> fairly logical: Perform a search (<code>std::search</code>) starting from the “reverse” beginning (<code>rbegin</code>) of <code>filepath</code> and ending at the “reverse” end (<code>rend</code>) of same, looking for the sequence that starts with the reverse end of <code>".exe"</code>, and ends with the reverse end of same. Is the position found equal to the reversed beginning of <code>filePath</code>?</p>

<p>Either way, if we buy into the STL mindset, then we gain a whole new advantage: <code>std::string</code> is extensible. The STL relies heavily on non-member functions to define the interface of a class. There is nothing to stop us from defining a non-member function <code>ends_with()</code> which, using one implementation or the other, checks whether a string ends with the given substring. I have already shown how we can, in one or two lines of code, perform a check for “begins with” and “ends with”. If we do the right thing, and wrap this functionality in small non-member helper functions, then we could simply use them like this</p>

<pre><code>std::string filePath = "/tmp/downloaded.exe";
if (begins_with(filePath, "/tmp" &amp;&amp; ends_with(filePath, ".exe")
    // fits the pattern.
</code></pre>

<p>To a Java programmer, this would be some kind of capital offense (it’d also be flat out impossible, because Java doesn’t allow non-member functions), but to a programmer used to the STL, <em>this is idiomatic</em>. The STL is designed to prefer non-member functions where possible. We’re used to them, and so extending <code>std::string</code>’s interface in this manner comes naturally.</p>

<p>Most likely, though, we prefer my first version. And while it’s a bit more verbose than the Java equivalent, every part of it is pretty easy to understand. <code>find</code> does exactly what you’d expect, and there’s no weird “if the comparison returned 0, it succeeded” check. Instead, the result of the search is compared against <code>filePath.begin()</code> which, to me at least, seems very obvious: we are checking if the found occurrence is at the beginning of the string, and likewise for the second check, we test whether the found occurrence is 4 characters before the end of the string.</p>

<p>It is certainly better than his so-called STL implementation. It’s not significantly worse than the Java implementation, and while he doesn’t show an implementation using <code>MlfString</code>, I’m willing to bet a few dollars that my version is cleaner than that as well.</p>

<p>Since I don’t have the source code for his class, the best I can do in order to provide a <em>relevant</em> comparison is to implement the same functionality without using <code>std::string</code>. So here’s the C version:</p>

<pre><code>const char* filePath = "/tmp/downloaded.exe";
if (strstr(filePath, "/tmp") == filePath &amp;&amp; strstr(filePath + strlen(filePath) - 4, ".exe") == filePath + strlen(filePath) - 4)
    // fits the pattern.
</code></pre>

<p>Perhaps I’m biased, but I think this is ugly and unintuitive. Let’s run through a few of the reasons:</p>

<ul>
<li><code>strstr</code> isn’t a very obvious name. True, I know that it searches for the first occurrence of a string within another string, but would you have guessed that from the name? Recall that he just threw a fit over the name “OutputIterator”, so he’s clearly concerned about good naming conventions.</li>
<li>while the the first <code>strstr</code> call is fairly straightforward (we search in <code>filePath</code> for the string <code>"/tmp"</code>, and see if the result is a pointer to <code>filePath</code> itself, the last part, at least, requires intimate knowledge of how C-style strings work. Comparing the result against <code>filePath</code> only makes snse because <code>filePath</code> isn’t a string, it is a pointer to a <code>char</code>, and by convention, it is a pointer to the <em>beginning</em> of a sequence of characters that we’d like to treat as a string. by contrast, the STL example clearly compared against <code>filePath.begin()</code>, which makes sense just from reading the code, even if you’re not familiar with the string class.</li>
<li>and the second call is where it gets hairy. Now we don’t just search for a substring within <code>filePath</code>, but we explicitly search within the string found at <code>filePath + strlen(filePath) - 4</code>: that is, in the last 4 characters, because otherwise, we might get find an early occurrence of the substring, and get the wrong answer to our query.</li>
</ul>

<h1>3. STL Encourages (Lures?) Programmers to Use Very Complex Data Structures</h1>

<p>And here, it honestly becomes hard to see what the author is even driving at. I find it hard to imagine that anyone could seriously claim that “giving the user access to bug-free implementations of commonly used data structures is a bad idea”, but that seems to be what he suggests. And this is only moments after saying how much nicer Java is. Consider how many complex classes Java encourages/lures programmers into using. If he objects to a standard library providing pre-rolled functionality, then C++ is an odd place to start. Why doesn’t he object to Java or .NET, both of which offer standard class libraries hundreds of times larger? Why doesn’t he object to Python which contains <a href="http://xkcd.com/353/">practically everything</a> in its standard library?</p>

<p>I generally assume that those reading and using my code are going to be reasonably well qualified. I imagine that they probably know their data structures, and will choose to use the one that <em>makes sense</em>. And I think it is a good thing for a library to cater to those who actually know how to use it, because those who don’t will manage to write bad code no matter what I do. They’re a lost cause, so why worry about them? If I can just give the <em>qualified</em> programmers the tools they need to write sound code, then I feel I have done a good job.</p>

<p>And the STL offers qualified programmers such commonly used data structures as linked lists, dynamic arrays, sets and a map/dictionary mapping from objects of some key type <code>T</code> to objects of a value type <code>U</code>. A programmer who doesn’t know when to use these has much bigger problems than the STL.</p>

<p>And then he makes the claim that…</p>

<blockquote>
  <p>If a programmer will have to spend 10 minutes writing their own linked list, they will make sure it is as simple as it can possibly be</p>
</blockquote>

<p>which may be true, but if a programmer spends a mere 10 minutes writing their own linked list in C or C++, then</p>

<ol>
<li>it <em>will</em> be buggy, and</li>
<li>they’ll be using the absolute <em>worst</em> data structure ever invented. There is hardly ever a reason to use a linked list. It does not allow random access, it requires an absurd number of memory allocations, and it completely thrashes your CPU’s cache.</li>
</ol>

<p>Of course, the second point could be considered a premature optimization <sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>, but the first one is unforgivable. Who in their right mind would, when choosing between reusing a well-tested and highly reliable class which can be accessed in a single line of code, and writing their own ad-hoc implementation, choose the latter?</p>

<p>Finally, we have a screenshot of where one of his coworkers found an instance of them using the wrong data structure. Where they use a list of pairs (which, by the way, even if it had been necessary, looks like something you’d only write if you didn’t know <code>std::map</code> existed) they just needed to loop over some other data.</p>

<p>Well, duh. I’m not sure how the STL is to blame for that. I’d have blamed the programmer who thought “I need a list of pairs here”. The code wouldn’t have been any better if he’d implemented his own linked list. The problem here isn’t that the STL makes robust and useful data structures available. It’s that a programmer chose to <em>use</em> them when they weren’t a good fit for the problem at hand.</p>

<p>And finally, he shows us that the code fails to compile, and asks us to decipher the error message, once again, of course, blaming it on the STL.</p>

<p>The only problem is, this is nothing to do with the STL.</p>

<p>One of the awkward facts of the syntax of C++ templates is that if you do something like <code>foo&lt;bar&lt;baz&gt;&gt;</code>, the compiler will fail to parse the code. It won’t see the <code>&gt;&gt;</code> as “end of parameters for the <code>bar</code> template, followed by the end of parameters for the <code>foo</code> template, but instead assume that it is <code>operator &gt;&gt;</code>.</p>

<p>Yes, that’s awkward. And yes, it is to do with templates, the other of his pet peeves. Luckily, C++0x, due to be standardized this year, fixes this, allowing <code>&gt;&gt;</code> to be parsed as you’d expect.. And while the issue will exist until then, it is certainly nothing to do with the STL, and the compiler actually offers us a pretty easily readable error message. It explicitly <em>tells</em> us that it found a <code>&gt;&gt;</code> instead of the <code>&gt;</code> it expected.</p>

<p>Finally, of course, I’ve been itching to point out one more problem with this rant. He hates the standard library string class, but <em><code>std::string</code> is not part of the STL</em>. It was added to the standard library separately, and received some last-minute polish to make it interact better with the STL, but it was not part of the STL — this also explains why it has a <code>find</code> method which doesn’t return an iterator. And funnily enough, that is why many C++ programmers, myself included, actually <em>agree</em> with the author that the <code>std::string</code> class is too complex. It should have been much simpler and more streamlined, like the “true” STL containers. <code>std::vector</code> doesn’t have 5 different overloads of a <code>compare</code> function which is a member for no reason, and uses a surprising and unintuitive return value convention copied from the C standard library’s <code>strcmp</code>. <code>std::string</code> is overengineered. Not because it’s part of the STL, as claimed in the article claims, but because it is <em>not</em>. Because it was added by people who <em>hadn’t</em> yet realized the elegance of the STL.</p>

<p>So in summary, yes, STL code sure is ugly when the person writing it doesn’t know what the STL is, and doesn’t know how to use it.</p>

<p>Does that surprise you? The same thing can be said for Java code, PHP code (although PHP code tends to be ugly no matter who writes it), Python code, or code written for any other language or any other library. I think the correct conclusion here is not “STL sucks”, but rather “If I try to write code using a library or language I don’t know how to use, the result is going to be messy”. But it is much more comforting to blame the tool, isn’t it? And so we get people hating some exceedingly elegant and usable parts of the C++ language because they themselves never bothered to learn how to use it.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>Although I’d argue that even before performance becomes an issue, it may be a good idea to ensure that it is <em>possible</em> to optimize your code. If you use the standard library linked list implementation, then the other data structures are almost drop-in replacements. If you implement your own linked list anywhere you need it, then “upgrading” it to a more sensible data structure later on is going to be painful. <a href="#fnref:1" rev="footnote">↩</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jalf.dk/blog/2011/01/hating-that-which-you-dont-understand/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>“Good design”, and why OOP isn’t going to get us there</title>
		<link>http://jalf.dk/blog/2010/11/good-design-oop/</link>
		<comments>http://jalf.dk/blog/2010/11/good-design-oop/#comments</comments>
		<pubDate>Sat, 06 Nov 2010 23:13:09 +0000</pubDate>
		<dc:creator>jalf</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://jalf.dk/blog/?p=656</guid>
		<description><![CDATA[in which I probably get strangled by a horde of angry OOP programmers… I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras — families of interfaces that span multiple types. I find OOP [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li>in which I probably get strangled by a horde of angry OOP programmers…</li>
</ul>

<blockquote>
  <p>I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras — families of interfaces that span multiple types.<br />
   I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting — saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms — you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work. 
   — <a href="http://www.stlport.org/resources/StepanovUSA.html">Alexander Stepanov</a></p>
</blockquote>

<p>This post is an attempt at extracting something coherent from a series of comments I recently left on a <a href="http://stackoverflow.com/questions/4102411/abstract-factory-dependency-injection-and-good-design">StackOverflow question</a> about “good design” (in what’s quite clearly an object-oriented context). The person asking the question has been gracious and patient enough to deal with my countless comments repeatedly pointing out that he’s <em>doing it wrong</em>, which would probably have driven a lot of people mad.</p>

<p>Many people have come up with many varied criticisms of the object-oriented programming paradigm. My problem with it is not new — in fact it is pretty much exactly what Stepanov pointed out in the interview I quoted above (and which is definitely worth reading in its full length). The only real difference is that he is an extremely intelligent mathematician, and I’m… not. So I’m not able to express it as concisely. But then, on the other hand, maybe my take on it will be easier to swallow for others who also aren’t hyper-intelligent mathematicians.
<span id="more-656"></span></p>

<p>When we design software, what we really design are <em>processes</em>. A program is, without exception, a piece of code that <em>does something</em>. Code which does nothing does not constitute a program. (even a program such as this does <em>something</em>: <code>int main() { return 0; }</code>: it takes up several CPU cycles. It spawns a process that, if I’m quick, I’ll be able to see in Task Manager, <code>ps</code> or <code>top</code>. It enters the main function, after running all the CRT startup code. And what’s probably the most important property: it compiles and runs with no errors, giving us a solid starting point for further development. It does something, just nothing very interesting.</p>

<p>A webserver is not “something which has an HTTPListener object”, it is a process which given a string containing a HTTP request, produces a HTTP response. A compiler is not “something that has a Parser class and a Lexer class and an Inliner class and an ErrorMessage class”. It is a process which, given a program written in one language produces an equivalent program expressed in another language (or an error message). The parser doesn’t <em>matter</em>. But the pars<em>ing</em> does. A parser by itself doesn’t <em>do</em> anything. It is no help to us. It only becomes useful if it is utilized in the process of parsing the supplied source code.</p>

<p>But OOP often becomes an exercise in designing code that does <em>nothing</em>.</p>

<p>The StackOverflow question that triggered this was about how to come up with a good design for a system which runs in a “car” and controls some of its components. Not a car that <em>does</em> anything in particular, just a car. A car which has an engine and a few other components, but which has no <em>purpose</em>, and are not associated with any <em>process</em>.</p>

<p>So my rather snarky, but accurate and concise, suggestion for a good design was this:</p>

<pre><code>class Car {};
</code></pre>

<p>the above perfectly models a car which does nothing. In fact, I can extend it without writing a single line of code too. Here I create a BMW:</p>

<pre><code>Car myBmw;
</code></pre>

<p>here I create a Land Rover:</p>

<pre><code>Car myLandRover;
</code></pre>

<p>and I can represent electric cars, hybrids, tanks and trucks too, in the same way. Because our requirements don’t specify any <em>processes</em>, because our data model is completely inert, I don’t need to further distinguish between different types of cars.</p>

<p>This design is even suitable for “a system which runs in a car and controls various components of it”, which is a more verbose way to express “no requirements at all”. I can run this code in a car, and it will control every component of the car, provided that the components don’t actually have to <em>do</em> anything (and they don’t, because the specifications don’t say anything about we plan to <em>do</em> with the car that we’re controlling. Until we do <em>something</em> with the car, controlling its components is extremely simple. And if there is nothing we wish to <em>do</em> with the car, then <em>any</em> design will work.)</p>

<p>And yet such examples are <em>always</em> what OOP “gurus” talk about, what’s used to teach students, and for some reason, most people seem happy with this. OOP programmers<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> think such models of cars or animals are the most obvious things in the world. They sincerely believe that there is such a thing as “a good model of a car”.</p>

<p>There isn’t. Well-designed software is dependent on context. A good design for “a car” depends on what we want to use the car <em>for</em>. It depends on the processes and transformations we wish to put it through.</p>

<p>Say we’re building a racing game. the big dirty truth is that <em>we’re not really interested in the car</em>.</p>

<p>What matters is the data transformations that we wish to apply: it is the racing, not the car, that’s important.</p>

<p>Given information about the track we’re driving on, as well as position, heading, speed and input from the player, we wish to compute a new position, heading and speed for the car.</p>

<p>Of course a variety of properties and characteristics of the car the player is driving influence this transformation as well: perhaps the game models grip, acceleration, weight, shape/size (for collision detection), and let’s throw in manual vs. automatic transmission as well. All of these are inputs to our algorithm, whose output is a new state for the player’s car: it may have moved further along the track, it may have taken damage, or it may be spinning out of control. But the racing game doesn’t really care about the car. It cares about all these inputs which control the <em>process</em> of racing.</p>

<p>In fact, we may not even need a <code>Car</code> class (just like we probably won’t need a <code>Game</code> class). Or we may have several: one for use in the process of drawing the player’s car on the screen, one which represents the process of “driving a car” (when I drive a car, I can control the car radio, I can turn the steering wheel, I can start and stop the engine or change gears), and one which models the process of moving through the world, updating the car’s logical position in the world, reacting to physical forces and to any obstacles that I may accentally collide with.</p>

<p>But this is just <em>one</em> possible representation of a car. If we were designing software to control a car (because a car contains an awful lot of computers these days, and much of what makes it go is automated), then the process we wish to model is completely different. We may no longer care about the car’s position, for example (hopefully the driver keeps track of that), but the heating in the seats needs to be kept in check, we need to verify that the passengers have fastened their seatbelts, we need to respond to the drivers’ inputs, we need to ensure the engine keeps running. We need to control all the “cold start” magic that saves the driver the trouble of having to leave the car and turn a handle to start the engine. We have to listen for wireless signals from the little key thingy you click on to remotely unlock the doors and disable the alarm, and we have to <em>react</em> when we receive the “unlock” signal.</p>

<p>In this case, I almost certainly <em>wouldn’t</em> have a <code>Car</code> class; after all, what would I use it for? the entire program is supposed to be in a car already, so every line of code is conceptually already part of the car. I won’t have any code that’s <em>outside</em> the <code>Car</code> class. I’m modelling a car, but none of the processes I’m interested in require an object that represents “the car” as a whole. One process might require information about the fuel tank as an input, and one might provide commands for the car radio as an output, but none of the have “a car” as an input, and none of them produce “a car object”</p>

<p>In both cases, an OOP programmer would say that we are “designing a car”. And in both cases, I suppose that’s true. But hopefully, it is also obvious that we arrive at completely different designs, depending on what program we’re writing. And neither of them look like the traditional “design a class hierarchy for modelling cars” exercise, which would have been a terrible design in <em>both</em> cases.</p>

<p>So what does this tell us? <em>Bad design</em> may be universal (it’s easy to come up with a design that is bad in every context), but <em>good design</em> is not. Good design depends on the context. A good design is a design that satisfies the criteria imposed by the use cases for the design. Is it supposed to be used in a racing game? Then a certain kind of design works well, and is therefore “good”. Is it for controlling the internals of an <em>actual</em> car? Then a completely different kind of design works, and then <em>that</em> design is “good”. Is it for car manufacturers to design and evaluate car prototypes? Then the software design is going to look entirely different again. And if the context is simply “be a good design for modelling a car”, then I maintain that <code>class Car{}</code> is both the simplest, cleanest and most flexible design. It satisfies every rule of OOP (it is perfectly encapsulated: you have absolutely no way of mucking around with the internals of the class; it is polymorphic, even without having to resort to virtual methods and inheritance, this simple class can represent <em>any</em> car you care to think of, and so on). The <em>only</em> weakness of this design is that it doesn’t actually participate in any interesting processes. We can’t use it to <em>do anything</em> with the car. Oh sure, we can manipulate the car itself easily:</p>

<pre><code>Car myCar;
// the car's engine is now running
// the car's left door is now open
// here, I refuel the car
</code></pre>

<p>and in fact this design allows an amazing level of extensibility: no matter what operation you wish to perform on the car, you don’t actually need to write a single line of code. You can merely decide that the car is now in the desired state. If you like, you can add a comment, like I did, clarifying this to the next maintainer of the code.</p>

<p>But while we can modify and extend the car itself easily, we can’t use it in a program that <em>does</em> anything. It is useless in my racing game, it is useless for controlling the internals of a car, and it is useless to car manufacturers. It doesn’t <em>do</em> anything, it just sits there. But that’s what we were asked to produce: a model of a car, which is “good OOP”, which is extensible and so on. It was required to be all these things. It just wasn’t required to be <em>useful</em>.</p>

<p>When teaching children to read, we don’t ask them to “come up with something to read”. We don’t encourage them to “write something, and then read it”. Architects are taught how to build houses by studying the properties of <em>actual</em> houses, not by drawing a house, and then trying to learn from that drawing.</p>

<p>And yet OOP students are taught that the way to learn “good design” is to, well, design the code for some problem they just made up: design a class hierarchy for cars; design one for farmyard animals. And it doesn’t work. The only way anyone is going to learn “good design” (to the extent that it is something that can be learned) is by studying design “in the wild”.  Just like children have to read text written by others, and architects have to look at houses already built by others.<sup id="fnref:2"><a href="#fn:2" rel="footnote">2</a></sup></p>

<p>And that is OOP in a nutshell: as Stepanov pointed out, saying “everything is an object” may be true, but it’s not very interesting. I just created a car object, I just can’t use it for anything, because it’s really not the object in itself that’s important: it’s the process we want it to participate in.</p>

<p>Functional programming avoids this pitfall: it focuses explicitly on the <em>functions</em>, on the manipulation and transformation of data. Functional programming is all about taking an input and producing an output. If a functional programmer is required to “design a car”, he won’t make a useless and inert “car” class which doesn’t actually <em>do</em> anything. Instead, he will program the <em>functionality</em> required. If he needs to write a racing game, he will write functions which, given the current state of the car and the input from the player, produces an updated car state. He will write code that <em>does</em> something, which <em>solves a problem</em> (in this case, the problem of moving a car in a game in response to the player’s input)</p>

<p>Generic programming also avoids the trap (perhaps obviously, since it was invented by the Alexander Stepanov whose criticisms of OOP I quoted), by focusing on the algorithms and the data transformations, and only <em>then</em> coming up with a suitable interface to describe the data. For a racing game, I need to be able to race. That’s the process I want the program to carry out. And as I code this, I will eventually get to the point where I need to express the car “being raced”. And <em>then</em> I have the information needed to come up with a “good design” for a car.</p>

<p>Even plain old procedural programming got it right: the important parts are the procedures that you write to <em>do</em> things to your data. Without them, your program just isn’t very interesting.</p>

<p>So a good design is not actually about the car, it is about the processes we wish to perform on it. That is true, no matter what we are designing.</p>

<p>Take something as simple as the <code>int</code> datatype. It generally works pretty well. Is it well designed? I suppose so; it’s extensible (I can define new operations that work on an <code>int</code>), it is easily reusable and so on.</p>

<p>But there is nothing universal about it. It uses a base-2 representation internally, which makes good sense in the context in which <code>int</code> is typically used: efficient integer computations on a von Neumann computer. It has some obvious limitations (it can’t store numbers above a certain size, for example), but it usually works for what we need it to do, and it is efficient and compact.</p>

<p>So why don’t we use it in the “real” physical world? Why do we use the decimal system instead? Mainly because we (well, most of us) have 10 fingers, and so that makes it a bit easier for us to learn to count. So in <em>that</em> context, a good design for an “integer datatype” uses the base-10 representation.</p>

<p>And then again, perhaps it doesn’t. If you asked me to design a “good” integer for real-world use, I think I’d go for base-8. That does limit our range a bit (If I count naively on my fingers, I can only get to 8, instead of 10), but on the other hand, 8 is a power of two, which gives us a whole lot of other benefits: it makes it easier to convert to and from a lot of other bases, for example, and even for counting on our fingers, I believe there are significant benefits. It frees up two fingers which we can use as a “carry bit”, for example, and then a “temp” bit for storing other information related to what we’re counting, but not part of the number itself (or I could use it as a sign bit, allowing me to count negative numbers too). Or we can use both of the two remaining fingers to represent the second digit, and then we’re able to count all the way up to 27 on our fingers.</p>

<p>I think that would’ve been a better design when initially designing our number system. But today, of course, the context is another yet again. Now backwards compatibility is a concern. Switching to a base-8 system would confuse 6 billion people, which is probably a non-starter. So in the situation we’re in <em>today</em>, base-10 is, after all, the optimal design. I just wish I’d been consulted when it was initially decided on as a standard.</p>

<p>Even roman numerals were a good design choice for a certain context: it’s good enough for simple counting, which was what most people needed, even though it fell flat at more advanced mathematics (which most people at the time never needed). And it didn’t involve inventing or learning any new symbols. If you knew the regular alphabet, you also knew the symbols necessary for writing numbers.</p>

<p>Just like with the cars, the “goodness” of a design decision depends on the context in which it is intended to be used. It depends on the processes we wish to perform. Binary is a good choice in a computer because we wish to perform integer arithmetic efficiently, and because it doesn’t cause significant confusion for users of the program. Decimal numbers are fine for counting on our fingers, which was one of the things we required our “real-world” number system to support when we came up with it.</p>

<p>The design is about the <em>algorithms</em>, the <em>processes</em>, the <em>transformations</em>. The representation of the data is a consequence of those decisions.</p>

<p>So, am I saying that objects are useless, or even harmful? No, they’re just not important. They’re a convenience. They can do some useful things, like enforcing constraints and invariants so that we can easily keep our data in a consistent and valid state. Designing classes just won’t make our program <em>do</em> anything. Objects are handy enough to have around. But it’s absurd to “orient” your program around them, just like you never see “brick-oriented architecture”. Architecture is about making a house that serves the purpose of a house, and bricks are just one of many materials that can be useful in getting there. But an architect doesn’t start from the brick. Bricks aren’t interesting, they just lie there, waiting to be used for something. A brick only becomes interesting when it is <em>used</em> for something: when it participates in the process of keeping out the cold, or the process of creating an aesthetically pleasing facade, or the process of keeping the building from collapsing.</p>

<p>Classes are, as Stepanov pointed out, something you design at the end, when you need to create data structures to pass through your algorithms. Once we have the algorithms that we want our program to perform, we’re going to need to define data structures that they can process. And here, objects are very handy. If I use a class to represent my car, then I can make sure that a car always has 4 wheels. I can ensure that the amount of fuel in the tank is never negative, and so on. I can enforce a lot of invariants that makes it easier to reason about the rest of my program. But the program is not “about” my car class. It is not “object-oriented”. It is oriented around the process I want to carry out <em>on</em> the car.</p>

<p>The question of “how do I represent a car” is impossible to answer until I know what I want to <em>do</em> with the car. Once we have that information, we can, if we wish, apply all the OOP teachings to come up with a suitable representation of this particular bit of data. And then we can evaluate whether this is a “good design” for a car by looking at how well it works with the algorithms and processes that make up the <em>functionality</em> of the program.</p>

<div class="footnotes">
<hr />
<ol>

<li id="fn:1">
<p>defined as “programmers who know nothing except OOP” <a href="#fnref:1" rev="footnote">↩</a></p>
</li>

<li id="fn:2">
<p>sure, they are <em>also</em> required to draw houses (or letters) themselves, and study these, but only to drive home individual lessons; “no, an ‘S’ does not look like that”, or “you forgot to put in the bathroom”, or “very good, now do the math and see if that pillar can support the weight you’re putting on it”, or “now please read back to me the story you wrote” <a href="#fnref:2" rev="footnote">↩</a></p>
</li>

</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://jalf.dk/blog/2010/11/good-design-oop/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>STL, language lawyers and pedantry</title>
		<link>http://jalf.dk/blog/2010/08/stl-language-lawyers-and-pedantry/</link>
		<comments>http://jalf.dk/blog/2010/08/stl-language-lawyers-and-pedantry/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 00:29:24 +0000</pubDate>
		<dc:creator>jalf</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[stl]]></category>

		<guid isPermaLink="false">http://jalf.dk/blog/?p=645</guid>
		<description><![CDATA[Anyone who’s been around a C++ programmer for any length of time has probably realized that we tend to be horrible language lawyers: we only trust the ISO standard describing the language. We certainly would never assume something to work just because the compiler happens to generate code that works right now. If it’s not [...]]]></description>
			<content:encoded><![CDATA[<p>Anyone who’s been around a C++ programmer for any length of time has probably realized that we tend to be horrible language lawyers: we only trust the ISO standard describing the language. We <em>certainly</em> would never assume something to work just because the compiler happens to generate code that works <em>right now</em>. If it’s not in the standard, we can’t count on it.</p>

<p>I’m fine with that. It’s often annoying that we have to be so paranoid, that we so often have to double-check that our code not only compiles, not only passes our tests, but also avoids the dreaded Undefined Behavior (where the behavior is not constrained by the standard), but you get used to it. And all in all, being precise and specific when talking to a compiler is probably not a bad habit to get into, regardless of which language you program in.</p>

<p>However, every once in a while, people try to carry the same level of pedantry over into discussions <em>about</em> C++.<span id="more-645"></span> In particular, a certain subset of C++ experts regularly complain that nearly every C++ programmer has their terminology mixed up. And <em>that</em> annoys me. If 99.9% of all C++ programmers use a term in one specific way, then even if it’s not supported by the ISO standard, perhaps we should just <em>accept it</em>. Yes, if you’re a compiler, it would introduce an ambiguity, but we’re not. We’re human beings, and we’re good at dealing with ambiguities. And while using the term correctly would <em>theoretically</em> eliminate any ambiguity, in practice it would <em>cause</em> a lot of it instead: today, we can guess with 99.9% certainty that people use the “incorrect” definition when they use the term. If we tried to make everyone use the term correctly, we’d be unable to guess at which meaning people <em>actually</em> intend to use.</p>

<p>The term in question is, of course, the STL. The Standard Template Library, developed by <a href="http://www.stepanovpapers.com/">Stepanov in 1994</a>, <a href="http://www.sgi.com/tech/stl/">made available by SGI</a> and finally adopted with some changes and some parts left out by the <a href="http://www.open-std.org/jtc1/sc22/wg21/">C++ standards committee</a> into the C++ language in 1998.</p>

<p>Strictly speaking, the name “STL” refers to the SGI library (and, some would argue, to the language-agnostic idea for a library gradually developed by Stepanov before he implemented it in C++). Strictly speaking, the C++ standard makes no mention of a “Standard Template Library”. Strictly speaking, “STL” refers to a 15 year old library that no one would ever dream of using, because we’ve got an up-to-date near-copy in the C++ standard library. Strictly speaking, no one would ever want to use the name “STL” today.</p>

<p>And yet even C++ experts like <a href="http://www.amazon.com/Effective-STL-Specific-Standard-Template/dp/0201749629">Scott Meyers</a> and <a href="http://www.gotw.ca/consulting.htm">Herb Sutter</a> use the term incorrectly (unless we accept that Sutter offers courses in a 15-year old obsolete library rather than effective use of the C++ standard library)</p>

<p>And of course, the best part is that <em>if</em> we all were to start using the term correctly, <em>we have nothing to replace it with</em>.
We don’t <em>have</em> another name for “the STL-derived parts of the C++ standard library”. We can say “the C++ standard library”, which, apart from being an extremely verbose name, also covers all the <em>other</em> parts of the standard library.</p>

<p>So really, is it worth it? What purpose does it serve to try to convince every C++ programmer in the world, to stop using the name “STL” to describe “the parts of the C++ standard library which look suspiciously like the STL”? We free up the name so we can use it to name a library that we virtually never <em>need</em> to mention. And we get to be wonderfully pedantic when talking about the C++ <em>language</em>, just like we already are when talking about C++ <em>code</em>. But we’ll also cause a lot of confusion, making it needlessly difficult to discuss one of the most commonly discussed areas of C++, because 1. it no longer has a simple name, and 2. when people <em>use</em> that name, we no longer have <em>any</em> idea what they’re referring to. They could be a “reformed” well-behaved C++ programmer, using it to refer, for some reason, to a library no one has used for the past 10 years, or they could be a rebellious troublemaker abusing the name to refer to a subset of the C++ standard library.</p>

<p>So, an appeal to all those C++ experts who think the world would be a better place if we all used the name STL correctly:
stop it. Sit down, take a deep breath and accept and assume that the name is going to be used incorrectly by virtually everyone virtually all the time. Don’t pretend to be confused when people say “STL”, because you’re not. The ambiguity exists only on a theoretical level. In practice, no one ever wants to talk about the SGI library, and if they do, they will make it clear from context.</p>
]]></content:encoded>
			<wfw:commentRss>http://jalf.dk/blog/2010/08/stl-language-lawyers-and-pedantry/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Thesis</title>
		<link>http://jalf.dk/blog/2009/07/thesis/</link>
		<comments>http://jalf.dk/blog/2009/07/thesis/#comments</comments>
		<pubDate>Tue, 28 Jul 2009 15:27:42 +0000</pubDate>
		<dc:creator>jalf</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[cell]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[diku]]></category>
		<category><![CDATA[shaders]]></category>
		<category><![CDATA[stl]]></category>
		<category><![CDATA[thesis]]></category>

		<guid isPermaLink="false">http://jalf.dk/blog/?p=131</guid>
		<description><![CDATA[Finally, after too many years studying at DIKU, I’m about to start on my master’s thesis. That feels weird. But I’m still not sure what I want to write about. I’ve got a few ideas, mainly by asking some of the professors I might want as advisors if they had any interesting projects lying around. [...]]]></description>
			<content:encoded><![CDATA[<p>Finally, after too many years studying at <a href="http://diku.dk/">DIKU</a>, I’m about to start on my master’s thesis. That feels weird.</p>

<p>But I’m still not sure what I want to write about. I’ve got a few ideas, mainly by asking some of the professors I might want as advisors if they had any interesting projects lying around.
<span id="more-131"></span></p>

<p>So far, this is what I have:</p>

<ol>
<li>Efficient inversion of <em>huge</em> block-diagonal matrices on a CELL processor</li>
<li>Multi-threaded implementation of the C++ STL</li>
<li>writing a GPU shader language, probably in a more functional style than existing languages, taking advantage of the inherently side-effects-free platform</li>
</ol>

<p>The first one is based on a project I did last year. It was fun, and there’s still plenty left to do. The algorithm may sound dull (matrix inversion?), but the fun part is implementing it on a CELL, and the algorithm has a lot of steps that are challenging to implement efficiently on the hardware. Working with a CELL is interesting, and since I’ve done it before, I can get started relatively quickly, sidestepping all the beginners’ trouble figuring out how to program the monster. So that’s definitely an option. On the downside, it’s, well, stuff I’ve done before, more or less.</p>

<p>The second sounds like a blast, to be honest. It could be a lot of fun. Unlike the CELL project, I wouldn’t have to worry about weird hardware limitations, but can instead focus on crazy C++ templates and generic programming. I still have to figure out a specific angle on it though. Simply implementing multithreaded versions of the functions in the <code>algorithm</code> header is obvious, but has been done already. Implementing the containers with multithreading in mind might be interesting, but then the problem is no longer that of automatically parallelizing code (which is fun), but rather that of ensuring our code is thread-safe (which is… less fun). A third option might be to use such a parallel STL implementation to solve some problem.</p>

<p>The third one is a pet project I got the idea for a year or so ago. I’m still not sure about it. I think the basic idea is good, and it could be fun, (and would be relevant if I want to get into the games industry after I graduate) but there are a lot of unknowns involved:</p>

<ul>
<li>I’m not exactly a hardcore compiler writer. I’ve taken both the basic and advanced compiler courses at uni, and passed them with good grades and without too much trouble, but all the more theoretical courses about partial evaluation, big-step semantics and other fancy theory just leave me cold. I doubt any of that will be necessary, but.… is it a risk I want to take on my thesis?</li>
<li>GPUs have a lot of unusual hardware characteristics I’ll have to deal with — first of course, that they are inherently SIMD instruction sets, second that there is very little support for branch/jump instructions, a fixed number of registers and no memory you can spill into. Writing a compiler for that seems</li>
<li>It’ll most likely have to target one of the existing shader languages (Cg, GLSL, HLSL). Is that practical? How should it interface with OpenGL/Direct3D, if it were to be useful in practice?</li>
<li>It seems like <em>a lot</em> of work…</li>
</ul>

<p>So yeah, the last one has a certain attraction in that it’s <em>my</em> idea, where the others are suggestions I’ve been given, but it’s also scary as hell. And like I said, the two first suggestions are great fun too.</p>

<p>What to do? I’ll have to decide in a couple of days. I don’t want to wait any longer before starting on it.</p>
]]></content:encoded>
			<wfw:commentRss>http://jalf.dk/blog/2009/07/thesis/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

