<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://www.oscar.nierstrasz.org/feed.xml" rel="self" type="application/atom+xml" /><link href="https://www.oscar.nierstrasz.org/" rel="alternate" type="text/html" /><updated>2026-02-05T07:12:48-08:00</updated><id>https://www.oscar.nierstrasz.org/feed.xml</id><title type="html">Oscar Nierstrasz</title><subtitle></subtitle><author><name>Oscar Nierstrasz</name><email>oscar@nierstrasz.org</email></author><entry><title type="html">Example-Driven Development</title><link href="https://www.oscar.nierstrasz.org/posts/2024-04-25-EDD" rel="alternate" type="text/html" title="Example-Driven Development" /><published>2024-04-25T00:00:00-07:00</published><updated>2024-04-25T00:00:00-07:00</updated><id>https://www.oscar.nierstrasz.org/posts/EDD</id><content type="html" xml:base="https://www.oscar.nierstrasz.org/posts/2024-04-25-EDD"><![CDATA[<p>Example-Driven Development is superficially like Test-Driven Development, where you drive development by constructing test methods that return example objects. It sounds simple, but it actually changes the development process in several fundamental ways.</p>

<h2 id="the-trouble-with-tdd">The Trouble with TDD</h2>

<p>With TDD, you develop code by incrementally adding a test for a new feature, which fails. Then you write the “simplest code” that passes the new test. You add new tests, refactoring as needed, until you have fully covered everything that the new feature should fulfil, as specified by the tests.</p>

<p>But: <em>Where do tests come from?</em> When you write a test, you actually have to “guess first” to imagine what objects to create, exercise and test.</p>

<p><em>How do we write the simplest code that passes?</em> A test that fails gives you a debugger context, but then you have to go somewhere else to add some new classes and methods.</p>

<p><em>What use is a green test?</em> Green tests can be used to detect regressions, but otherwise they don’t help you much to create new tests or explore the running system.</p>

<p>With Example-Driven Development we try to answer these questions.</p>

<h2 id="whats-an-example">What’s an Example?</h2>

<p>An <em>example method</em> is just a test method that happens to return the object being tested. Through this simple change, instead of a passing test simply being green, we get back an <em>object</em> that we can inspect, explore, and reuse for various purposes.</p>

<p>Here we see a simple example of an example method for a “Memory” game. It is annotated with a <code class="language-plaintext highlighter-rouge">&lt;gtExample&gt;</code> pragma to flag it as an example.</p>

<p><a href="/assets/images/edd/1000.png"><img src="/assets/images/edd/1000.png" alt="fixedGame example method" /></a></p>

<p>Like any test, it has a setup, which in this case creates a <code class="language-plaintext highlighter-rouge">game</code> object. We check some assertions, in this case perform no further operations, and then we return the object under test.</p>

<p>This allows us not only to carry out the tests, but also to inspect the result. Here we see a screenshot of the <em>Live</em> GUI view of the memory game instance.</p>

<p><a href="/assets/images/edd/1001.png"><img src="/assets/images/edd/1001.png" alt="A Memory game live view" /></a></p>

<h2 id="composing-examples">Composing examples</h2>

<p>Once we have an example, we can also use it as a setup for another example.
<code class="language-plaintext highlighter-rouge">chooseMatchingPair</code> is another example method that starts with <code class="language-plaintext highlighter-rouge">fixedGame</code> as its setup.</p>

<p><a href="/assets/images/edd/1002.png"><img src="/assets/images/edd/1002.png" alt="chooseMatchingPair example method" /></a></p>

<p>As in a conventional test, we can check some preconditions, perform one or more operations, and then check some postconditions. The difference, again, is that we return the object under test, so we can explore it.</p>

<p><a href="/assets/images/edd/1003.png"><img src="/assets/images/edd/1003.png" alt="Memory game after one matched pair" /></a></p>

<p>We can also reuse it as a setup for yet another example, in this case, <code class="language-plaintext highlighter-rouge">playToEnd</code>.</p>

<p><a href="/assets/images/edd/1004.png"><img src="/assets/images/edd/1004.png" alt="playToEnd example method" /></a></p>

<p>If we switch to the <em>Examples map</em> view, we can see all the dependencies between the examples.</p>

<p><a href="/assets/images/edd/1005.png"><img src="/assets/images/edd/1005.png" alt="An Example  map for the memory game" /></a></p>
<h2 id="what-are-example-methods-good-for">What are example methods good for?</h2>

<p>As we have seen, examples make dependencies between tests explicit by reusing examples as setups for other examples, thus forming a hierarchy of examples.</p>

<ul>
  <li>Example composition reduces:
    <ul>
      <li><em>code duplication,</em></li>
      <li><em>cascading failures.</em></li>
    </ul>
  </li>
  <li>Examples can be reused in <em>live documentation.</em></li>
  <li>EDD is an <em>exploratory approach</em> to TDD.</li>
</ul>

<p>Best practice in test design supposedly should avoid dependencies between tests, but <a href="https://scg.unibe.ch/assets/scgbib/?query=Haen09a">studies</a> have shown that this practice instead leads to implicit dependencies due to duplicated code in test setups. This in turn leads to cascading failures due to the same setups being repeated in numerous tests. By factoring out the commonalities as examples, the duplication is removed, and cascading failures are avoided.</p>

<p>A further benefit is that examples can be used in live documentation, and, as we shall see, examples support an exploratory approach to test-driven development, that we call example-driven development, or EDD.</p>

<h2 id="modeling-prices">Modeling prices</h2>

<p>Let’s work through an example where we want to model <em>prices</em> for goods, that may be <em>discounted</em> by fixed amounts, or percentages, or even combinations of different types of discounts.</p>

<ul>
  <li><em>A price can be something like 100 EUR.</em></li>
  <li><em>Prices can be added or multiplied.</em></li>
  <li><em>A price can also be discounted either by a fixed amount of money, or by a percentage.</em></li>
  <li><em>All operations can be combined arbitrarily.</em></li>
  <li><em>And for audit purposes, we want to track all operations that lead to a concrete amount of money.</em></li>
</ul>

<h2 id="money-classes">Money classes</h2>

<p>To simplify our task, we assume that we already have classes that model different amounts of money, such as 42 € or 10 USD.</p>

<p>All these classes have a common abstract <em>GtTMoney</em> superclass for shared behavior.</p>

<p><a href="/assets/images/edd/1006.png"><img src="/assets/images/edd/1006.png" alt="The Money class hierarchy" /></a></p>

<p>An amount of money is always in a <em>currency</em> such as euros or US dollars.
A <em>bag</em> of money consists of amounts of mixed currencies.
A <em>zero</em> amount of money doesn’t have a currency.</p>

<p>This expression:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>42 euros.
</code></pre></div></div>

<p>yields:</p>

<p><a href="/assets/images/edd/1007.png"><img src="/assets/images/edd/1007.png" alt="A Money instance" /></a></p>

<p>While:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>42 euros + 10 usd.
</code></pre></div></div>

<p>yields:</p>

<p><a href="/assets/images/edd/1008.png"><img src="/assets/images/edd/1008.png" alt="A MoneyBag instance" /></a></p>

<h2 id="money-examples">Money examples</h2>

<p>The money classes are heavily covered by examples, which are essentially unit tests that also return example objects. For example, this method tests that adding a zero amount of a different currency won’t accidentally create a bag of monies.</p>

<p><a href="/assets/images/edd/1009.png"><img src="/assets/images/edd/1009.png" alt="Adding zero money example" /></a></p>

<p>A passing test is not just green, but also returns an object that can be explored, reused as a setup for another example, or embedded into live documentation. Unlike tests, however, examples don’t come “first” but they are extracted during the example-driven development process.</p>

<h2 id="introducing-a-concrete-price">Introducing a Concrete Price</h2>

<p>Just like we have a hierarchy of Money classes, we expect to end up with a hierarchy of Price objects, including an abstract root class, a concrete, fixed price, and several kinds of discounted prices.
Instead of designing this hierarchy up-front, we’ll develop it incrementally, driven by examples.</p>

<p>We’ll start with an example of a concrete (as opposed to an abstract) Price object.</p>

<ul>
  <li><em>A price can be something like 100 EUR.</em></li>
  <li><em>Prices can be added or multiplied.</em></li>
  <li>…</li>
</ul>

<h2 id="start-from-an-object">Start from an object</h2>

<p>Instead of starting by imagining and writing a test case as an example method, we start by creating an instance of the class we need. We first simply ask how we want to create our concrete instance of a price, and we write that code in a snippet.</p>

<p>Neither the class nor the constructor exist, so we create them as fixit operations. We start with a snippet to create an instance of the class we want to design.</p>

<p><a href="/assets/images/edd/1010.png"><img src="/assets/images/edd/1010.png" alt="A non-existing class with a fixit" /></a></p>

<p>The <code class="language-plaintext highlighter-rouge">ConcretePrice</code> class does not exist, so we see a <em>fixit</em> (wrench) icon. We click on it to generate the list of fixit options.</p>

<p><a href="/assets/images/edd/1011.png"><img src="/assets/images/edd/1011.png" alt="A fixit dialog" /></a></p>

<p>We fill in the form to create a new <code class="language-plaintext highlighter-rouge">ConcretePrice</code> class in the <code class="language-plaintext highlighter-rouge">EDDPrices</code> package, tag it as a <code class="language-plaintext highlighter-rouge">Model</code> class, and assign a <code class="language-plaintext highlighter-rouge">money</code> slot. We click the <code class="language-plaintext highlighter-rouge">Create</code> button to perform the fixit.</p>

<p><a href="/assets/images/edd/1012.png"><img src="/assets/images/edd/1012.png" alt="Creating a new class" /></a></p>

<p>We also generate accessors as a standard code transformation.</p>

<p><a href="/assets/images/edd/1013.png"><img src="/assets/images/edd/1013.png" alt="Creating accessors" /></a></p>

<p>Now we have a <code class="language-plaintext highlighter-rouge">ConcretePrice</code> instance to explore!</p>

<p><a href="/assets/images/edd/1014.png"><img src="/assets/images/edd/1014.png" alt="Inspecting a ConcretePrice instance" /></a></p>
<h2 id="create-a-factory-method">Create a factory method</h2>

<p>We would  like to be able to create a price object by directly sending <code class="language-plaintext highlighter-rouge">asPrice</code> to a Money instance. We prototype this behavior in the playground of the <code class="language-plaintext highlighter-rouge">GtTCurrencyMoney</code> instance we have in front of us.</p>

<p><a href="/assets/images/edd/1015.png"><img src="/assets/images/edd/1015.png" alt="Prototyping the asPrice behavior" /></a></p>

<p>Now we can perform an <em>Extract method</em> refactoring on this code snippet, and change its category to be an <em>extension method</em> from our <code class="language-plaintext highlighter-rouge">EDDPrices</code> package.</p>

<p><a href="/assets/images/edd/1016.png"><img src="/assets/images/edd/1016.png" alt="Our code extracted as an extension method" /></a></p>

<p>And now we can simply write <code class="language-plaintext highlighter-rouge">100 euros asPrice</code>.</p>

<p><a href="/assets/images/edd/1017.png"><img src="/assets/images/edd/1017.png" alt="A factory method for prices" /></a></p>
<h2 id="adding-a-view">Adding a view</h2>

<p>Our new Price object has only an ugly generic view, but its money slot has a nice  view we could reuse.</p>

<p>We go to the <code class="language-plaintext highlighter-rouge">Meta</code> view of the Price object and add a new view method that forwards itself to the Details view of its <code class="language-plaintext highlighter-rouge">money</code> slot.</p>

<p><a href="/assets/images/edd/1018.png"><img src="/assets/images/edd/1018.png" alt="Defining a new view" /></a></p>

<p>A view is just a method that takes a view object as an argument, has a <code class="language-plaintext highlighter-rouge">&lt;gtView&gt;</code> pragma, and uses the view API to create the view we want, in this case a <code class="language-plaintext highlighter-rouge">forward</code> view. We set the title of the view to <code class="language-plaintext highlighter-rouge">Money</code>, and the priority to 10 so it appears early in the list of views. The object we want to forward to is the money slot, and the view is its <code class="language-plaintext highlighter-rouge">gtDisplayFor:</code> view.</p>

<p>The moment we commit the view code, the view becomes available.</p>

<p><a href="/assets/images/edd/1019.png"><img src="/assets/images/edd/1019.png" alt="The Money view installed" /></a></p>
<h2 id="extracting-an-example">Extracting an example</h2>

<p>At this point it looks like we have a nice example for testing, so let’s extract it as an example by applying an <em>Extract example</em> refactoring.</p>

<p><a href="/assets/images/edd/1020.png"><img src="/assets/images/edd/1020.png" alt="The Extract example refactoring" /></a></p>

<p>We introduce a new class to hold our examples, and give the example a suitable name.</p>

<p><a href="/assets/images/edd/1021.png"><img src="/assets/images/edd/1021.png" alt="An extracted example method" /></a></p>

<p>Note that the extracted example method has a <code class="language-plaintext highlighter-rouge">&lt;gtExample&gt;</code> pragma, and unlike a usual test method, it returns an instance.</p>

<h2 id="adding-assertions">Adding assertions</h2>

<p>We now have an example, but we aren’t testing anything yet.</p>

<p>Rather than directly adding tests to the example method, let’s explore first. We expect that a price object should equal another price object with the same money value. We see that this fails.</p>

<p><a href="/assets/images/edd/1022.png"><img src="/assets/images/edd/1022.png" alt="A failing test case" /></a></p>

<p>If we look at the <code class="language-plaintext highlighter-rouge">=</code> method and see that it’s testing for object identity, not object equality. Let’s see what happens if we directly compare the <code class="language-plaintext highlighter-rouge">money</code> slots.</p>

<p><a href="/assets/images/edd/1023.png"><img src="/assets/images/edd/1023.png" alt="Comparing money slots" /></a></p>

<p>This passes. We see that Money has implemented <code class="language-plaintext highlighter-rouge">=</code>, so we should do the same. We have the code we want right here, so let’s extract it as a new <code class="language-plaintext highlighter-rouge">=</code> method.</p>

<p><em>Caveat:</em> actually there is a bit more work to do to implement a proper <code class="language-plaintext highlighter-rouge">=</code> method, but let’s skim over this point.</p>

<p><a href="/assets/images/edd/1024.png"><img src="/assets/images/edd/1024.png" alt="Comparing Price equality, not identity" /></a></p>

<p>Now we can go back to the example and rewrite it to add the new assertion.</p>

<p><a href="/assets/images/edd/1025.png"><img src="/assets/images/edd/1025.png" alt="Our assertion as part of the example" /></a></p>

<h2 id="price-examples">Price Examples</h2>

<p>After a number of iterations we end up with something like this, with a hierarchy of examples covering test cases for prices.</p>

<p><a href="/assets/images/edd/1026.png"><img src="/assets/images/edd/1026.png" alt="The Price Examples map" /></a></p>

<h1 id="embedding-examples-in-live-documentation">Embedding examples in live documentation</h1>

<p>An important benefit of examples is that they can be embedded within live notebooks to document significant use cases and scenarios. Here we see not just the source code, but the live example of a Money bag being used to document the price model.</p>

<p><a href="/assets/images/edd/1027.png"><img src="/assets/images/edd/1027.png" alt="Embedding a live Money Bag as an example" /></a></p>

<p>And within the same notebook page, we see a live example of a multiple-discounted Price object, with a view that documents each discounting step.</p>

<p><a href="/assets/images/edd/1028.png"><img src="/assets/images/edd/1028.png" alt="Embedding a live discounted Price as an example" /></a></p>

<h2 id="edd-in-a-nutshell">EDD in a Nutshell</h2>

<p>Summing up, instead of starting by writing a test, we first create a <em>live object</em> to explore.</p>

<ul>
  <li>Start with an <em>object</em>
    <ul>
      <li><em>Prototype</em> behavior in the playground</li>
      <li><em>Extract</em> methods</li>
      <li>Introduce useful <em>views</em></li>
    </ul>
  </li>
  <li><em>Extract</em> examples
    <ul>
      <li>Prototype <em>assertions</em> in the playground</li>
      <li><em>Add them</em> to the example method</li>
      <li><em>Reuse</em> examples as setups for new examples</li>
      <li><em>Embed</em> examples within live documentation.</li>
    </ul>
  </li>
</ul>

<p>We prototype any behavior in the playground of the live object, and then extract methods that work. We create views that explain what is interesting about the object.</p>

<p>We extract interesting instances as example methods of a dedicated examples class. We prototype tests in the playground of the live example, before adding them as assertions to an example. We reuse the examples as setups for new examples, and as live documentation.</p>

<p>We iterate until we’re done!</p>

<hr />

<p>This article was originally posted on the <a href="https://lepiter.io/feenk/example-driven-development-ekmic0u0o8swpblzkcdzy608s/">feenk blog</a>.</p>]]></content><author><name>Oscar Nierstrasz</name><email>oscar@nierstrasz.org</email></author><summary type="html"><![CDATA[Example-Driven Development is superficially like Test-Driven Development, where you drive development by constructing test methods that return example objects. It sounds simple, but it actually changes the development process in several fundamental ways.]]></summary></entry><entry><title type="html">Teaching Moldable Development</title><link href="https://www.oscar.nierstrasz.org/posts/2023-08-28-TeachingMoldableDevelopment" rel="alternate" type="text/html" title="Teaching Moldable Development" /><published>2023-08-28T00:00:00-07:00</published><updated>2023-08-28T00:00:00-07:00</updated><id>https://www.oscar.nierstrasz.org/posts/TeachingMoldableDevelopment</id><content type="html" xml:base="https://www.oscar.nierstrasz.org/posts/2023-08-28-TeachingMoldableDevelopment"><![CDATA[<p>Moldable Development is a way of developing software in which you build many, small custom tools to solve problems. This implies new tools and new associated skills. As with any new way of thinking, teaching can be challenging. In this session we go draw lessons from our experience of teaching Moldable Development in practice, including how it changes the teaching experience itself.</p>

<hr />

<p>Moldable development is a <em>new</em> way of programming. In many ways it looks like programming as we are used to it, but it actually entails fundamentally different ways of thinking about programming, and new <em>patterns</em> of programming.</p>

<h1 id="what-is-moldable-development">What is Moldable Development?</h1>

<p>Moldable Development is a way of programming in which you build custom tools for each problem. In this way the system becomes <em>explainable</em>, and thus supports decision making for a range of stakeholders. Let’s look at a simple example.</p>

<h2 id="exploring-the-esug-website">Exploring the ESUG website</h2>

<p>Let’s take an easy domain that we can easily relate to, namely the <a href="https://esug.github.io/">ESUG website</a>. Here we are inspecting the cloned repo of the ESUG website.</p>

<p><a href="/assets/images/esug2023/esugWebSiteInspectorViews.png"><img src="/assets/images/esug2023/esugWebSiteInspectorViews.png" alt="ESUG website custom Inspector views" /></a></p>

<p>We can browse the pages of the website, and see the contents of a page.</p>

<p><a href="/assets/images/esug2023/esugPageContents.png"><img src="/assets/images/esug2023/esugPageContents.png" alt="ESUG website page contents" /></a></p>

<p>From the website inspector we also see all the links, possibly missing internal links, reachable pages, as well as an overall map of root pages (blue), reachable pages (green) and unreachable pages (red).</p>

<p><a href="/assets/images/esug2023/mondrianMap.png"><img src="/assets/images/esug2023/mondrianMap.png" alt="ESUG website Mondrian map" /></a></p>

<p>We can also check the status of links using a background process. Finally, we can search for pages or links by title or content.</p>

<p><a href="/assets/images/esug2023/esugWebsiteSpotter.png"><img src="/assets/images/esug2023/esugWebsiteSpotter.png" alt="ESUG website custom Spotter search" /></a></p>

<h2 id="recap">Recap</h2>

<p>So what have we seen? We have domain objects representing a website, the web pages and the links. We have custom views for each domain object allowing us to explore the information that interests us, and to navigate to other objects. We also have custom actions to open a web browser or to start an analysis, and we have a custom search to query lists of pages and links.</p>

<p>Each of these custom tools is implemented in just a few lines of code in a method of the domain object concerned annotated with a dedicated pragma. For example, here is the code for the <code class="language-plaintext highlighter-rouge">Pages</code> view (we Alt+click on the view to see the code).</p>

<p><a href="/assets/images/esug2023/esugWebsitePagesView.png"><img src="/assets/images/esug2023/esugWebsitePagesView.png" alt="ESUG website pages view" /></a></p>

<p>Now we get to the key question:</p>

<p><em>How hard is it to teach people to build their own explainable system for their domain of interest?</em></p>

<h1 id="moldable-development-patterns">Moldable Development Patterns</h1>

<p>Since Moldable Development is a <em>way</em> to develop explainable systems, rather than focusing on technology, it makes sense to start from the <em>patterns</em> that we observe when building such systems.</p>

<p>Moldable development patterns express <em>best practices</em> in the process of molding software to make it explainable. Let’s have a look a few of these patterns.</p>

<h2 id="pattern-moldable-object">Pattern: Moldable object</h2>

<p>This is perhaps the hardest pattern to learn. Where would you rather be when you are developing code? Staring at the source code, or viewing the live object that you are working on?</p>

<p><a href="/assets/images/esug2023/pillarWebsiteCoder.png"><img src="/assets/images/esug2023/pillarWebsiteCoder.png" alt="PillarWebsite class coder" /></a></p>

<p>Here we see at the top a typical Coder view of a class where we can browse and edit the methods. But this is actually the least interesting view we can have because each method is seen divorced from the context in which it is used and interacts with other methods.</p>

<p>From the very first day that we start to program, we learn to write some code in a text editor, and we compile it and run it. It always takes a few steps to see the end result.</p>

<p>But why not reverse this? Below here we see a <em>moldable object</em>, that is, a live instance of the PillarWebsite object that we can interact with.</p>

<p><a href="/assets/images/esug2023/esugWebSiteInspectorViews.png"><img src="/assets/images/esug2023/esugWebSiteInspectorViews.png" alt="ESUG website Inspector views" /></a></p>

<p>While it can be cumbersome to navigate from the code view to see its effect, it is usually easy to navigate from the live object to its code. Suppose for, for example, that we want to extend the overview with new attributes. We can directly navigate to the code and adapt it.</p>

<p><a href="/assets/images/esug2023/esugWebsiteOverviewView.png"><img src="/assets/images/esug2023/esugWebsiteOverviewView.png" alt="ESUG website ovierview view" /></a></p>

<p>From the moldable object we can experiment with new features, extract methods and examples or tests, and immediately see the effect.</p>

<h2 id="pattern-viewable-data-wrapper">Pattern: Viewable data wrapper</h2>

<p>Although sometimes you may have the luxury to work on a greenfield project, most projects start from some existing data and code. When we load the data into our environment, we will obtain the default views for that data. Here, for example, we have loaded the cloned ESUG website repo and are inspecting the contents.</p>

<p><a href="/assets/images/esug2023/repoFilesView.png"><img src="/assets/images/esug2023/repoFilesView.png" alt="Repository files view" /></a></p>

<p>We obtain a completely generic view of the folders and files that tells us nothing about the domain. We would like to turn this into a proper domain object that tells us interesting things about itself. As a first step, then, we can <em>wrap</em> the data into a dedicated object.</p>

<p>When we do this, at first glance the result appears to be even worse, as now we just get a generic <em>Raw</em> view of the new object.</p>

<p><a href="/assets/images/esug2023/esugWrapperRawView.png"><img src="/assets/images/esug2023/esugWrapperRawView.png" alt="ESUG website wrapper raw view" /></a></p>

<p>But now we have the possibility to explore it, add behavior, and add new views. After some iterations we obtain the view we have seen earlier.</p>

<h2 id="pattern-contextual-playground">Pattern: Contextual playground</h2>

<p>When you program in a conventional IDE, the code is strictly disconnected from any live instance. Experimenting and exploring the state of the running program is only possible by setting breakpoints and running the code in the debugger, or by writing additional dedicated test code.</p>

<p>Another way is to start coding from an Inspector on a live, moldable object. This should remind you of the Smalltalk practice of coding in the debugger, but the difference is that you can code in an inspector without having to get a debugger instance.</p>

<p>Here we see a live instance of our simple EsugWebsiteWrapper with a Playground opened at the bottom.</p>

<p><a href="/assets/images/esug2023/esugWrapperWithPlayground.png"><img src="/assets/images/esug2023/esugWrapperWithPlayground.png" alt="ESUG website wrapper with playground" /></a></p>

<p>Why is this interesting?</p>

<p>Because the playground is <em>bound to the context of the object</em>, unlike code that we write in a normal code editor. For instance, the variable <code class="language-plaintext highlighter-rouge">repoDir</code> is bound to that slot of the live instance. We can experiment with code in the playground, and when we see something we like, we can copy the code to a method, or even directly apply an extract method refactoring.</p>

<h2 id="pattern-viewable-entity">Pattern: Viewable Entity</h2>

<p>How do you know when to create a custom view?</p>

<p>This is another fundamental pattern. The idea is that, whenever you find yourself navigating to get to some interesting objects, you should turn that navigation path into a custom view so you can get to that information directly.</p>

<p>Let’s look at a trivial example: as we explore the Esug website model, we navigate to the pages using a Playground snippet, and then we can navigate to individual pages.</p>

<p><a href="/assets/images/esug2023/esugWrapperWithPages.png"><img src="/assets/images/esug2023/esugWrapperWithPages.png" alt="ESUG website wrapper with pages" /></a></p>

<p>Instead we’d like the list of pages view to be visible directly in the website object. We can inspect that view to see that it is implemented as a <code class="language-plaintext highlighter-rouge">#gtItemsFor:</code> method in the class <code class="language-plaintext highlighter-rouge">SequenceableCollection</code>. We could copy-paste the code and later adapt it, but as a first quick step we can simply define a <em>forwarding</em> view from the website to the collection.</p>

<p>We just open a Coder view and add the view that forwards to the existing view of the pages collection. The new view is instantly available.</p>

<p><a href="/assets/images/esug2023/pageFilesView.png"><img src="/assets/images/esug2023/pageFilesView.png" alt="ESUG website page files view" /></a></p>

<h2 id="gt-book-moldable-development-patterns">GT Book: Moldable Development patterns</h2>

<p>We have just seen some of the most basic moldable development patterns. They are described in further detail in the GT Book, together with several other patterns.</p>

<p><a href="/assets/images/esug2023/patternsPage.png"><img src="/assets/images/esug2023/patternsPage.png" alt="Moldable Patterns page" /></a></p>

<h1 id="what-works">What works?</h1>

<p>Teaching Moldable Development is challenging not only because there are the patterns to learn, but also a fair bit of technology to get acquainted with. Here are a few things that can ease the learning process.</p>

<h2 id="live-documentation">Live documentation</h2>

<p>GT comes with a live knowledge base of notebook pages documenting the system itself as well as numerous case studies. For example, here is a page describing how to interact with the GitHub REST API as a case study in Moldable Development.</p>

<p><a href="/assets/images/esug2023/gitHubRestApiBookPage.png"><img src="/assets/images/esug2023/gitHubRestApiBookPage.png" alt="GitHub REST API GT book page" /></a></p>

<p>The GT book not only offers users documentation to read and live tutorials to try out, but also serves as a concrete example for users to start their own projects from their personal database of notes.</p>

<h2 id="discord">Discord</h2>

<p>Discord can be a great platform for community building, however it must be well-curated. It’s critical not only to make people feel welcome and encouraged to ask any kind of questions, but their questions need to be taken seriously, and answered reasonably quickly.</p>

<p>One interesting pattern in community building is to teach people when they share screenshots to capture an entire window showing the flows between snippets of code and views of interest. A well-designed screenshot goes a long way to telling a story or explaining an issue.</p>

<p><a href="/assets/images/esug2023/discord.png"><img src="/assets/images/esug2023/discord.png" alt="GT Discord" /></a></p>

<h2 id="videos">Videos</h2>

<p>Some people love to watch long, meandering videos at double speed, but I’m not one of them. A short, compact video can be a very effective way to explain and demonstrate a complex topic, but it also requires considerable planning. It can, however, take more time to prepare a seven minute video than one that runs over an hour.</p>

<p><a href="/assets/images/esug2023/youTubeGTshorts.jpg"><img src="/assets/images/esug2023/youTubeGTshorts.jpg" alt="Getting started with GT in 7'" /></a></p>

<h1 id="challenges">Challenges</h1>

<p>Let me round up with a couple of the biggest challenges we have encountered in trying to explain moldable development.</p>

<h2 id="people-hate-change">People hate change</h2>

<p>People hate change, or perhaps rather it’s the case that it’s extremely hard for people to change habits once they have become ingrained. I personally took a long time to get into the habit of starting to code from live objects rather than heading to a code editor first. The code editor is a comfortable place to start from, even if it is not very useful for exploring implementation options or understanding existing code.</p>

<p>What helps here best is live mentoring on a real project. When you see over and over again the benefits of coding from live objects, you begin to build up a Pavlovian instinct to stay away from the code editor as your starting point. Demos and videos also help, but they are not as effective as the first-hand experience.</p>

<h2 id="people-focus-on-what-they-see-first">People focus on what they see first</h2>

<p>The Glamorous Toolkit contains many pieces of technology that fit together to support moldable development. People like to put things into boxes, so they tend to focus on the first bit of technology that captures their imagination, and so risk to lose the big picture. For example, visualization is an important component, but it is a mistake to equate moldable development with visualization.</p>

<p><a href="/assets/images/esug2023/bookTreeMap.png"><img src="/assets/images/esug2023/bookTreeMap.png" alt="GT Book TreeMap visualization" /></a></p>

<p>The same can be said for the live notebooks, the language workbench, or the pervasive use of examples.</p>

<h1 id="conclusions">Conclusions</h1>

<p>In the end, what is important to convey is that Moldable Development is a <em>process</em> in which you ask questions about a software system, explore it, and build lots of small, custom tools to answer those questions and make the system explainable.</p>

<p>Moldable Development is a new way of programming that takes time to learn, but that in the end boils down to a set of learnable patterns.</p>

<p><a href="/assets/images/esug2023/patternsMap.png"><img src="/assets/images/esug2023/patternsMap.png" alt="Moldable Patterns map" /></a></p>

<hr />

<p>This blog article is based on a talk presented at <a href="https://esug.github.io/2023-Conference/conf2023.html">ESUG 2023</a>, in which we report on the challenges and and insights we have experienced in teaching moldable development to newcomers.</p>

<p>See the original article on the <a href="https://lepiter.io/feenk/teaching-moldable-development-dkbj2hlidhiph2eodusb87ye6/">feenk blog</a>.</p>]]></content><author><name>Oscar Nierstrasz</name><email>oscar@nierstrasz.org</email></author><summary type="html"><![CDATA[Moldable Development is a way of developing software in which you build many, small custom tools to solve problems. This implies new tools and new associated skills. As with any new way of thinking, teaching can be challenging. In this session we go draw lessons from our experience of teaching Moldable Development in practice, including how it changes the teaching experience itself.]]></summary></entry><entry><title type="html">Mind the gap — 50 years of shortening feedback loops</title><link href="https://www.oscar.nierstrasz.org/posts/2023-06-12-MindTheGap" rel="alternate" type="text/html" title="Mind the gap — 50 years of shortening feedback loops" /><published>2023-06-12T00:00:00-07:00</published><updated>2023-06-12T00:00:00-07:00</updated><id>https://www.oscar.nierstrasz.org/posts/MindTheGap</id><content type="html" xml:base="https://www.oscar.nierstrasz.org/posts/2023-06-12-MindTheGap"><![CDATA[<p>On the occasion of the <a href="https://www.berner-architekten-treffen.ch/event/50">50th BATbern event</a>, it occurred to me that it has been roughly 50 years since I started programming.
In that time I’ve seen quite a few advances in Software Engineering.
I’d like to take this opportunity to reflect on how these advances have not only shortened feedback loops in software development processes, but also how they have enabled new possibilities for innovation.</p>

<hr />
<h1 id="the-execution-gap">The execution gap</h1>

<p>My first experience with gaps between expectations and reality in Software Engineering took place in 1972 when I started to learn to program.
In this case the gap was simply the time between designing a program and actually seeing it run.
I was a tenth-grade high-school student in Toronto when I was invited to the University of Waterloo for a week of Mathematics and a bit of programming.</p>

<p>My first programming experience was with <a href="https://en.wikipedia.org/wiki/APL_(programming_language)">APL</a>, a live programming language for manipulating matrices and arrays.
We were taught by the amazing <a href="https://uwaterloo.ca/pure-mathematics/people-profiles/leroy-j-dickey">Prof. Lee J. Dickey</a>, and we programmed interactively on a timesharing system, getting immediate feedback.</p>

<p>APL is facetiously known as a “write-only” language, due to its highly compact notation using Greek letters as array manipulation operators.
Here we a see a one-line APL program to generate prime numbers.
I remember writing a similar one-line APL prime sieve that looked something like this one.</p>

<p><a href="/assets/images/bat50/aplPrimeSieve.jpg"><img src="/assets/images/bat50/aplPrimeSieve.jpg" alt="An APL prime sieve" /></a></p>

<p class="small"><i>[Sources: <a href="https://old.aplwiki.com/SieveOfEratosthenes">APL wiki</a>, <a href="https://commons.wikimedia.org/wiki/File:APL-keybd2.svg">Wikimedia commons</a>]</i></p>

<p>As an amusing parenthesis, I saw this sign displayed in the <a href="https://reykjavikcitymuseum.is/arbaer-open-air-museum">Open Air museum in Reykjavik</a> in 2015.
It looks fine, except the “typewriter” was not a typewriter at all.</p>

<table>
  <thead>
    <tr>
      <th><a href="/assets/images/bat50/reykjavikMuseumTheTypist.jpg"><img src="/assets/images/bat50/reykjavikMuseumTheTypist.jpg" alt="The typist at the kitchen table" /></a></th>
      <th><a href="/assets/images/bat50/ibm2741.jpg"><img src="/assets/images/bat50/ibm2741.jpg" alt="IBM 2741" /></a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>The typist at the kitchen table</td>
      <td>IBM 2741</td>
    </tr>
  </tbody>
</table>

<p>The so-called typewriter was actually an <a href="https://en.wikipedia.org/wiki/IBM_2741">IBM 2741</a> used to program in APL.
It is exactly the same kind of terminal I first used in 1972, including the APL typeball with Greek characters.
I somehow doubt it was used to type letters in a kitchen in Iceland.</p>

<p>In the Autumn of 1972, the Toronto Board of Education introduced the first high school computer programming courses.
We coded our programs with pencil on optical cards, like the one you see here.</p>

<p><a href="/assets/images/bat50/ibmOpticalMarkCard.jpg"><img src="/assets/images/bat50/ibmOpticalMarkCard.jpg" alt="IBM optical mark card" /></a></p>

<p>We would hand our decks to the teacher, and get our printed output three days later.
Debugging was not a pleasant experience.
After my first experience with interactive APL, I felt I had moved back decades in time.</p>

<p>Later in the semester one of my classmates discovered that anyone at all could walk in off the street and use the keypunches and the high-speed job stream at the University of Toronto.
After that we did all our homework at UofT.</p>

<h2 id="closing-the-execution-gap">Closing the execution gap</h2>

<p>Here we see a “<a href="https://en.wikipedia.org/wiki/Wardley_map">Wardley map</a>”, a diagram for business strategy that maps components with respect to user need.</p>

<p><a href="/assets/images/bat50/map1executionGap.png"><img src="/assets/images/bat50/map1executionGap.png" alt="Wardley map: closing the execution gap" /></a></p>

<p>At the top we see the need for getting our programs running.
The other nodes are components that contribute to that need.
From <em>bottom to top</em> components provide <em>more value</em> to the user, and from <em>left to right</em> they <em>evolve</em> from <em>genesis</em>, through <em>prototypes</em>, to <em>products</em>, and all the way to <em>commodities</em>.</p>

<p>The grey lines show which components contribute to others higher up.
So, optical mark cards are sent by courier and contribute to getting the code running.
The red arrows indicate evolution of components towards products and commodities.
Greyed-out components are those from the past.
The dark red arrows point to new components that emerge from the evolution.</p>

<p>In this case we see that the source code medium evolves from optical mark cards via punch cards to interactive terminals, shortening the feedback loop.
Similarly, getting the program to run evolves from sending it by courier to just hitting the “enter” key.</p>

<p>What’s interesting, however, is that when the technology is sufficiently evolved, <em>new opportunities arise</em> that could not be imagined before.
In this case, since the feedback loop is so short with live programming, we can <em>experiment</em> in ways that were not possible before.
Since this form of experimentation is a new thing, it appears towards the left of the map, so can also be expected to evolve.</p>

<hr />
<h1 id="the-modeling-gap">The modeling gap</h1>

<p>After high school, I studied Mathematics at Waterloo, and later switched to do a Masters and PhD in Computer Science at UofT.
There I experienced the enormous gap between conceptual models and implementation.</p>

<p>The task for my <a href="https://scg.unibe.ch/assets/scgbib/?query=Nier81a">MSc thesis</a> was, together with another Masters student, to build a workflow system, called TLA, on top of another prototype of an electronic Office Forms System.
OFS was itself built as a layer on top of MRS, the Micro-Relational System, one of the first implementations of a relation database management system for Unix.</p>

<p><a href="/assets/images/bat50/theElectronicOffice.jpg"><img src="/assets/images/bat50/theElectronicOffice.jpg" alt="The electronic office" /></a></p>

<p>I was very excited about the project, and had a clear idea of what to do, before even looking at the code.
When I opened the box, however, I had trouble mapping the concepts to the C code.
Essentially the problem was that I was looking for the domain concepts in the code, but <em>I could not find the objects</em>.</p>

<p>I then had an epiphany when I saw the <a href="https://archive.org/details/byte-magazine-1981-08">August 1981 special issue of Byte</a> magazine dedicated to <a href="https://en.wikipedia.org/wiki/Smalltalk#:~:text=Smalltalk%20is%20a%20purely%20object,Diana%20Merry%2C%20and%20Scott%20Wallace.">Smalltalk</a>, a brand-new object-oriented language and system.
This was exactly what I was looking for!</p>

<table>
  <thead>
    <tr>
      <th><a href="/assets/images/bat50/Byte-August1981.jpg"><img src="/assets/images/bat50/Byte-August1981.jpg" alt="Byte August 1981" /></a></th>
      <th><a href="/assets/images/bat50/Byte-IntroducingSmalltalk80.jpg"><img src="/assets/images/bat50/Byte-IntroducingSmalltalk80.jpg" alt="Introducing Smalltalk" /></a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="https://archive.org/details/byte-magazine-1981-08">August 1981 Byte special issue on Smalltalk</a></td>
      <td><a href="https://www.tech-insider.org/star/research/acrobat/8108.pdf">Introducing the Smalltalk-80 System</a></td>
    </tr>
  </tbody>
</table>

<p>Object-oriented programming was born in Norway in 1962, where <a href="https://en.wikipedia.org/wiki/Ole-Johan_Dahl">Ole-Johan Dahl</a> and <a href="https://en.wikipedia.org/wiki/Kristen_Nygaard">Kristen Nygaard</a> struggled to implement simulation software using <a href="https://en.wikipedia.org/wiki/ALGOL">ALGOL</a>, an early procedural language.</p>

<p><a href="/assets/images/bat50/simulaDahlNygaard.jpg"><img src="/assets/images/bat50/simulaDahlNygaard.jpg" alt="Ole-Johan Dahl
and Kristen Nygaard" /></a></p>

<p class="small"><i>[Source: <a href="https://www.jot.fm/issues/issue_2002_09/eulogy/">Journal of Object Technology</a>]</i></p>

<p>They invented objects, classes and inheritance to model real-world simulations as a thin layer on top of ALGOL.
The resulting language was called <a href="https://en.wikipedia.org/wiki/Simula">Simula</a>, which was standardized in 1967.
Roughly 20 years later Bjarne Stroustrup, an experienced Simula programmer, started adding a similar thin layer to C, called “C with Classes”, and later renamed “C++”.</p>

<p>Also during the 1960s, an American computer scientist, <a href="https://en.wikipedia.org/wiki/Alan_Kay">Alan Kay</a>, noticed that computer hardware was getting smaller and faster at an astonishing rate.
He predicted that, somewhere down the line, you would be able to hold a computer in your hand, providing access to an encyclopedia of multimedia data.
He figured that it would only be possible to build the software for such a so-called “<a href="https://en.wikipedia.org/wiki/Dynabook">Dynabook</a>” using a fully object-oriented language and system.
He convinced Xerox PARC to fund the development of not just the language, but the entire system down to the metal.
The Smalltalk team indeed built not only the Smalltalk language and VM technology, but also the first graphical workstations and windowing systems.</p>

<p>I read about this and proposed to my supervisor at UofT, Prof. Dennis Tsichritzis, that to build our advanced electronic office systems we needed an object-oriented language and system.
Since Smalltalk wasn’t available for our hardware, we started research into building our own language and system.
Dennis told me, <em>“Grab a couple of MSc students and go implement an object-oriented system.”</em>
It was not that easy, but we did manage to come up with <a href="https://scg.unibe.ch/assets/scgbib/?query=Nier83b">something interesting</a>.</p>

<h2 id="closing-the-modeling-gap">Closing the modeling gap</h2>

<p>Object-oriented programming made it possible to trace concepts from requirements through design down to implementation.
This certainly made it easier to develop software systems, but what is interesting is that this <em>enabled long-term growth</em>.
Not only development, but maintenance and evolution of such systems was facilitated by making it easier to navigate from requirements to code.</p>

<p><a href="/assets/images/bat50/map2OOmodeling.png"><img src="/assets/images/bat50/map2OOmodeling.png" alt="Wardley map: closing the modeling gap" /></a></p>

<hr />
<h1 id="the-productivity-gap">The productivity gap</h1>

<p>Whereas in the 1980s most of the resistance to OO technology came from concerns about performance (after all, every message to an object entails at least one additional indirection), by the 1990s machines were fast enough that developer productivity was seen as being more important.
But what is “productivity”?</p>

<p>This great photo shows Margaret Hamilton, NASA’s lead software engineer for the Apollo Program, standing next to printouts of all the code produced by her team for the 1969 moon landing.</p>

<p><a href="/assets/images/bat50/margaretHamiltonApolloCode.jpg"><img src="/assets/images/bat50/margaretHamiltonApolloCode.jpg" alt="Margaret Hamilton with Apollo code" /></a></p>

<p class="small"><i>[Source: <a href="https://en.wikipedia.org/wiki/Margaret_Hamilton_(software_engineer)#MIT_Instrumentation_Laboratory_and_the_Apollo_Guidance_Computer">Wikipedia commons</a>]</i></p>

<p>But software productivity clearly isn’t just producing more code in the same amount of time, otherwise refactoring would be seen as negative productivity! The trick is to produce more <em>value</em> for the customer, whether this is more code or less.</p>

<p>In the 1990s, the mantra was “Objects are not enough”.
But if so, what else was needed?
This photo shows Ralph Johnson, Erich Gamma, Richard Helm and John Vlissides, the “Gang of Four” who produced the first “<a href="https://en.wikipedia.org/wiki/Design_Patterns">Design Patterns</a>” book.
All four were also experienced in developing object-oriented frameworks based on reusable architectures and software components.
They noticed that the same design ideas appeared in all the systems they had developed independently, and figured something interesting was going on.</p>

<p><a href="/assets/images/bat50/gangOfFour.jpg"><img src="/assets/images/bat50/gangOfFour.jpg" alt="The Design Patterns “Gang of Four”" /></a></p>

<p class="small"><i>[Source: <a href="https://avelonpang.medium.com/gang-of-four-design-patterns-intro-e884af24b85f">Medium</a>]</i></p>

<p>Object-oriented programming was so successful that, by the mid 1990s, there were already many, very large OO systems.
Despite the increased ease of evolution, many of these older OO systems started to show the typical symptoms of legacy systems predicted by Lehman and Belady’s <a href="https://en.wikipedia.org/wiki/Lehman%27s_laws_of_software_evolution">laws of software evolution</a>.</p>

<p>We started a European project called <a href="https://scg.unibe.ch/archive/famoos/">FAMOOS</a> in 1996 with industrial partners Nokia and Daimler-Benz to reengineer legacy OO software towards cleaner, more scalable component-based frameworks.</p>

<p>Our strategy was to recover lost design knowledge by reverse engineering and analyzing the legacy software, and then migrating it step-by-step towards a newer and cleaner architecture.</p>

<p><a href="/assets/images/bat50/reengineeringLifecycle.jpg"><img src="/assets/images/bat50/reengineeringLifecycle.jpg" alt="The Reengineering lifecycle" /></a></p>

<p>In the process of analyzing dozens of diverse OO software systems at Daimler and Nokia, we discovered numerous <em>reverse and reengineering patterns</em> that could be applied in multiple contexts.
For example, the pattern <em><a href="https://eng.libretexts.org/Bookshelves/Computer_Science/Programming_and_Computation_Fundamentals/Book%3A_Object-Oriented_Reengineering_Patterns_(Demeyer_Ducasse_and_Nierstrasz)/03%3A_First_Contact/3.05%3A_Interview_During_Demo">Interview during demo</a></em> helps a stakeholder you are interviewing to focus attention on concrete features and usage scenarios as you are trying to gain an initial understanding of a software system.
This is far more effective than watching a slideshow or scribbling on a whiteboard.
One of the key outcomes of this work was the open-source book, <em><a href="https://www.oscar.nierstrasz.org/oorp/">Object-Oriented Reengineering Patterns</a></em>.</p>

<p><a href="/assets/images/bat50/reengineeringPatterns.jpg"><img src="/assets/images/bat50/reengineeringPatterns.jpg" alt="OO Reengineering Patterns" /></a></p>

<h2 id="closing-the-productivity-gap">Closing the productivity gap</h2>

<p>Design patterns are valuable not only as a way to teach software developers about best practices, but they also offer a way to raise conversations about design to higher levels.
If I say to you, <em>“Do we need a Singleton here?”</em>, you should immediately understand what’s at stake.</p>

<p>Frameworks and components also raise the level of conversation.
Instead of dealing with many unconnected applications, we deal with a Software Product Line of applications sharing a common code base.</p>

<p><a href="/assets/images/bat50/map3productivity.png"><img src="/assets/images/bat50/map3productivity.png" alt="Wardley map: closing the productivity gap" /></a></p>

<hr />
<h1 id="the-testing-gap">The testing gap</h1>

<p>Once upon a time (and also today), testing was a manual process.</p>

<p>This great photo shows the ENIAC, one of the very first digital computers, completed in 1945.
As you can imagine, testing was a slow, laborious process of rewiring.
Before automation, manual testing of software systems could be as painful as rewiring the ENIAC.</p>

<p><a href="/assets/images/bat50/eniac.jpg"><img src="/assets/images/bat50/eniac.jpg" alt="ENIAC" /></a></p>

<p class="small"><i>[Source: <a href="https://education.blogs.archives.gov/2015/10/08/upcoming-events-for-educators-at-the-national-archives-at-new-york-city/1260_original/">National Archives</a>]</i></p>

<p>Automated testing only started to become popular with the introduction of Kent Beck’s <a href="https://en.wikipedia.org/wiki/SUnit">SUnit</a> framework for Smalltalk, and the subsequent <a href="https://en.wikipedia.org/wiki/Unit_testing#History">port of SUnit</a> by Kent and Erich Gamma to Java.</p>

<p>During the FAMOOS project we were concerned about a particular project we were analyzing, and for which we could find no test cases.
When we asked, we were told, <em>“Oh, but we have very extensive test cases!”</em> <em>“Great!”</em> we said, <em>“Can we see them?”</em> They then brought us a big book of test cases that some poor person had to manually step through every time the tests were run.</p>

<h2 id="closing-the-testing-gap">Closing the testing gap</h2>

<p>The transition from manual to automated testing not only shortened the feedback loop from coding to validating that predefined test cases would pass, but it enabled something new.</p>

<p><a href="/assets/images/bat50/map4testing.png"><img src="/assets/images/bat50/map4testing.png" alt="Wardley map: closing the testing gap" /></a></p>

<p>With high test coverage, it was now possible to introduce radical changes to the design of a software system, and to subsequently ensure that everything that worked before was still working.
The obvious downside was the need to manually write the test cases.
In any case, you only had to write an automated test once, whereas a manual test had to be evaluated each time by hand.</p>

<p>The open question is where we can go with generated tests.
So far these mostly just identify cases where the system fails, but there are some exceptions.
For example, <a href="https://medium.com/criteo-engineering/introduction-to-property-based-testing-f5236229d237">property-based testing</a> can test business logic.
When generated tests are ready to replace manually-written tests, there will certainly be new opportunities that can be hard to imagine now.</p>

<hr />
<h1 id="the-deployment-gap">The deployment gap</h1>

<p>Although there were many other exciting advances in the 1990s, let us skip ahead.</p>

<p>Earlier we saw the “execution gap” between design and execution of a running program.
The <em>deployment gap</em> concerns the gap between having a running and validated system and deploying it with end users.
Until the introduction of <a href="https://en.wikipedia.org/wiki/DevOps">DevOps</a>, this could be a slow and painful manual process.</p>

<h2 id="closing-the-deployment-gap">Closing the deployment gap</h2>

<p>Although DevOps clearly served to automate and close the gap between development and deployment, what is interesting is the new opportunities it created.</p>

<p><a href="/assets/images/bat50/map5devOps.png"><img src="/assets/images/bat50/map5devOps.png" alt="Wardley map: closing the deployment gap" /></a></p>

<p>In particular, with DevOps it is possible to experimentally introduce new features for selected groups of users to monitor and assess their impact on business.
Without DevOps, the very idea is laughable.</p>

<hr />
<h1 id="the-sustainability-gap">The sustainability gap</h1>

<p>Let us move to the present day.
We know that unfettered growth of software systems leads to legacy issues.
Very large software systems don’t scale well for decision making because we don’t, and <em>can’t</em>, understand them.
Let’s take a look for some of the reasons.</p>

<p><strong><em>Mainstream IDEs are glorified text editors</em></strong></p>

<p>All mainstream IDEs are pretty much the same: <em>they focus on editing source code</em>.</p>

<p>Why is this a problem?
First of all, putting a text editor at the center of the IDE presupposes that you are generally either reading or writing code.
But in fact <a href="https://drpicox.medium.com/developers-spend-less-than-10-of-time-coding-51c36c73a93b#:~:text=It%20turns%20out%20that%20the,was%20far%20below%20the%204%25.">we only spend a small part of our time writing code</a>.</p>

<p><strong><em>Reading code does not scale</em></strong></p>

<p>On the other hand, <em>reading code for very large systems does not scale.</em>
You simply cannot read hundreds of thousands of lines of code, let alone many millions of LOC.</p>

<p><strong><em>Lightweight tools are more effective than reading code</em></strong></p>

<p>One of the key reengineering patterns is <em><a href="https://eng.libretexts.org/Bookshelves/Computer_Science/Programming_and_Computation_Fundamentals/Book%3A_Object-Oriented_Reengineering_Patterns_(Demeyer_Ducasse_and_Nierstrasz)/04%3A_Initial_Understanding/4.04%3A_Study_the_Exceptional_Entities">Study the Exceptional Entities</a></em>, which helps you to learn quickly about potential problems in a software system by asking questions about outliers, such as very large classes, or classes with many fields but little behavior.
Lightweight tools and metrics can help you to gain insight into a complex system.</p>

<p><a href="/assets/images/bat50/systemComplexity.jpg"><img src="/assets/images/bat50/systemComplexity.jpg" alt="System complexity view" /></a></p>

<p>In this system complexity view, we map the numbers of attributes, methods and lines of codes to the width, height and color of classes in a hierarchy.
This immediately highlights classes with abnormally many lines of code, or lots of data with little behavior.</p>

<p>While such tools are useful early when investigating a system, they are still generic.
To support solving concrete problems, tools have to take the context of those problems into account.
The key question is whether such tools can be cheaply produced to answer specific questions about a given software system.</p>

<p><strong><em>Code is disconnected from the running application</em></strong></p>

<p>There is a huge gap between software source code and a running application.
In a classical development environment you stare at source code, modify it, then run the code to see the effect in the running application.
When that fails, you go back to staring at the code.</p>

<p>Perhaps you will have a test case or a breakpoint that will land you in a debugger to explore the live object, but from there you can only go back to playing with the source code.
Worse, if you start from the running application, you may struggle to answer questions such as, <em>“Where is this feature implemented?”</em></p>

<p><strong><em>Q&amp;A tools lack context, so give unreliable results</em></strong></p>

<p>When we are at a loss, and no colleague is nearby to lend a hand, we often turn to Google and friends, which sends us to other well-known Q&amp;A sites.
The problem with the answers we find on these sites is that they <em>lack our specific context</em>, so we can waste considerable time on non-trivial questions to assess their relevance to our problem.</p>

<p>Although Stack Overflow clearly suffers from this problem, statistically-generated answers such as those provided by ChatGPT are no better, and in some ways worse, because of the high level of confidence (or hubris?) displayed by the answers.</p>

<table>
  <thead>
    <tr>
      <th><a href="/assets/images/bat50/SO.png"><img src="/assets/images/bat50/SO.png" alt="Asking Stack Overflow a question" /></a></th>
      <th><a href="/assets/images/bat50/chatGPT.png"><img src="/assets/images/bat50/chatGPT.png" alt="Asking ChatGPT a question" /></a></th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A typical Stack Overflow answer</td>
      <td>A typical ChatGPT answer</td>
    </tr>
  </tbody>
</table>

<p>These screenshots show answers I obtained from Stack Overflow and ChatGPT to actual questions I had about GitHub pages.
In both cases I struggled to get the information relevant for my context.
Worse, the answer from ChatGPT looked authoritative, but in fact was fanciful and inaccurate.</p>

<p>The fact that we nevertheless tend to search for answers <em>outside</em> the system shows that there is a crisis that is not being addressed.</p>

<p><strong><em>Plugins are hard to find, hard to build, and hard to compose</em></strong></p>

<p>Instead of leaving the IDE to find answers to questions we have about our software base, it would be so much nicer if we could extend the IDE with the tools we need.
Luckily there exist <em>plugins</em>.</p>

<p>Unluckily plugins are (in my experience) not pleasant to implement, it is hard to find any that are truly helpful, and they pretty much never play nicely with other plugins.
Finally, plugins don’t know anything about your context, so like Stack Overflow and ChatGPT, the likelihood that they will help you for <em>your</em> problem is slim.</p>

<p>The key issue is that software is so <em>contextual</em> that it is not possible to predict the specific questions that will arise in developing and evolving it.
(We’ll see some examples shortly.)
As a consequence, generic tools and plugins will always fail to be useful at some point.
Instead, we need to be able to cheaply and quickly build or adapt tools to answer our specific, contextual questions.</p>

<hr />
<h1 id="moldable-development">Moldable development</h1>

<p>The IDE is more than a text editor.
For a software system to be explainable, it must be <em>explorable</em>.</p>

<ul>
  <li>First, instead of starting to explore a system from source code, we can <em>start from a live object</em> and navigate from there.</li>
  <li>Second, we must be able to answer questions relevant to our <em>context</em>. Instead of using off-the-shelf tools or plugins, we should be able to <em>cheaply build composable tools</em> specific to our domain.</li>
</ul>

<p>For example, to understand the <a href="https://github.com/onierstrasz/gt-talks">slideshow implementation</a> of the talk this blog post is based on, we don’t start from the source code but from a live instance.
We can navigate from the slideshow to its slides, to the Wardley maps, or even to the source code, if we need to.</p>

<p><a href="/assets/images/bat50/exploringTheSlideshow.png"><img src="/assets/images/bat50/exploringTheSlideshow.png" alt="Exploring the slideshow" /></a></p>

<p>In this screenshot, we create an instance of the <code class="language-plaintext highlighter-rouge">BATbern50Slideshow</code> class, and inspect it in the <a href="https://gtoolkit.com">Glamorous Toolkit</a> (AKA GT), an open-source, moldable environment for authoring explainable systems.
We can explore, for example, the <em>Slide methods</em> view to see the methods in order, and for each method we see the <em>Slide</em> view, the source code, or other views.</p>

<p>We can similarly explore any kind of system to understand it.
Here we explore the git repository of the slideshow’s source code.
We can explore the changes, the commits, the packages, and from each entity navigate further to deepen our understanding.</p>

<p><a href="/assets/images/bat50/exploringAGitRepo.png"><img src="/assets/images/bat50/exploringAGitRepo.png" alt="Exploring a GitHub repo" /></a></p>

<p>It doesn’t matter whether the domain is that of slideshows, git repositories, computer games, social media data, or life insurance policies.
In any of these cases, we can navigate through the network of domain objects to answer our questions, or to navigate from the objects to the code, rather than the other way around.</p>

<p>To make systems explainable, you need to be able to add cheap, composable tools, such as views.
Understanding doesn’t arise simply from navigating, but from being able to navigate efficiently and effectively to the answers you need.
This implies that you need to be able to easily and cheaply define your own plugins to mold the IDE to your needs.</p>

<p>For each of the custom navigational views we have seen, a few lines of code are all that are needed to define them.
We can ALT-click on the tabs to see the code.
For example, the <em>Slide deck</em> view is extremely short, and leverages the fact that all the parts are composable.</p>

<p><a href="/assets/images/bat50/inspectingTheCodeBehindAView.png"><img src="/assets/images/bat50/inspectingTheCodeBehindAView.png" alt="Inspecting the code behind a view" /></a></p>

<p>All the views we have seen are examples of custom tools added to a moldable IDE.
In addition to custom views, there are several other ways the IDE can be molded, such as by adding custom actions, search capabilities, and quality advices.</p>

<p><a href="/assets/images/bat50/customViewsAreCheap.png"><img src="/assets/images/bat50/customViewsAreCheap.png" alt="Custom views can be cheap toimplement" /></a></p>

<p>The <em>Metrics</em> view of each extension shows that they are generally small and cheap to implement.
For example, there are nearly 3000 inspector views in the standard GT image, and they average under 12 LOC.</p>

<h2 id="example-exploring-lifeware-test-runs">Example: exploring Lifeware test runs</h2>

<p><a href="https://www.lifeware.ch/about/">Lifeware</a> is a company that provides software infrastructure and services for life insurance companies.
Lifeware has a <em>very</em> large number of test cases for their life insurance SPL.
These tests are run on up to 960 processors, or “workers”, on a cluster of AWS machines, each with between 16-64 processors.
Each worker runs a number of test tasks.
The goal is to run all the tests within 8 minutes, but because tests can take varying lengths of time to complete, this goal is not so trivial to reach.</p>

<p><em>The moldable development strategy is to ask questions of the live system, and where the answers are not immediately evident, to introduce custom views to answer those questions.</em>
By creating a few custom views, we can get some insight into what’s going on in the live system.</p>

<p>In this lightweight visualization we see that a number of workers, i.e., the long grey bars near the bottom, are taking twice as long, but why?</p>

<p><a href="/assets/images/bat50/lifeware/1-cluster-view.png"><img src="/assets/images/bat50/lifeware/1-cluster-view.png" alt="Exploring Lifeware test runs" /></a></p>

<p>Here we highlight in red those tasks that took longer for the same worker than an earlier task.
This tells us that there are scheduling issues, and not just with the slowest workers.</p>

<p><a href="/assets/images/bat50/lifeware/2-clusters-slow-tasks-highlighted.png"><img src="/assets/images/bat50/lifeware/2-clusters-slow-tasks-highlighted.png" alt="Highlighting slower tasks" /></a></p>

<p>Since the machines in our cluster are not all the same, we ask if the scheduling issues are related to particular machines.
Here we inspect the execution timelines of all the workers on a given machine.
We see that just a few machines are having problems meeting the deadline.
Is there something special about these machines?</p>

<p><a href="/assets/images/bat50/lifeware/3-clusters-by-machine.png"><img src="/assets/images/bat50/lifeware/3-clusters-by-machine.png" alt="rouping workers by machine" /></a></p>

<p>We dive into a particular machine to see what’s going on.
We can see clearly that only one worker (second from the bottom at the right) is having scheduling issues, so it’s clearly not an issue of the specific machine.</p>

<p><a href="/assets/images/bat50/lifeware/4-machine-view.png"><img src="/assets/images/bat50/lifeware/4-machine-view.png" alt="Diving into a machine" /></a></p>

<p>Are there issues with the memory usage?
We inspect the total VM memory consumption and free memory per worker.
We see nothing too unusual.</p>

<p><a href="/assets/images/bat50/lifeware/5-worker-view.png"><img src="/assets/images/bat50/lifeware/5-worker-view.png" alt="VM consumption per worker" /></a></p>

<p>Finally we can dive into the individual tasks.
Here we can verify that indeed the problem is just with the scheduling.
By updating the historical data of the time taken to run each test, we can better schedule the test runs and reduce the delays.</p>

<p><a href="/assets/images/bat50/lifeware/7-task-view.png"><img src="/assets/images/bat50/lifeware/7-task-view.png" alt="Inspecting individual tasks" /></a></p>

<p>We were able to perform this analysis because we could <em>turn every question into a cheap and lightweight tool</em> that would let us transform the execution data into an explorable model of the test runs.</p>

<h2 id="mapping-moldable-development">Mapping moldable development</h2>

<p>At the bottom here we see a transition from fixed and rigid IDE tools to moldable tools that can be easily and cheaply extended with new behavior.
I have only shown you some custom inspector views, but the idea applies just as well for search tools, quality advices, and even customizable debuggers.</p>

<p><a href="/assets/images/bat50/map6moldableDevelopment.png"><img src="/assets/images/bat50/map6moldableDevelopment.png" alt="Wardley map: mapping moldable development" /></a></p>

<p>At the next level we see how moldable tools are leveraged by moving from manual inspection to custom queries that we plug into the tools.
We saw this when we browsed the slides of a slideshow or the recent changes of a git repo.
Now, instead of manually cobbling together a view, we can easily obtain a view using the molded tools.</p>

<p>We can have “inside-out conversations” that emerge from exploring the system itself, instead of classical “outside-in” conversations that treat the software as a black box with inputs and outputs.
This then allows us to spot risks and opportunities that are observable only inside a system, and to support quick decision making not only for developers, but also business stakeholders.</p>

<hr />
<h1 id="conclusion">Conclusion</h1>

<p>What lessons can we draw from all this?</p>

<p><strong><em>Programming is Modeling</em></strong></p>

<p>First, I would say, that <em>“programming is modeling”</em>.</p>

<p>This is not a new observation, but it can be interpreted in several different ways.
I found the live programming approach of APL far more exhilarating than the plodding punchcard model of programming supported by FORTRAN, but both languages suffered from a very limited view of what a program is.
It was just as hard to build a clean conceptual model in APL as it was in FORTRAN.</p>

<p>Object-oriented programming changed that by allowing not only the design but the domain model to be reflected in the code.</p>

<p>I am reminded of <a href="https://bertrandmeyer.com">Bertrand Meyer</a>’s observation that he could never understand the fascination with modeling notations and CASE tools when <em>everything is there in the code</em>.
Then one day it hit him: <em>“Bubbles and arrows don’t crash!”</em></p>

<p>In contrast to model-driven approaches, instead of generating code from models, perhaps we are better off generating views from the code.</p>

<p><strong><em>Programming is Understanding</em></strong></p>

<p>We can go further, however.
Kristen Nygaard, one of the inventors of Simula, the first OO language, was apparently fond of saying <em>“<a href="https://amturing.acm.org/award_winners/nygaard_5916220.cfm">To program is to understand</a>.”</em>
I would interpret that today as meaning that <em>software is more than just source code</em>.
It can and should be seen as a <em>living system</em> can expresses knowledge about itself.</p>

<p>I would like to propose a new mantra, namely:
<em>“The software wants to talk to you.”</em></p>

<p>This means that instead of letting the IDE lock up software inside the prison of a text editor, it should <em>enable</em> the exploration, querying and analysis of live systems.
Then, instead of having to head to Google, Stack Overflow or ChatGPT to answer questions about our software, we should be able to answer the questions we have with the help of the systems themselves.</p>

<p style="text-align: center;">&#xFE4C;&#xFE4C;&#xFE4C;&#xFE4C;&#xFE4C;</p>

<hr />

<p><em>This blog post is based on an <a href="/talks/2023-06-09-MindTheGap-BATbern50">invited talk</a> I gave at the <a href="https://www.berner-architekten-treffen.ch/event/50">50th anniversary Berner Architekten Treffen</a> on June 9, 2023.</em></p>]]></content><author><name>Oscar Nierstrasz</name><email>oscar@nierstrasz.org</email></author><summary type="html"><![CDATA[On the occasion of the 50th BATbern event, it occurred to me that it has been roughly 50 years since I started programming. In that time I’ve seen quite a few advances in Software Engineering. I’d like to take this opportunity to reflect on how these advances have not only shortened feedback loops in software development processes, but also how they have enabled new possibilities for innovation.]]></summary></entry><entry><title type="html">Ten Things I Hate About Object-Oriented Programming</title><link href="https://www.oscar.nierstrasz.org/posts/2010-08-26-JOT-TenThingsIHateAboutOOP" rel="alternate" type="text/html" title="Ten Things I Hate About Object-Oriented Programming" /><published>2010-08-26T00:00:00-07:00</published><updated>2010-08-26T00:00:00-07:00</updated><id>https://www.oscar.nierstrasz.org/posts/JOT-TenThingsIHateAboutOOP</id><content type="html" xml:base="https://www.oscar.nierstrasz.org/posts/2010-08-26-JOT-TenThingsIHateAboutOOP"><![CDATA[<p>Boy, I some days I really hate object-oriented programming.</p>

<p>Apparently I’m not the only one. In the immortal words of Edsger Dijkstra: <em>“Object-oriented programming is an exceptionally bad idea which could only have originated in California.”</em></p>

<p>Well, I’m not normally one to complain, but I think it is time to step back and take a serious look at what is wrong with OOP. In this spirit, I have prepared a modest list of <em>Ten Things I Hate About Object-Oriented Programming</em>.</p>

<h1 id="1-paradigm">1. Paradigm</h1>

<p>What is the object-oriented paradigm anyway? Can we get a straight story on this? I have heard so many different versions of this that I really don’t know myself what it is.</p>

<p>If we go back to the origins of Smalltalk, we encounter the mantra, “Everything is an object”. Except variables. And packages. And primitives. And numbers and classes are also not really objects, and so on. Clearly “Everything is an object” cannot be the essence of the paradigm.</p>

<p>What is fundamental to OOP? <a href="http://doi.acm.org/10.1145/38807.38823">Peter Wegner once proposed</a> that <em>objects + classes + inheritance</em> were essential to object-oriented languages. Every programming language, however, supports these features differently, and they may not even support them as built-in features at all, so that is also clearly not the paradigm of OOP.</p>

<p>Others argue convincingly that OOP is really about <em>Encapsulation</em>, <em>Data Abstraction</em> and <em>Information Hiding</em>. The problem is that some sources will tell you that these are just different words for the same concepts. Yet other sources tell us that the three are fundamentally different in subtle ways.</p>

<p>Since the mid-eighties, several myths have been propagated about OOP. One of these is the <em>Myth of Reuse</em>, which says that OOP makes you more productive because instead of developing your code from scratch, you can just inherit from existing code and extend it. The other is the <em>Myth of Design</em>, which implies that analysis, design and implementation follow seamlessly from one another because i<em>t’s objects all the way down</em>. Obviously neither of these candidates could really be the OO paradigm.</p>

<p>Let’s look at other paradigms which offer a particular way to solve programming problems. Procedural programming is often described as <em>programs = data + algorithms</em>. Logic programming says <em>programs = facts + rules</em>. Functional programming might be <em>programs = functions + functions</em>. This suggest that OOP means <em>programs = objects + messages</em>. Nice try, but this misses the point, I think.</p>

<p>For me the point of OOP is that it isn’t a paradigm like procedural, logic or functional programming. Instead, OOP says “for every problem you should design your own paradigm”. In other words, the OO paradigm really is: <em>Programming is Modeling</em></p>

<h1 id="2-object-oriented-programming-languages">2. Object-Oriented Programming Languages</h1>

<p>Another thing I hate is the way that everybody loves to hate the other guy’s programming language. We like to divide the world into curly brackets vs square brackets vs round brackets.</p>

<p>Here are some of the nice things that people have said about some of our favorite OOPLs:</p>

<p><em>“C makes it easy to shoot yourself in the foot; C++ makes it harder, but when you do, it blows away your whole leg.”</em></p>

<p>It was Bjarne Stroustrup who said that, so that’s ok, I guess.</p>

<p><em>“Actually I made up the term ‘object-oriented’, and I can tell you I did not have C++ in mind.”</em> — Alan Kay</p>

<p><em>“There are only two things wrong with C++: The initial concept and the implementation.”</em> — Bertrand Meyer</p>

<p><em>“Within C++, there is a much smaller and cleaner language struggling to get out.”</em> — Bjarne Stroustrup</p>

<p><em>“C++ is history repeated as tragedy. Java is history repeated as farce.”</em> — Scott McKay</p>

<p><em>“Java, the best argument for Smalltalk since C++.”</em> — Frank Winkler</p>

<p><em>“If Java had true garbage collection, most programs would delete themselves upon execution.”</em> — Robert Sewell</p>

<p>But perhaps the best blanket condemnation is the following:</p>

<p><em>“There are only two kinds of languages: the ones people complain about and the ones nobody uses.”</em> — Bjarne Stroustrup</p>

<h1 id="3-classes">3. Classes</h1>

<p>Classes drive me crazy. That might seem strange, so let me explain why.</p>

<p>Clearly classes should be great. Our brain excels at classifying everything around us. So it seems natural to classify everything in OO programs too.</p>

<p>However, in the real world, there are only objects. <em>Classes exist only in our minds.</em> Can you give me a single real-world example of class that is a true, physical entity? No, I didn’t think so.</p>

<p>Now, here’s the problem. Have you ever considered why it is so much harder to understand OO programs than procedural ones?</p>

<p>Well, in procedural programs procedures call other procedures. Procedural source code shows us … procedures calling other procedures. That’s nice and easy, isn’t it?</p>

<p>In OO programs, objects send messages to other objects. OO source code shows us … classes inheriting from classes. Oops. There is a complete disconnect in OOP between the source code and the runtime entities. Our tools don’t help us because our IDEs show us classes, not objects.</p>

<p>I think that’s probably why Smalltalkers like to program in the debugger. The debugger lets us get our hands on the running objects and program them directly.</p>

<p>Here is my message for tool designers: please give us an IDE that shows us objects instead of classes!</p>

<h1 id="4-methods">4. Methods</h1>

<p>To be fair, I hate methods too.</p>

<p>As we have all learned, methods in good OO programs should be short and sweet. Lots of little methods are good for development, understanding, reuse, and so on. Well, what’s the problem with that?</p>

<p>Well, consider that we actually spend more time reading OO code than writing it. This is what is known as productivity. Instead of spending many hours writing a lot of code to add some new functionality, we only have to write a few lines of code to get the new functionality in there, but we spend many hours trying to figure out <em>which</em> few lines of code to write!</p>

<p>One of the reasons it takes us so long is that we spend much of our time bouncing back and forth between … lots of little methods.</p>

<p>This is sometimes known as the <em>Lost in Space</em> syndrome. It has been reported since the early days of OOP. To quote Adele Goldberg, <em>“In Smalltalk, everything happens somewhere else.”</em></p>

<p>I believe that the code-oriented view of today’s IDEs is largely to blame — given that OO code does not accurately reflect the running application, the IDE gets in our way instead of helping us to bridge the gap. Another reason I believe that Smalltalkers like to develop in the debugger is that it lets them clearly see which objects are communicating with which other objects. I am guessing that one of the reasons that Test-Driven Development is popular is that it also exposes object interactions during development.</p>

<p>It is not OOP that is broken — we just haven’t figured out (after over 40 years) how best to develop with it. We need to ask ourselves: <em>Why should the source code be the dominant view in the IDE?</em></p>

<p>I want an IDE that lets me jump from the running application to the code and back again. (For a demonstration of this idea, have a look at the <a href="http://seaside.st">Seaside web development platform</a> which allows you to navigate directly from a running web application to the editable source code.)</p>

<h1 id="5-types">5. Types</h1>

<p>OK, I admit it. I am an impatient guy, and I hate having to say everything twice. Types force me to do that.</p>

<p>I’m sure some of you are thinking — “Oh, how could you program in an <em>untyped</em> language. You could never be sure your code is correct.”</p>

<p>Of course there is no such thing as an “untyped” programming language — there are just statically and dynamically typed ones. Static types just prevent you from writing certain kinds of code. There is nothing wrong with that, in principle.</p>

<p>There are several problems, however, with types as we know them. First of all they tend to lead to a false sense of security. Just because your Java program compiles does not mean it has no errors (even type errors).</p>

<p>Second of all, and much more evil, is that type systems assume the world is consistent, <em>but it isn’t!</em> This makes it harder to write certain useful kinds of programs (especially reflective ones). Type systems cannot deal well with the fact that programs change, and that different bits of complex systems may not be consistent.</p>

<p>Finally, type systems don’t cope well with the fact that <em>there are different useful notions of types</em>. There is no one type system to rule them all. Recall the pain we experienced to extend Java with generics. These days there are many interesting and useful type systems being developed, but we cannot extend Java to accommodate them all. <a href="http://bracha.org/pluggableTypesPosition.pdf">Gilad Bracha has proposed</a> that type systems should not only be <em>optional</em>, in the sense that we should be able to run programs even if the type system is unhappy, but that they should be <em>pluggable</em>, meaning that we can plug multiple type systems into different parts of our programs.  We need to take this proposal seriously and explore how our languages and development tools can be more easily adapted to diverse type systems.</p>

<h1 id="6-change">6. Change</h1>

<p><em>“Change is inevitable — except from a vending machine.”</em> — Robert C. Gallagher</p>

<p>We all hate change, right? So, if everyone hates change, why do we all complain when things don’t get better? We know that useful programs must change, or they degrade over time.</p>

<p>(Incidentally, you know the difference between hardware and software? Hardware degrades if you <em>don’t</em> maintain it.)</p>

<p>Given that real programs must change, you would think that languages and their IDEs would support this. I challenge you, however, to name a <em>single</em> programming language mechanism that supports change. Those mechanisms that do deal with change restrict and control it rather than enable it.</p>

<p>The world is not consistent, but we can cope with that just fine. <em>Context</em> is a great tool for managing change and inconsistency. We are perfectly comfortable adapting our expectations and our behavior in our daily lives depending on the context in which we find ourselves, but the programs we write break immediately if their context changes.</p>

<p>I want to see context as a first-class concept in OO languages and IDEs. Both source code and running software should be able to adapt to changing context. I believe that many design patterns and idioms (such as visitors, and dependency injection) are simply artifacts of the lack of support for context, and would disappear if context were available as a first-class construct.</p>

<h1 id="7-design-patterns">7. Design Patterns</h1>

<p>Patterns. Can’t live with ’em, can’t live without ’em.</p>

<p>Every single design pattern makes your design more complicated.</p>

<p>Visitors. I rest my case.</p>

<h1 id="8-methodologies">8. Methodologies</h1>

<p><em>“All methodologies are based on fear.”</em> — Kent Beck</p>

<p>Evidently some of my students follow the Chuck Norris school of Agile Development:</p>

<p><em>“Chuck Norris pairs alone.”</em></p>

<p><em>“Chuck Norris doesn’t do iterative development. It’s right the first time, every time.”</em></p>

<p><em>“Chuck Norris doesn’t do documentation. He stares down the code until it tells him everything he wants to know.”</em></p>

<h1 id="9-uml">9. UML</h1>

<p>Bertrand Meyer tells this story about always wondering why diagrammatic modeling languages were always so popular, until one day it hit him: <em>“Bubbles don’t crash.”</em> I believe his point is that OO languages are modeling languages. (AKA “All you need is code”)</p>

<p>There similarly appears to be something fundamentally wrong with model-driven development as it is usually understood — instead of <em>generating</em> code from models, the model should <em>be</em> the code.</p>

<p>By analogy, when FORTRAN was invented, it was sold as a high-level language from which <em>source code</em> would be generated. Nowadays we think of the high-level languages as <em>being</em> the source code.</p>

<p>I like to think that one day, when we grow up, perhaps we will think of the <em>model</em> as being the source code.</p>

<h1 id="10-the-next-new-thing">10. The Next New Thing</h1>

<p>Finally, I hate the catchphrase: “Objects are not enough. We need …” Over the years we have needed frameworks, components, aspects, services (which, curiously, seems to bring us back to procedural programming!).</p>

<p>Given the fact that objects clearly <em>never</em> were enough, isn’t it odd that they have served us so well over all these years?</p>

<h1 id="conclusion">Conclusion?</h1>

<p>25 years ago we did not expect object-oriented programming to last as a “new” phenomenon for so long. We thought that OO conferences like ECOOP, OOPSLA and TOOLS would last for 4 or 5 years and then fade into the mainstream. It is too soon to dismiss OOP as just being part of the mainstream. Obviously we cannot feel passionately about something that does not interest us. The fact that academic and industrial research is still continuing suggests that there is something deep and important going on that we do not yet fully understand.</p>

<p>OOP is about taming complexity through modeling, but we have not mastered this yet, possibly because we have difficulty distinguishing real and accidental complexity.</p>

<p>I believe that to make further progress we must focus on change and how OOP can facilitate change. After all these years, we are still in the early days of OOP and understanding what it has to offer us.</p>

<p>Oscar Nierstrasz</p>

<hr />

<p><em>Banquet speech given at ECOOP 2010. Maribor, June 24, 2010.</em></p>

<p>First published on <a href="https://blog.jot.fm/2010/08/26/ten-things-i-hate-about-object-oriented-programming/">The JOT Blog</a>.
DOI: <a href="http://dx.doi.org/10.5381/jot.2010.9.5.e1">10.5381/jot.2010.9.5.e1</a></p>]]></content><author><name>Oscar Nierstrasz</name><email>oscar@nierstrasz.org</email></author><summary type="html"><![CDATA[Boy, I some days I really hate object-oriented programming.]]></summary></entry></feed>