Monday, April 20, 2009

Mental Filters

I write about a pretty wide variety of topics. Some common ones are:
  • Algorithm Design
  • Ethics and Morality
  • Philosophy
  • Politics
  • Learning
While these topics seem somewhat distinct, they all intersect on one question:

What things are good and how can I best do them?

The site's tag line is "Genuine and Artificial Intelligence", but the purpose of intelligence is to do good things, rather than bad things, inefficient things, or evil things. I think of each post as an opportunity to learn how to learn.

So it shouldn't surprise you that I love well reasoned and articulated explanations, especially things explaining how we think. For example, this essay on Lies We Tell Children was worth a blog post. I found one last week on the subject of open-mindedness. It's well worth the 10 minutes, so I highly recommend watching it:



There's a lot of good stuff in there, but I particularly liked the point about mental filters, starting at roughly 7:23. A lot of people think that being open-minded means you are willing to consider any idea, which essentially means your brain lacks a mental filter. They define being open-minded as accepting any idea you are told, no how far-fetched the circumstantial evidence is. What this really means is, "you should agree with me no matter what." And ironically, that's the exact definition of being close-minded, as it means they aren't open to other ideas.

The main point is that being open-minded means considering the evidence and logic for different explanations, then believing the explanations that best fit the evidence and throwing out the ones that don't. In other words, being open-minded is predicated on having an evidence filter.

Everyone is confronted with both true and false concepts all the time, and it's impossible to have a world view that only believes the "correct" things. Statistically speaking, you are virtually guaranteed to believe some ideas that are flat out wrong. But the objective is to minimize the percent of incorrect ideas you believe. That means the key word is "filter". If you have a brick wall for your mind, you are unable to accept any new ideas, so the incorrect premises you have will only turn into more incorrect conclusions. And if you have no mental protection at all, you'll believe all kinds of crazy things.

I believe many people who are truly close minded mistake the mental filters other people have for brick walls. They falsely conclude that because someone rejected their idea, that person must not be open to any opposing ideas, rather than simply having a good reason for rejecting theirs.

All of this is well and good for understanding "the other guy". But how do you make sure that you aren't "the other guy"? Remember, the most close-minded people think they are open-minded, in the same way that arrogant people think they are humble. There's no firm method to conclude whether you are actually open-minded, but keep this in mind: Truly open-minded people occasionally change their beliefs. Ask yourself this question:

When was the last time I philosophically disagreed with someone, and after we expressed our beliefs, they changed my mind?

If you think you are open-minded but can't remember the last time someone else changed your opinion on something substantive, you are probably more close-minded than you think. Recognizing when you are wrong and having the humility to admit it is the true mark of an adult mind.

Monday, April 6, 2009

Ballistic Programming

Last Wednesday I attended a talk at MIT from Larry Wall, the designer of the Perl programming language. The talk was entitled, "Ballistic Programming", but really it was excuse to talk about Life, the Universe, and Everything. And by everything I mean programming languages, their design, shortcomings and benefits, natural languages, grammar, and how his perspectives on all of these things impact the design of Perl.

Perhaps it's better to say that the talk was about "everything".

At any rate, the study of ballistics is literally about the art of projectiles. It's the source of the the term ballista, and it's based on the Greek verb for "to throw". Pretty much every sport involving a ball is a ballistic sport, as well as a few others, like the javelin toss and gun target practice. Ballistics is the art of throwing an object from one point to another, and the process works like this:
  • Select intended destination
  • Estimate force required to move object
  • Make attempt
  • Evaluate effectiveness
  • Correct next attempt using these results
Of course, this procedure applies just as well to programming as it does golf or basketball. Larry had an excellent set of diagrams explaining the two major theories of software project design. First, he showed Waterfall, a complete failure of a process in which each stage seamlessly and perfectly flows from one step the next with no backtracking. It's been known for decades that it doesn't work and causes projects to be over budget, but here's are the stages:
  • Specification (select destination)
  • Design (estimate force)
  • Implement (make attempt)
  • Test (evaluate)
  • Maintenance (correct)
The problem with waterfall is that it has no flexibility anywhere. Sometimes something will come up in implementation that demonstrates an issue with specifications or design, and those portions need to be corrected. But waterfall states that all the specifications have to be done first, then all the design, and so on. Either the whole project gets held up as flaws in the process are found, or the project is completed with flaws, producing something that no one needs and is impossible to maintain.

The other common methodology is known by the laden buzzphrase "Extreme Programming". The two main tenants of extreme programming are that you want lots of feedback loops so problems can be corrected as soon as possible, and that people should program in pairs. Since pair programming isn't relevant to the discussion at hand, I'll just give my two cents and let the issue rest. It's very useful for educating half of the pair and otherwise it's a waste of time, in that it takes more than twice as many worker-hours to do.

Larry Wall joked that in Extreme Programming, you start with the test which shows you how to implement the program. After you've implemented it, you can write your design document, and finally at the end of the project you can write the specifications. In other words, it's the reverse of Waterfall:
  • Test
  • Implement
  • Design
  • Specs
Naturally it's easy to run into problems early if you don't know what your design and specs will actually end up as. And just because you are constantly refactoring when you encounter a problem doesn't mean you refactored in the right way. Knowing something needs fixing is different from knowing how to fix it. Sometimes your next attempt isn't even an improvement on the last issue.

That said, it's is a clear improvement over Waterfall. It's easy for Extreme Programming to beat Waterfall in the same way that it's easy to beat a blind man in boxing. Just because you won doesn't mean you're any good.

Waterfall is always bad, but there's "good" Extreme Programming and "bad" Extreme Programming. Whether or not Extreme Programming works depends heavily on how you skip between the different ballistic steps. Sometimes you start in specs and move directly to implementation, then before you even get to test, you detect a problem in design. You fix the design problem, quickly make an implementation fix to reflect it, and then test it. In you can skip from any step to any other step if you are truly following the fast turn-around tenet to its optimum. In other words, Extreme Programming is just another name for:

Cowboy Coding

Losely put, Cowboy Coding is a system in which "every man does as he sees fit." No system can ever tell you the optimal way to construct the program. There will be speccing, design, implementation, and test, but who knows in what quantities and chronology. Good programmers just know from experience and intuition when to move to the next step. Now cowboy coding is used pejoratively by some programming methodology evangelists, especially those in the Agile community (a subset of extreme programming). When bad programmers try to use Cowboy Coding, the result is always a train wreck. But ironically it's the only good part of Extreme Programming, even if its proponents don't realize it. Think about it like this:

Software design metholodigies instruct programmers when to switch from one ballistic step to the next. Sometimes the methodology's suggestion is optimal and sometimes it is not. Good programmers will generally outperform the methodology's suggestions and almost never do worse. Bad programmers don't know why the next step is the correct one, so even if the methodology suggests the right step, their chances of doing the next step well are low.

You can lead a man to reason, but you can't make him think.

No amount of restriction on the software design process or programming language can turn bad programmers into good ones. They tried this with languages like Java and Python, and while they are fine languages, bad programmers still write equally horrific code in them. So you are better off optimizing your design process for the good programmers and letting natural selection weed out the bad ones.