Archive for May, 2010|Monthly archive page

Mea Culpa

This is a great quote:

…what really matters in programming … is realizing that the complexity of software dwarfs even the most brilliant human; that cleverness cannot win. The only weapons we have are simplicity and convention. Tattoo that on your forehead in reverse so that you always see it reflected in the screen

Coding without a license 2: Getting your license

There’s a very interesting discussion on stack overflow right now about learning how to program:  http://stackoverflow.com/questions/2823571/im-graduating-with-a-computer-science-degree-but-i-dont-feel-like-i-know-how-to

Beautiful, elegant, and smart too.Yesterday, my pair-programming partner mentioned that he thinks code should be art.  A few weeks ago, another programmer said she wanted to write beautiful code.  These are awesome goals, and I it made me happy that they even realized these are laudable goals; code, application design, and a running program can (and usually should) be beautiful and elegant.

So, I’m going to start a series of posts all about beautiful coding, elegant designs, and creating wonderful applications.

The advice on the above stack overflow discussion is very good, and I recommend reading it.   A related post is Joel’ Spolsky’s excellent “The Perils of Java Schools”.

Certainly there’s nothing better for learning about how a computer works internally than programming 2D or 3D graphics routines in assembler and linking that to your hybrid C/C++ program managing the rest of your game.  If you’re using a C++ object oriented approach for the elements of your game (weapons, characters, land tiles, whatever) then you can start to get a sense of good object oriented design.

However, my understanding is that very few game programmers are doing things in assembler these days – DirectX with C/C++ is blazingly fast, and DirectX with .NET is usually fast enough and is much nicer to program in with its automatic memory management and the extensive functionality of the .NET framework.

At the heart of becoming a great programmer is – not surprisingly – a desire to become a great programmer!  You have to want to write beautiful code using elegant designs to produce wonderful applications.  You have to want to write code that you can be proud of, even years later.

It’s going to take at least 10 years.  That’s not 10 years working in a big corporation where 50% of your time is writing TPS Reports, 20% is in meetings, 10% is office gossip, and 10% 😉 is maybe spent fixing somebody else’s mess with the cacophony of 5 simultaneous conversations about TPS Reports rage in the cubicles around you.

3167591319_1b163496d9[1]

To really learn to program you need to work on things you’re passionate about – a small personal project, or better yet a large personal project.  There’s nothing better than fixing bugs in your own code 2 years later while cursing the idiot that wrote the code for not using a better design and writing some useful documentation.

image My own project was a 75,000 line artificial intelligence natural language application written in C++ (and later migrated to C#) that I started shortly after graduating university.  It was really hard and I made a lot of mistakes.  I fixed them.  I made more mistakes, and cursed myself for repeating some mistakes, and then I fixed them.  Over 3 years I worked on this project a lot; I learned a lot.

Similarly, back in high school and university I programmed games.  I made a lot of mistakes there too, and I learned a lot.  A few years ago somebody said to me, “I wish I had your knowledge of computers”.  I replied, “It’s easy, just devote years of your life to programming something you’re passionate about.”  He didn’t seem interested, and fair enough, but that’s why I can charge a lot for my consulting time.

Of course I still make mistakes, although it’s a lot less now than I used to, and usually I make new mistakes.

I studied math at university, and the amazing thing about studying math is that you’re usually being taught things first discovered hundreds or even thousand of years ago; Newton published Principia Mathematica over 300 years ago!   Computer science and object oriented programming are really only about 50 years old (and yes, I’m not talking about the difference engine), so it’s only natural that as a discipline we’re all still learning.  Which, really, is great because it’s a lot of fun.

Coding without a license – ubiquitous method parameters

I saw some very poor code today, and amazingly it was written by a programmer of 10+ years.  The programmer had updated an existing class by adding a new parameter – exactly the same parameter – to each and every method of the class.  In fact, the object couldn’t work properly without this information.  Here’s my Java pseudo-code version of the updated code:

public class Before {
    public Before() {...}
    public void SomeMethod(int x, int y) {...}
    public void AnotherMethod(int x, float y) {...}
    public void AThirdMethod(int x, String a, String b) {...}
    public void YetSomeOtherMethod(int x ) {...}
}

He had also deprecated all the previously existing methods, figuring I guess that he could simply force all users of this highly shared component to update all their code.

I politely pointed out that if the data was always required, perhaps it would be better to require the data in a constructor.  Here’s  my Java version of the same change:

public class After {
    public After(int x) {
        this.x = x;
    }

    public void SomeMethod(int y) {...}
    public void AnotherMethod(float y) {...}
    public void AThirdMethod(String a, String b) {...}
    public void YetSomeOtherMethod() {...}

    // A new immutable variable, which completely
    // eliminates the pervasive x parameter
    private final int x;
}


This has a number of benefits:

  1. It simplifies the method signature of every method in the class
  2. It eliminates the need to check the parameter’s validity in every method. Instead, the parameter can be checked once by the constructor.
  3. It allows the variable to be frozen to avoid accidental tampering – in this case using Java’s “final”, but this can also be done in C#’s using “readonly”, or in VB.NET using “ReadOnly”.
  4. There is no need to deprecate all of the existing methods
  5. It may be possible to leave previous constructors in place and assume a reasonable default, or even use the C++/C#4/VB.NET feature of default parameter values to reduce rework (although this requires a re-compile).

In this case, the change was even more egregious because the class was actually implementing an interface, and the programmer had updated the interface.  Updating the interface required all implementations of the interface to pass in the “x” parameter – but “x” was an implementation detail!  So the other implementations didn’t need anything to do with “x” whatsoever!  (“x” wasn’t an integer in the real code).  Instead, using the constructor approach above, any consumer of the interface remains unchanged, and other implementations that do not rely on “x” also remain unchanged, so the impact to the API and the many, many applications that depend on the API is much less.

Think before you code, and document as you go.

Paradigm shift

For a few years I was both a Java and a .NET expert – I was even got certified in Java and got something like 98% on my test.  I made most of my consulting money off Java and its complexities – especially around the early versions of EJB and any IBM software; unfortunately I’ve had to let the Java expertise slide a fair bit to get really good with .NET.  Learning LINQ, WPF, and all the amazing new stuff in .NET 4 including the BCL improvements, language improvements, dynamic programming,  and Parallel programming with .NET 4, takes a lot of time, and with a social life that I don’t want to die completely, and three wonderful children and my beautiful/wonderful wife something had to give.

Back around 2005’s I decided to start really focusing on .NET because Microsoft really seems to care about making developers as productive as possible – every new release makes programming even easier and faster.  This makes sense, because they care deeply about having developers build great products that run on their platforms.

While Java lets me run “anywhere”, the Java platform folks just don’t seem to care about my productivity anywhere near as much as the folks over at Microsoft.  (Nor does Java have anything near as cool as WPF for building amazing applications.)  It will be interesting to see how Java evolves now that Oracle owns Java (what the hell was IBM thinking?!) and James Gosling has left the company.  Interestingly, Microsoft often lags behind Java in adding new features, and it seems to me that the Microsoft folks learn a lot from Java’s exploration of new ideas.  However Microsoft also adds lots of new stuff such as LINQ, WPF, and now the DLR.

I’ve also glanced at Ruby and Python a few times and lots of people seem to love them and I’m sure they’ are very cool languages, but I just don’t have time to become very proficient, and they don’t seem like enterprise/commercial software languages (certainly I have never seen a consulting job with Python).  An amazing graphics designer I know tells me that ActiveState’s Komodo is an amazing IDE, but I just don’t have the time anymore to pick up a new IDE, new language and a new platform.

As for JavaScript/JQuery/HTML/CSS I would love to learn these, but it takes 10 years to become a master of something, and – you guessed it – unfortunately I just don’t have the time.  These technologies – more than any other I think – are changing very rapidly, especially with the introduction of new browsers and HTML 5.  Additionally, there are lots of web designers with fine arts degrees that can draw circles around me with Photoshop and makes things look much better than my “command line” like view, so I’m happy to hire them to make things look good visually – I’ll focus on making elegant code and building applications that add business value.

So when a friend was telling me today that he’s trying to learn all these different technologies it gave me pause for thought.  For me personally, I’m not happy being a jack-of-all-trades; I want to be a master of at least platform, because that means I build applications quickly and elegantly that help solve a business or personal problem.  And being a master in just one platform still requires being a master of OOAD, design patterns, unit testing, debugging techniques and general problem solving, deployment techniques, database design, etc.  And off course these additional skills are usually easily transferable or “leveragable” if a paradigm shift to a different platform is required or desired.

So I responded to my friend that the language he chooses to become really proficient in largely depends on his goals. It seems to me that if you want to build a cool new open source technology that you tinker with in your spare time then Ruby or Python using Komodo are your best choice. If you want to be a web developer then be a great web developer and master Photoshop while you’re at it. If you want to build serious commercial applications then learn .NET.  (My friend is proud-to-be-cheap, so I directed him here: http://www.microsoft.com/Express/.)  And if you want to build applications that can even run on your toaster, learn Java, but be prepared to write a lot of code.

Update:

This was referenced by the morning Code Project e-mail:  http://iamgabeaudick.tumblr.com/post/576987756/which-language

Design Patterns

Amazingly, there are still many developers out there that have never read Design Patterns Elements of Reusable Object-Oriented Software:

image

This book was the start of the design patterns revolution, and if you haven’t read it yet and you are serious about writing software, you should stop reading your Star Trek fan fiction and instead rush out to buy this book and read it.  But, with two caveats:

  1. Do not read it cover-to-cover – it’s just too dry and you’ll find yourself consuming large amounts of liquids (H2O or C2H5OH) just to get through it.   I mean seriously, I’m a pretty hard-core geek and I still didn’t want to read this book cover-to-cover.  Instead, I read the introductory chapters in their entirety because they were interesting, and then I just read the first page and a half of each “pattern chapter”; this approach gives a nice overview of the available patterns.  Then, when you’re working on a problem and get that nagging “I’ve seen this before” feeling, you can flip through the book, find the relevant pattern and read the now suddenly interesting chapter in its entirety, solve your problem 10 times faster and more elegantly than you would have otherwise, and THEN you can go out and sip your liquid of choice with your many happy friends on a sunny patio.
  2. Do NOT read this book and then attempt to apply every pattern to your code in the next month.  Seriously.  This book is full of awesome ideas, many of which I have used many times, and some of which I still haven’t needed to apply.  This book provides you with a toolbox of great solutions to apply to very specific problems.  Don’t go looking for problems that need a solution.  I knew a guy that read this book, and then applied one pattern to his code every day for the next month, whether the pattern was relevant or not.  It made his code really, really bad.  Please don’t do this.  If you do, people will think your code stinks, and then probably think that you stink, and then not even the ugly girls (or boys, whatever you’re interested in) will want to dance with you at the next company party, and pretty soon you’ll find yourself all alone because everybody moved to a new corporate headquarters and forgot to mention it to you – all because you decided to apply these design patterns where they weren’t appropriate.
  3. Go to #2.  Then go study up on infinite loops.