<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-697929553688711480</id><updated>2011-08-25T08:43:41.775-07:00</updated><category term='programming users goals'/><title type='text'>Too Much Code</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-3140244460474770216</id><published>2010-11-27T09:05:00.000-08:00</published><updated>2010-11-27T09:37:30.366-08:00</updated><title type='text'>Start by embracing your limits</title><content type='html'>&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; font-family: Times; font-size: medium; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Nothing in human history has offered more promise but has seen as many failures as software.  We’ve all seen moments of greatness, where a program seems like magic -- but such gems are surrounded by minefields of bugs and indecipherable interfaces.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;The result of all this is we programmers are often a frustrated bunch. But should we be? After all, what makes us think that as a species we should have the aptitude to create great software?  Our skill sets evolved in an environment that favored those who could hunt boar and find berries -- any capacity to succeed in the abstract world of software is pure, accidental side effect.  Perhaps we should be awed by software’s successes rather than frustrated by its failures.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;The good news is we can improve despite our limitations, and it starts with this: accept that we generally have no innate ability to create great systems, and design our practices around that.  It seems like &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;every&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; major step forward in software has followed this pattern of embracing our limitations.  For instance, we move to iterative development since we can’t anticipate all variables of a project.  We aggressively unit test because we realize we’re prone to error. Libraries derived from practical experience frequently replace those built by expert groups.   The list goes on.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;This type of admission is humbling, but it can also be liberating.  Here’s an example: In years past I would spend hours agonizing over an internal design decision for a system I was building.  I figured if I got it right we could easily bolt on some new feature.  Sometimes I was right, but often times I was not.  My code often was littered with unnecessary structure that only made things more complicated.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Contrast that to today:  I know I can’t anticipate future needs in most cases, so I just apply this simple heuristic: &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;ol&gt;&lt;li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;When in doubt, do the simplest thing possible to solve the problem at hand&lt;/span&gt;&lt;/li&gt;&lt;li style="list-style-type: decimal; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Plan on refactoring later.&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; &lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;The first step frees us from trying to anticipate all future needs -- but this is not quick and dirty cowboy coding.  An essential element of code is to create an understandable and maintainable system.  Don't try to code for future needs.  Instead, structure code for present needs so it can be leveraged in the future.  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;So how do we do this? A couple things to keep in mind:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;ul&gt;&lt;li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;When in doubt, leave it out. (also known as “You Ain’t Gonna Need It”)&lt;/span&gt;&lt;/li&gt;&lt;li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Unit-Testable designs tend to be reusable designs.  Unit tests not only catch bugs that can result from refactoring, but they encourage modularity to enable that refactoring.&lt;/span&gt;&lt;/li&gt;&lt;li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Don’t try to design an API independently of an application.  You won’t understand your users’ needs well enough to create a good experience.   Build the API as part of the application to make sure its needs are met, then factor out and generalize.&lt;/span&gt;&lt;/li&gt;&lt;li style="list-style-type: disc; font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; "&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Group code together that tends to change for similar reasons.  If your Widget class is responsible for rendering its UI &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;and&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; writing to the database &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;and&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; business logic, you can’t use it anywhere else without significant changes.  High cohesion and loose coupling.&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;There are no hard-and-fast rules to building software, but we all need a compass to help guide us through the thousands of micro-decisions we make every time we write code.  Hopefully this post can help build that compass.&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-3140244460474770216?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/3140244460474770216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=3140244460474770216' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3140244460474770216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3140244460474770216'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2010/11/start-by-embracing-your-limits.html' title='Start by embracing your limits'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-3226463729104098113</id><published>2010-10-18T19:03:00.000-07:00</published><updated>2010-10-18T19:14:14.944-07:00</updated><title type='text'>Can "Agile in the Large" Succeed?</title><content type='html'>&lt;div    style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-   font-family:Times;font-size:medium;color:transparent;"&gt;&lt;span class="Apple-style-span"  style="font-family:Arial;"&gt;&lt;span class="Apple-style-span" style="white-space: pre-wrap; font-size: -webkit-xxx-large;"&gt;&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; font-family: Times; white-space: normal; font-size: medium; "&gt;&lt;span id="internal-source-marker_0.45896949572488666" style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Agile Development isn’t perfect, but it got something right.  Right enough, at least, to gain enough momentum to become a buzzword -- and for consultants to latch on by selling “Agile” to big enterprises.  The result is “Agile in the Large”.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Agile in the Large ranges from the &lt;/span&gt;&lt;a href="http://www.halfarsedagilemanifesto.org/"&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Half-Arsed Agile Manifesto&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; to &lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Cargo_cult"&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 153); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: underline; vertical-align: baseline; white-space: pre-wrap; "&gt;Cargo Cult&lt;/span&gt;&lt;/a&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; practices.  Too often we simply bolt on a few agile practices without understanding how they provide value.  Adding scrums and iteration reviews to your current process and expecting improvement is like building a runway in your back yard and expecting planes to land.  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Whether it’s labelled agile or not, a cohesive development team works for a couple reasons.  It creates a focused team fully aligned to a common goal. It avoids “Us and Them” mentalities, enabling everyone to adapt to meet the goal. It offers a self-correcting strategy for the thousands of micro-decisions when building software:  It must be testable, “You Ain’t Gonna Need It”, and it creates quick feedback to make sure you’re solving the actual problem.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Agile in the Large is flawed because it often fails to achieve these basic ingredients.  Take Scrum of Scrums, for example.  It tries to coordinate and resolve technical dependencies between teams by having representatives from each team get together and talk through them.  It’s better than nothing, but an emerging system has too much ambiguity: the interaction between components is still being defined, bugs can lead to finger pointing, and the important sense of ownership is lost.  Everyone feels like cogs in a machine rather than someone solving an important problem for a real user.  Our ability to adapt the microdecisions that build great software is lost.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;In fact, Agile in the Large seems doomed from the beginning. Once you’re beyond some number of people in a single project, it’s impossible to create that sense of shared ownership and adaptability.  Great software is created by small, dedicated teams.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;So, what then? It seems the only way out is to make Agile in the Large more like Agile in the Small.  A team should be working on one and only one project, and include everything necessary for that project to be successful.  How we do that depends on where we are in a project’s maturity curve.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;New vs. mature systems&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;New development is the most easily handled.  Look at the problems at hand, and make sure the team is equipped to handle them end-to-end.  This new project may have several components, but &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;now is not the time to split those components into their own teams;&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; keep a single team aligned to the user’s goals.  After all, if a component isn’t aligned to some user’s goal, what is its value?  Organize around components too early, and team cohesion is lost.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;So we are off to a good start, but we need to adjust our strategy as a successful project matures.  You may find parts of your system has value for other uses.  This seems timeless: C first was a successful tool for building Unix, Ruby on Rails was an application before it was a framework, Amazon was an online book store before it was a cloud platform, and so on.  In all of these cases a successful system was built, and then groups arise around the reusable pieces.  Reusable technology will naturally arise from a successful project.  Embrace that, but don’t force it.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Open source as a model for reuse&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Later in a system’s life we find ourselves consuming many assets from a variety of teams. Now it’s easy to let coordination and communication friction kill our focused project.  Fortunately, the open source world gives us the answer.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Quite simply, needed enhancements to common assets should be written and contributed by consuming teams.  This offers several advantages over logging an enhancement request.  For instance, we reduce deadline haggling and misaligned schedules.  We also reduce the need for frequent status updates and opportunities for miscommunication between teams.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Of course, not all changes to open source projects come in the form of patches.  There should still be a team around the asset in question, responsible for its architecture and fundamental direction.  That team also operates as a gatekeeper, ensuring all patches are properly unit tested, documented, and don’t threaten the integrity of the system.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Changes must be handled on a case-by-case basis, but the primary mode of operation should follow the agile ideal: a single team with responsibility for a project end-to-end.  This includes contributing to assets it consumes.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: bold; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;What if even the initial project is too big?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;I’ll touch on one final question: what if even the initial scope of a project is beyond what a single team can accomplish?  Find a smaller initial scope, get it working, and grow from there.  Do this even if the initial scope means building placeholders that are discarded in the final result.  The time saved and friction eliminated by creating a single, focused team will outweigh this.  Think of it as scaffolding that eventually gets removed.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;In the end, &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Agile in the Large only works if we make it more like Agile in the Small.&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;  Hopefully this article is a step in that direction.&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-3226463729104098113?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/3226463729104098113/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=3226463729104098113' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3226463729104098113'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3226463729104098113'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2010/10/can-agile-in-large-succeed.html' title='Can &quot;Agile in the Large&quot; Succeed?'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-298577078390205805</id><published>2010-10-16T20:17:00.001-07:00</published><updated>2010-10-16T20:20:51.871-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming users goals'/><title type='text'>Beware of the Flying Car</title><content type='html'>&lt;div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; background-color: transparent; font-family: Times; font-size: medium; "&gt;&lt;span id="internal-source-marker_0.4220108645968139" style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Every so often we developers are asked to build a flying car. Our users obviously need one to avoid traffic and get to meetings on time. So we set down the path to meet those needs.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;The trouble is most of us have no idea how to build a flying car. Even so, this is the project so we better get started! Our first release of the flying car will be small, and carried around on a string. We show good progress to our user's needs and gain approval from our superiors. We will simply remove the string in a later release.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Hopefully most of us will recognize a Flying Car Project and take time to understand and address the users’ goals rather than sprinting toward a brick wall.  The Flying Car is a means, not an end in itself -- and there are other, executable means to the desired end.  &lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;Of course, there will always be &lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: italic; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt;someone&lt;/span&gt;&lt;span style="font-size: 11pt; font-family: Arial; color: rgb(0, 0, 0); background-color: transparent; font-weight: normal; font-style: normal; text-decoration: none; vertical-align: baseline; white-space: pre-wrap; "&gt; eager to go build that flying car.  If that happens, try to steer them in the right direction.  If all else fails, just don’t be standing underneath it when they cut the string.&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-298577078390205805?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/298577078390205805/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=298577078390205805' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/298577078390205805'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/298577078390205805'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2010/10/flying-car-projects.html' title='Beware of the Flying Car'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-1895625763134001674</id><published>2010-10-16T06:52:00.000-07:00</published><updated>2010-10-16T07:04:13.422-07:00</updated><title type='text'>And We're Back</title><content type='html'>After an unbelievably long hiatus, I'm going to start blogging again.  It's funny how becoming a parent makes everything else seem to go away for a while.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I don't expect I will ever post at a regular intervals here.  I'll post when I feel like I can express something that gets closer to some truth about software -- at least to me.   How often will that happen?  Who knows?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The rebirth of this blog will come with a shift in material, at least for the near future.  I've recently become more interested in the social aspect of building software.  How should we organize ourselves to create great software?  How should that change over time?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am and always will be a programmer at heart.  My shift in emphasis simply comes from the realization that our biggest challenges aren't technical.  They're social.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-1895625763134001674?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/1895625763134001674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=1895625763134001674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/1895625763134001674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/1895625763134001674'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2010/10/and-were-back.html' title='And We&apos;re Back'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-8554645918704504779</id><published>2008-11-15T10:57:00.000-08:00</published><updated>2008-11-15T10:59:04.592-08:00</updated><title type='text'>The Guru Myth</title><content type='html'>Anyone who has worked in software long enough has heard questions like this:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;i&gt;I'm getting exception XYZ.  Do you know what the problem is?&lt;/i&gt;&lt;br /&gt;&lt;/div&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;The questioner didn't bother to include a stack trace, an error log, or any context leading to the problem.  He or she seems to think you operate on a different plane, that solutions appear to you without analysis based on evidence.  This person thinks you are a guru.&lt;br /&gt;&lt;br /&gt;We expect such questions from those unfamiliar with software; to them systems can seem almost magical.  What worries me is seeing this in the software community.  Similar questions arise in program design, such as "I'm building inventory management.  Should I use optimistic locking?"  Ironically, the person asking the question is often better equipped to answer it than the question's recipient.  The questioner presumably knows the context, knows the requirements, and can read about the advantages and disadvantages of different strategies.  Yet this person expects an intelligent answer without supplying context.  He or she expects magic.&lt;br /&gt;&lt;br /&gt;It's time for the software industry to dispel this guru myth.  "Gurus" are human; they apply logic and systematically analyze problems like the rest of us.  Consider the best programmer you've ever met:  At one point he or she knew less about software than you do now.  If that person seems like a guru, it's because of years dedicated to learning and refining thought processes.  A "guru" is simply a smart person with relentless curiosity.&lt;br /&gt;&lt;br /&gt;Of course, there remains a huge variance in natural aptitude.  Many hackers out there are smarter, more knowledgeable, and more productive than I may ever be.  Even so, debunking the guru myth has a positive impact.  For instance, when working with someone smarter than me I am sure to do the legwork, to provide enough context so that person can efficiently apply his or her skills.  Removing the guru myth also means removing a perceived barrier to improvement.  Instead of a barrier I see a continuum on which I can advance.&lt;br /&gt;&lt;br /&gt;Finally, one of software's biggest obstacles is smart people who purposefully propagate the guru myth.  This might be done out of ego, or as a strategy to increase one's value as perceived by a client or employer.  Ironically this attitude makes a smart person less valuable, since they don't contribute to the growth of their peers.  We don't need gurus.  We need experts willing to develop other experts in their field.  There is room for all of us.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-8554645918704504779?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/8554645918704504779/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=8554645918704504779' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8554645918704504779'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8554645918704504779'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2008/11/guru-myth.html' title='The Guru Myth'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-8064368483482312144</id><published>2008-03-09T09:58:00.000-07:00</published><updated>2008-03-09T13:25:44.942-07:00</updated><title type='text'>Tearing Down the Software Factory</title><content type='html'>Tom DeMarco &lt;a title="said it well" href="http://www.amazon.com/Measuring-Managing-Performance-Organizations-Robert/dp/0932633366" id="wp1z"&gt;said it well&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;The idea of a software factory is a joke -- that we can build software by rote -- that's ridiculous.  If the work is deterministic, we will do with it what we do with any other big piece of deterministic work.  We'll let the computer do the deterministic portion, leaving the person who interacts with the computer -- the other half of the system -- to do the work whose roteness has decreased, not increased.  Every time you automate something, what's left of the person's work is less deterministic, until eventually, when you automate enough, there's no deterministic element left for the person's work--no rote. ... Our work is not deterministic.  It's far too inventive.  We're knowledge workers, not factory workers.&lt;br /&gt;&lt;/blockquote&gt;Of course, similar thoughts have been articulated &lt;a title="many" href="http://www.developerdotstar.com/mag/articles/reeves_design_main.html" id="j1bs"&gt;many&lt;/a&gt; &lt;a title="times" href="http://virtualschool.edu/mon/SoftwareEngineering/BrooksNoSilverBullet.html" id="s7.0"&gt;times&lt;/a&gt; before, and was a theme of the &lt;a title="previous post" href="http://www.toomuchcode.org/2007/10/design-crisis.html" id="oihe"&gt;previous post&lt;/a&gt; on this blog.  The idea of a software factory contradicts our best understanding of the essence of software, yet industrial style command-and-control management of software continues.  Why is this?  One problem is we developers haven't effectively presented a convincing alternative.  Remove command and control, and to some extent developers must manage themselves.  From &lt;a title="Watts Humphrey" href="http://www.sei.cmu.edu/news-at-sei/columns/watts_new/2007/06/watts-new-2007-06.htm" id="hcuj"&gt;Watts Humphrey&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt;Since your manager’s performance depends on your performance, and since the performance of software groups has historically been so poor, managers do not trust software professionals to manage themselves. To overcome this problem, all we have to do is to convince management that we can manage ourselves and then perform that self management so well that management will continue to trust us.&lt;br /&gt;&lt;/blockquote&gt;The theme of trust and credibility runs throughout Humphrey's &lt;a title="written extensively" href="http://www.sei.cmu.edu/news-at-sei/columns/watts_new/watts-new.htm" id="hbo3"&gt;extensive writing&lt;/a&gt; on this topic.  This is not new, but progress has been slow.  The major obstacle is that managers rightly want concrete, objective data on which to base their decisions.  This conflicts with the black box that software development so often becomes.  We need better transparency.  It is time to open up the black box of software engineering.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The black box of software&lt;/b&gt;&lt;br /&gt;Opening the black box means programmers and managers must meet each other halfway.  Managers must create and adapt to a new post-industrial management science, and programmers must produce data useful to that management science.   This does not mean attempting to make programmers into assembly line workers.  To the contrary, it means embracing the creative nature of software, and managing the output as a side effect of development.&lt;br /&gt;&lt;br /&gt;How do we do this?  Empirically manage everything that can be empirically managed, and complement it with the judgment of your best engineers.  Many pieces of the puzzle already exist.  &lt;a title="Unit testing" href="http://en.wikipedia.org/wiki/Unit_testing" id="lze7"&gt;Unit testing&lt;/a&gt;, &lt;a title="code coverage reports" href="http://en.wikipedia.org/wiki/Code_coverage" id="rqf8"&gt;code coverage reports&lt;/a&gt;, &lt;a title="bug tracking" href="http://en.wikipedia.org/wiki/Bug_tracking_system" id="gezm"&gt;bug tracking&lt;/a&gt;, &lt;a title="static code analysis" href="http://en.wikipedia.org/wiki/Static_code_analysis" id="z03-"&gt;static code analysis&lt;/a&gt;, dependency management and others provide transparency into the state of a project.  Such data is purely informational, but technically inclined managers can and should use it to ensure a project is on track.  With context, problems like bloated dependencies, poor test coverage, or fixing related bugs many times are all signs of a project going astray.  Modern software organizations must be able to detect and correct problems before they grow.&lt;br /&gt;&lt;br /&gt;Unfortunately many managers today are not equipped to work with such data.  This must change.  Managers must build their skill sets for the post-industrial world.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Trust through transparency&lt;br /&gt;&lt;/b&gt;Of course tools like code coverage and defect tracking only tell part of the story.  &lt;a title="Code is design" href="http://www.toomuchcode.org/2007/10/design-crisis.html" id="f.tg"&gt;Code is design&lt;/a&gt;, and no set of tools can define the quality or progress of design.  Therefore we must complement these tools with the best judgment of our best engineers.  But if managers don't trust the best engineers, this judgment is wasted.&lt;br /&gt;&lt;br /&gt;So how do we solve this?  Use transparency into software as a tool for building trust.   Concrete data on the progress and quality of software gives managers greater confidence in engineers, even if the picture is incomplete.  Trust begins to grow.  Engineers should qualify empirical data and use it appropriately as a basis for design decisions.   If we can provide managers a glimpse into software and prove we are making progress, they will be more willing to accept our opinions.&lt;br /&gt;&lt;br /&gt;Some tension between managers and developers may be inevitable, but we can meet each other halfway.  Our development practices should yield hard data for everything appropriate.  In exchange managers must accept that code is design and trust the judgment of developers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-8064368483482312144?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/8064368483482312144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=8064368483482312144' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8064368483482312144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8064368483482312144'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2008/03/tearing-down-software-factory.html' title='Tearing Down the Software Factory'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-312471067495459824</id><published>2007-12-26T10:09:00.000-08:00</published><updated>2007-12-26T10:19:04.288-08:00</updated><title type='text'>What we can learn from databases</title><content type='html'>While not perfect, relational databases are among the most successful software ever used.  Their behavior is easily understood even under high concurrency. Sets of changes can be composed with almost no effort, with strong guarantees of consistency.  The question is: would this be true if we built our databases the same way we build applications?&lt;br /&gt;&lt;br /&gt;Transactions and read consistency would be the first to go.  Users must then cooperatively synchronize on some external monitor; any failure to do so can result in invalid data.  Next, system state and logic become intermixed.  Gone are simple ways to inspect the state of the system, or create a well-defined state space with known transitions.  In short, if databases were written like applications, they become vulnerable to all of the bugs we see in applications.&lt;br /&gt;&lt;br /&gt;Suppose we turn the question on its head, and ask what characteristics of the database we can apply to the rest of software?  Consider the following advantages:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The system itself guarantees a consistent view of data under concurrency, eliminating many types of race conditions&lt;/li&gt;&lt;li&gt;State changes are composable; updates are committed atomically, ensuring the database is never in an invalid state.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The state space is understandable.  Because updates are composed to an atomic state change, countless permutations of state are eliminated&lt;/li&gt;&lt;/ul&gt;The key is this: we can confidently inspect, reason about, and change the state space of a database.  The complexity of large models is mitigated by allowing only for valid, composable transitions.  Imagine if we had such guarantees when building software in general.  We could understand the state of an application at any time, and ensure all changes are valid and consistent.  Our system would be much more understandable and predictable.&lt;br /&gt;&lt;br /&gt;In fact, much language research is focused on this area.  &lt;a title="Software-Transactional Memory" href="http://research.microsoft.com/%7Esimonpj/papers/stm/stm.pdf" id="r1g6"&gt;Software Transactional Memory&lt;/a&gt; in languages like Haskell is the most visible.  The question is how such progress will reach the mainstream.  History suggests an evolutionary model.  Languages that gain adoption tend to have a good deal in common with an established language, lowering the barrier to entry.  Because of this, I have yet to see a language with the above characteristics that I think will achieve widespread adoption.  Hopefully that will change.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Understandable systems today&lt;br /&gt;&lt;/b&gt;A couple of &lt;a title="recent" href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html" id="b02u"&gt;recent&lt;/a&gt; &lt;a title="posts" href="http://www.codinghorror.com/blog/archives/001025.html" id="pqvj"&gt;posts&lt;/a&gt; point out the burden of large code bases.  I agree, as suggested by the title of this blog, but it's easy to confuse a symptom with the problem itself.  So I phrase it differently:  Unmanageable complexity is the enemy.  Code size is often what the enemy smells like.&lt;br /&gt;&lt;br /&gt;Developers can better manage complexity even without guarantees similar to what a database offers.  Code should have a clear, easily understood state space, preferably applying related changes atomically.  Such systems are easier to reason about and change because developers need not concern themselves with side effects of unrelated code; they can focus on the problem at hand.  For those who haven't explored this, I'm indirectly describing the functional style of programming.  This is the great hope for pure functional programming: it may spread predictability and a simple model to all development.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-312471067495459824?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/312471067495459824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=312471067495459824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/312471067495459824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/312471067495459824'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/12/what-we-can-learn-from-databases.html' title='What we can learn from databases'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-2570962668951751408</id><published>2007-10-18T19:07:00.000-07:00</published><updated>2007-11-04T06:13:43.990-08:00</updated><title type='text'>The Design Crisis</title><content type='html'>Imagine waking up tomorrow and learning the construction industry has made the breakthrough of the century.  Millions of cheap, incredibly fast robots can now fabricate materials out of thin air, have a near-zero power cost, and can repair themselves.  And it gets better: given an unambiguous blueprint for a construction project, the robots can build it without human intervention, all at negligible cost.&lt;br /&gt;&lt;br /&gt;One can imagine the impact to the construction industry, but what would happen upstream?  How would the behavior of architects and designers change if construction costs are negligible?  Today, physical and computer models are built and rigorously tested before investing in construction.  Would we bother if the construction was essentially free?  If a design collapses, no big deal...just find out what went wrong and have our magical robots build another one.  More implications follow.  With models obsolete, unfinished designs evolve by repeatedly building and improving upon an approximation of the end goal.  A casual observer may have trouble distinguishing an unfinished design from a finished product.&lt;br /&gt;&lt;br /&gt;Our ability to predict time lines will fade away as well.  Construction costs are more easily calculated than design costs -- we know the approximate cost to install a girder, and how many girders we need.  As predictable tasks shrink toward zero, the less predictable design time grows to dominate the project.  Results are produced more quickly than before, but reliable time lines slip away.&lt;br /&gt;&lt;br /&gt;Of course, the pressures of a competitive economy still apply.  With construction costs eliminated, a company that can quickly complete a design gains a market edge.  Pressure on getting design done fast becomes the central push of engineering firms.  Inevitably, someone not deeply familiar with the design will see an unvalidated version, see the market advantage of releasing early, and say "This looks good enough."&lt;br /&gt;&lt;br /&gt;Some life-or-death projects will be more diligent, but in many cases consumers learn to suffer through the incomplete design.  Companies can always send out our magic robots to "patch" the broken buildings and vehicles they sell.  All of this points to an amazing, counter-intuitive conclusion: our sole premise was a dramatic reduction in construction costs, and the result is&lt;i&gt; quality got worse.&lt;/i&gt;&lt;i&gt; &lt;/i&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;The Design Crisis&lt;br /&gt;&lt;/b&gt; It shouldn't surprise us the above story has played out in software.  If we accept that &lt;a href="http://www.developerdotstar.com/mag/articles/reeves_design_main.html" id="oj-0" title="code is design"&gt;code is design&lt;/a&gt; -- a creative process rather than a mechanical one -- the software crisis is explained.   Now we have a design crisis:&lt;i&gt; &lt;/i&gt;the demand for quality, validated designs far exceeds our capacity to create them.  The pressure to use incomplete design is strong.&lt;br /&gt;&lt;br /&gt;Fortunately, this model also gives us some clues on how we can get better.  Physical simulations equate to automated testing; software design isn't complete until it is validated with a brutal battery of such tests.  To make such tests more effective we are finding ways to rein in the huge state space of large systems.  Improved languages and design practices give us hope.  Most importantly, there is one inescapable fact.  Great designs are produced by great designers dedicating themselves to the mastery of their craft.  Code is no different.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-2570962668951751408?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/2570962668951751408/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=2570962668951751408' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2570962668951751408'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2570962668951751408'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/10/design-crisis.html' title='The Design Crisis'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-4349706347372042912</id><published>2007-06-30T11:41:00.000-07:00</published><updated>2007-06-30T11:44:42.709-07:00</updated><title type='text'>von Neumann's Long Farewell</title><content type='html'>A big step in solving the software crisis is to accept that programming is not about computers.  Yes, it used to be, and still is for brave souls working on operating systems or compilers.   But in the long list of the world's software struggles, compilers rank pretty low.&lt;br /&gt;&lt;br /&gt;It's easy to think programming is about computers because that's where we see problems.  Of course, these are only symptoms of human error.  Developers are constantly stretching to express behavior in terms friendly to a computer, making life harder so we can be easier on our machines.  Such problems have been pointed out decades ago by the likes of &lt;a href="http://www.cs.utexas.edu/%7EEWD/transcriptions/EWD03xx/EWD340.html" title="Dijkstra"&gt;Dijkstra&lt;/a&gt;, &lt;a href="http://www.stanford.edu/class/cs242/readings/backus.pdf" title="Backus [pdf]"&gt;Backus [pdf]&lt;/a&gt;, and &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book.html" title="Abelson and Sussman"&gt;Abelson and Sussman&lt;/a&gt;.  Surely there is a way to describe our systems better than the terms of the von Neumann architecture.&lt;br /&gt;&lt;br /&gt;For years we were limited by the capabilities of the machines, but this limitation has vanished for most of us.  We've entered a new era, where improving the way we build software is as much a social problem as a technical one.  Fortunately, there are signs of a growing social bedrock that could finally help us.&lt;br /&gt;&lt;b&gt;&lt;br /&gt;The Thirst for Abstraction&lt;/b&gt;&lt;br /&gt;For a long time I didn't understand Guy Steele's comments on how Java can pull C++ developers about halfway to Lisp.  Surely that fraction must be off; writing code in Java certainly feels a lot closer to C++ than Lisp.  But independent of the Java language, the platform did a major service for the industry: it proved to the masses that we no longer need to express our designs directly in terms of the von Neumann architecture.&lt;br /&gt;&lt;br /&gt;The abstraction offered by Java-like languages is small but significant.  The conventional wisdom in software has long held that code must be expressed in terms of the machine to achieve passable performance.  This myth is gone.  Nearly every major software company is adopting some form of garbage collected, virtual machine-based language.  We rely on the platform to map our higher-level expressions to efficient machine code.&lt;br /&gt;&lt;br /&gt;This is a big step because accepting this level of abstraction opens the door to others.  Why should we explicitly state data type information, when it can be inferred at compile or run time?  Why not abandon primitives and arrays for objects and lists, since our platforms can now optimize away unneeded allocation?  Why struggle with keeping track of many small state changes when major operations could change state atomically?  Such abstractions make life easier for us, and previous successes suggest it will work.  The result is a self-perpetuating thirst for abstraction.  Expressing designs so humans can easily reason about and manipulate them is addicting.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;von Neumann's Long Farewell&lt;/b&gt;&lt;br /&gt;For many of us the shift away from the von Neumann architecture is painfully slow.   Unfortunately the best ideas are often slow to be adopted.  People are used to the way they've worked before, or averse to risk.  So our transition toward better software is incremental -- but it is happening.  Mainstream languages are offering higher-level concepts in their latest revisions.  Adding concepts like closures, type inference, and applicative libraries does the software industry a service.  It moves us toward a better way to write code.  Hopefully some day we'll realize the low-level complexity we've dealt with isn't really necessary and abandon it altogether.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-4349706347372042912?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/4349706347372042912/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=4349706347372042912' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/4349706347372042912'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/4349706347372042912'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/06/von-neumanns-long-farewell.html' title='von Neumann&apos;s Long Farewell'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-7238340738200714099</id><published>2007-06-03T09:33:00.000-07:00</published><updated>2007-06-03T09:38:05.038-07:00</updated><title type='text'>Why are we so polarized about Java?</title><content type='html'>It seems impossible to constructively praise or criticize Java without eliciting strong reactions.  It comes from both sides; some seem to love to hate Java, and parts of the Java community become defensive as a reaction.&lt;br /&gt;&lt;br /&gt;For example, Paul Buchheit recently &lt;a title="posted some insights" href="http://paulbuchheit.blogspot.com/2007/05/amazingly-bad-apis.html"&gt;posted some insights&lt;/a&gt; into API design, referring to poor examples that happen to be written in Java.  He immediately states he doesn't hate Java.  The post is about APIs, not the language.  Even so, he still had to update his post saying "It's not about Java, really", presumably because of some polarized reactions.   This is unfortunate because it distracts us from Paul's excellent commentary.&lt;br /&gt;&lt;br /&gt;I suspect the polarization starts from a trap I have fallen into myself.  Like many involved in language discussions, I use Java professionally and other languages at night, so I run into examples analogous to the one described by Paul Buchheit.  I sometimes get frustrated with poor APIs, and also with the Java language -- either directly or by association with poor APIs.  I wonder, couldn't it use powerful constructs I use in other languages, or could the APIs just plain be simpler?  &lt;br /&gt;&lt;br /&gt;The problem is my frustration may linger when I discuss programming languages, and (knowingly or unknowingly) be reflected in my tone when discussing Java.  The resulting post is more acidic, and less level handed than I would like.  Those who disagree with my arguments are likely to pick up on that tone and may respond in kind.  Before long we've spiraled into isolated camps, and meaningful discussion is hard to achieve.  My &lt;a title="last post" href="http://toomuchcode.blogspot.com/2007/05/why-java-lost-its-mojo-and-what-sun-is.html"&gt;last post&lt;/a&gt; had signs of this.&lt;br /&gt;&lt;br /&gt;So, where did I go wrong?  When discussing constructive criticism of Java and its APIs, we need to view Java with some perspective.  We need to remember its history.  So my first point is:&lt;br /&gt;&lt;blockquote&gt;&lt;div style="text-align: left;"&gt; &lt;/div&gt;&lt;i&gt;We are critical of Java in a context different from the one in which it was designed.&lt;/i&gt;&lt;/blockquote&gt;&lt;i&gt;&lt;/i&gt;  A key goal for Java was to replace C++, and this goal led to design decisions that are often targets for criticism today.  In 1996 it wasn't clear we could create a sufficiently fast language without primitive types and arrays.  It wasn't clear how much boilerplate code would be required by anonymous callback classes or checked exceptions.  It wasn't clear that since the &lt;i&gt;new&lt;/i&gt; syntax exactly specifies implementation, factory patterns would proliferate, and so on.  So my second point:&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;blockquote&gt; &lt;i&gt;Criticisms of Java should not imply any negatives about the designers of Java.  Critics of Java are likely working in a problem space that differs from Java's original design goals, or incorporating new knowledge from the past decade.&lt;/i&gt;&lt;/blockquote&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;  There are certainly some that disagreed with the above decisions in 1996, but it was surely more debatable then, and different decisions may have slowed Java's proliferation -- which was opposed to its original design goals.&lt;br /&gt;&lt;br /&gt;The key is we need to keep this background in mind whenever discussing Java.  We can criticize Java and its APIs without insulting anyone.  When being critical of Java, any frustrations should be tempered by knowing the landscape has changed.  Similarly, apologists should recognize that criticism need not be viewed as an attack; it might be an attempt to make things better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-7238340738200714099?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/7238340738200714099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=7238340738200714099' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/7238340738200714099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/7238340738200714099'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/06/why-are-we-so-polarized-about-java.html' title='Why are we so polarized about Java?'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-8450458275844381367</id><published>2007-05-30T21:44:00.000-07:00</published><updated>2007-06-02T06:36:30.193-07:00</updated><title type='text'>Why Java lost its mojo, and what Sun is doing about it</title><content type='html'>&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;It's old news to some, and hotly debated by others, but Java has lost its mojo.  The Java community still has growth from large companies, but it hasn't been the darling language of hackers for a while (if it ever was).  But don't think Sun isn't doing anything about it.&lt;br /&gt;&lt;br /&gt;Java's popularity is a function of market position, the perception of one product compared to its competitors.  When it first came out, Java was positioned against C++, to which it compares favorably.  Yes, I miss operator overloading and a handful of other items, but these are outweighed by the fact that Java prevents entire classes of errors made by C++ developers.  All of this was done before, but Sun was able to make it mainstream and practicable.&lt;br /&gt;&lt;br /&gt;Now the Java vs. C++ battle is effectively over.  Today Java's market position is measured against a variety of languages, most frequently C#, Python, and Ruby.  For many of us, Java compares much less favorably to these than to C++.  Proponents of these languages love to show problems solved in a handful of lines, with a Java-based solution including dozens of lines of boilerplate code.  The poor Java developer is then pushed around and has his lunch money stolen.&lt;br /&gt;&lt;br /&gt;Naturally, much of the Java community wants to do something about this.  So &lt;a title="closures" href="http://www.javac.info/"&gt;closures&lt;/a&gt; and &lt;a title="type inference" href="http://weblogs.java.net/blog/forax/archive/2006/12/call_me_santa.html"&gt;type inference&lt;/a&gt; have been proposed for Java 7, and the debate in the Java community begins.  Some say "Hooray, Python programmers will stop making fun of me!"  Others object "Don't we already have enough constructs to worry about in this language?"  Throw in the glacier-like JCP, and we have no idea what the next release of Java will look like.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Can we fix Java?&lt;/span&gt;&lt;br /&gt;I am sympathetic to both arguments.  The language &lt;span style="font-style: italic;"&gt;is&lt;/span&gt; getting big.  If only we could get rid of artifacts like primitive types and arrays, we could remove clutter and make conceptual room for more advanced concepts.  Even so, I still land firmly in the pro-closure camp.  This is partially for selfish reasons; I got hooked on them while hacking in functional languages at night, and want to use them in my day job.  My company uses Java because it is actually the right choice for us.  No other platform offers that combination of portability, reliability, tooling, and performance.  Too bad it's not with a better language.&lt;br /&gt;&lt;br /&gt;With this in mind, the rumblings of the last few years make sense, and the future is clear.   It's not about Java at all, it's about the JVM.  And Sun is positioning the JVM to become a light, efficient virtual machine available everywhere.  Consider everything that has happened:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a title="JavaFX" href="http://java.sun.com/javafx/"&gt;JavaFX&lt;/a&gt; has been announced, creating a simple, declarative model to compete with the likes of Flex.&lt;/li&gt;&lt;li&gt;Sun has committed to releasing an update to Java 6 that will shrink the minimal JRE download to two megabytes.&lt;/li&gt;&lt;li&gt;Sun hired &lt;a title="Charles Nutter" href="http://headius.blogspot.com/"&gt;Charles Nutter&lt;/a&gt; to make JRuby a first-class language for the JVM.  The 1.0 release nears.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Glassifish -- the open-source application server sponsored by Sun -- will run JRuby applications directly in v3, and be pluggable for new hosts.  Java SE and EE need never enter the picture.&lt;/li&gt;&lt;li&gt;The JVM is now available under the GPL, which should increase availability on Linux.&lt;/li&gt;&lt;li&gt;The 2007 JavaOne conference included a &lt;a title="Scala" href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt; session for the first time&lt;/li&gt;&lt;/ul&gt;What does this tell us?  The JRE is becoming the new POSIX.  And the Java language is becoming less and less relevant.  (Can't find where I first saw this idea posted...please send link if you have it.)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;But what about the mean time?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The reality is Java-the-language will be around for some time to come, at least until a clear successor is established.  Sun and other members of the JCP have an opportunity to define the language's legacy.  As Guy Steele famously said, Java "managed to drag a lot of them [C++ programmers] about halfway to Lisp."  Now Java can drag programmers one step closer to Lisp, and set the stage for the next generation of languages.&lt;br /&gt;&lt;br /&gt;Of course, I'm referring to closures.  Users of functional languages will attest how working with such constructs changes how you think.  By adding closures to Java, we do more than provide a powerful tool for those of us already familiar with the construct.  We introduce a large community to a better way of solving many problems.  We'll see if it sticks, but I can't think of a better way to spread a thought model many believe to be superior.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Update:&lt;/span&gt;  I actually don't think Java sucks.  It meets the early goal as a straightforward replacement for C++ very well.  I do believe we can create a language that is better than Java based on what we've learned over the last decade.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-8450458275844381367?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/8450458275844381367/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=8450458275844381367' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8450458275844381367'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8450458275844381367'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/05/why-java-lost-its-mojo-and-what-sun-is.html' title='Why Java lost its mojo, and what Sun is doing about it'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-6593080032520945886</id><published>2007-04-08T13:57:00.000-07:00</published><updated>2007-04-08T14:01:32.996-07:00</updated><title type='text'>The Imaginary Concurrency Debate</title><content type='html'>It's finally being accepted: the shared memory, critical region model for concurrent programming is broken.   Even good programmers slip up and introduce race conditions, and bad programmers don't even understand the semantics.  (You mean I have to lock an object just to &lt;span style="font-style: italic;"&gt;read&lt;/span&gt; its values?)&lt;br /&gt;&lt;br /&gt;The question is: how do we fix it?  Two proposals have drawn attention: The Actor/Message model and Software-Transactional Memory (STM).  The former eliminates shared state entirely, using messaging primitives for communication between threads, which may or may not be in the same process or physical machine.  The latter preserves shared memory, but each thread has a consistent view of shared state during an operation and makes updates atomically, much like a database transaction.  We'll refer to these as the &lt;a title="Erlang model" href="http://www-128.ibm.com/developerworks/java/library/j-cb04186.html?ca=drs"&gt;Erlang model&lt;/a&gt; and the &lt;a title="Haskell model (pdf)" href="http://research.microsoft.com/%7Esimonpj/papers/stm/stm.pdf"&gt;Haskell model (pdf)&lt;/a&gt;, respectively, referring to the programming languages that most visibly use these synchronization techniques.&lt;br /&gt;&lt;br /&gt;A debate between these models has quietly arisen.  Proponents of the shared-nothing model point out the scalability and simplicity of Erlang.  Proponents of STM point out the composability of guaranteeing updates to two components can be made atomically.  Incredibly, it seems like this entire debate is ill-formed, and can be resolved with some simple generalization.&lt;br /&gt;&lt;br /&gt;First we realize nearly all non-trivial applications use both a form of messaging and shared resources.  A simple web application accepts messages from clients and shares state in a database.  Therefore, any widely used programming environment must offer first-class support for transacted resources &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; messaging.&lt;br /&gt;&lt;br /&gt;Now, suppose we view transacted memory simply as a hidden optimization of a transacted resource.  In Erlang I can send messages to an Erlang process in the same physical address space or on a different machine -- the former is simply a runtime optimization and not the concern of the developer.  STM is just a local optimization of a transacted resource; with abstraction we can also host the resource remotely like a database or distributed cache.&lt;br /&gt;&lt;br /&gt;In fact, the Erlang and Haskell models are closer than they first appear.  The STM proposal for Haskell has almost nothing to suggest a TVar must be locally hosted.  There are Erlang libraries allowing use of an RDBMS.   Both of these could be implementations of a general "transacted resource" API or Monad.  Similar parallels can be made for the messaging model.  Of course the languages have other significant differences, but these concepts are not so far apart.&lt;br /&gt;&lt;br /&gt;So where does this leave us in the concurrency debate?  I think we can draw some conclusions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Today's concurrency primitives can be abandoned, replaced by messaging and transacted resources&lt;/li&gt;&lt;li&gt;Messaging and shared resources are complementary constructs used in most applications&lt;/li&gt;&lt;li&gt;Shared memory is to transacted resources what in-process messaging is to general messaging: a hidden optimization&lt;/li&gt;&lt;li&gt;Applications should use messages, transactions, or an appropriate combination depending on their needs&lt;br /&gt; &lt;/li&gt;&lt;/ul&gt;  Now we need to ask why no widespread language has yet to replace critical region primitives with messaging and transacted memory.  I think this is largely because such languages are hard to design.  Notice how I'm generalizing STM and transacted databases to the same concept, but they have very different usage patterns in practice.  It will be a challenge to design something this general yet simple enough so people will actually want to use it.  But I'm an optimist.&lt;br /&gt;&lt;br /&gt;One final note: both of these models are more easily implemented using a functional programming style.  Something as simple as immutable objects makes both local messaging and transactions much simpler and more efficient.  It's funny how good practices pay off in ways we don't expect.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-6593080032520945886?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/6593080032520945886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=6593080032520945886' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/6593080032520945886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/6593080032520945886'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/04/imaginary-concurrency-debate.html' title='The Imaginary Concurrency Debate'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-7332801335499385979</id><published>2007-02-26T21:40:00.000-08:00</published><updated>2007-02-26T21:49:00.112-08:00</updated><title type='text'>Imperfect Approximation of Perfect Code</title><content type='html'>It needs to be said: the quality of a programming language is not inversely proportional to the number of bytes needed for a Sudoku solver.  Not that there's anything wrong with comparing Sudoku solvers; they can contrast certain aspects of languages, and differing solution styles can help readers think differently about code.  But this only gets us so far.&lt;br /&gt;&lt;br /&gt;The problem is the public language debate rarely ranges to topics that span more than a couple dozen lines of code.  Anything bigger is difficult to manage in a single discussion.  Therefore we need a model to debate the higher-order concerns of programming languages.  Fortunately, I'm shameless, and will shamelessly steal such a model from Donald Norman's excellent &lt;a href="http://mitpress.mit.edu/catalog/item/default.asp?tid=5393&amp;ttype=2" title="Design of Everyday Things"&gt;Design of Everyday Things&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The idea I'm referring to is Norman's modeling of human interaction with software and physical tools as a &lt;span style="font-style: italic;"&gt;series of imperfect approximations to approach a perfect goal.&lt;/span&gt;  A system should assume all user input is imperfect, but guide the user to her goal.  A user should have feedback indicating progress toward the goal.  Mistakes should be easily reversible and never take her far astray.&lt;br /&gt;&lt;br /&gt;Let's apply this to programming languages and practices.  The biggest step forward in recent years has been the adoption of test-driven development.  This fits nicely -- a solid safety net of unit tests allows developers to move towards the perfect goal.  It also brings to mind a humorous &lt;a href="http://programmingkungfuqi.blogspot.com/2007/02/real-reason-why-building-software-is.html" title="recent post"&gt;recent post&lt;/a&gt; by &lt;span class="misspell" suggestions="Jet,Jot,Jut,Kt,Jct"&gt;Jt&lt;/span&gt; Gleason.  One of the reasons programming is harder than bridge building is even small defects can cause us to jump radically away from our goal.&lt;br /&gt;&lt;br /&gt;So, what can improved languages and practices do to help?  They can guarantee no programmer mistake will cause us to jump to across an ocean, to use Gleason's metaphor.  Programming will never be truly analogous to bridge building, but if bugs can be localized -- like how a bad bolt is localized for a bridge -- we might make progress.  We can't eliminate bugs, but we can bound them and trend towards perfection.  This reminds me of a &lt;span class="misspell" suggestions="Piety,Poet,PET,Pet,Pit"&gt;Piet&lt;/span&gt; &lt;span class="misspell" suggestions="He in,He-in,Heine,Hen,Heinz"&gt;Hein&lt;/span&gt; poem reportedly displayed in Donald Knuth's home:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt; The road to wisdom? Well, it's plain&lt;br /&gt;&lt;/span&gt;&lt;span style="font-style: italic;"&gt; And simple to express:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; Err&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; and err&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; and err again&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; but less&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; and less&lt;/span&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt; and less.&lt;/span&gt;&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;  With all this in mind, I recently saw something that just might be a glimpse of the future.  Giles &lt;span class="misspell" suggestions="Beckett,Becket,Bocked,Booked,Bucket"&gt;Bowkett&lt;/span&gt; posted a &lt;a href="http://gilesbowkett.blogspot.com/2007/01/seaside-screencasts.html" title="screencast"&gt;&lt;span class="misspell" suggestions="screen cast,screen-cast,scrawniest,scroungiest,crankest"&gt;screencast&lt;/span&gt;&lt;/a&gt; showing modification of code in a Seaside-based web application as it was running.  Sure, we've been able to hot-swap code for a while, but that's usually a painful process requiring specific launch configuration and use of an external debugger.  Imagine if every menu in every program had an "edit" button available to experts, allowing them to adjust code on the fly.  The code-build-test-debug loop would become instantaneous, applications could be grown in the context of existing pieces, and good design and languages can prevent local bugs from creeping elsewhere.  This is our series of approximations toward a perfect goal.&lt;br /&gt;&lt;br /&gt;Of course, the above ideal might be unachievable for many applications.  Even so, it still might be possible to build an imperfect approximation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-7332801335499385979?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/7332801335499385979/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=7332801335499385979' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/7332801335499385979'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/7332801335499385979'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/02/imperfect-approximation-of-perfect-code.html' title='Imperfect Approximation of Perfect Code'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-4165241779873402054</id><published>2007-02-11T09:57:00.000-08:00</published><updated>2007-02-08T18:05:02.010-08:00</updated><title type='text'>Part 4: The Killer App</title><content type='html'>Technologies get adopted when there is a compelling reason.  People bought PCs for the killer app; game consoles sold for the killer game.  Programming languages take off because they have a killer feature.  Philip &lt;span class="misspell" suggestions="Waddle,Wader,Adler,Waller,Wailer"&gt;Wadler&lt;/span&gt; &lt;a title="pointed this out" href="http://citeseer.ist.psu.edu/wadler98why.html"&gt;pointed this out&lt;/a&gt; nine years ago:&lt;br /&gt;&lt;blockquote&gt;Instead, experience shows that users will be drawn to a language if it lets them conveniently do something that otherwise is difficult to achieve. Like other new technologies, functional languages must seek their killer app.&lt;/blockquote&gt;Java was adopted largely because it was easy for C++ developers to pick up, and offered killer features like cross-platform development and garbage collection.  So what is the killer feature of the next language?  I'll take a shot: the complete and final eradication of undefined behavior.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;No Behavior Left Undefined&lt;/span&gt;&lt;br /&gt;"Undefined behavior" is the biggest euphemism in software engineering.  It even beats out "non-trivial problem".  It's why your code works great on your laptop, but every one of your users runs a &lt;a title="DeathStation 9000" href="http://en.wikipedia.org/wiki/DeathStation_9000"&gt;&lt;span id="bad_word" class="misspell" suggestions="Death Station,Death-Station,Detestation,Devastation,Dissertation"&gt;DeathStation&lt;/span&gt; 9000&lt;/a&gt;.  Amazingly, most mainstream languages still have areas where behavior is undefined and unpredictable.&lt;br /&gt;&lt;br /&gt;Fortunately, modern languages have made great strides as compared to, say, C++.  However, we still have a long way to go.  The big problem these days is race conditions caused by improperly synchronized code.  And it looks like concurrent programming will only become more common. &lt;br /&gt;&lt;br /&gt;What makes undefined behavior particularly evil is not that it might fail; it's that it might succeed.  We &lt;span style="font-style: italic;"&gt;want&lt;/span&gt; incorrect code to consistently fail.  This way every time we find a bug we can isolate it with a unit test and ensure it never happens again.  But undefined behavior shoots a hole in this: we can have incorrect code that &lt;span style="font-style: italic;"&gt;passes every possible unit test.&lt;/span&gt;  The result is bugs showing up in the worst possible place, production.&lt;br /&gt;&lt;br /&gt;Consider the practical implications of working in a language without undefined behavior.  If we can create a reliable unit test for any bug we find, we can guarantee that bug never recurs.  Good development practices can cause defect counts to trend towards zero.  It also makes development itself easier by strengthening our &lt;a title="firewall against complexity" href="http://toomuchcode.blogspot.com/2007/02/building-firewall-against-complexity.html"&gt;firewall against complexity&lt;/a&gt;.  Although we'll never eliminate buggy code, hopefully we can create enough stability to prevent bugs from spiraling out of control, which has led to the death of many projects.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Where is our new language?&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The &lt;a title="first" href="http://toomuchcode.blogspot.com/2007/02/part-1-programming-and-metaphorical.html"&gt;first&lt;/a&gt; &lt;a title="three" href="http://toomuchcode.blogspot.com/2007/02/part-2-languages-and-lesser-skilled.html"&gt;three&lt;/a&gt; &lt;a title="posts" href="http://toomuchcode.blogspot.com/2007/02/building-firewall-against-complexity.html"&gt;posts&lt;/a&gt; and this one describe an ideal for a new programming language.  Many details were intentionally left out to focus on the essence, so many language styles might work.  Now I have a question for you: what current or upcoming language best meets these ideals?  Much of this exists in part in Haskell, Erlang, Ruby, &lt;span class="misspell" suggestions="Scalar,Scale,Scaly,Scald,Scalp"&gt;Scala&lt;/span&gt;, F# or others, but I know of no language meeting them all.  I hope that will change soon.    &lt;span style="font-weight: bold;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Thanks to everyone who made it through these posts.  I do want to hear your thoughts.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-4165241779873402054?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/4165241779873402054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=4165241779873402054' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/4165241779873402054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/4165241779873402054'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/02/part-4-killer-app.html' title='Part 4: The Killer App'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-2453866660035555212</id><published>2007-02-08T17:59:00.000-08:00</published><updated>2007-02-08T18:04:05.564-08:00</updated><title type='text'>Part 3: Building a Firewall Against Complexity</title><content type='html'>In the &lt;a title="first" href="http://toomuchcode.blogspot.com/2007/02/part-1-programming-and-metaphorical.html"&gt;first&lt;/a&gt; &lt;a title="two" href="http://toomuchcode.blogspot.com/2007/02/part-2-languages-and-lesser-skilled.html"&gt;two&lt;/a&gt; posts in this sequence, I argued a few key points:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; A language must be usable by mediocre developers to achieve widespread use.&lt;/li&gt;&lt;li&gt; A language that prevents quick and dirty application development will not be widely adopted.&lt;/li&gt;&lt;li&gt;Widespread adoption is important so good programmers can use better languages in their day jobs.&lt;/li&gt;&lt;li&gt;Haskell shows important innovation in language design, but has major hurdles to widespread adoption.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Assuming the above, we have a big problem: how do we make the essential innovation in Haskell available to the broader industry?  We need to first define the essence of Haskell's contribution, and then look for ways to package that essence for widespread use.&lt;br /&gt;&lt;br /&gt;I will use a simple model of software problems to define Haskell's essential contribution.  Complexity kills, but Haskell helps contain it&lt;span style="font-style: italic;"&gt;.&lt;/span&gt;  We were in trouble the moment systems got too big for a single human to understand, and we kept digging the hole deeper.  This needs to stop.&lt;br /&gt;&lt;br /&gt;So far the best answer to complexity has been good design abstraction.  And there have been successes -- I usually don't think about the virtual memory system when writing code, for instance.  But as Joel Spolsky pointed out, "&lt;a title="All non-trivial abstractions, to some degree, are leaky." href="http://www.joelonsoftware.com/articles/LeakyAbstractions.html"&gt;All non-trivial abstractions, to some degree, are leaky&lt;/a&gt;."  I don't &lt;span style="font-style: italic;"&gt;usually&lt;/span&gt; think about virtual memory, but if I have locality of reference problems and huge numbers of page faults, the abstraction leaks.   Suddenly I have to think about everything my program does, everything its libraries do, all existing abstraction leaks, &lt;span style="font-style: italic;"&gt;and&lt;/span&gt; the virtual memory system.  Soon there isn't room in my limited mind to keep track of everything.  The result is almost inevitable: a system gets more complex, details are missed, and defects creep in.&lt;br /&gt;&lt;br /&gt;To make matters worse, the difficulty of understanding a system grows exponentially with size.  Every variable added must be tracked with every other variable.  I see two possible solutions to this:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Stop building such complex software.&lt;/li&gt;&lt;li&gt;Find ways to build airtight firewalls around complexity.  Stop the leaks.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;History suggests option one is not likely.  Great programmers can solve complex problems with simple code, but this is not the broader trend.  Even if it was, this answer is unsatisfying; it's really just avoiding the problem.&lt;br /&gt;&lt;br /&gt;The second solution might have potential.  Imagine if we had abstractions that didn't leak, even if they could only be used in special conditions, or applied to certain problems.  There will always be complexity, but by bounding it with airtight abstractions we limit the number of variables involved.  Heck, if we do a great job, it's possible even we humans will be able to understand the systems we build.&lt;br /&gt;&lt;br /&gt;This is where we reach the essential contribution of Haskell (or any pure functional language): &lt;span style="font-style: italic;"&gt;it builds a firewall around the rest of the system's complexity.&lt;/span&gt;  You only have to think about the part you're working, and you can make that small enough to be understandable.   Because functions can't have side effects, you don't have to worry about locking a resource or dealing with inconsistent state.  Your universe is defined by a function's arguments.&lt;br /&gt;&lt;br /&gt;So far, so good...but we still need to package our firewall against complexity to be more easily adopted and used.  Notice large parts of functional languages are not included in the essential contribution.  For instance, a chunk of code could be written in any style, as long as its side effects are encapsulated.  Here we break away from the pure functional model.  If local destructive updates, statements, for loops, or other imperative constructs make coding easier, we can allow them.  The key is not allowing these local decisions escape; our firewall against complexity must hold.  A similar point came up in a recent &lt;a title="discussion on Channel 9" href="http://channel9.msdn.com/Showpost.aspx?postid=273697"&gt;discussion on Channel 9&lt;/a&gt;.  Erik Meijer described it as "local impurity, but global purity".&lt;br /&gt;&lt;br /&gt;This is a key element for our hypothetical new language: allow developers to code in their style of choice, provided it does not compromise the system's guarantees.  The merits of different styles are open to debate, but surely no one style is the best for all programs.  Ultimately, our hypothetical language might really be a set of languages, all keeping the same guarantee of isolation.  The key is we can build a language with stronger guarantees than any commonly used language, but make it easy for most developers to adopt.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Can we live without state?&lt;/span&gt;&lt;br /&gt;System state is the biggest source of complexity for imperative programs.  It's also the biggest reason imperative code is considered easier for quick and dirty solutions.  You want to change state?  Go for it.  Just be sure you synchronize with other threads, and your state change is consistent with the rest of the system, and you leave the system in a consistent state in case of error, and...well, hope others changing the state follow the same rules.     &lt;br /&gt;&lt;br /&gt;All of these problems go away with functional languages.  But I can't shake the idea that a language restricting all access to state simply won't get adopted.  Haskell elegantly solves this solution with the Monad; you write code in isolation, and simply describe the side effects to be evaluated as needed.  Sounds good, until you run into problems like the one described &lt;a title="here" href="http://kawagner.blogspot.com/2006/12/my-haskell-experience.html"&gt;here&lt;/a&gt;.  In that case, the developer discovered a deep function needed some additional piece of information, and had to refactor large amounts of code to get it there.  This drawback may well be justified by the advantages of isolated coding.  Then again, our goal is to get a better language adopted, and most businesses will reject one that makes writing quick and dirty code harder, even if there is a net gain.&lt;br /&gt;&lt;br /&gt;I really hope I'm wrong about this one.  (And I'm sure many will try to convince me that I am.)   I suspect, though, that languages must make accessing state information easy to gain widespread adoption.  Is there a way we can do this while holding on to our firewall against complexity?  Maybe.  There are some tempting ideas that might solve this.  Possibilities include &lt;a title="Software Transactional Memory" href="http://en.wikipedia.org/wiki/Software_transactional_memory"&gt;Software Transactional Memory&lt;/a&gt; (STM), or messaging-based models like Erlang.  The answer to which is better must come from experimentation, although STM elegantly solves some problems others do not, as &lt;a title="Tim Sweeny described (pdf)." href="http://morpheus.cs.ucdavis.edu/papers/sweeny.pdf"&gt;Tim Sweeny described (pdf).&lt;/a&gt;   Assuming an adopted system must be able to easily change state, we can still use STM to attain many advantages of the functional style:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;No race conditions or deadlock.  STM can make code seem like it's running in a single-threaded environment.  This is our firewall against concurrency complexity.&lt;/li&gt;&lt;li&gt; No inconsistent state.  If any error occurs, the transaction is simply rolled back.  As a result, the state space of the system is dramatically reduced, and all possible states are logically consistent.&lt;/li&gt;&lt;li&gt;External side effects (like database updates) should happen in the same transaction as memory updates, again ensuring consistent state.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;A new language could allow only special annotated functions to use STM, clearly indicating which functions are logically pure.  This is analogous to implicitly passing a Haskell Monad to every pertinent function.  Yes, we are sacrificing functional purity.   However, we keep our firewall, and build a language that just might find a widespread audience.  Also, we need not sacrifice other great features of functional languages to get there.  For instance, a function may do destructive updates internally but always return an immutable object, lending itself to memoization.&lt;br /&gt;&lt;br /&gt;In summary, we have two new requirements for our hypothetical language:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;blockquote&gt;Developers should be able to choose their style of programming, but still have strong guarantees of isolation from the rest of the system.&lt;/blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;The system should limit the number of variables the developer must track while writing code.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;In my next post, I will add more requirements in this spirit, and hopefully draw these thoughts to a close.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-2453866660035555212?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/2453866660035555212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=2453866660035555212' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2453866660035555212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2453866660035555212'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/02/building-firewall-against-complexity.html' title='Part 3: Building a Firewall Against Complexity'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-2016758909228910089</id><published>2007-02-05T17:28:00.000-08:00</published><updated>2007-02-11T23:18:14.359-08:00</updated><title type='text'>Part 2: Languages and the Lesser-Skilled Developer</title><content type='html'>My &lt;a title="last post" href="http://toomuchcode.blogspot.com/2007/02/part-1-programming-and-metaphorical.html"&gt;last post&lt;/a&gt; ended with an assertion: we need a language with the best of Haskell in a more accessible form.  This leads to an old debate.  After all, building good software requires tremendous skill.  How can we make progress if we tailor it to the weakest practitioners?  Bjarne Stroustrup &lt;a href="http://www.technologyreview.com/Infotech/17868/page1/" title="made this point well"&gt;made this point well&lt;/a&gt;:&lt;br /&gt;&lt;blockquote&gt; The idea of programming as a semiskilled task, practiced by people with a few months' training, is dangerous. We wouldn't tolerate plumbers or accountants that poorly educated. We don't have as an aim that architecture (of buildings) and engineering (of bridges and trains) should become more accessible to people with progressively less training. Indeed, one serious problem is that currently, too &lt;i&gt;many&lt;/i&gt; software developers are undereducated and undertrained.&lt;/blockquote&gt;Stroupstrup is right, of course.  Too many developers &lt;span style="font-style: italic;"&gt;are&lt;/span&gt; undereducated; we &lt;span style="font-style: italic;"&gt;should&lt;/span&gt; demand greater skill.   However, this doesn't change the fact that language adoption for a given shop has as much to do with politics as technical merit.  Businesses have a perceived need to hire armies of developers to quickly write bad code and bad software.  We'll be asking "&lt;a title="WTF" href="http://thedailywtf.com/"&gt;WTF&lt;/a&gt;?" for a long time to come.&lt;br /&gt;&lt;br /&gt;The problem is highly skilled developers are often forced to use the languages accessible to their less competent colleagues.  Browse the forums at &lt;a title="Reddit" href="http://reddit.com/"&gt;Reddit&lt;/a&gt; and you'll find lots of developers coding C# or Java by day and Haskell or Lisp by night.  In short, a language must be usable by lesser-skilled developers so high-skilled developers have more opportunities to use it.   Ruby is a great example of this in action -- building a quick and dirty web application is trivial, but the language still offers powerful constructs such as closures.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Battling the Hack&lt;/span&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;Anyone who has written software for a couple years has come across the Nasty Hack -- what should have been a simple piece of code made horribly complex, requiring an alignment of planets to work.  Languages such as Haskell have the laudable goal of &lt;a title="preventing nasty hacks" href="http://neilbartlett.name/blog/?p=11"&gt;preventing nasty hacks&lt;/a&gt; by &lt;a title="restricting what can be done in a given context" href="http://syntaxfree.wordpress.com/2007/01/08/haskell-bondage-and-discipline-and-separation-of-concerns-programming/"&gt;restricting what can be done in a given context&lt;/a&gt;.  Sadly, good design often takes second place to deadlines -- and a language that has the appearance of slowing development won't get far, even if it offers a net gain.&lt;br /&gt;&lt;br /&gt;Even a language that prevents some classes of nasty hacks will &lt;a title="allow other kinds" href="http://trevion.blogspot.com/2006/11/functional-anti-patterns.html"&gt;allow others&lt;/a&gt;.  No language will free us from bad code altogether.  Even worse, languages that free us from large classes of bad code have trouble getting adopted because businesses indirectly want to hack.  This has depressing implications:  the nasty hack is here to stay, and languages attempting to eliminate it will struggle to find widespread adoption.  Our only hope is a fundamental cultural change in the way most organizations build software.&lt;br /&gt;&lt;br /&gt;There is nothing I want to see more than this cultural shift.  Maybe some day the market will get so sick of bad software it will force change.  Consumers might realize great software&lt;span style="font-style: italic;"&gt; is &lt;/span&gt;possible, as shown by a few innovative companies.   Other companies might finally delay entry to a market, knowing a buggy solution will be rejected.   The lesser-skilled developer might be forced to improve or leave the field.&lt;br /&gt;&lt;br /&gt;However, while attempting to change the culture we still need to innovate under the current constraints.  This means it must be easy to write quick and dirty code in a widely adopted language.  So I submit a requirement for our new language:&lt;br /&gt;&lt;span style="font-style: italic;"&gt;&lt;blockquote&gt;A language should encourage good code -- but make quick and dirty code possible.&lt;/blockquote&gt;&lt;/span&gt;Today languages like Ruby and Python are probably the closest to the mark.  Inexperienced developers can quickly get code working, and more advanced developers have access to powerful features drawn from the functional world.  However, both of these languages have shortcomings when compared to Haskell.  Incorrect code can lead to unpredictable behavior, and poorly designed code can lead to a state space too big for any human to understand.  Specifically, they do not offer a tractable solution to &lt;a title="concurrency and composability" href="http://research.microsoft.com/%7Esimonpj/papers/stm/stm.pdf"&gt;concurrency and composability&lt;/a&gt; (pdf).&lt;br /&gt;&lt;br /&gt;In my next post I will attempt to outline a language concept drawing from the best of Ruby, Haskell, and other sources.&lt;br /&gt;&lt;br /&gt;(Edit: fix typo)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-2016758909228910089?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/2016758909228910089/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=2016758909228910089' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2016758909228910089'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/2016758909228910089'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/02/part-2-languages-and-lesser-skilled.html' title='Part 2: Languages and the Lesser-Skilled Developer'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-3313177337037523315</id><published>2007-02-03T13:03:00.000-08:00</published><updated>2007-02-03T13:17:57.418-08:00</updated><title type='text'>Part 1:  Programming and the Metaphorical Mind</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Hello, World&lt;/span&gt;&lt;br /&gt;This is the first of a set of posts on what we need from a new programming language.  Everything I discuss exists in some language -- at least in part -- but no language yet has them all.  This content is a mixture of my experience and many borrowed ideas, which I will do my best to cite.  My goal is to represent the language needs of some segment of developers.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Metaphorical Mind&lt;/span&gt;&lt;br /&gt;I'll start simply: a language must be designed and taught with its users in mind.  There is a psychology to programming which may explain why some languages get adopted and better ones don't.  To model this psychology, I borrow the idea of the "Metaphorical Mind"&lt;span style="font-style: italic;"&gt;&lt;span style="font-style: italic;"&gt;,&lt;/span&gt;&lt;/span&gt; as described in Steven Pinker's excellent &lt;a title="How the Mind Works" href="http://pinker.wjh.harvard.edu/books/htmw/index.html"&gt;How the Mind Works&lt;/a&gt;.   In Pinker's words, "The human mind, we see, is not equipped with an evolutionarily frivolous faculty for doing Western science, mathematics, chess, or other diversions."  Our minds evolved to work with the physical world, and we reason with abstract ideas using physical metaphors.  Pinker cites Ray Jackendoff for examples:&lt;br /&gt;&lt;br /&gt;The messenger &lt;span style="font-style: italic;"&gt;went from&lt;/span&gt; Paris &lt;span style="font-style: italic;"&gt;to&lt;/span&gt; Istanbul.&lt;br /&gt;The inheritance finally &lt;span style="font-style: italic;"&gt;went to &lt;/span&gt;Fred.&lt;br /&gt;The light &lt;span style="font-style: italic;"&gt;went from&lt;/span&gt; green &lt;span style="font-style: italic;"&gt;to&lt;/span&gt; red.&lt;br /&gt;The meeting &lt;span style="font-style: italic;"&gt;went from&lt;/span&gt; 3:00 &lt;span style="font-style: italic;"&gt;to&lt;/span&gt; 4:00.&lt;br /&gt;&lt;br /&gt;(emphasis in original)&lt;br /&gt;&lt;br /&gt;The first sentence shows physical movement; the others use the same terms but have nothing moving.  Beyond movement, spatial metaphors permeate our thoughts and language.  "The meeting is &lt;span style="font-style: italic;"&gt;at&lt;/span&gt; 3:00", for instance.  In fact, it's hard to describe almost anything without physical metaphors.&lt;br /&gt;&lt;br /&gt;Many examples exist in software.  Imperative programmers deal with &lt;span style="font-style: italic;"&gt;pointers, objects, stacks, messages, events&lt;/span&gt; and so on.  Our secondary storage uses &lt;span style="font-style: italic;"&gt;folders, files&lt;/span&gt; and &lt;span style="font-style: italic;"&gt;paths.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In fact, there is an alarming predictability on language adoption: languages that strengthen the physical metaphor -- or at least solve problems without weakening it -- have found widespread use.  Languages with weaker physical metaphors remain with a small base.  Compare the adoption rates of object-oriented languages to their functional counterparts.&lt;br /&gt;&lt;br /&gt;This might be an indictment of functional languages, since they are typical expressed in abstract mathematics rather than physical analogs.  That is unfair.  Functional languages can be built and explained in straightforward physical terms -- they just aren't.  Take, for instance, Haskell's Monad.  I've written only small programs in Haskell, but for my purposes it's much easier to think of a Monad as a "to-do list".  (Some use the term "action".  I know it's an over-simplification, but that's the point.)  The bulk of the language is a means to construct to-do lists in isolation.  Put in these terms, Haskell can be simpler than many languages -- the functional purity eliminates all kinds of moving parts imperative programmers have to worry about.&lt;br /&gt;&lt;br /&gt;This is a good step, but widespread adoption means more than renaming of concepts.  Unfortunately, programmers who find and learn functional languages are not representative of the population.  I'm afraid we would lose a broader audience in the first hour of learning Haskell, as soon as they got to this:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;fibs = 1: 1: zipWith (+) fibs (tail fibs)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Beautiful, isn't it?  One line of code for Fibonacci numbers, what amounts to built-in memoization, the ability to get and manipulate any sequence, and so on.  But it also has only the weakest of ties to a physical analog.  Non-trivial examples are much harder to understand.  Sadly, an incredibly powerful tool for some is simply too abstract for others to use effectively.&lt;br /&gt;&lt;br /&gt;Because of this and other examples, I doubt Haskell will ever be widely used despite all of its advantages.  But this is okay -- we need powerful tools for the hands of experts.  What I want to see is a more accessible language borrowing the best ideas from Haskell and others.  I wish I could use Monads every day, and am willing to sacrifice some of Haskell's other power to achieve this.&lt;br /&gt;&lt;br /&gt;This raises an important question: shouldn't we raise our expectations of developers rather than take away powerful features?  A valid point, which I will tackle this in my next post.&lt;span style="font-style: italic;"&gt;&lt;/span&gt;  For now, the central thesis of these posts should start to emerge: we need a language with the best parts of Haskell and others in a more accessible form.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-3313177337037523315?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/3313177337037523315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=3313177337037523315' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3313177337037523315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/3313177337037523315'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2007/02/part-1-programming-and-metaphorical.html' title='Part 1:  Programming and the Metaphorical Mind'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-8144595511058701140</id><published>2006-12-26T13:09:00.000-08:00</published><updated>2006-12-26T15:17:38.633-08:00</updated><title type='text'>The Software Engineer's New Clothes</title><content type='html'>The problem with experts is they're too smart.  The problem with the rest of us is we don't have the expertise to reign in the experts.&lt;br /&gt;&lt;br /&gt;Consider the following conversation:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mortal Developer:&lt;/span&gt; This system seems complicated.  Can we do without the WhackAMole feature?&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Expert: &lt;/span&gt;No, some clients might need WhackAMole to interact with their legacy abacus.&lt;br /&gt;&lt;br /&gt;Now our poor mortal developer is stumped.  After all, this is the &lt;span style="font-style: italic;"&gt;expert&lt;/span&gt; we're talking to here -- and if he says we need WhackAMole you better get whacking.&lt;br /&gt;&lt;br /&gt;What our developer missed is this: &lt;span style="font-style: italic;"&gt;complexity alone is enough to reject a design.&lt;/span&gt;  After all, you're a smart engineer with years of programming experience.  Even if you're not an expert, if a system is hard for you to comprehend, it's probably too complicated.  Sadly, there seems to be an "Emperor's New Clothes" phenomenon in software  -- no one wants to admit something is hard to understand.&lt;br /&gt;&lt;br /&gt;This shouldn't be surprising -- objecting to complexity might be viewed as looking stupid in an industry where intelligence is the highest virtue.  Unfortunately this can do a lot of harm.  Imagine if the J2EE specification had involved a developer without expertise, but with veto power.  Surely the result would have been a lot simpler.  This lesson may have been learned for newer versions, but once added this complexity cannot be completely removed.&lt;br /&gt;&lt;br /&gt;For anyone that might be struggling with this right now, some humble advice:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Follow Alan Kay's axiom: "Simple things should be simple, complex things should be possible." -- If something complicated &lt;span style="font-style: italic;"&gt;must &lt;/span&gt;be in the system, it still should not affect the simple things.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;View the project as a constant battle against complexity -- A single complex module may seem unimportant, but it quickly compounds.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Understand a project end-to-end -- the project should be easily broken down into problems that are known to be solvable.  (Avoid Southpark's 1. Collect Underpants. 2. ??? 3. Profit!!!).   &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;   &lt;li&gt;       A strong-willed engineer or executive can will a group down the wrong path -- it's an engineer's duty to object and prevent spiraling complexity&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;The clever hack should be a last resort -- a hack that is hard to come up with is much harder to debug or support&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;All of this boils down to Keep It Simple, Stupid.  It turns out keeping things simple is pretty hard.&lt;br /&gt;&lt;br /&gt;Update: This isn't to suggest that all experts fall into this trap, but there is certainly evidence suggesting that &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-8144595511058701140?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/8144595511058701140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=8144595511058701140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8144595511058701140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/8144595511058701140'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2006/12/software-engineers-new-clothes-problem.html' title='The Software Engineer&apos;s New Clothes'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-319772288258656865</id><published>2006-11-26T15:24:00.000-08:00</published><updated>2008-01-06T19:51:50.135-08:00</updated><title type='text'>End of software's dark age?</title><content type='html'>Software has held more promise and yet met with more failure than any other technology.  Meanwhile the hardware guys have been merrily creating more and more CPU cycles for us to swamp.&lt;br /&gt;&lt;br /&gt;A lot has been written about why software sucks.  &lt;span style="font-style: italic;"&gt; &lt;/span&gt;Fred Brooks famously predicted there would be &lt;a title="no silver-bullet" href="http://inst.eecs.berkeley.edu/%7Emaratb/readings/NoSilverBullet.html"&gt;no silver bullet&lt;/a&gt;   improvement in software productive over the next ten years.  That was twenty years ago, but there are signs that the dark age of software might be slowly and quietly coming to an end.&lt;br /&gt;&lt;br /&gt;Brooks was right about the lack of a silver bullet, of course.  But since then we've learned that we've been trying to kill the wrong monster.  Building a program was compared to the reliable timeline and quality of building a bridge or skyscraper, and we were mystified on how to get there.  This is the wrong monster; instead we need to view code as design and adopt our practices to match.  Coding is a creative process with much more in common with design than with any industrial process -- &lt;a href="http://www.developerdotstar.com/mag/articles/reeves_design_main.html" title="Jack Reeves got it right"&gt;Jack Reeves got it right&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Notice successful development methodologies jibe with viewing code as design.  We unit test because a design isn't complete until validated with a simulation.  We work in iterations because a change in one part of the design affects others.  We document in the source code itself because that is the definitive source of design.&lt;br /&gt;&lt;br /&gt;The code-is-design perspective also predicts many supposed mysteries: huge productivity variance, a high number of defects, and failures of rote process are all expected in unvalidated, untested design.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Mysteries and Problems&lt;/span&gt;&lt;br /&gt;Fortunately we've taken an important step: software development was once a mystery in search of a silver bullet; now it is a problem with real progress.  Noam Chomsky pointed out the first step to understanding the natural world is to turn mysteries into problems.  We're seeing the same with software engineering.&lt;br /&gt;&lt;br /&gt;Given the premise of code being design, here are some steps to take us in the right direction:&lt;br /&gt;&lt;br /&gt;1. Boil out the remaining accidents.  We can still have race conditions or leak resources in many programming languages.  Newer languages should make these mistakes impossible.  We can also learn from existing languages.  For instance, the messaging model in Erlang prevents many types of timing problems.   Functional languages may eliminate the many types of bugs which arise from side effects.  The essence of a design should not be concerned with timing or unexpected side effects, so whenever possible this should be solved in the language itself.&lt;br /&gt;&lt;br /&gt;2. Make validation of designs easy.  How about the following requirement for a new programming language:   &lt;br /&gt;&lt;br /&gt;   &lt;span&gt;It must be straightforward to write a unit test to reproduce any possible bug.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since designs must be validated with computer simulation, we must make those simulations easy.  Huge strides have been made with various unit testing frameworks, but there are still shortcomings.  Proofs of correctness are impractical for most systems, but the ability to easily assert a system doesn't have a particular bug is the next best thing.  Furthermore, any bug discovered at any time should be added to the test suite to make sure it never occurs again.  This ensures the defect rate of a system trends towards zero.&lt;br /&gt;&lt;br /&gt;3.  Design and code should merge into a single artifact.  We still need design at a higher level than current programming languages, but this design needs to be an asset rather than a burden that gets out of synch with the code.&lt;br /&gt;&lt;br /&gt;We are already seeing this: documentation has been merged with source code and tools convert code to UML diagrams and vice versa.  But there is a lot of room for improvement.  Code in object-oriented languages often includes many unessential objects that are just noise from a high-level view.  These should be eliminated from the language, or at least filtered from the high-level design.&lt;br /&gt;&lt;br /&gt;There are surely many other examples that I'm overlooking, and functional languages do hold promise.  What's important is we now have an idea of why software sucks, and an inkling of what the solution might be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-319772288258656865?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/319772288258656865/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=319772288258656865' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/319772288258656865'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/319772288258656865'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2006/11/software-has-held-more-promise-and-yet.html' title='End of software&apos;s dark age?'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-697929553688711480.post-6535180899820843682</id><published>2006-11-14T20:49:00.000-08:00</published><updated>2006-11-14T21:07:03.095-08:00</updated><title type='text'>The real reason we need strongly-typed languages</title><content type='html'>There aren't many hard-and-fast facts about software, but here's one:&lt;br /&gt;&lt;br /&gt;    The more code you have, the more bugs you have.&lt;br /&gt;&lt;br /&gt;More formally, lines of code is a strong predictor of defects.  So, any language that allows you to do the same work with less code must be a Good Thing.  This is why Python is better than Java is better than C++ is better than assembly, right?&lt;br /&gt;&lt;br /&gt;Well, almost.  The standard counter argument is strongly-typed languages catch mistakes at compile time that slip to run time for dynamic languages.   I don't buy this argument, because  even though it will catch &lt;span style="font-style: italic;"&gt;some&lt;/span&gt; mistakes, there are so many other errors to be made you still need to unit test the code.  And good unit tests will catch the same errors of strongly-typed languages.  Okay, so a lot of people don't write good unit tests, but until they do they're beyond our help anyway.  As Bruce Eckel said, &lt;a href="http://www.mindview.net/WebLog/log-0025" title="if it's not tested, it's broken"&gt;"if it's not tested, it's broken"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So why am I a proponent of strongly-typed languages for many (but not all) problem sets?  Because they give us one thing dynamic languages by definition never will: unambiguous, guaranteed documentation.   Building large software systems means interfacing with subsystems written by others, and they must be documented.  Strongly-typed languages have an important part of that documentation built in: they precisely define the input and output types of each procedure call.  An API in a dynamic language needs the same documentation anyway, so why provide the chance for error?  Even for well-documented libraries, the reduced amount of code in the dynamic language is balanced by increased documentation.&lt;br /&gt;&lt;br /&gt;In fact, I'd like to see languages with even stronger guarantees.  A &lt;a href="http://nice.sourceforge.net/language.html" title="Nice"&gt;Nice&lt;/a&gt; addition to Java would be to define references that can never be null.  Many times I've used an API and asked, "do I need to check for null?"  The answer to my question should be part of the API itself.&lt;br /&gt;&lt;br /&gt;Of course, specific dynamic languages may have other advantages over their strongly-typed counterparts.  Also, some programs may not need the detailed level of documentation offered by strong typing.  Even so, type definitions are a key part of the documentation needed for a large system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/697929553688711480-6535180899820843682?l=www.toomuchcode.org' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.toomuchcode.org/feeds/6535180899820843682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=697929553688711480&amp;postID=6535180899820843682' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/6535180899820843682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/697929553688711480/posts/default/6535180899820843682'/><link rel='alternate' type='text/html' href='http://www.toomuchcode.org/2006/11/real-reason-we-need-strongly-typed.html' title='The real reason we need strongly-typed languages'/><author><name>Ryan Brush</name><uri>http://www.blogger.com/profile/14619577469724926326</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry></feed>
