Recently in Software Development Category

The Atlassian Dragons Exercise

|

The installation process for the Atlassian Starter suite - Crowd, Bamboo, Fisheye, JIRA, Greenhopper and Confluence - is quite daunting and takes about 5 hours+ (way more on my Parallels VM setup, but I did expect that).

It's obvious that the different Atlassian products have been built by different teams, at different times and sometimes even different companies. Although, AFAIK, all products are built with basically the same base technology (J2EE), each product has some minor differences in

  • Installation
  • Configuration
  • Directory set-up
  • Starting up / Stopping products (e.g. there's no shutdown command for Crowd, Bamboo automatically installs as a service)
  • Configuration files

If the suite has to be installed manually, consistency in the setup process trumps everything. This is even more relevant if the suite is installed by a non-IT, non-Java plain old-fashioned C++ hacker like me.

Generally, editing the configuration files was no big deal, although the sheer number of changes necessary induced cross-eyes at times.

Including Crowd into the installation process made the setup process quite involved and complicated. Although single sign-on is quite a feature, I wouldn't consider it crucial for a 10 user set-up. I would've preferred to make integration with Crowd an optional exercise. Plus, removing Crowd from the standard equation would have enabled more detailed feedback on setting up the different applications's integration features.

Kudos to the Atlassian documentation team responsible for the detailed step-by-step descriptions. It was close to perfect, just very very minor errata in terms of version numbers. A few more screenshots would have been helpful, but would have made the endeavour of documenting the suite's installation process not only daunting, but outright impossible to maintain over time.

I was very disappointed that Crucible was neither part of the exercise nor part of the $10 offer. Atlassian, please make Crucible part of the Dragons exercise and part of the $10 / 10 users offer. I'm sure there were very good technical and/or business reasons not to include it, but if the Atlassian team can pull of a stunt like the Dragons exercise, I know they can pull off including Crucible, too. It just takes a few more beers, I suppose. German beer, of course. :-)

English as a second language

|
Jeff Attwood - The Ugly American Programmer:
Advocating the adoption of English as the de-facto standard language of software development is simple pragmatism, the most virtuous of all hacker traits.
Let's face it: If you aren't able to read & write English in a reasonably fluent fashion, you're in trouble - you won't be able to participate in any discussion or project on a global scale. Plus, you'll be late to every party - and you like the latest fad as everyone else, don't you? Yup, this requires some work on your behalf. Get over it and start working on it. Right now.

On Functional Specifications

|

Reading through Christoph's take on Joel's latest "How to be a Program Manager", I stumbled across the term "Functional spec".

Coming from a C.S. background (admittedly, a sin of my youth), I continue to struggle with the term "specification", as I associate it with

I don't think you can fully understand the problem domain, the software to be written and it's interaction with users or other systems by creating a text document in plain English (or any natural language of your choice) deliberately sprinkled with some graphics - of course you can't do it with predicate logic either.

The main reason is that while creating your "specification" you will lack the feedback you get from actually implementing the system and from putting your code in front of users. This is way more valuable than sitting in an ivory tower waxing eloquently about a system's intended features.

So I suggest to put another label on the document Joel is talking about - "Functional Overview", "Functional Description" or "Functional Outline". Don't burden a useful document and its intended purpose with putting an inappropriate and misleading label on it.

Now that we this issue out of our way, we can start having a more useful discussion about what to put in the "Functional spec", err, "Functional Overview". Here's my take on it:

Here's what we know now. This is what we have to be aware of when starting out. This is how the interaction with the user might work out. Here are the external dependencies on other systems.

Just write enough "Functional Overview" that you are confident in your ability to move through the problem domain and take turns as you learn new things implementing the system and putting it in from of customers. You will be way better off investing your energy in defining the expected inputs & outputs of the system (and its components) as automated functional, acceptance and unit tests. And getting the system out to users & testers in order to get real feedback of a real system and learn about the shortcomings of your initial specification.

There. I said it.

Effective C++ - Third Editon

|

Re-Read Effective C++, Third Edition by Scott Meyers over the weekend - a fantastic book about the intricacies of C++.

The very existence of such a book is a testament to the many things which are wrong with C++.

[Update: As I'm writing this, Burce Eckel has posted a thoughtful article about The Positive Legacy of C++ and Java - which approaches the topic of C++ being a complex & convoluted language from a different angle]

[Update: John D. Cook mentions another interesting post (dating back from 2007) on this very topic]

[Update: The C++ FQA Lite sums up the main intricacies quite nicely]

Is Quality Dead?

|

This looks like the start of an extremely interesting series: Quality is Dead #1: The Hypothesis.

Another factor contributing to this crisis are insanely short release cycles (even for desktop software) and the expectation that each major update has to introduce substantial new features. Lot's of them. There's no more time to polish & deepen existing features.

Be liberal on what you accept...

|

In stackoverflow podcast #36, Joel & Eric are waxing eloquently about how adhering to the principle


Be liberal on what you accept and conservative in what you send.

causes massives problems for Web browser developers. While I understand that having a strict HTML / Javascript parser would ease our pain as engineers tremendously, I would argue that this very principle actually caused the explosive growth of the web in the first place. It opened up building web pages to thousands, if not millions of people whose brains aren't wired in the strange ways tradional programmers' brains are wired. A strict HTML parser spitting out cryptic error messages (and that's all you get from a strict compiler, trust me, I've seen them all) would have stopped them dead in the tracks.

Jeff Atwood has a slightly different, but interesting angle on the topic.

Just to beat an already dead horse into the ground... :-)

Why Unicode isn't enough

|

A birds-eye (but nevertheless important) view of why "Just use Unicode" isn't the solution to all i18n problems: Pet Peeves - Unicode.

(Via Sam Ruby.)

Google Guide to Writing Testable Code

|

Solution vs. Feature Requests

|
Quit Putting Your Solution In My Feature Request! Getting feature requests instead of solution requests - priceless.

Looks like...

|
...somebody touched a nerve with Uncle Bob:

Do you want to know the real secret behind writing good software? Do you want to know the process that will keep your code clean? Do you want the magic bullet, the secret sauce, the once and for all one and only truth?

OK, here it is. Are you ready? The secret is…

The secret is…

Do a good job.

Oh, yeah, and stop blaming everything (and everybody) else for your own laziness.

And to do a good job, you gotta work hard on improving your code and your skills. Every day. What did you learn today that makes you do a better job tomorrow?

Animated sorting algorithms

|

Animated Sorting Algorithms.

For those who haven't read neither "Algorithms and Data Structures" by Niklaus Wirth nor "Algorithms in C" by Robert Sedgewick (both available in our companies engineering library).

(Via Ned Batchelder)

Create your own Version of Microsoft BASIC for 6502

|

This is just amazing:

Create your own Version of Microsoft BASIC for 6502.

Even if you haven't experienced these systems yourself, you have to appreciate the amount of work which is put into these posts and in documenting these antique systems.

More on painted on the inside

|

A thoughtful elaboration by Sarah Allen on why it pays to "paint your software on the inside".

Steve Yegge talks about me...

|

...embarassing.

Make sure to read it all the way to the end. Here's a fantastic quote

You'd be absolutely astonishedly flabbergasted at how many programmers don't know how to READ.

On bugreporting

|

Painted on the inside

|

Great post by David Weiss: Painted on the inside.

If there's only one thing you need to read today, than this is it.

Software hygiene?

|

Seth Godin - More vs. enough.

Great thought to start the day.

The Null Pattern is a Good Thing

|

Time Management - The Trickle List

|

Well worth a read for anyone interested in time-management: The Trickle List.

Tiny Types

|

Tiny Types - Going overboard with classes? I don't think so. The real problem is that it's ways to expensive to add a new class to the system in C++.

How do we make it cheaper?

Embedded Smalltalk?

|

A Smalltalk implementation which is explicitely targeted towards embedding in other applications: Smalltalk YX. Sounds great.

(Via James Robertson).

The secret of the web

|

Seth Godin: The secret of the web: Patience.

I wonder if this is the secret of the web or something bigger (software development, success, ...). You name it.

iPhone Apps & Hamburgers

|

TechCrunch: iPhone Apps: One Month And 60 Million Downloads Later. But Not One Of Them Is A Killer App.

If an application is 99 cent, it doesn't matter if it's a killer app.

A hamburger is 99 cent, too. It disappears in a few seconds. Why wonder about applications which are 99 cent? If I'm using the application for more than 60 seconds, it's a great deal. If I'm using them for a few minutes, it's a fantastic deal. That's way longer than it takes to wolf down the hamburger. I may even have fun using the application. Plus it's way healthier...

So, why bother?

Fantastic Series on Concurrency...

|

This looks like a stupendous blog...

|

...for Real Programmers:

pagetable.com - Deals with such topics as the 6502 illegal opcodes etc.

Comments

|

Jeff Atwood hits the nail on the head - Coding Without Comments.

Erlang screencast...

|

Erlang By Example with Kevin Smith.

Sounds like a great way to get an overview of Erlang.

(Via Announcing Pragmatic Screencasts!)

Interview with Donald Knuth

|

Here's a very interesting (and partially controversial) interview with the man himself, Donald E. Knuth.

My, let's say rocky, relationship with the work of Donald Knuth started when I was forced to write a lengthy paper using TeX and vi on a SUN 3/60 workstation during my stint at the University of Karlsruhe.

Looking back, I don't know if I should blame TeX, vi or the crappy windowing manager on the SUN or the combination of all three factors which made this a nerve-wrecking experience.

:q!

Home Simpson - Done in CSS

|

There are folks who have too much time on their hands.

I'm jealous.

On reading

|
People Don't Read - Nothing to add here / Dem habe ich nun wirklich gar nichts hinzuzufügen.

Those were the days...

|

It's Always Your Fault

|

This one is too good not to pass on....

|

On a lighter note...

|

Game over.

Yes, indeed.

Joseph Weizenbaum passed away

|

Back in the days when Borland was at its prime (yes, this was right after the Paleozoic era), I had the distinct pleasure to attend a Borland conference in Munich with Joseph Weizenbaum and Marvin Minsky as keynote speakers on Artifical Intelligence - I've never heard again two über-smart speakers going head-to-head on the same topic with such an enormous breadth and depth - and from two radically different angles. I was (and am) deeply impressed by both of them.

Weizenbaum's voice will be missed.

io language

|

I stumbled across a new scripting language: io.

Looks promising.

Is this cool or what...

|

My take on FlickrFan

|

FlickrFan.

Fantastic idea, crappy implemention.

What a fantastic idea - Streaming Flickr photo feeds to either a screen saver, HDTV or a digital picture frame. Simple, but effective. Stupendous. Can't say enough good things about it.

But boy, does the implementation suck. And I'm not talking functionality here - I'm talking about everything else

  • Installation
  • Look
  • Feel
  • Usability
  • ...

While I understand that it's very tempting to whip up a working prototype in a non-mainstream scripting language in no time, such a prototype shouldn't be released.

Dave, hire a group of smart students for 2 months and let them do a real, polished, native application for MacOS, Windows & Linux. Think about the leverage such a native application would provide for FlickrFan.

I fondly remember the days when you did real, polished applications for real users.

Disclaimer:

  • I'm not saying FlickrFan sucks
  • I'm not saying Frontier sucks

Being an idiot...

|

You know what's really annoying? Wearing both hats - Being both the engineer explaining things to idiots and being the idiot making bad decisions based on the things explained to me.

Check it out here.

How Big Should a Function Be?

|

Uncle Bob: How Big Should a Function Be?.

There's nothing to add to this post and nothing to trim from this post. Right on target.

On O(n) notation

|

Jeff Atwood: Everything Is Fast For Small n.

On a lighter note, O(n) notation is not related to inlining code in header files.

November, 9th

|

Uh oh.

Must resist urge to run to the T-Mobile shop around the corner right now. Must resist...

Assembler programmers don’t have groupies

|

Password / Rainbow Tables / Hashes

|

Essential - Critical - Must have

|

Hilarious. Wie aus dem Leben gegriffen.

There's a nice meme going on about What I am doing to become a better developer?. Sounds like a great question to meditate over while vacationing in Rhodes for two weeks :-)

If you happen to be trapped in the office, it's still a very worthwhile question to ask yourself. Plus, as a bonus, you get to read a great review of Working Effectively with Legacy Code.

Understanding Engineers: Feasibility

|

Pitr & Sid coding on an Apple II

|

Start here. Click "Next Cartoon" to follow the story.

You may want to guess who I cheer for (being an old geek myself who started coding on the Apple II in 6502 assembler - well, those were the days).

The Humble Dialog Box & more...

|

Even if you are not into .NET, WinForms etc. this series by Jeremy D. Miller is a great one to follow. Posts so far:

Plus, as a bonus, you will notice that Jeremy is not afraid of using really long function names:

void CloseTheScreenWhenTheScreenIsDirtyAndTheUserDecidesNOTToDiscardTheChanges()

And I'm mentioning this not to make fun of Jeremy.

Excellent tip

|

I'm not a tester

| | Comments (1)

Erkan Yilmaz tagged me with a few questions regarding testing. However, I'm not a tester, I just happen to be interested in some areas of testing, e.g. unit testing & test-first-coding.

Could you tell something about your first tests?

I started getting interested in unit testing in the late 90s when XP came up. Still not 100% sure about where unit testing ends and acceptance testing begins.

What would you like to highlight as an important thing of testing - from your personal experiences?

As far as unit testing & test-first-coding is concerned, the most important aspect is "Just doin' it even if you think you can't do it".

Why is testing not trivial?

Testing is always hard for a software developer because his/her brain knows about the inner workings of the code and therefore it requires an enormous amount of discipline to thoroughly test the code.

Test-first-coding is hard because it requires to change your mind set from testing as an afterthought to testing before you start coding.

What do you do after testing at work?

Coding :-)

How do you think testing will evolve in the next 13 years?

Most of the kind of testing I'm interested in very much depends on the way the code is structured. So I would guess that the most interesting things will happen round tools & patterns which enable testable code.

Mäschaps...

|

Frank Westphal on Mashups: Remix me! (Wer nicht weiß, was mit Mashups gemeint ist, sollte den Artikel erst recht lesen - sogar auf Deutsch)

Advice on How to Become a Programmer

|

Software by Rob: Advice on How to Become a Programmer:

What made me a good programmer was not my knowledge of each language, but my desire to understand and refine concepts like D.R.Y., the broken window theory, and code re-use.

RIAs

|

Here's a nice write-up on Adobe's Apollo project: Why Apollo?.

Forth

|

Here's a fantastic introduction to Forth.

Forth, you may ask? Yes, Forth. Used in Open Firmware, for example.

Balls...

|

I sure like drastic metaphors when talking about software development, but it looks like I have a long way to go: Keep 'em clean, boys..

The Great Variable Shortage

|

Interesting Point of View on OO-Principles & Testing

|

Roy Osherove on Object Oriented Testable Programming:

...in many ways, pure object oriented design does not go well hand in hand with the notion of testable design.

Uh oh...

|

Bratt McLaughlin wonders: What's XML really good for?.

Indeed. Most of the time, XML looks like overkill to me.

Great Quote

|

Jeff Atwood:

"A smart software developer knows that there's no point in writing code if it's code that nobody will see, code that nobody will use, code that nobody will ultimately benefit from...A smart software developer realizes that their job is far more than writing code and shipping it; their job is to build software that people will actually want to use. "

Tog on iPhone

|
User interface guru Bruce Tognazzini talks about the iPhone.

Why Size Matters

|

Bob Koss analyzes why long methods and large classes are bad: Size Matters.

Amen.

Orthogonal Code

|

Excellent, albeit quite lengthy post by Jeremy Miller on Orthogonal Code.

Get a coffee and read it. You may learn a few things along the way (or get reminded of a few things, which isn't bad, either).

Moving to multi-core CPUs and 64bits HW/OSes

|
Here are two great pieces talking about the challenges of taking advantage of new hardware technologies in the context of a large application. Highly recommended.

Managing expectations

|

Another great post from Creating Passionate Users: Don't make the Demo look Done.

But you have them in your reading list already, don't you?

On Simplicity

|

Here's a great read by Don Norman: Simplicity is highly overrated. After you digested it, make sure to read Joel Spolsky's comment: Simplicity.

On comments

|

Jeff Atwood: Code Tells You How, Comments Tell You Why.

Indeed, this is a fantastic comment:

/* A binary search turned out to be slower than the Boyer-Moore
algorithm for the data sets of interest, thus we have used the more
complex, but faster method even though this problem does not at
first seem amenable to a string search technique. */

However, I would suggest not to add the comment

# Reverse the string

to document the Pearl statement

$string = join('',reverse(split('',$string)));

I would prefer to wrap the code (even if it is a one-liner) into a function `reverse_string()` instead. That way, we got rid of a comment and reduced duplication in the code.

Skype / VOIP & NATs

|

Here's a great write-up of the trick Skype uses to get through firewalls.

(Via Don Park's Daily Habit.)

Advice for Writing Shrinkwrapped Software

|

Writing Shrinkwrapped Software - Although somewhat Windows / .NET centric, it contains some real gems. Recommended reading.

(Via Software by Rob.)

Too many features / choices

|

Excellent post by Joel Spolsky:

This highlights a style of software design...driven by a desire for consensus and for "Making Everybody Happy," but it's based on the misconceived notion that lots of choices make people happy, which we really need to rethink.

The Wrong Duplication

|

Stupendous post by Kevin Rutherford on why it's important to look beyond mere code duplication: The wrong duplication.

Great advice...

|

...by The Braidy Tester: R E S P E C T.

No, this isn't a subtle hint to anybody in particular. It's just a great post on a very important topic.

"Getting Real" book gets real

|

Looks like the book "Getting Real" finally got real. Note to self: No excuses anymore.

Threads in C++

|

Very cool stuff: Trip Report: Ad-Hoc Meeting on Threads in C++.

I recommend to have a good breakfast first (I read it at lunch time and had stir-fried noodles first). Then grab a cup of coffee. Breath in and out. Sit down and read.

A timeless classic: How to Shoot Yourself in the Foot in Any Programming Language

Pretty up-to-date including Ruby, Python etc. Love the Unix one, though. MacOS 7/8/9 are cool, too.

Blaming users

|

Creating Passionate Users: "Oops... we forgot about the users.".

Hmm. I can't plead I'm innocent, your honor.

Creating Passionate Users on empowering users

|

When Understanding means Refactoring

|

Jeff Atwood on When Understanding means Rewriting:

"It's not that developers want to rewrite everything; it's that very few developers are smart enough to understand code without rewriting it. And as much as I believe in the virtue of reading code, I'm convinced that the only way to get better at writing code is to write code. Lots of it. Good, bad, and everything in between. Nobody wants developers to reinvent the wheel (again), but reading about how a wheel works is a poor substitute for the experience of driving around on a few wheels of your own creation."

When I try to understand a given piece code (most embarrassing, my own code written a few months ago), reading the code doesn't cut it. Instead I try to nibble around on the edges, working from the inside out:

  • Looks like the one who wrote the code was short on vowels & consonants for variables - Let's try to change that - Ah, it still compiles. Cool.
  • There are these two lines of code I understand - How about making that a method
  • Looks like there's a comment describing what's done - Maybe I should try to extract a method
  • There's a certain piece of code used over and over again, maybe I can try to extract that?
  • Is this method called from other places too? What do these other places feed in there as parameters?
  • There's this weird global (singleton) there, why is it needed? Let's change its name. Ah, the compiler tells me where it's used elsewhere in the system
  • Stepping through the code in the debugger, I get a picture of the state of variables
  • ...

With every tiny step, I gain understanding. Little by little. After understanding this one method, I'm in better shape to understand the next one - Or even the object the method belongs to. Now I apply similar tiny baby steps to classes.

My suggestion is to refactor in order to understand the code instead of rewriting it.

Yup, backing up these refactorings with unit tests is a great idea - but I can still back out from fiddling around with the code without the tests, start the refactorings from scratch, with unit tests - but with some increased knowledge about the system.

Niklaus Wirth books

|

Chris Hanson notes that some of Niklaus Wirth's books are available online (for free).

If you want to read one (very approachable) book on compiler construction, read Compiler Construction by Niklaus Wirth. Excellent stuff.

Comment Smell

|

Here's some code from the rather interesting blog "Extreme Programming - Simulating an XP project":

public string SaveToXml()
{
    XmlDocument document = new XmlDocument();

    //Create a root node called task
    XmlElement rootNode = document.CreateElement("Task");
    document.AppendChild(rootNode);

    //If the name exists, store this information
    if (this.Attributes.Contains("Name"))
    {
        //Append the name information as an attribute
        XmlAttribute nameAttribute = document.CreateAttribute("Name");
        nameAttribute.InnerText = this.Attributes["Name"].ToString();
        rootNode.Attributes.Append(nameAttribute);
    }

    //If the creation date exists, store this information
    if (this.Attributes.Contains("CreationDate"))
    {
        //Append the creation date information as an attribute
        XmlAttribute creationDateAttribute = document.CreateAttribute("CreationDate");
        creationDateAttribute.InnerText = this.Attributes["CreationDate"].ToString();
        rootNode.Attributes.Append(creationDateAttribute);
    }

    //If the due date exists, store this information
    if (this.Attributes.Contains("DueDate"))
    {
        //Append the due date information as an attribute
        XmlAttribute dueDateAttribute = document.CreateAttribute("DueDate");
        dueDateAttribute.InnerText = this.Attributes["DueDate"].ToString();
        rootNode.Attributes.Append(dueDateAttribute);
    }
}

It's a rather typical example for a "Comment smell":

  • The comments are not needed because the code communicates very clearly what is done (even to someone like me who's not an XML-Guru at all)
  • If the comments are not needed, we should get rid of them because they pollute the code plus they will get out of sync with the code in the long term (Can you say "Cut/Copy/Paste"? :-)

Plus, the comments are hints on potential refactorings like extract method.

Excellent Blog on Testing

|

Michael Hunter is doing a great job with his blog: THE BOOK OF TESTING - Thoughts From a Braidy Tester.

This is required reading for everybody involved with software testing.

I have setup (and will maintain :-) an RSS feed for all entries in the "You are not done yet" category of this blog.

SugarCRM.

Interesting. To my (limited knowledge), the closest thing to an open source, vertical business application.

Removing duplication

|

Ivan on Programming in the small - removing duplication:

"Look out for duplication - it might be telling you something"

Interesting observation: Removing duplication isn't about removing redundancy only, it's about migrating towards a better, more object-oriented design, too.

Food for thought

|

Michael Feathers: Designing Away Preconditions.

Conditionals

|

This time, I have nothing to add or to pick on: Ivan Moore on Conditionals.

Stupendous. Looks like he's listening when I preach to our apprentices.

Veni. Vidi. Codi.

|

Asterix. There's no doubt that this comic must be part of the most basic education everybody receives:

Veni. Vidi. Codi.

Functions as first class-citizens

|

Joel Spolsky on functions as first-class citizens in a programming language.

Highly recommended.

// End if

|

Andrew Forward on

if {
...
} // End if
It is comments like this that are absolutely a complete waste of time. Comments should be written to help other developers run through your code, not to show your boss that this curly brace closes off the the if above, whereas that curly braces completes the while loop.

Maybe those comments are needed because the if/while { ... } statement spans more than a few lines - which is a strong indication that the method should be broken into smaller, more digestible pieces.

Incremental vs. Revolutionary Improvements

|

Creating Passionate Users:


Our users will tell us where the pain is. Our users will drive incremental improvements. But the user community cant do the revolutionary innovation for us. Thats up to us.

Ignoring the competition

|

Creating Passionate Users on ignoring the competition.

12 Benefits of Test Driven Development

|

J. Timothy Kingblogs about 12 Benefits of Test Driven Development:

The first thing you ask is not “What code will I write?” The first thing you ask is “How will I know that I’ve solved the problem?”.

(Via MemoRanda.)

Test-Driven Development

|

Oren Ellenbogen started a great series of posts on Test-Driven Development. Well worth following:

(Via ISerializable.)

Getting Answers

|

Mike Ash on getting answers (to programming questions via IRC). Good stuff.

Some of his advice applies to old-fashioned e-mail questions, too.

Activity-Centered Design

|

Programming & Typing

|

Keith Ray and Chris Hanson (and others, I bet) have commented on Bruce Eckels post "Programming as Typing".

I would like to take this (wrong - as those fine gentleman have proven) analogy and add a slightly different twist to it - and thus prove that, if viewed from a totally different angle - the analogy works just fine.

(For the sake of simplicity, let's assume that "typing" means "typing & clicking").

If you're not typing, you're not programming - If you're not typing, you're not making any progress. Sounds rather obvious, doesn't it? It's not.

I've seen it over and over (both by observing others and - in rare moments - myself) that a software developer who doesn't type, but sits in front of his computer thinking about the problem at hand for more than 2:30min (I made this number up at this very moment :-) is not actively developing software.

He is stuck.

  • Because he's not typing, he is not using all the feedback the code can give him on how the problem should be solved.
  • Because he is not typing, he is not actively playing with different approaches to the solution - he is just thinking about the different approaches. He's making up a mental model of the code - and more often than not, this mental model is rather different from what the code does (This happens to the best of us, doesn't it?).
  • Because he's not typing, he is not using the feedback which comes from writing & running a simple test. He is not trying to solve a small chunk of the problem to get a deeper understanding of the larger problem.

Typing is more closely related to software development than you think.

(There may be others who frantically scribble boxes on a sheet of paper for more than 2:30min - those are stuck too, not as stuck as those just mediating, but still stuck)

(Of course, this doesn't apply to you if your belonging to the elite group of geniuses - but that's only about 0.0001% of the software developers out there)

Closed-Source Cocoa

|

Andy Dent asks: Closed-Source Cocoa - Arrogance, Empowerment or Commercial Necessity?

Cocoa (and its predecessor NeXTStep) never shipped with source code. I remember seeing one of the early (very impressive) demonstrations of NeXTStep back in the late '80s and the source was closed right from the start. I brought up the question about availability of the source code (I was a MacApp developer back then, a Object Pascal/C++ framework which shipped with source code). The NeXT engineers said that there's plenty of documentation available and if they would make source code available, developers might rely on certain, undocumented behavior which is only revealed by looking at the source code.

So I guess it's just paranoia - which I consider unfortunate. Despite a great community, excellent documentation and superior technical support the availability of source code is extremely import for solving problems efficiently when developing with a framework.

On code formatting issues

|

Jeff Atwood wonders:

The code formatting, as promised, is pretty. But the emphasis on formatting does make me wonder-- rather than focusing on the external, cosmetic attributes of the code, shouldn't we be searching for something prettier on the inside? Such as a higher level language?

I used to be a code formatting fetishist. I remember spending ages on nicely formatted parameter lists, comments etc. Not to mention the dreaded pascal.h incident. About 20 years later, I find:

Placement of curly braces is really relevant if the while loop in question includes multiple nested if's and thus spans several pages. But if this very same piece of code is properly refactored, it's probably a collection of very brief functions/methods & classes. Now the functions are short and to the point - and the code's formatting doesn't really matter that much anymore. Who cares where the curly braces are if the method is about 7-10 lines?

If the code's formatting is consistent, the code is properly refactored and functions, classes & variables names precisely reflect the concepts they represent - what more can you ask for? The real beauty comes from within: The structure of the code.

(BTW, it took me years to come to that conclusion - and, from time to time, I still reformat legacy code I work with - old habits are hard to break :-).

Very interesting gem on binary seaches.

(via Bill de hÓra).

Automating "All" Tests

|

Ron Jeffries:

"Sure, test automation is a good thing. But we can't, and shouldn't, automate them all. Why then, ask people to 'automate all tests'?"

The YAGNI Development Assistant

|

Very Cool: The YAGNI Development Assistant.

Mising in both Visual Studio 2003 & Xcode 2.3.

(Via Jeremy D. Miller)

Programmers and Chefs

|

Jeff Atwood elaborates on Programmers and Chefs inspired by the Ron Jeffries's quote I posted a few days ago.

As always, Jeff's thoughts are a great read. Plus, to kind of push the kitchen analogy even further, it's always great to come up with some vague idea for a meal and someone else is doing the hard work of actually cooking the meal (and cleaning the kitchen afterwards, of course).

Test automation capabilities

|
Another great quote by Ron Jeffries (this time picked up via MemoRanda):
"The only time not to automate a test ought to be if we are never going to want to run it again. But it isn't. The more common time we don't automate a test is because it would be 'too hard' to automate it. That is, however, not really a property of the test, though we like to put it that way. It's really a property of our own test automation capability and tools."

Code Smells

|

An excellent collection of Code Smells by Coding Horror.

Usability

|

Creating passionate users:

Make the right things easy and the wrong things hard.


On Big Upfront Design

|

Ron Jeffries (taken from an interview with Bruce Eckel):

"The reason the kitchen is a mess is not because the kitchen is poorly designed, it is because we did not do the dishes after every meal."

Hallmarks Of A Great Tester

|

Hallmarks Of A Great Tester - Great presentation by The Braidy Tester.

I also like the subtitle of his blog: Making developers cry since 1995.

Discipline

|

Smell to Refactoring Cheat Sheet

|

Nice overview of code smells and what to do about them: Smell to Refactoring Cheat Sheet.

(Via William C. Wake)

Coercing Your Developer

|

Here's a good one: Coercing Your Developer.

The Smalltalk Browser

|

Andy Dent on Object Master & the classic beauty of the Smalltalk Browser.

That's something I crave: Having a Smalltalk 3-pane browser to edit C++ code - like Object Master. Occasionally, I spent some time googling for one, but it looks like there's nothing like that out there.

Foundation

|

Here's an excellent post by Jonathan Pickup on the need for a solid foundation to successfully complete advanced projects.

I would like to add that you will need to work on your foundation, the basic skill set of your profession every day. It's one of most important things you can do.

Why face-to-face still matters

|

Another excellent post from Creating Passionate Users.

Wrapping (procedural) APIs

|

Why wrap a (procedural) API of a third-party library / host application - instead of using the API straight away? Here are some reasons plus some simple techniques to accomplish just that:

  • Wrapping the API makes unit testing much easier because you can mock your own classes instead of mocking the API itself (which tends to have more dependencies)
  • Creating your wrapper may actually deepen your understanding of the API
  • You may be able to tie up a few loose ends in the API (e.g. mix of deprecated and new API functions to accomplish a task)
  • Creating your wrapper may simplify the API (witness the change from AddPopupItem() to AppendPopupItem() in the sample provided below

Here are some simple techniques for wrapping:

  • Save on parameters - Instead of using AddPopupItem(..., long dialogID, short popupID, short insertAfterEntry, String entry) you could use MyAppendPopupItem(long dialogID, short popupID, String entry) - not a substantial improvement, but if combined with the next techniques quite powerful...
  • Transmogrify the API into an object-oriented API - Use myDialog.AppendPopupItem(short popupID, String entry) instead
  • Make it even more object-oriented - Use myPopup.Append(String entry) instead

There are a number of arguments against wrapping an API - but at the end of the day, I'm quite firmly in the "Wrap it" camp.

Illusion of agreement

|

Here's a great one from the 37signals blog: Illusion of agreement.

Darren Hobbs:

...just because all the fields (of a class) are final and there are no setters, this doesn't mean that the object is immutable.

Microsoft's Mac testing lab

|
Here's a nice tour of Microsoft's Mac testing labs - courtesy of David Weiss.

Providing Feedback with Courtesy

| | Comments (1)

I don't mind people giving us feedback on our products. I don't mind people making suggestions on how the software could be improved. I don't mind people pointing out glaring omissions, substantial flaws, bugs & crashes. I know our software has bugs, can & should be improved substantially. As Dave Winer puts it: "We make shitty software and we know it".

In fact, we rely on the feedback to provide a better product.

What I mind is the way in which feedback is provided - and 37signals post showed some of the ways. What I mind is the general attitude of somebody not involved with the development of some piece of software presuming to know that some things are trivial & absurd.

I don't talk about diplomacy - I talk about courtesy. That's something we should have learned from mom and dad back when we were kids. Courtesy doesn't come in the way of pointing flaws & bugs precisely. In fact, courtesy requires us to point out flaws & bugs precisely. Courtesy also doesn't hinder us from cursing at software developers, screaming, yelling, wonder about their stupidity or using a broad selection of four-letter words. As long as we're doing it while in a room all by ourself.

Courtesy is about treating others with the respect they deserve. Because we want to be treated the same.

Desirable Complexity

| | Comments (1)

As a developer, I face complex problems everyday (or should I say complex problems are upon me everyday? :-). I may come up with a rather lengthy serial blurb of code with a couple of conditions & loops. This blurb may neither be an object-oriented nor a clean, maintainable piece of code - yet. The code may look easy-to-understand and simple to me now because I'm still fully engaged in the problem and its solution. There are three key factors which contribute to its complexity:

  • Length of methods / scoped code blocks
  • Number of conditionals
  • Number of loops

Reducing this undesirable complexity is straightfoward: Ruthlessly reducing duplication. During this process, I will most likely introduce new methods and new classes. This sure makes the system itself more complex, too. However this is desirable complexity - complexity which can be easily dealt with in future revisions of the code. Because I reduced duplication and decoupled the different components of my solution.

Or, to rephrase it, reducing unmaintainable complexity with managable & maintainable complexity.

So for any reasonably powerful feature or piece of functionality added to a system, the code won't be simple. It will add complexity to the system. But doing it right will ensure that the system can still be dealt with in the future.

Private instance variables

|

Here's an excellent post by James Shore: Quality With a Name.

If you haven't time to read it all, make sure to read the section "Principles in Practice", where James discusses private instance variables and nails the issue right on the head.

Office 12 UI

|

I applaud the courage of the Office 12 UI team to take the risk and introduce a new UI (the "Ribbon" being the most prominent feature of the new UI) to deal with making Office more accessible, discoverable and in the very end, usable.

This is great stuff and worth looking into in great detail. Here are some great resources on the new Office 12 UI:

Great article on refactoring...

|

Here's a great article on refactoring by Keith Ray.

Excellent.

Guard Clauses

| | Comments (1)
Another interesting topic are Guard clauses as outlined in Michael Mahemoff's Guard Clause Considered Helpful. Here's my take on this topic:

How about rephrasing

void foo() {
 if (nothingToDo) { return; }
   // Implement typical behaviour of foo()
}
not like
void foo() {
  if (!nothingToDo()) { 
   // Implement typical behaviour of foo()
  }
}
but like
void foo() {
  if (someThingToDo()) { 
   // Implement typical behaviour of foo()
  }
}
The latter version avoids the double negative (thus concentrating on the standard case and not the exception), and I consider it quite readable in practice, e.g. if (resourceAvailable()) doSomeThing(). However, this will only be a viable alternative to the guard clause if foo() is very short. If foo() get's so long that using the guard clause seems appropriate because the function will be more readable, maybe it's time to take a long hard look at foo() to search for refactoring opportunities. Avoiding guard clauses may help in detecting functions which got out of control in terms of length & complexity - because there's an awful lot of "intended code" in the function.

In the end, it boils down to personal preferences. Guard clauses are probably fine as long as the length & complexity of the function is monitored closely.

More on Single-exit functions

|
Ivan Moore posed the question what happens to the solution I suggested if the function returns the result of some other function:
void foo(boolean condition)
{
    int returnValue = calculateSomeValue();
    if (condition)
        returnValue = calculateSomeOtherValue();
    return returnValue;
}

Two considerations:

First, if calculateSomeValue() is O(1) or even O(n), I would still use the proposed single-exit/no-else variation. Truth to be told, I don't even care if calculateSomeValue() is O(n*n) - I would go for the simple solution anyway. If, and only if, performance analysis shows that foo() is a system bottleneck, I would change it.

Second, if calculateSomeValue() has some undesired side-effects and thus should only be called if condition is indeed true. What's "undesired side-effect" in this context? If the undesired side-effect is performance / resource-related (e.g. calculateSomeValue() goes out to fetch some data from a database or from a web-service), then it's just a variation of the O(1)/O(n)/O(n*n) discussion above. I would still go for my single-exit approach and worry about performance later. On the other hand, if "undesired side-effect" means calculateSomeValue() does some changes to the systems state in addition to, well, calculating some value, then my suggestion is to check if this wouldn't be great opportunity to improve the design & implementation of calculateSomeValue(). If that's not possible, e.g. when working in a legacy-code environment, then I would go for the two-exits approach.

Single-exit functions

|
Ivan Moore suggests that single-exit functions should be considered cargo cult. I don't think so. My suggestion for improving his sample code is as follows:
void foo(boolean condition)
{
    int returnValue = 6;
    if (condition)
        returnValue = 5;
    return returnValue;
}
Single exit. I even managed to save on a rather confusing else. Short. Easy to read. Even easier to understand.

Anyway, as long as we're dealing with code of the complexity like the function shown, it doesn't really matter if you use the single-exit rule or not (As long as you don't work in my team :-). Single-exit becomes important if your function gets longer & more complex. However, if your function gets substantially longer and substantially more complex, you should consider refactoring it anyway.

Dependency Injection Demystified

|

Variable/Function/Object/Class naming

|

Coding horror: "Creating good names is hard, but it should be hard. Good variable, object, and function names can make the difference between Daily WTF code and.. well, code you'd actually want to work on."

Click on both links.

Short Methods and Small Classes

|

If you're used to writing & reading long methods, dealing with small methods & classes can take some time to get familiar with. Keith Ray has a great writeup on Reading Short Methods and Small Classes.

He also cites Jerry Weinberg's great test to determine if a function/method is too long:

  1. Pick a function.
  2. Understand it, what it's supposed to do, how that is accomplished.
  3. Memorize the function.
  4. Then, without looking at the original code, write the function from memory.
  5. If you've made a mistake, the function was too long, or otherwise too complex.

Ideal workplace?

|

Herb Sutter on Concurrency

|

The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software.

This is a must-read if you're a software developer or into computer science. But don't stop there. Here is great talk (for your podcasting pleasure) by Herb Sutter on this very topic (slides). It offers way more in-depth information, analysis and insight on the topic than the article.

Textboxes

|

Coding Horror:

Web Forms: Death By a Thousand Textboxes

Interesting thoughts on reducing the number of textboxes & text entry controls in a UI.

On Bugs

|
Wil Shipley:
Now, let me state something unequivocally: 98% of the time when you think you've found a bug that is not your fault, it really is your fault. The other 2% of the time... well, it's probably your fault as well.
Amen to that.

Another Take on Simplicity

|

Features & Simplicity

| | Comments (1)

Damien Katz: Why Features Don't Matter Anymore.

Excellent. Note the distinction between selling to businesses versus selling to individuals. The question is: Will selling to businesses (slowly) migrate to the model of selling to consumers or will both remain separate beasts?

On Getters

|

Martin Fowler on Getters.

Brown Numbers

|

Here's a good one: Brown Numbers.

I like it. We have lots of brown numbers, brown schedules and brown ship dates over here.

The Ten Commandments of Egoless Programming

|

Dilbert

|

This one is goooooood.

Hiring beta testers

|
Here's an interesting post by Wil Shipley on beta-testing.
It's worth pointing out that beta testing is a great way to start a career in software. It looks good on a resume, and it gets you noticed by engineers in your field -- if you submit a bunch of bugs to a company, it shows you have a keen eye and understand software, and they are going to remember your name later. Seriously, we've always known our top beta-testers by name, and they get much respect; someone might say, 'Oh, O'Donnel reported a cosmetic bug in the main panel,' and the engineers would be all, 'O'Donnel? Dang, I better hop on that!'

...

And, in turn, lots of the guys I've hired over the years first came to our attention as beta testers.
An interesting twist on the topic of dealing with beta-testers.

Specialized User Interfaces

|

Here's an interesting podcast of Brian Ferren's speech at Web 2.0.

He makes quite a compelling argument for specialized user interfaces to empower users instead of creating standard GUIs using a keyboard, mouse & monitor for computing tasks.

Although his thoughts are probably not applicable for us working in standard Web/PC-UI Environment, they resonate with the end of consistency in GUIs. Maybe those of us doing traditional desktop apps should think "out-of-the-box" when creating a GUI.

Sometimes standard Windows / MacOS controls don't cut it.

Behind the scenes at a Jobs keynote

|

Just-in-time for todays keynote of His Steveness, here's a great article on all the work that is involved in creating a Steve Jobs Keynote.

Worth reading, especially if you consider yourself to be a member of the Anonymous Perfectionist fellowship.

(Via The Unofficial Apple Weblog).

Beethoven's Piano

|

Here's a great post on the inadequacy of todays CAD tools for architects: Beethoven's Piano.

While I fully admit that the tools are not yet where we want them to be (and ours isn't different), I find that complaining about tools has a longstanding tradition, especially among software developers.

It's easy to produce crap - with any tool. First and foremost, your results depend on your personal skills (and I'm not talking about your in-depth knowledge of J2EE here, but about code-writing skills).

That's not to say that a great & adequate tool won't propel you to new heights, but if you aren't working on mastering the basics of your profession every day, changing the tool won't make a difference. It may make things worse. I would even say that the 80/20 rule applies: 80% of the result is directly related to your personal skills, 20% of the result is related to the tool you use. Which one do you tackle first?

A point worth remembering if you're involved in the daily flame wars about the merits of Java, C++, XML, Ajax, Flash, Ruby, Python etc.

Less software?

|

Tilman wonders about 37signals "Less software" approach and concludes that “Less” sometimes is - less!.

Here are a few unstructured thoughts of mine on this very topic:

  • The need to integrate a software product in a complex workflow with different, heterogeneous components makes it hard to build "less software". Interfacing with different machines, different ERP-systems is hard. And complex. Which translates into more, not less software.

  • The software 37signals creates is great stuff. The apps work beautifully. However, these are not "mission-critical" apps used by companies to run their core business processes. Plus these apps are very much targeting the "knowledge worker" who's used to work all day long in front of his/her computer. There are many users out there who don't want to spend a lot of time in front of their computer & who don't have the time to play around on their computer. Because they aren't interested in computers at all plus - more importantly - they get paid to run a business, build real products and face real-world problems. These types of users tend to expect a lot of features with minimum intervention on their behalf.

  • You may get away with less features by creating a product which appeals to both tourists & sailors as outlined in Guy Kawasaki's The Macintosh Way. However, most likely you'll end up with powerful software with a great, easy-to-use multi-level UI. To my understanding, that's not the "less software" approach 37signals is advocating.

However, I still think a lot of the "less software" concepts which came up in the context of 37signals are worth pondering and worth pursuing. Especially if you think about them as related to the well-known YAGNI principle used in XP style software development:

It's not about anticipating and building what may be needed tomorrow, it's about building great software for what is needed today.

[Update: Another twist to the topic is that the type of customer I described above wants to pay for features he/she most likely will never use, but doesn't want to pay for simplicity or ease-of-use]

Killing Applications...

|

Looks like Don Park is wondering about document-centric computing.

Don, read this first before following this road any further.

Irrelevant UI improvements

|

Don Park makes an interesting observation on the average computer user, and Dave Winer agrees.

I've rambled about this topic quite a while ago: 95% of the UI improvements in Windows Vista or MacOS X are irrelevant to 95% of the computer users out there. Why? Because they don't address the fundamental challenges these 95% face.

I would even go farther and say that 99% of all past improvements to the Windows Explorer or Macintosh Finder (remember the spatial orientation discussion?) were irrelevant to 99% of the users.

[Update: And I don't subscribe to the theory that the Web is a fundamental advance for these 95% of the users, as David Berlind notes. It's not that the desktop (OS) is flawed and the Web-based UIs change that. Web-based UIs just have different kinds of fundamental problems.]

Amazon's Mechanical Turk

|

Amazon’s Mechanical Turk. I missed that one a while back. Very, very cool. There's still a lot of manual work out there to be done, even in an IT-centric environment.

(Via TechCrunch).

Eating like a bird and pooping like an elephant...

|

Eat like a bird and poop like an elephant". A classic quote from Guy Kawasaki, whose best book remains The Macintosh Way.

Ruby interpreter in your browser

|

Try Ruby in your browser. Very cool.

(Via Bob Congdon.)

Auto-Commenting your code

|

Commentator. Hilarious.

(Via Mock Turtle Soup.)

Try wiggling the cable...

|

Writing Code

|

Red. Green. Refactor.

|

Sam Gentile provides a great write-up on the Test-Driven-Development (TDD) process.

In-Memory Databases

|

Here's an article by Martin Fowler on In-Memory Databases, which brings back fond memories of a seminar at the FZI long ago...

Joel's Reading List

|

Here's Joel Spolskys Recommended Reading List. A great list.

Here are a few books which yours truly would add to a recommended reading list (in descending order of importance):

Refactoring: Improving the Design of Existing Code - Martin Fowler

Extreme Programming Installed - Ron Jeffries et. al.

Test Driven Development: By Example - Kent Beck

Working Effectively with Legacy Code - Michael Feathers

Agile Software Development, Principles, Patterns, and Practices - Robert C. Martin

Extreme Programming Explained - 1st edition - Kent Beck

Code Complete, Second Edition - Steve McConnell

Debugging the Development Process - Steve Maguire

Thinking in C++, Volume 1: Introduction to Standard C++ (2nd Edition) - Bruce Eckel

Extreme Programming Explained - Second Edition

|

Having read the book on my recent vacation in Turkey, I must confess that I'm not happy with the
2nd edition of "eXtreme programming explained" by Kent Beck and Cynthia Andres.


Although it adds a lot of useful, practical insight to the ideas presented in the 1st edition, it lacks the precision, unambiguousness and purity of its predecessor.

If the book was meant as a definition and reference for XP, it failed. If it was meant as a collection of anecdotes, war stories and valuable lessons learned from applying XP in the field, then it's a great book.

In a reference book, rules have to stated clearly, precisely, maybe even provocatively. After all, the rules are the basis of any methodology.

Applying these rules or specs in practice is a totally different stories. It requires taking into account the specific culture of a company, the boundary conditions of a given project, code base, engineering team etc. That's why rules have to be bend and to be adjusted to a given situation. After all, they're just rules.

But this doesn't mean that you should dilute the specification.

Estimating features

|

Signal vs. Noise: "It is trivial to estimate a new feature as trivial."

How to create great bug reports...

| | Comments (1)

Here's a site which features great bug reports (mostly on topics related to MacOS X / MS Office X). These bug reports are in depth, with lots of screen-shots, suggestions on how things could be improved etc. In fact, I would be glad if the bug reports we receive would be half as good as these posted on betalogue.com.

However (and you knew this would come, don't you), there's one major caveat. The author sometimes uses judgmental language to comment on these bugs and the software developers responsible for these bugs.

Don't do that. Don't use judgmental or even insulting language.

Refrain from using phrases like "I wonder what these guys have been thinking...." or "It's obvious that XYZ doesn't think about..." or "Again, XYZ proves that they don't pay enough attention to....". Don't speculate about issues with the developers code.

State what's wrong. State what you expect. State how this bug affects you. Provide sample documents/screen shots - anything which may help to resolve the bug.

If you're really pissed, still use neutral language. If you're not pissed, but slightly annoyed, use upbeat language. You will be surprised how much this will help a constructive discussion about the bug and how much more attention is paid to your report.

Are you writing "Refrigerator code"?

|

Refrigerator code - What a great concept.

(Via Jeffrey Fredrick).

On Automating Tasks

|

Seth Dillingham (Via inessential.com.):

‘Never spend an hour doing by hand what you can spend four hours automating.’

I would advocate:


  1. Do the task manually once - will save you 3hours now
  2. After the same task came up again sometime in the future - automate it

Minimizes the risk of YAGNI.

Encapsulation

|

Excellent post by Dave Astels: Violating Encapsulation.

OOP isn't about coding an algorithm based on the methods an object provides, it's about asking an object to get a specific job done.

Here's a great collection of error messages...

|

Pop-up Potpourri: Arcade Edition.

I like

If you choose to continue, do you wish to continue? [OK]
best. That's a question which justifies some rather in-depth philosophical thinking...

Real users...

|

My dad (70 yrs) has finally gotten himself PocketPC including a GPS-based mapping application. He was rendering account on how the first week of using the gadget in his car was working out for him. Of course, he was using it on well-known routes first to see how it performs. The conversation went something like this:

Dad: "So I was using this thing to get me from Kandel (a town nearby) to Jockgrim (his hometown) and it was guiding me quite OK back to our house..."
Mom: "Well remember that it guided us through this very narrow street in Kandel where you can't even pass a cyclist..."
Dad: "...yes, this didn't make sense."
Me: "Maybe you set it to shortest route instead of fastest route and that's why it chose the narrow street?"
Dad: "I set it to shortest route, sure."
Me: "Shortest route isn't necessarily the fastest route..."
Dad: "Yes, sure. If I would have chosen fastest route it would have guided me right over the autobahn."
Mom: "...but it guided us through this very narrow street."
Me: "Yes, of course, because it is part of the shortest route..."
Mom: "...but this doesn't make sense. Nobody would use this lane..."
Dad: "Yes, it doesn't make sense. You can't even pass a cyclist in there."
Me: ...
Talk about a mismatch between user expectations (or the users model) and the software.

Here's a nice C++ FAQ

|

Over here. Lot's of useful information.

The slippery slope to consultingware

|

Joel on the slippery slope from shrinkwrap to consultingware.

The essence

|

Here's the essence what Apple's all about:


theessence.jpg


(Showing remote controls for Windows Media Center and for Apples FrontRow.)

(Screen Capture taken (without permission) from QuickTime stream of the Apple Special Event on Oct, 13 2005).

Hint: It's not about the size.

Intelligent Reaction

|

Impressive thoughts in this presentation by Adam Bosworth. Worth pondering if and how Intelligent Reaction can be implemented in more traditional desktop application.

Three rules...

|

...of TDD.

Extreme programming adventures in C#

|

This book is neither about extreme programming per se, nor about C# or .NET.

Instead, it provides a unique opportunity to look over the shoulders of a great Ron Jeffries to watch him create an (albeit simple) application, learn from the mistakes he makes, learn how he tackles problems, learn about how to improve the design of a software - and learn a few words of wisdom along the way.

Excellent read. Highly recommended.

Less as a competitive advantage

|

Avoiding "Blank Page Syndrome"

|

Interesting thoughts on Avoiding "Blank Page Syndrome".

The first question our users asked when confronted with a non-blank document was:

"How do I remove this stuff?"

So the jury is still out on that one. Labelling the "default" sample content as "Example" plus describing that this is only default sample content and will go away requires the users to read (quite a lot) & understand what's written.

Judging from my experience, this spells trouble.

Five Design Skills

|

Why software sucks...

|

Stumbled about that one while desparately trying to work through my "flagged-but-not-read-blog-posts" list.

Stupendous.

Read it. Now.

On unit testing

|

Michael Tsai responds to Will Shipley's now infamous Unit testing is teh suck, Urr.

Here's one important aspect of TDD Michaels well-balanced post is not elaborating enough:

Unit-Testing is about design (& specification of behaviour) as much as about testing, as many proponents of TDD point out (check Dave Astels blog who's taking this aspect of TDD to the extreme).

While I'm at it, Michael states:

If you need a new class or method, I think it’s a waste of time to write a test that simply checks for the existence of the class or method, then write a stub, then run the tests, and then then flip back and write the real tests.

I beg to differ. If you intend to write a unit test anyway, there's no time wasted doing it with tiny little steps like mentioned above - in fact, I would argue to use the tiniest steps possible, asking the compiler/linker/runtime for help as much as possible). Plus, it saves precious spare brain cycles for those really hard problems. Of course, you're smarter than me, so you probably have brain cycles to spare :-)

Must read

|

A rather elaborate must-read by Tim O'Reilly: What is Web 2.0. Don't let the title fool you into thinking it's about Web Development exclusively.

Encouraging Good Practice

|

Alay Francis:

"I think the language we choose to use also shapes our development methods and practices."

Coming at this from a slightly different angle: Don't let the development language you use (and it's culture) limit your thinking & learning of development techniques. Think (and learn) outside of the box and look for ways to apply what you learnedto your current development environment.

On Configuration...

|

Take it slow if you need it fast

|

Take it slow if you need it fast.

David nails it.

(Signal vs. Noise is a great blog. If you haven't subscribed to it yet, do it. Right now.)

Coding style & structure

|

I was reading Ken Arnolds "Style is Substance" essay this morning (as part of Joel Spolskys book "The Best Software Writing I") and can't resist to add my 2c worth (plus I won't tell you were I was sitting when reading the essay :-)

Coding Style doesn't matter. It doesn't matter where you put your curly braces (as long as you're doing it in a consistent way).

What does matter is

  • that your code clearly expresses your intent
  • doesn't violate the DRY principle
If you do that, your methods will be short enough to make coding style irrelevant - magic. Because coding style will get in your way only if it is used to structure your code. And code isn't structured by a certain coding style, it is structured by classes and methods and design principles on how objects should work together.

It's just easier to debate white-space & curly braces. Everyone can do that. But not everyone can write clear code. Spend your energy on improving your coding skills.

It took me years to come to this conclusion. Don't make the same mistakes I made.

And, BTW, of course, as long as you're working in my team, you are supposed to put your curly braces where I say they belong :-)

Memory management

|

John Siracusa tackles the problem of C(++) & Memory-Management from a totally different angle. Very much worth reading.

The days of consistency are over

|

Jason Fried notes that The days of consistency are over. It sure looks like. Today Microsoft previewed Office 12 with a totally new UI - while some components of Office 12 (OneNote comes to my mind) seem to stick to the "old-fashioned" Look & Feel.

Here are some rambling thoughts of mine on the whole topic viewed from the humble perspective of software developer working on a cross-platform desktop application.


Yoda on code maintainability

|

Yoda: You will know. When your code you try to read six months from now.

Via Tao of Mac.

5 Tips for surviving as a Tester

|

What an excellent quote...

|

...by Uncle Bob:

"You might find that the XP community is comprised not of a bunch of wild-eyed 'fanatics', but of a group of sincere old-timers who simply want to teach the industry (these kids nowadays!) how to take small, careful steps."

C++ & Memory Management

|

Len Holgate has an excellent post on C++ & memory management (although the following citation sounds quite harsh, there are lots of insightful thoughts in his post):

Memory is only one of the many resources that need to be managed in a program and if you're unable to get your head around memory management then you're unlikely to understand how to manage files, or sockets or database connections or event handles or critical sections...

Having done C & C++ development for almost 20 years now, I would say that memory management is a waste of time for most types of applications. It's just one more thing to worry about and I would prefer not to worry about it (and have the system worry about it for me) and worry about topics closer to the domain instead.

Best of both worlds...

|

This is really cool: A web application built as a desktop application.

I wonder if this is the dawn of web applications taking over desktop applications for creating cool GUI apps.

Geoffrey Moore on Open Source

|

...here's a great podcast of Geoffrey Moores keynote at the Open Source Business Conference 2005.

Very worth listening too. Most excellent thoughts. Even if you're not involved with open source at all.

I just listened to it on my new iPod shuffle while driving down highway 280, with cruise control set to 65 :-)

Working at MS...

|

Omar Shahine has some excellent advice on working at MS.

Of course, his advice can be applied pretty much at any company. I like

  • Get out of your office
  • Use your product (the one your customers will)
  • Fix things that are broken rather than complain about them being broken
  • Use the right communication tool for the job

most. Looks like I should finally get my hands on our product and start using it.

Musings on single-point-of-return functions

|

Cedric Beust muses on single-point-of-return functions.

I'm firmly in the single-point-of-return-function camp:

public int dilbert() {

  int result = 0;

  if (...) {

    result = 1;

  }

  return result;

}

It eliminates an else statement - and I strongly dislike them. Plus I'm dead sure that the return value is initialized at least once with a reasonable return value.

However, as long as the function in question is short, using multiple returns is just fine with me. Of course, it may happen that, while looking at the code, I'll refactor it to a single-point-of-return function. Just because my sub-consciousness makes me do it :-)

Design Patterns

|

Ned Batchelder has some very profound thoughts on Design Patterns as units of computation.

Yak shaving

|

Of course, I'm the very last one to get it, but it looks like yak shaving is a really useful phrase. Seth Godin explain the concept in great detail.

Writing

|

Jason Fried:

In today's business world, most communication is done through writing, whether it's via email or via instant messenger, or if you use Basecamp or Backpack or whatever. You have to write things down, because instant messaging and email are so easy and fast. I think it's really important—especially these days—that people should be able to express themselves through writing.
If they can't quite formulate sentences or explain things clearly in writing, it's going to be a problem. Because communication is really the key to everything here. You need to be able to be clear about what you mean and what your intentions are. If someone can't write, that's going to be a problem down the road, especially for teams that are geographically spread out. [...] So writing is very important; that's how we communicate almost 90 percent of the time.

I should add that reading is the complementary, equally important skill.

The last 90%

| | Comments (1)

The first 90% of the work is done: Dave Winer has released his OPML Editor this morning.

I sure hope he'll come around to working on the last 90% of the product. The OPML Editor deserves it. Great potential. Excellent.

For anybody unfamiliar with the 90% rule:

It takes 100% of work to create a software product. Within the first 90% you'll come up with something a decent product. The next 90% are needed to add polish & refinements to the product. The last 90% of the work are spent making the software a first-class citizen on all supported platforms.

Then you'll have a software product.

Cool Calculator UI

|

Very cool calculator UI - watch the movie.

Inspiring.

Via stevenf.

Goodbye, Scotty.

|

Good-bye Scotty.

The actor, whose Star Trek character "Scotty" was a role model for any software engineer (How long will this take, Scotty? 3 hours! You have 10 minutes, Scotty! OK, captain.) passed away.

Free/Low cost online collaboration tools

|

Here's a great list of online collaboration tools compiled by Jonathan Boutelle.

Know What You Don’t Know

|

Condensed

|

Christopher Diggins' list of Everything I Know About Programming.

How to report bugs effectively...

|

...from an engineers perspective.

Indeed.

Let me re-phrase it: Developers are from Mars, Marketing & Sales are from Venus :-)

Very funny.

Code Smells - Long Method

|

Another excellent post by Keith Ray on Code Smells - Long Method.

Comments should deal with why a certain design decision was made, why a certain algorithmn was chosen etc. - and not describe what's going on in the code. Everytime you encounter a comment describing what a piece of code does, there's an opportunity for Extract Method.

Keeping the Design Good

|

Keith Ray on Keeping the Design Good.

Excellent read. If you end up with a switch statement like this, you know there's something fishy going on.

Erich Gamma on Patterns & Practice

|

Patterns & Practice - A Conversation with Erich Gamma, Part IV.

Design Principles from Design Patterns - A Conversation with Erich Gamma, Part III.

Understanding and Using ValueModels

|

AJAX Overview

|

Here's a good essay on the much-hyped AJAX approach to building web applications.

UI frameworks focussing on extensibility

|

Brent Simmons, Michael McCracken, Dan Wood, Michael Dupuis, Sven S. Porst and others have been taking up with the latest "advances" of MacOS X's UI, as found in its latest incarnation "Tiger".

Back in the old System 7/8/9 days, the MacOS had a pretty limited but system-wide consistently used set of UI widgets. Apple wasn't (that much) into the software applications business, and third-party developers (both big shops and one-man shows) were forced to advance the state of the art in terms of UI widgets. Remember, those were the days when there was no tab-control, no combo-box control, no multi-column list control etc. (Come to think of it, some of it holds true today for Carbon- and Resource-based MacOS X applications - sic). In order to come up with a great MacOS application in those days, you had to invest substantial resources into widget/UI development.

Fast-forward to 2005. Cocoa/HIViews provide a set of reasonably powerful UI widgets. Apple is cranking out software applications like mad. And still third-party developers and Apple itself regularily come up with new UI widgets & styles.

Why is that?

IMHO, a major suspect are web applications/pages. No User Interface Guidelines. No limits. Web applications don't have strong ties in platform specific UI frameworks and widgets. It's pretty straightforward to come up with a new look for a button control - in fact, it's way easier to create a new button or list control style for use in a web app than for any desktop applications. This is putting an enormous pressure on desktop applications to advance their UI.

Traditionally, desktop UI frameworks and widget sets haven't been able to keep up with the state of the art. Most likely, they never will.

What third-party developers should be advocating is a UI framework which makes it as straightforward as possible to come up with new UI styles and widgets. Because UI development is damned hard. It shouldn't be that way.

Erich Gamma on Flexibility and Reuse

|

On Flexibility and Reuse - A Conversation with Erich Gamma, Part II.

Hitting the nail on the head...

|
Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius, and a lot of courage, to move in the opposite direction.
---Albert Einstein

(Via /\ndy's Weblog.)

How to Use Design Patterns

|

How to Use Design Patterns - A Conversation with Erich Gamma, Part I.

Writing comments in your code

|

Write Sweet-Smelling Comments. Excellent overview by Mike Clark.

This could become...

|

...a great reference on the PrinciplesOfObjectOrientedDesign.

A History of the GUI

|

Excellent read.

Unit Testing Anti-Patterns

|

...by Ian Bourke.

Brush painting

|

Undeveloped thoughts of the week:

"UI development is like painting the faces of a thousand army men with a little brush. Enterprise server development is like painting a stadium with a roller in the dark."

Let me add that each soldier of the thousand army men is made out of different materials, requiring you to change your brush & color technology constantly. And some of them move while getting painted.

Exploratory Testing using Personas

| | Comments (1)

Exploratory Testing using Personas:


Lesson learned: Get the customer data when they are using the software in their own work environment.

Good read.

Usable Help

| | Comments (1)
Usable Help: "Examining documentation and help systems for software and consumer products."

Great content plus a great blogroll on technical writing. Recommend for all folks dealing with technical documentation (you know who you are, don't you).

(via michael-mccracken.net).

Code duplication in tests

|

Tame the Name

|

Mike Clark on Code Craft: Tame the Name.

Recommended reading.

A Unit test should test only one thing

|

MPW C Error Messages

|

Rick Schaut digs up some of the cool MPW C Error messages.

You haven't lived if you never compiled a substantial MacApp-based application on a 8 MHZ 68000-based Mac using MPW. Upgrading to a 16MHZ 68030 machine helped, but you could still watch half a decent Wimbledon tennis match while the machine was building your app.

Those were the days.


One loop per method

|

Cyrille talks about one loop per method and how breaking up a loop into processing things and processing a thing helps structuring the code.

Having one if...then...else statement helps, too. While you're at it, get rid of the else. Way to complex.

If you think I'm joking, you're wrong. I'm not.

The first rule of debugging

|

Martin Fowler:

"Early on in my programming youth an older programmer taught me the first rule of debugging - the bug's always in your code, not the compiler"

Amen.

Tell, Don't Ask

|
You should endeavor to tell objects what you want them to do; do not ask them questions about their state, make a decision, and then tell them what to do.

Source: Tell, Don't Ask.

Evolving the architecture of a system

|

Uncle Bob on IncrementalArchitecture.

Next generation UI development?

|

Adobe's Adam & Eve (Via Lambda The Ultimate)

Cool stuff (but it sure has a smell of over-engineering).

Model-View-Presenter

|

A good introduction to the Model-View-Presenter Pattern, also known as the Humble Dialog Box. Required reading.

More patterns by Martin Fowler related to rich client user interfaces can be found here.

Tim Bray on Agile

|

Tim Bray on XP and Agile:

Writing tests after you’ve written the code is boring and painful: writing them first (a key premise of XP) makes it more interesting, and thus less likely that you’ll skip them.
...
Feature-at-a-time development makes development project schedules immensely more predictable
...
Detailed specification, in advance, of the functions of a large software system is essentially impossible.

Make sure to read Tim's posting for more context & insight.

What do you want from tests?

|

While we're at it...

|

Uncle Bob: Speed Kills.

The Next Big Thing

|

Uncle Bob:

"I hope the next big thing is a consolidation of what we have learned over the last forty years. I hope the next big thing is the realization that software is not about hours worked, but about care. I hope the next big thing is the gradual understanding that developing good software is not about man-hours and raw labor; but about creativity, inventiveness, and a drive for elegance and beauty. I hope the next big thing is a change in attitude from big vanilla software groups, to small energetic teams. I hope the next big thing is the growth of professionalism and craftsmanship, and the realization that these are the attributes, not documented process or raw manpower, that will make our industry productive, accurate, and respected.

Fantastic article. 'nuff said.

Managed developer testing

|

Ned Batchelder on Managed Developer Testing and the change of culture required to successfully introduce automated developer testing in an organisation.

Amen to that. However, those obstacles are no excuse for not trying hard and being persistent.

Evolving the UI

| | Comments (2)

Evolving the UI.

Although I don't agree with the authors conclusion on "Fat client UI frameworks", there are lots of great thoughts in this article. Forget visual forms designers is one of them. Read for yourself.

Predicate Logic

|

Kevin Lawrence:

*For All* thinkers look for the general rule and then search for exceptions. *There Exists* thinkers look for one special case after another until they have found them all.

This deal-with-one-case-at-a-time philosophy shows up everywhere in the agile approach to software development. We design systems one story at a time. We write code one test at a time.

Agile thinking is *There Exists* thinking.

"For Exists" also eases communication. It's easier to agree on a story/feature to work as expected using a specific acceptance test instead of argueing about general rules and how the software is expected to behave.

Of course, the "...until they have found them all" is the hard part. However, if you haven't found them all, you still have a lot of confidence about the cases you already found.

Back to working on speeding up our acceptance tests :-)

The Developer Testing Paradox

|

The Developer Testing Paradox:

The root cause of most software project failures, and of the poor general health of most software, is the lack of early-stage unit testing.

The metrics presented are a little bit off IMHO, especially when dealing with legacy systems. Still an excellent read.

TDD

|

Two excellent posts on TDD (Test-Driven-Development) by Keith Ray:

Managing Multi-Tasking in a Small Group

|
Johanna Rothmann:
'If we take time to add tests, we can't add as many features.'

You're absolutely right. But here's the problem. You're not adding the features now. You're adding broken almost-features. That's not helping the customers. The customers deserve to have features that work.

CodeGuru: Polygon Clipping

|

Thinking FORTH

|

Ahhh, sweet bird of youth: Thinking FORTH (via Mark Bernstein).

On GUI Conventions

|

Dave Heller:


As IT systems finally make their way into the non-info service sector such as health care practices, blue collar e-learning, etc. we are starting to really see that our notions of “(GUI) conventions” even the most basic are just totally bogus. People can’t even use a mouse, let alone know that a blue under lined piece of text means something that will show me something else.
(via Sarah Allen)

Lot's of good articles...

|

...on agile software development here. Here's one of them: The Humble Dialog Box.

Reviews of C++ Unit Testing Frameworks

|

Reviews of C++ Unit Testing Frameworks.

Great write-up. What a coincidence that I'm fighting with CppUnitLite (as we speak :-) to make it run within our environment.

Acceptance Tests

|

Roy Miller on Acceptance testing. Pretty java-centric, but still useful stuff.

Christopher Baus:

A few years ago there was a lot of discussion in the C/C++ community regarding the advantages of inlining of fuctions. The debate has been settled. The inline keyword exists as a hint to the complier. There are cases when inlining makes sense, but according to Mark Lacey of the Microsoft compiler team, the compiler ignores your advice. It decides what to inline and what to outline for you (ok it is possible to override this with a Microsoft specific keyword, but it isn't recommended). And the larger the program, the LESS chance that code it will be inlined.

Developer testing

|

Video webcast of Kent Beck's presentation on Developer testing. There's also a 1h mp3 at IT conversations.

Required listening.

Frequent Releases

|

Ron Jeffries on Frequent Releases.

Exactly the challenge we're facing right now.

Anyway, if you're a software engineer and you're not reading Ron's blog on a regular basis, you're missing out on something big time.

How Not To Request A Feature

|

Rogue Amoeba - Under The Microscope : How Not To Request A Feature:

  1. Be aware that you don't represent all of our users.
  2. Don't browbeat us.
  3. Our job isn't as easy as it looks.
Excellent. Recommended reading.

Planning Software

|
Ron Jeffries on Planning Software:
When you're working with a tool, someone owns the keyboard, and everyone else is an observer. It's easy to develop the habit of "check the database" instead of "talk with each other". It's easy for a manager to think that he's managing the group when he's really looking at his screen.
Excellent thoughts.

Cocoa (Coding) Style

|

Bugreports

|
Here are three great posts on how to do bug-reports (just putting the links contained in Brents first post into one quick post of mine for easy digestion): "XYZ doesn't work" is not a bug-report. It's a waste of both the developers and testers valuable time.

Testers: Are they Vegetable or Mineral?

|

Mr Ed.: Testers: Are they Vegetable or Mineral?.

Well, uhm, umpf. Ahem. Of course, from a software developers point of view, the answer is: "Yes."

Great post by Mr. Ed. I would like to elaborate a few points:

Omitting Screen Shots

It's not about screen-shots per se, it's about getting a snapshot of the systems state when the bug was noticed. In a desktop environment, that's obviously a test document created with your application (plus any support files). Otherwise 9 out of 10, the developers won't be able to reproduce the bug which causes lots of frustration. Plus it wastes valuable engineering resources.

Diagnosing Instead of Reporting

Refrain from wondering why the bug was introduced in the first place. Don't give hints on how to resolve the bug ("You should refrain from dereferenceing a null-pointer").

Irrelevant Estimates

Don't include phrases like "should be easy to fix" or "will only take 5minutes" in your bug reports. There are no easy fixes. The last easy-fix I heard about was seen in Tasmania in the late 1930s.

Bugs & Features

Carefully distinguish between bug and feature request. Especially if you're an engineer testing software.

Calm down

Last but not least: Don't write bug-reports when being stressed-out. Beware of your language after having discovered a bug while being at the wrong time in the wrong place.

People lie on surveys & focus groups

|

The Rule of The Big Two

|
The Rule of The Big Two - If you're into C++, a great read.

Relative Levels of Suckage - revisited

|

Dave Astels: Why your code sucks.

Yup, my code sucks. But I try hard everyday to make it suck less in certain areas.

The need for understanding

|

Ron Jeffries: ...when I refactor, it is without regard to the "big picture" of the system, or even of the code.

By letting loose of understanding and focussing on rote behaviour, I actually gain some minor understanding of a small part of the system, thus making progress in understanding of the complete system. One small refactoring/step at a time.

A very useful strategy when dealing with a large base of legacy code.

Interesting enough, letting loose of understanding requires a lot of courage and confidence.

Communication

|

Rachel's Place: ...form is unimportant, there is no right way to write a story and writing them is not the important part. What is essential, is that a conversation takes place between customer and developer.

An honest, frequent, ongoing, two-way conversation.

More on persistence

|

Looks like there are others out there pondering the idea of automatic persistence in desktop applications.

Implementing a UI enabling non-developers deal with versioning will be a real challenge.

Zero Defect Development

|

Some great thoughts on well, as the title of this post implies, Zero Defect Development (via And Another thing).

More on testers & developers

|

Some more material on testers & developers:

Brian Marick points to Bret Pettichord's "Testers and Developers Think Differently".

I was not alone...

|

Bob Congdon mentions Steve Bourne (author of the Bourne Shell) was using a set of C-macros which allowed him to code in an ALGOL-like fashion.

During the mid-/late-80s I was "famous" for using a hand-crafted PASCAL.H header file which made my C-source code look like PASCAL. Of course, this was just ridiculous and made it much harder for us to use any source-code browsers etc. which almost always barfed when trying to "parse" our "pascalized" C-code.

From today's point of view, my only excuse is that I was way too young back then.

Anyway, to close on a more serious and less reminiscent note: Of course, using macros to disguise one language as another is bullshit. If you keep your methods short (because you're refactoring mercilessly, don't you?), a new and potentially unfamiliar syntax shouldn't get in your way.

Syntax doesn't matter. Writing bad code is easy. Writing great code is hard. Doesn't matter what language you're using.


On developers and testers

|

Developers want to see their code to work, testers want to see it fail.

Mr. Ed elaborates on this topic in a great article: Testing and Card Tricks.

...Ned Batchelder provides a link to the Spirit Parser Framework.

EBNF implemented directly in C++ using templates. Which means, EBNF is embedded in your "standard" C++ code and executed. Stupendous. Even better than writing your own recursive-decent parser instead of relying on yacc.

However, I don't think I'm brave enough to look at the code for the parser framework itself.

On encoding...

|

..if you're into bit-shifting, here's a great reference post on BASE64 and UUEncode.

New C++ Blog/e-zine

|

There's a new blog/e-zine on C++ at artima.com: The C++ Source.

I look forward to some outrageous template usage introduced & explained.

Honestly, the world could certainly use a blog covering C++ topics with a healthy dose of reality-check mixed in.

Free Books

|

Bob Congdon points to a site with Free tech books.

Automated Daily Builds...

|

...are great.

However, it looks like there are some folks taking automated builds to the extreme (It sure looks like those folks have too much time on their hands).

Very cool.

FIT

|

Great article on FIT by Michael Feathers.

Math Installments...

|

Deleting Code

| | Comments (1)

Variable Naming Conventions

| | Comments (2)

Mikhail makes a case for hungarian notation.

There are two large gaping holes in his argument:

  • Naming variables a, b, c leaves a lot to be desired. Actually, as far as our team is concerned, if you would use a variable name like this in a method longer than 3 lines I would probably shoot you right away. No questions asked. Of course, you're welcome to use 'i', 'j' or 'k' in a three line for loop (if there's no iterator available).
  • If methods are that long to make you wonder if a specific variable was passed by reference or value, you're in for a major refactoring job before making any changes to the method

And don't get me started on hungarian notation.

Finally...

|

...even yours truly found out about IT Conversations. Pretty cool. Looks like I need an iPod now. :-)

Comments...

|

...gone wild.

ROFL.

Spending more time on creating useful, readable & understandable function/method/variable/contant names is time well spent. And you'll find you can cut back on comments substantially. Especially as those comments tend to be cut/copy/pasted across your source code files and you'll end up with a significant amount of comments which don't relate to the method/function they were supposed to comment.

Humbleness

|

Edsger Dijkstra: The people who are best at programming are the people who realize how small their brains are. They are humble. (via Coding Horror).

Be humble. Even if you're smart as hell, follow a set of simple practices (unit-test, small methods, refactor mercilessly, proper naming of functions/variables/constants, ...). Now you're in a position to put your brain to good use on those hard problems which inevitably come up while coding.

Intermediate Booleans

|

Ned Batchelder uses intermediate booleans to tame conditions from hell.

Ned does a great job of cleaning up those conditions from hell. I would recommend taking it one step further: When cleaning up complex conditions, create functions/methods instead of intermediate booleans, thus facilitating reuse of these partial conditions.

Boolean parameters

| | Comments (1)

Kevin Rutherford on avoiding boolean parameters and why there are two categories of if... statements (via Exploration through example)

TDD - Part 1

|

Software development is a team sport.

|

On mental models of persistence

|

Sara Allen posted a thoughtful article on persistence in web-applications/RIA.

Rethinking persistence in desktop applications seems to be a worthwhile endeavour, too. With todays 100GB+ hard-drives, multiple GHZ-machines and multiple-undo system architectures, why make it a requirement for the user to explicitly save a document? Why not saving it incrementally? Thus bringing versioning into the picture for the average user?

On a side note, explicit saves ("commits") are considered standard in database-applications, however there a database system which supports automatic persistence: FileMaker. To my knowledge, every keystroke/change to a record/table field/columns is made persistent automatically.

How to...

|

...set focus in a dialog box.

I always thought MacOS Carbon was messy.

Documenting software...

|

A couple of interesting thoughts on how to document APIs: It's not enough to say what it does. Altough the examples and lessons are drawn from a strictly technical background (documenting an API), they apply to end-user documentation (manuals, tutorials etc.) as well.

Software Professionals

|

James Robertson and Patrick Logan comment on an article titled The Dangers of End-User Programming:

James Robertson - If we want secure and safe software, we have to make it possible for the domain experts to create that software. Banishing them from the field sounds like 1960's glass house thinking to me.
Patrick Logan - End user programming is to be encouraged

While I'm all in favor of securly scriptable applications, I don't think domain experts should create software. After all, their expertise is in the domain. Creating complex software systems (not scripting software for a particular task) requires a special set of skills most "normal" folks just don't have. And I'm not talking in-depth technical knowledge about .NET, sockets etc. here.

We (read "Software professionals") have to come up with tools and processes enabling domain experts to fully participate in the software development process. User stories, acceptance test frameworks etc. come to my mind. Plus we have to come up with scriptability features allowing the automation of other tedious tasks.

Sketchup 4.0 Sneak Peak

|

SketchUp 4.0 will feature a Ruby Scripting Interface.

Didn't I talk about scripting languages for plug-in development just a few weeks ago?

Deep Thoughts on TDD...

| | Comments (2)

Don Park on Test-Driven Development.

I like the comparison with being deeply involved with a video game and pushing aside deep thoughts on design.

Hard thinking, heavy lifting and thinking deep thoughts is way overrated in software development. Most of the time, deep thoughts aren't necessary to accomplish the task at hand. Concentrating on following a set of simple practices will result in a better and more maintainable product than thinking deep thoughts.

John gruber hits the nail right on the head. Excellent. In-depth.

Reliability vs. Features

| | Comments (1)

Todd Bishop talks about a poll Reliability vs. Features. Users were choosing "Software that works reliably" over "Software with innovative new features" with 95% over 5%.

Sorry to say, but that's bullshit.

What's reliability? Software isn't crashing? Software performs correct calculation (speaking in most generic terms)? Software performs calculation as user expects? Software has the feature set (both in breadth & depth) users expect? Software is "bug-free"? What's considered a "bug" - from a users point of view? From a vendors point of view?

Reliability isn't the absence of bugs. It's not about stability. It's about meeting the users expectations. And that's damned hard. Most of the time, it involves creating new features.

Cyclomatic Complexity

|

Code Improvement Through Cyclomatic Complexity (via DevelopingStorm).

Interesting read. A couple of comments of yours truly:

  • I don't think there's a need for metrics here. Applying common sense is sufficient. Do you have to scroll to read the whole message?. It's pretty likely that the method is too complex. More than 2 or three if..then..elses? It's pretty likely that the method is too complex.
  • As the example on page 2 shows, you'll need to use good judgement when getting rid of cyclomatic complexity. Getting rid of intra-method complexity may introduce complexity on an architectural level. Although I prefer architectural complexity (or, for the lack of a better word - elaborate architecture) over cyclomatic complexity, I don't think getting rid of two if..then..elses justifies a substantial architectural change. If you re-visit those if..then..elses later on and you feel the need to add a few more if..then..else in the same method, go for the architectural change. But go for it when there's an actual need and not for the sake of architectural beauty.

On APIs and losing an API war

| | Comments (2)

Of course, I can't keep my mouth shut on Joel's latest rant How Microsoft Lost the API War.

Joel, keep in mind that there are lots of applications out there used by millions of customers which won't migrate to the web any time soon.

Do you really think Adobe, Autodesk, Microsoft, Lotus, Quark (just to name a few) will move their vastly successful rich-client applications to .NET/WinFX/... in the foreseeable future? Think again. Most likely, they will stick with their tools and technologies and APIs as long as possible. Which are based (way down in the systems where rubber meets road) Win32 on Microsoft Windows. And Carbon on MacOS.

Win32/MFC/COM etc. won't go away for a very long time. I agree, it has become an unholy mess. But we gotta deal with this mess.

A more interesting discussion on APIs would be: How do we marry existing application ecosystems, plug-in architectures and APIs with new technologies like .NET, scripting languages, ..insert-your-favorite-technology-here...?
For example, how do we enable an AutoCAD plug-in developer to take advantage of the productivity gains found in .NET?

Uhm, on a second thought, let me rephrase my example: How do we enable a VectorWorks plug-in developer to take advantage of the productivity gains found in .NET or Cocoa? :-)

Introduction to Apple Software Design Guidelines

|

Lot's of good advice here (from a "birds-eye-perspective-in-an-ideal-world-with-no-legacy-code", though) in the Introduction to Apple Software Design Guidelines. There's also a PDF version. (via Ranchero.com).

See also:


Why marketing is hard...

|

Good read for anybody in geek-land. Advertising is hard. Marketing is super hard, too. (via Scobleizer)

My favorite quote:

"It always bothers me when people outside a discipline believe that it is trivially simple"
.

The 22 Immutable Laws of Marketing

|

Eric talks about the book "The 22 Immutable Laws of Marketing".

(Yes, Scoble mentions this entry, too, but'm I'm reading Eric's weblog anyway :-)

More on weeding

|

Sarah Allen follows up on the metaphor of gardening & software development introduced by Ned Batchelder.

As I said in a previous post, weeding is extremly important. But I wouldn't consider weeding a second-class activity. Actually, it's a first-class activity. If you don't remove the weeds, you'll end up with software rot - the plants you (and your customers) expect to grow and flourish won't bring out the enjoyable fruit. And the longer you wait, the harder it'll be to get rid of the weeds. They spread fast.

Plus, weeding is enjoyable. You know that you've made a substantial contribution to your code and you'll reap the benefits tomorrow. Even on a rainy day when you just can't wrap your mind around the hard problem you're expected to tackle.

Uhm, looks like I get carried away with the metaphor now :-)

Removing weeds isn't rocket science. But more often than not, rocket science isn't required to improve your code.

UI complexity

|

Here's a lesson on UI complexity to be learned. While reading Rick's blog, I came across a link to the early 1984 Apple Macintosh introduction.

Check out this screenshot of MacPaint. It's interesting to see that MacPaint was featuring 6 menus. Six. Two of them are File and Edit. Now take a look at the remaining four menus. Three of them are concerned with Text properties: Font, FontSize and Style. This leaves one menu called Aids for additional functionality. Take a look at the palettes. That's it. Nothing more. Null. Nada. Nothing. Zilch. Users have been able to grasp the concept of MacPaint easily. And created pretty elaborate drawings with it. Now compare this UI with you favorite drawing application today. Do you see the difference? Do you see why the vast majority of users have trouble using today's applications? And even if they're able to accomplish a task, they most likely fail to take advantage of the applications feature set?

Better yet, check out this screenshot of the early Finder. Now open up a window on your Windows XP or MacOS X desktop. Do you see the difference? Talk about screen clutter. Talk about the user not seeing the forest for the trees.

BTW, if you're into Microsoft Word (for Mac), make sure to read Rick's blog. Great stuff.

Software development & gardening.

|

Ned Batchelder pulls weeds.
Although I'm fundamentally opposed to gardening in general, I second Ned's philosophy concerning clearing up the little things in your code. If you don't do it, start now.

Making it easier to build a great UI

|

Couldn't have said it better

|

More on UI development

|

The Rise of Interface Elegance in Open Source Software

One of the most important acts of a software project manager is to say ?no?. No, this patch introduces more code than it should. No, this feature will confuse more people than it will help. No, you?re ugly and stupid (sometimes the manager has a bad day).
(plus, simplifying the UI release after release sounds like an intriguing idea)


Ronco Spray-On Usability

UI development is the hard part. And it?s not the last step, it?s the first step. In my estimation, the difference between:
  • software that performs function X; and
  • software that performs function X, with an intuitive well-designed user interface
isn?t just a little bit of extra work. It?s not even twice the work. It?s an entire order of magnitude more work. Developing software with a good UI requires both aptitude and a lot of hard work.
(I'm not sure I like the phrase it's not the last step, it's the first step - having an excellent backend providing rich functionality is a requirement for a great app - as is a great UI - and separating both is also considered a good idea by many software architects including yours truly)

Tree Views

|

Brian Duff has some interesting observations (in the context of talking about iTunes' UI) regarding the tree-controls widgets widely used in the Windows UI (and to some extent on MacOS) - via Scobleizer.

Ryan Lowe makes a good argument why Testing is a First Class Job. Resonates with my post regarding Bugs. Bugs. Bugs. and offers lots of detailed insight.

Smalltalk for MacOS X

|

A new Smalltalk for MacOS X. I hope these guys will be more successful than QKS in the early 90s.

Compilers and Compiler Generators

|

Compilers and Compiler Generators.

Great read for everyone interested in compilers. Of course, it's only an introductory text, but still useful.

Software for Small Business

|

Frank Sommers asks: At the network's edge, is software a service business?.

Interesting enough, German ISVs targeting the SOHO markets are fighting with this problem since the early 80s. Looks like a great opportunity for us :-)

Bugs. Bugs. Bugs.

|

Keith Pitty and Charles Miller have some very useful thoughts on software testing and finding bugs.

Automated software tests taking care of possible regressions are extremly important, especially if you intend to release often. However, automated tests are not an after-thought, neither unit-tests nor acceptance-tests. If you change the fundamental algorithmn, you are not finished as long as the unit tests don't reflect the new/different boundary conditions. If you add a new feature, you're not done as long as you've added a new acceptance test covering the feature. This requires a lot of discipline on behalf of the developers. Plus it requires patience on behalf of management, because changing the algorithmn/implementing the feature will take a little bit longer than expected. Last but not least, having automated tests provides a great starting point for external testers, ensuring they don't complain about those nasty regressions.

Having external software testers is vital to find the bugs in areas/paths not vovered by automated tests (most likely the majority of bugs). Developers test their code to see if it works the way they think it should work. They're testing with knowledge of the code written a couple of minutes ago. They want to see it work, not fail - after all, who want's to see his/her work fails? External testers expect the code to deliver the results they expect. Plus, they want to see the code fail, which, BTW, create a significant tension between the two camps. Make sure to remind everyone involved that both teams are working together to deliver a great product.

Keith makes a good point about over-reliance on automated tests. However, note that you got to have a comprehensive suite of automated tests first, covering all the regressions you want to avoid by all means. Then start worrying about over-reliance on automated tests. But not the other way round.

Fundamental issues...

|

Fundamental issues with open source software development by Michelle Levesque.

Michelle raises a couple of good points, however, the issues mentioned can be found in commercial software development, too. I hope to find some more time later this week to comment on User interface design and Feature?centric development. Reminder to self: I wanted to ramble about document-centric computing, too.

More on sticking with it...

|

Sarah Allen: Good GUI involves interaction design. You can't draw a picture or a flow chart of it. To know if it's going to work you have to prototype it or even fully implement some of it.

In the context of the discussion about UI programming, sticking with it is extremly important when doing UI development.

Put v1.0 out of the door. Listen to customer's feedback. Act on it. Add in a healthy dose of what you learned in the meantime. Put v2.0 out of the door. Listen to your customer's feedback. Act on it. Add in a healthy dose of what you learned in the meantime. Put v3.0 out of the door. Still with me? Keep on going. It just get's better.

On the lost art of user interface programming

|

Extending the discussion about why UI programming is hard, David Temkin comes up with a great post on the lost art of user interface programming.

I can't say enough good things about his post. His recapitulation of the influence the Web had on UI programming is a must-read.

The advent of the Web moved the emphasis plus the "coolness" to the backend. UI work was only considered cool because it was delivered in the HTML to a generic application called the browser. Coming up with a half-way decent UI required ridiculous amounts of coding (mostly in environments and languages which, uhm, were not on par with the tools used for desktop application development). In terms of user interaction, moving to HTML was like starting to focus on flintstones and spears again to provide for daily food. And despite all the hard work, you ended up with a UI which was a far cry from the rich interactivity users where experiencing on their desktop systems.

The advent of the web also killed some of the more interesting approaches to human-computer interaction like document-centric computing (witness OLE or OpenDoc). While there's a lot to say about the deficiencies of these approaches, they were off to a great start trying to put the GUI to the next level - but I'm getting off-track here, looks like this is material for another post.

On a related note, some of the now famous GoF patterns were widely used or even originated in the UI frameworks created the late 80's and early 90's.

It's great to see that companies like Lazlo are starting to come up with tools enabling developers to deliver a rich user-experience on top of the now omni-present network we all depend on in our daily work.

UI development is damn hard.

|

Check out Eric M. Burke's post GUI Programming is Hard. In a related post, Rick Schaut talks about UI design. Both posts hit the nail right on the head and are considered a must-read. Yes, I'm talking to you, dear reader involved with SW development or SW sales.

Why is creating a great UI hard?

  • Because it requires artistic/aesthetic skills most software developers don't have
    If you're lucky enough, you will have a great UI designer or at least someone who has a great feel for how the UI should look (from an aesthics point of view) and feel (from an interaction point of view) - Preferrably someone who is also working very close with customers

  • Because the tools used are not up to the task
    As Rick Schaut says in his post, as soon as you start to go beyond the "put-a-few-edit-fields-checkboxes-and-buttons-on-a-form" UI, you are basically on your own. Most trivial example: I have yet to encounter a multi-column list box control which ships as part of a standard UI framework which can be easily extended without - all of a sudden - forcing the UI developer re-invent basic things like managing focus etc. And don't get me started on more complex interaction in forms/dialogs. Most likely, UI developers already have a very hard time coming up with an elegant, approachable UI for the applications problem domain. Being forced to re-create basic UI mechanismns doesn't help a lot.

And while I'm rambling along, I have yet to see how using XML to describe the UI will help tackling the problem.

Lazlo - XML coding

| | Comments (1)

Dave Temkin, CTO of Lazlo Systems started promising blog with a great Lazlo overview.

Lazlo is an XML-based development environment and deployment environment for building rich internet applications. Basically, the compiler outputs SWF-files.

It takes some time to get used to the verbose XML syntax, but it looks like a couple of major players are moving in the XML/UI direction, e.g. XAML within Longhorn or XUL in Mozilla.

However, I'm pretty sure that using XML for UI development won't change the basic premise: UI development is damn hard. I'm not talking "Hello World" type apps here, folks. I'm talking UIs for complex real-world applications.

How do we enable developers to create visually appealing, consistent UIs? How do we empower developers to extend the set of given UI controls in a consistent & straightforward manner? The latter is what all UI development environments/class libraries/frameworks etc. fail. But the latter is what UI developers are struggling with.

Using XML doesn't change anything.

VS6 SP6

|

VS6 SP6.

Not sure if I'm brave enough to install it. Like Don, I'm wondering if the build corruption issues have been addressed.

Online update & patch service...

|

Here's a cool service for MacOS X third-party developers: Centralized online update & patch services for applications. Are there equivalent services for Windows?

Sure, there are security/privacy issues, but don't get me started on these topics...

Smalltalk-like Code Browser?

|

While I'm at it, anybody knows about a Smalltalk-like code browser & editor for the Visual Studio environment? Uhm, no, I'm not talking about the classes view in the project window.

Scheduling trains with Smalltalk

|

I had a nice meeting with a customer this morning - they are using Smalltalk (VisualWorks) to schedule the trains for a large part of Germany. That was neat; the system has some very nice graphical pieces with very fast zoom in/zoom out capabilities. That was cool.

[Smalltalk with Rants]

Smalltalk is one of the best-kept secrets in the industry. I remember KHK working on a Smalltalk framework (X-Line) for business applications back in the early 90s. Third-party developers were expected to buy a source-code license and develop vertical-market applications based on the framework.

Using Smalltalk for this kind of project was a very bold move by KHK.

Of course, the project was a major failure. But the main reason for the failure wasn't Smalltalk's lack of capabilities, it was mismanagement and misjudgement of the markets needs and driving forces.

Uhm, plus, we shouldn't attribute delays in the German train systems to the use of Smalltalk in the scheduling application :-)

Guidebook

|

Guidebook, a website dedicated to preserving and showcasing Graphical User Interfaces. Excellent. Highly recommended.

Exact String Matching Algorithmns

|

Exhaustive list of String Matching Algorithmns (via Ned Batchelder)

Epigrams

|

Epigrams on Computing. A classic.

Great Compiler Errors...

| | Comments (2)

Here's another compiler error message from the MPW 68K C-compiler:

"This symbol is a complete surprise to me..."

(this reminiscent of the good ol' days triggered by another MPW error message.)

Ahh, remember compiling MacApp applications on a 8MHZ 68K-machine?

Great reference for everyone who is wondering what all the different unix directories /dev/bin/etc are meant for [via Mac OS X Hints]

Failure, Preconditions, and Reuse

|

Failure, Preconditions, and Reuse, A Conversation with Bertrand Meyer, Part IV [via artima.com]

Naming classes

|

Excellent post on Naming Conventions for Classes.

Beta Testing

|

A Pixel is Not A Little Square...

|

...and other great memos by Alvy Ray Smith.

Design by Contract

|

Bertrand Meyer on Deriving Tests from Contracts (via artima.com). Excellent read.

Tools for Registry and File Monitoring

|

Great list of Tools for Registry and File Monitoring by Bret Pettichord.

More from artima.com

|

Elegance and Other Design Ideals - A Conversation with Bjarne Stroustrup, Part IV. Although talking about "Elegance" with the designer of C++ seems somewhat an oxymoron, Stroustrup always offers some great insights. Here's one of them:

A library has to evolve. The best libraries are by people who are also users of the libraries.

Java/Smalltalk Coding...

|

Here's a post on artima.com dealing with multiple asserts in a test vs. one assert per test.

What's interesting is that the authors codes up a few functions both in Smalltalk and Java at the same time, which makes up for a nice (albeit by no means exhaustive) intro to Smalltalk for Java developers

How to Write Perfect Software

|

One day, the novice came to the master and asked, “Master, how can I write perfect code?” to which the master replied:

“To write perfect code, you must not code.”

The novice looked at the master and begged him to explain further, but the Master was silent...via [The Fishbowl]

Practical File System Design PDF

|
Dominic Giampaolo's book, "Practical File System Design with the Be File System", is available for free download in PDF format via [rentzsch.com: Tales from the Red Shed]

Although BeOS is kind of, uhm, well, no longer relevant, it's a great read on the fundamentals of a file system.

Microsoft Visual C++ Floating-Point Optimization

|

In-depth article on Floating-Point Optimization in Microsoft Visual C++ (Whidbey).

GetDialogBaseUnits is a crock

|

Here's a post at Old New Thing:

There are two functions that let you convert dialog units (DLUs)
to pixels. One is

GetDialogBaseUnits
,
which returns the base
units directly (leaving you to do the math), and another is

MapDialogRect
,
which takes a rectangle in DLUs and returns a rectangle in pixels.
...

Introductory article on TDD

|

Destructors instead of Catches

|

Ned Batchelder on Destructors instead of Catches in C++. One of my favorite techniques. A must-read.

Abstraction and Efficiency

|

Bjarne Stroustrup on Abstraction and Efficiency via. [Artima.com Articles]

DomainSpecificLanguage

|

Martin Fowler on Domain Specific Languages.

Martin's always an inspiring read.

A Mice Article

|

A wonderful article with some wise and amusing observations about mice and software methodologies. via [Andy Pols' Blog]

Extreme Mice. I like that one.

DataModels

|
Martin Fowler on DataModels. He raises a couple of interesting points, e.g. the advent of databases residing in main memory and how these databases change the way we think about storing data.

Here's a good one...

|

Here's a quote from Robert Scoble worth pondering for a while:

One problem with the software industry right now is we're all stuck in a rut. We all assume that software has to be forms. Text. Keyboard driven. And that it has to look like Windows XP or Office. Can't we break out of that rut?

Good list of MacOS X utilities/add-ons

|

Here's a pretty comprehensive list of useful MacOS X add-ons/utilities by Ted Leung.

CLR Design Choices

|

Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about IL instructions, non-virtual methods, unsafe code, value types, and immutables [via Artima.com Articles]

SCPlugin

|

Here's a CVS contextual menu plugin for MacOS X.

The format of string resources

|

Robert Scoble on great uses of Avalon in Longhorn

|
In a response to Will Avalon be Ready?, Robert Scoble writes:
...That said, you will see some really great uses of Avalon in Longhorn. The clock that we shipped at the PDC is built in Avalon, for instance. There will be plenty of examples to prove to you that it's ready for serious app development.

Well, clock samples are no sign that Avalon is ready for serious app development. Neither are NotePad clones etc. Avalon will be ready for serious app development if a major app like Outlook can be written with out-of-the-box controls & widgets supplied by the UI infrastructure of Longhorn.

Out-of-the-box? Yes. Because, for the sake of consistency, lots third-party developers will try to mimic the UI of Microsoft apps. And it's neither in their nor in Microsofts best interest to re-invent the wheel.

.Net Overview

|

Official .NET overview.

A simple proposal

|
A simple proposal by Alan Green (via Smalltalk with Rants):

Henceforth, any developer that uses the word "just" while describing or estimating the implementation of a new feature to a manager will be assigned the design, coding and testing tasks for that feature.

Uhm, oops. Gotta watch my language. Excellent post. Nice comments, there, too.

Generics in C#, Java, and C++

|

Anders Hejlsberg, the lead C# architect, talks with Bruce Eckel and Bill Venners about C# and Java generics, C++ templates, constraints, and the weak-strong typing dial. via [Artima.com Articles]

Immutable Objects

|

Keith Ray on Immutable Objects.

Speeding C++ links

|

The Simplest Thing That Could Possibly Work

|

Ward Cunningham talks with Bill Venners about complexity that empowers versus complexity that creates difficulty, simplicity as the shortest path to a solution, and coding the simplest thing when you're stuck. [Artima.com Articles]

Writing style and blogging

|

Joi Ito on Writing Style....

Poor writing style, like bad manners, makes someone appear less intelligent than they are. Writing style, like manners, can be learned in many ways. Reading and writing a lot is the first step. Having people critique your writing is probably the next best thing. There are many basic writing mistakes that people make, which can easily be avoided by being aware of them.

I have never been a great writer and I am self-concious about my writing style. If you are serious about your blogging, I think that time spent polishing your writing style is well worth the investment.

My favorite reference is the Chicago Manual of Style.

Some web pages:

Special thanks to my editors on #joiito.

[Joi Ito's Web]

Interesting Website on Test-Driven-Development

|

The history of calling conventions, part 5: amd64

|

The last architecture I'm going to cover in this series is the AMD64 architecture (also known as x86-64).

The AMD64 takes the traditional x86 and expands the registers to 64 bits, naming them rax, rbx, etc. It also adds eight more general purpose registers, named simply R8 through R15.

  • The first four parameters to a function are passed in rcx, edx, r8 and r9. Any further parameters are pushed on the stack. Furthermore, space for the register parameters is reserved on the stack, in case the called function wants to spill them; this is important if the function is variadic.

  • Parameters that are smaller than 64 bits are not zero-extended; the upper bits are garbage, so remember to zero them explicitly if you need to. Parameters that are larger than 64 bits are passed by address.

  • The return value is placed in rax. If the return value is larger than 64 bits, then a secret first parameter is passed which contains the address where the return value should be stored.

  • All registers must be preserved across the call, except for rax, ecx, edx, r8, r9, r10, and r11, which are scratch.

  • The callee does not clean the stack. It is the caller's job to clean the stack.

  • The stack must be kept 16-byte aligned. Since the "call" instruction pushes an 8-byte return address, this means that every non-leaf function is going to adjust the stack by a value of the form 16n+8 in order to restore 16-byte alignment.

Here's a sample:

void SomeFunction(int a, int b, int c, int d, int e);
void CallThatFunction()
{
    SomeFunction(1, 2, 3, 4, 5);
    SomeFunction(6, 7, 8, 9, 10);
}

On entry to CallThatFunction, the stack looks like this:

xxxxxxx0.. rest of stack ..
xxxxxxx8return address<- RSP

Due to the presence of the return address, the stack is misaligned. CallThatFunction sets up its stack frame, which might go like this:

    sub    rsp, 0x28

Notice that the local stack frame size is 16n+8, so that the result is a realigned stack.

xxxxxxx0.. rest of stack ..
xxxxxxx8return address
xxxxxxx0 (arg5)
xxxxxxx8 (arg4 spill)
xxxxxxx0 (arg3 spill)
xxxxxxx8 (arg2 spill)
xxxxxxx0 (arg1 spill) <- RSP

Now we can set up for the first call:

        mov     dword ptr [rsp+0x20], 5     ; output parameter 5
        mov     r9d, 4                      ; output parameter 4
        mov     r8d, 3                      ; output parameter 3
        mov     edx, 2                      ; output parameter 2
        mov     ecx, 1                      ; output parameter 1
        call    SomeFunction                ; Go Speed Racer!

When SomeFunction returns, the stack is not cleaned, so it still looks like it did above. To issue the second call, then, we just shove the new values into the space we already reserved:

        mov     dword ptr [rsp+0x20], 10    ; output parameter 5
        mov     r9d, 9                      ; output parameter 4
        mov     r8d, 8                      ; output parameter 3
        mov     edx, 7                      ; output parameter 2
        mov     ecx, 6                      ; output parameter 1
        call    SomeFunction                ; Go Speed Racer!

CallThatFunction is now finished and can clean its stack and return.
        add     rsp, 0x28
        ret

Notice that you see very few "push" instructions in amd64 code, since the paradigm is for the caller to reserve parameter space and keep re-using it. [The Old New Thing]

The history of calling conventions, part 4: ia64

|

The ia-64 architecture (Itanium) and the AMD64 architecture (AMD64) are comparatively new, so it is unlikely that many of you have had to deal with their calling conventions, but I include them in this series because, who knows, you may end up buying one someday.

Intel provides the Intel® Itanium® Architecture Software Developer's Manual which you can read to get extraordinarily detailed information on the instruction set and processor architecture. I'm going to describe just enough to explain the calling convention.

The Itanium has 128 integer registers, 32 of which (r0 through r31) are global and do not participate in function calls. The function declares to the processor how many registers of the remaining 96 it wants to use for purely local use ("local region"), the first few of which are used for parameter passing, and how many are used to pass parameters to other functions ("output registers").

For example, suppose a function takes two parameters, requires four registers for local variables, and calls a function that takes three parameters. (If it calls more than one function, take the maximum number of parameters used by any called function.) It would then declare at function entry that it wants six registers in its local region (numbered r32 through r37) and three output registers (numbered r38, r39 and r40). Registers r41 through r127 are off-limits.

Note to pedants: This isn't actually how it works, I know. But it's much easier to explain this way.

When the function wants to call that child function, it puts the first parameter in r38, the second in r39, the third in r40, then calls the function. The processor shifts the caller's output registers so they can act as the input registers for the called function. In this case r38 moves to r32, r39 moves to r33 and r40 moves to r34. The old registers r32 through r38 are saved in a separated register stack, different from the "stack" pointed to by the sp register. (In reality, of course, these "spills" are deferred, in the same way that SPARC register windows don't spill until needed. Actually, you can look at the whole ia64 parameter passing convention as the same as SPARC register windows, just with variable-sized windows!)

When the called function returns, the register then move back to their previous position and the original values of r32 through r38 are restored from the register stack.

This creates some surprising answers to the traditional questions about calling conventions.

What registers are preserved across calls? Everything in your local region (since it is automatically pushed and popped by the processor).

What registers contain parameters? Well, they go into the output registers of the caller, which vary depending on how many registers the caller needs in its local region, but the callee always sees them as r32, r33, etc.

Who cleans the parameters from the stack? Nobody. The parameters aren't on the stack to begin with.

What register contains the return value? Well that's kind of tricky. Since the caller's registers aren't accessible from the called function, you'd think that it would be impossible to pass a value back! That's where the 32 global registers come in. One of the global registers (r8, as I recall) is nominated as the "return value register". Since global registers don't participate in the register window magic, a value stored there stays there across the function call transition and the function return transition.

The return address is typically stored in one of the registers in the local region. This has the neat side-effect that a buffer overflow of a stack variable cannot overwrite a return address since the return address isn't kept on the stack in the first place. It's kept in the local region, which gets spilled onto the register stack, a chunk of memory separate from the stack.

A function is free to subtract from the sp register to create temporary stack space (for string buffers, for example), which it of course must clean up before returning.

One curious detail of the stack convention is that the first 16 bytes on the stack (the first two quadwords) are always scratch. (Peter Lund calls it a "red zone".) So if you need some memory for a short time, you can just use the memory at the top of the stack without asking for permission. But remember that if you call out to another function, then that memory becomes scratch for the function you called! So if you need the value of this "free scratchpad" preserved across a call, you need to subtract from sp to reserve it officially.

One more curious detail about the ia64: A function pointer on the ia64 does not point to the first byte of code. Intsead, it points to a structure that describes the function. The first quadword in the structure is the address of the first byte of code, and the second quadword contains the value of the so-called "gp" register. We'll learn more about the gp register in a later blog entry.

(This "function pointer actually points to a structure" trick is not new to the ia64. It's common on RISC machines. I believe the PPC used it, too.)

Okay, this was a really boring entry, I admit. But believe it or not, I'm going to come back to a few points in this entry, so it won't have been for naught. [The Old New Thing]

To Plan or Not to Plan

|

Ward Cunningham talks with Bill Venners about using the programming language, rather than the whiteboard, to design and communicate ideas. [Artima.com Articles]

Of course, a must-read.

Software Testing 6: Good Tests for Bad Parameters

|

Framework: NFVersionChecker 2.0

|

A free Cocoa class that lets developers set up version checking with zero effort. It notifies users of the developers program when a new version is available and has a direct download button. (that can point to VersionTracker!) [Studio Log]

Is there something equivalent for Carbon && MFC out there?

The history of calling conventions, part 3

|

Okay, here we go: The 32-bit x86 calling conventions.

(By the way, in case people didn't get it: I'm only talking in the context of calling conventions you're likely to encounter when doing Windows programming or which are used by Microsoft compilers. I do not intend to cover calling conventions for other operating systems or that are specific to a particular language or compiler vendor.)

Remember: If a calling convention is used for a C++ member function, then there is a hidden "this" parameter that is the implicit first parameter to the function.

All

The 32-bit x86 calling conventions all preserve the EDI, ESI, EBP, and EBX registers, using the EDX:EAX pair for return values.

C (__cdecl)

The same constraints apply to the 32-bit world as in the 16-bit world. The parameters are pushed from right to left (so that the first parameter is nearest to top-of-stack), and the caller cleans the parameters. Function names are decorated by a leading underscore.

__stdcall

This is the calling convention used for Win32, with exceptions for variadic functions (which necessarily use __cdecl) and a very few functions that use __fastcall. Parameters are pushed from left to right and the callee cleans the stack. Function names are decorated by a leading underscore and a trailing @-sign followed by the number of bytes of parameters taken by the function.

__fastcall

The first two parameters are passed in ECX and EDX, with the remainder passed on the stack as in __stdcall. Again, the callee cleans the stack. Function names are decorated by a leading @-sign and a trailing @-sign followed by the number of bytes of parameters taken by the function (including the register parameters).

thiscall

The first parameter (which is the "this" parameter) is passed in ECX, with the remainder passed on the stack as in __stdcall. Once again, the callee cleans the stack. Function names are decorated by the C++ compiler in an extraordinarily complicated mechanism that encodes the types of each of the parameters, among other things. This is necessary because C++ permits function overloading, so a complex decoration scheme must be used so that the various overloads have different decorated names.

There are some nice diagrams on MSDN illustrating some of these calling conventions.

Remember that a calling convention is a contract between the caller and the callee. For those of you crazy enough to write in assembly language, this means that your callback functions need to preserve the registers mandated by the calling convention because the caller (the operating system) is relying on it. If you corrupt, say, the EBX register across a call, don't be surprised when things fall apart on you. More on this in a future entry. [The Old New Thing]

MIT OpenCourseWare

|

Für diejenigen Auszubildenden, die mal reinschnuppern möchten was so im Informatik-Studium am MIT gemacht wird.

The history of calling conventions, part 2

|

Foreshadowing: This information will actually be useful in a future discussion. Well, not the fine details, but you may notice something that explains... um... it's hard to describe. Just wait for it.

Curiously, it is only the 8086 and x86 platforms that have multiple calling conventions. All the others have only one!

Now we're going deep into trivia that absolutely nobody remembers or even cares about: The 32-bit calling conventions you don't see any more.

All

All of the processors listed here are RISC-style, which means there are lots of registers, none of which have any particular meaning. Well, aside from the zero register which is hard-wired to zero. (It turns out zero is a very handy number to have readily available.) Any meanings attached to the registers are those imposed by the calling convention.

As a throwback to the processors of old, the "call" instruction stores the return address in a register instead of being pushed onto the stack. A good thing, too, since the processor doesn't officially know about a "stack", it being a construction of the calling convention.

As always, registers or stack space used to pass parameters may be used as scratch by the called function, as can the return value register.

You may notice that all of the RISC calling conventions are basically the same. Once again, evidence that the 8086/x86 is the weirdo. A wildly popular weirdo, mind you.

The Alpha AXP

The Alpha AXP ("AXP" being yet another of those faux-acronyms that officially doesn't stand for anything) has 32 integer registers, one of which is hard-wired to zero. By convention, one of the registers is the "stack pointer", one is the "return address" register; and two others have special meanings unrelated to parameter passing.

The first six parameters are passed in registers, with the remaining parameters on the stack. If the function is variadic, the parameters can be spilled onto the stack so they can be accessed as an array.

Seven other registers are preserved across calls, one is the return value, and the remaining thirteen are scratch. 1 zero register + 1 stack pointer + 1 return address + 2 special + 6 parameters + 7 preserved + 1 return value + 13 scratch = 32 total integer registers.

Function names on the Alpha AXP are completely undecorated.

The MIPS R4000

The first four parameters are passed in a0, a1, a2 and a3; the remainder are spilled onto the stack. What's more, there are four "dead spaces" on the stack where the four register parameters "would have been" if they had been passed on the stack. These are for use by the callee to spill the register parameters back onto the stack if desired. (Particularly handy for variadic functions.)

Function names on the MIPS are completely undecorated.

The PowerPC

The first eight parameters are passed in registers (r3 through r10), and the return address is managed manually.

I forget what happens to parameters nine and up...

Function names on the PowerPC are decorated by prepending two periods.

Postclaimer: I haven't had personal experience with the MIPS or PPC processors, so my discussion of those processors may be a tad off, but the basic idea I think is sound. [The Old New Thing]

Great paper on the benefits of pair-programming.

Free Smalltalk Books

|

Stéphane Ducasse has an online collection of free Smalltalk books and articles. Very nice. Includes the missing chapters from the famous Smalltalk Blue Book which is, sadly, out-of-print. (Via LtU) via [Bob Congdon]

Working the Program

|

Ward Cunningham talks with Bill Venners about the flattening of the cost of change curve, the problem with predicting the future, and the program as clay in the artist's hand. [Artima.com Articles]

Kata Twenty One: Simple Lists

|

Lists are one of the first data structures we learn as programmers. But familiarity doesn’t mean that we can’t learn a little from them.
Nice kata by Dave Thomas of Pragmatic Programmer fame. Pretty useful, especially for beginners. Of course, his kata's tend to be pretty academic (and my profound aversion for academic exercises is well-known), but let's ignore this aspect for a second ;-)

Uncle Bob rambles...

|

...about much over-hyped concept of Web-Services.

Folgende Dinge bisher rausbekommen:

  • Beliebiges Symbol innerhalb eines SDK-basierten PIOs instantiieren (nicht ganz so einfach wie es sich anhört aber nach einem Nachmittag wildem Suchen im SDK dann doch hinbekommen)
  • Doppelklicken auf ein PIO kann ich nun abfangen und dann z.B. einen beliebigen Dialog aufreißen
  • Es besteht auch die Möglichkeit den "Edit Group" Event abzufangen, aber das macht wahrscheinlich weniger Sinn im Kontext eines KMs?

Nächste Tasks:

  • Sauberes CodeWarrior-Projekt (ich würge grade noch im Sample-Code rum) aufsetzen
  • Den Code zum Generieren eines KMs einbauen
  • Code zum Generieren eines KM im Kontext eines PIO zum Laufen bringen
  • Das innerhalb des PIOs erzeugte Korpusmöbel korrekt plazieren
  • Diese (hoffentlich orthogonalen :-) Änderungen am KM auch in die aktuelle Version im CVS einfließen lassen

A'll keep you posted on my progress...

Four Strategies for Iteration

|

RefactoringMalapropism

|

New Year's Regressions

|

The history of calling conventions, part 1

|

The great thing about calling conventions on the x86 platform is that there are so many to choose from!

In the 16-bit world, part of the calling convention was fixed by the instruction set: The BP register defaults to the SS selector, whereas the other registers default to the DS selector. So the BP register was necessarily the register used for accessing stack-based parameters.

The registers for return values were also chosen automatically by the instruction set. The AX register acted as the accumulator and therefore was the obvious choice for passing the return value. The 8086 instruction set also has special instructions which treat the DX:AX pair as a single 32-bit value, so that was the obvious choice to be the register pair used to return 32-bit values.

That left SI, DI, BX and CX.

(Terminology note: Registers that do not need to be preserved across a function call are often called "scratch".)

When deciding which registers should be preserved by a calling convention, you need to balance the needs of the caller against the needs of the callee. The caller would prefer that all registers be preserved, since that removes the need for the caller to worry about saving/restoring the value across a call. The callee would prefer that no registers be preserved, since that removes the need to save the value on entry and restore it on exit.

If you require too few registers to be preserved, then callers become filled with register save/restore code. But if you require too many registers to be preserved, then callees become obligated to save and restore registers that the caller might not have really cared about. This is particularly important for leaf functions (functions that do not call any other functions).

The non-uniformity of the x86 instruction set was also a contributing factor. The CX register could not be used to access memory, so you wanted to have some register other than CX be scratch, so that a leaf function can at least access memory without having to preserve any registers. So BX was chosen to be scratch, leaving SI and DI as preserved.

So here's the rundown of 16-bit calling conventions:

All
All calling conventions in the 16-bit world preserve registers BP, SI, DI (others scratch) and put the return value in DX:AX or AX, as appropriate for size.

C (__cdecl)
Functions with a variable number of parameters constrain the C calling convention considerably. It pretty much requires that the stack be caller-cleaned and that the parameters be pushed right to left, so that the first parameter is at a fixed position relative to the top of the stack. The classic (pre-prototype) C language allowed you to call functions without telling the compiler what parameters the function requested, and it was common practice to pass the wrong number of parameters to a function if you "knew" that the called function wouldn't mind. (See "open" for a classic example of this. The third parameter is optional if the second parameter does not specify that a file should be created.)

In summary: Caller cleans the stack, parameters pushed right to left.

Function name decoration consists of a leading underscore. My guess is that the leading underscore prevented a function name from accidentally colliding with an assembler reserved word. (Imagine, for example, if you had a function called "call".)

Pascal (__pascal)
Pascal does not support functions with a variable number of parameters, so it can use the callee-clean convention. Parameters are pushed from left to right, because, well, it seemed the natural thing to do. Function name decoration consists of conversion to uppercase. This is necessary because Pascal is not a case-sensitive language.

Nearly all Win16 functions are exported as Pascal calling convention. The callee-clean convention saves three bytes at each call point, with a fixed overhead of two bytes per function. So if a function is called ten times, you save 3*10 = 30 bytes for the call points, and pay 2 bytes in the function itself, for a net savings of 28 bytes. It was also fractionally faster. On Win16, saving a few hundred bytes and a few cycles was a big deal.

Fortran (__fortran)
The Fortran calling convention is the same as the Pascal calling convention. It got a separate name probably because Fortran has strange pass-by-reference behavior.

Fastcall (__fastcall)
The Fastcall calling convention passes the first parameter in the DX register and the second in the CX register (I think). Whether this was actually faster depended on your call usage. It was generally faster since parameters passed in registers do not need to be spilled to the stack, then reloaded by the callee. On the other hand, if significant computation occurs between the computation of the first and second parameters, the caller has to spill it anyway. To add insult to injury, the called function often spilled the register into memory because it needed to spare the register for something else, which in the "significant computation between the first two parameters" case means that you get a double-spill. Ouch!

Consequently, __fastcall was typically faster only for short leaf functions, and even then it might not be.

Okay, those are the 16-bit calling conventions I remember. Part 2 will discuss 32-bit calling conventions, if I ever get around to writing it. [The Old New Thing]

Hiding email addresses with JavaScript

|

JavaScript : Hiding Email Addresses presents a nice simple way of including your email address on a web page wiile hiding it from spambots. [Small Values of Cool]

Epigrams in Programming

|

Good one

|

Failing to fully specify what happens with input buffers. Returned buffers too.

For example, ponder a hypothetical (yeah, right) library routine--let's call it, say, new_form which takes a NULL (rather than NUL, which is different, but you knew that) terminated buffer of field pointers. You call it and the fields in the buffer are now part of a brand-spanking new form. Yay, us. Anything that handles even part of form and field stuff is welcome, as it's a pain (though I could rant about ncurses for a while. But not today) to handle.

But... what happens to that buffer? Is it now the property of the form library? Did it make a copy and now I can delete my copy? If the docs don't say, I don't know.

Looking at the source is no help--I don't care what the source says, I care about what guarantees are made by the API. Just because the library makes a copy now (it doesn't, I looked, but that's a separate rant) doesn't mean that it has to in the future. Someone might, at some random time after now, decide that since the behaviour's unspecified and as such open to change. I'm perfectly fine with that, too, as flexibility is good, and I for one have no compunctions about viciously and egregiously changing behaviours that I've promised are undefined. (I take a certain glee in it, in fact :) But I should at least know what behaviours are undefined, dammit! Don't make me guess.

APIs are promises of behavior. Be specific with your promises, and clear about what you're not promising.

[Squawks of the Parrot]

...having callback function arguments that do not take a corresponding invocation-specific data pointer.

You want to have a function that takes a function pointer, and have your library call that function at some point in the future if some event happens? Cool! Works for me. I like those. (Well, sorta, event/callback/async programming is a pain) However.... the signature should never be:

int register_callback(func_pointer_t callback);

Bad! Bad programmer! No cookie! That signature should be:

int register_callback(func_pointer_t callback, void *extra_data);

Or, if you'd rather, take a struct that has the function pointer and callback data in it, if you don't want to manage the two pointers in your library. The signature for that callback pointer should be:

int callback_func(struct instance_data *lib_data, void *extra_data);

though I'm less adamant about that. Very very simple signature lists are best.

Why? Simple. While you may think that I'm going to have a custom callback routine with private embedded data in it all primed and ready for your particular call, you're wrong. This is C we're talking here--it's not like we have closures, so there's no way to have any sort of data bound at runtime. If I want to bind any data to the call it means I need to stick it in a global somewhere. Blech. Very, very ungood.

It gets even worse when dealing with any sort of indirect access to the library--like, say, if you're trying to do this from an interpreter. For that to work without any sort of data pointer requires creating a custom C function, either at compile-time for the module (which requires having a C compiler of some sort handy) or at runtime (which requires the capability of creating new functions on the fly) neither of which is particularly desirable. (Parrot, for example, doesn't need a C compiler handy to interface to most C libraries)

Postgres, pleasantly, doesn't make this mistake. You should endeavor to not make it as well.

If you want a really good reason, consider the following. Someone is writing an interface to your library for an interpreted language. Perl, Python, Ruby, Java, something on .NET--doesn't matter. The program runs, conceptually at least, on the interpreter. The interface writer wants to be able to write those callback functions in the interpreted language.

With a separate data parameter, it's easy. The interpreter builds some sort of closure structure, sets the callback function to be an entry point to the interpreter, and the callback data to be that closure structure. When the callback's made, the entry point function yanks all the info it needs out of the data parameter, sets up the world, and calls into the properly set up interpreter. While there may be a lot of really nasty funkiness going on in there, it's at least doable.

With no data parameter, though... you're stuck. The only way to do it, short of generating a new custom function pointer (which isn't that tough, but is painfully non-portable and something that gives most people a screaming fit to even think about) is to stuff the information you need for the callback into a C global somewhere. The problem there is that it means you can only have one pending callback (which is often suboptimal) and you've got potentially unpleasant threading issues. This is an especially egregious mistake with things like GUI interfaces where you may have dozens of hundreds of some sort of thing instantiated. At least there you've often got an OO interface, so there's the data in the objects, but even then it makes the low-level stuff annoying.

Generally people who use the libraries realize the problem straightaway, but the problem is that often the people using the libraries aren't the people writing the libraries...

[Squawks of the Parrot]

Recompile

|

Charles Miller complains about an obvious flaw in his design:

If I had access to my own source-code, and could recompile myself whenever anything went wrong, life would be so much easier.

Python Windows GUI Automation

|

Interesting starting point for home-grown automated GUI-testing (although selecting a button via it's window text won't work well for us).

Floating Point Arithmetic

|

The canonical discussion of FP arithmetic (for this audience, at least) is a 1991 paper by David Goldberg titled "What Every Computer Scientist Should Know About Floating-Point Arithmetic" via [Eric Gunnerson's C# Compendium]

[via Thinking In .NET]

Cool.

|

The Museum of HP Calculators.

Yes, I own a HP-41CX. Not sure if it still works, but it used to be a cool gadget. Ahhh, RPN. [via Ned Batchelder].

HeisenBug. Never heard of this

|

HeisenBug. Never heard of this analogy, But it's right on target,

Standalone Trackback for Radio UserLand.

|

Standalone Trackback for Radio UserLand.

Debuggers are a wasteful Timesink?

|

Robert C. Martin thinks that Debuggers are a wasteful Timesink.

Well, Robert is a smart guy. But he's plain wrong on this one.

What's the cause for a bug in the first place? The programmer's expectation of what the code is supposed to do doesn't match what the code is actually doing. In this context, thinking about what might have gone wrong more often than not results in meditating in front of the computer instead of letting the running code tell you what went wrong.

Don't use the debugger instead of your brain, use it to complement your brain. Let's settle for this, more modest statement.

Charles Miller has are some more thoughts on the topic.

Fantastic

|

Obvious/Oblivious. A Tester's blog.

Subscribed.

Dynamic Productivity with Ruby -

|

Dynamic Productivity with Ruby - A Conversation with Yukihiro Matsumoto, Part II

Modern C++ Style - A

|

Modern C++ Style - A Conversation with Bjarne Stroustrup, Part II

Cross-platform String class.

|

Cross-platform String class.

Building the next new language

|

Ted Neward wants relational language extensions:

Basically, I want the object-relational impedance mismatch to go away, just like everybody else does. But instead of continuing to try to force objects on top of the relational model, how about we give up going in that direction, and instead try lacing relational semantics into our favorite languages of choice? ....What I really want to do, in a single sentence, is extend the data model away from a concept of "fields" and include some higher-order primitives into the mix. For example, coming from the relational world, I want to see a relvar, a relational variable a la C. J. Date, as a basic primitive type within the language....I want a node primitive type, to which I can apply XPath operations... I envision something along the lines of:

relvar r = { fn, ln, age} [ ["Ted", "Neward", 32] ["Don", "Box", 39] ];
foreach (tuple t in r)
{
  printOut("Name is " + t.fn + "" + t.ln + ", " + t.age + " years old");
}

relvar r2 = { fn, ln, age} [ ["Fritz", "Onion", 39] ];
relvar r3 = r UNION r2;
printOut(r3.count); // Prints "3", since there are 3 tuples

and so on. Syntax is somewhat derived from Date, 8th ed.

Similarly, I want the ability to do XPath over XML as built-in language capabilities; something along the lines of:


node n = Ted
string s = n/name/text(); // an XPath query against the node "n"
and, of course, both node and relvar types would support the usual range of insert/remove operations, such as the UNION used above, or a += syntax for appending nodes to n as child nodes, and so on.

.... Oh, and while we're at it, I want the language to understand transactions as a first-class processing concept, too:


x = 5;
transacted
{
x += 5;
throw new IllegalArgumentException("can't do this!");
}
finally // a.k.a. commit
{
printOut("We committed! x = " + x);
}
rollback
{
printOut("We rolled back! x = " + x);
}

// x has the value "5", since the exception forces an implicit rollback

via
[The Mountain of Worthless Information]
[Thinking In .NET]

Interesting thought. Especially for a die-hard relational database freak like me.

Ruby. Yeah, I'm late...

|

Ruby plus RubyCocoa Bridge. Interesting Smalltalk-like scripting environment. Also available on Windows.

Pre-installed on MacOS X.

In der MacUp Ausgabe 12/2003,

|

In der MacUp Ausgabe 12/2003, Seite 89ff. finden sich interessante Grundlagenartikel zum Thema "Schriften".

VisualWorks Smalltalk is available as

|

VisualWorks Smalltalk is available as a free download for non-commercial use. Excellent. Highly recommended.

Programmer's Font.

|

http://www.tobias-jung.de/seekingprofont/

Great Blog on Software Testing.

|

http://blogs.gotdotnet.com/jledgard/

Check out the post titled Software Testing 6: Good Tests for Bad Parameters. There are other posts from this series worth reading, too.

Subscribed.

Test-Driven Design/Development

|

Interesting rambling about Test-Driven Design/Development]

MS redefines refactoring

|

No, that's not Refactoring. That's bullshit. No, I'm not anti-Microsoft.

Via [Michael Lucas-Smith] via [Smalltalk with Rants]

CVS integrated with the MacOS Finder.

|

http://cvsfinder.sourceforge.net/

Has Java Reached The Inefficiency Phase?

|

Adding Generics to the Java language isn't going to revolutionary change the status quo. People extremely over estimate the value of language constructs in the overall scheme of providing compelling solutions to a customer. [Artima Weblogs]

Yes.

Longhorn - Introduction

|

Introducing "Longhorn" for Developers. More parts to follow.

Specification and expectation

|

The Demand for Software Quality - A Conversation with Bertrand Meyer, Part I.

Quality - What's lacking in the conversation so far is a precise definition what software quality really is.

  • Developers define software quality in terms of a specification ("works as designed")
  • Users define software quality in terms of their expectation ("works as expected").

Specification and expectation are not in-line most of the time.

Couple of ideas concerning Rendezvous

|

Couple of ideas concerning Rendezvous technology.

Pashua is a tool for

|

Pashua is a tool for creating simple, but native Aqua GUIs for Perl, PHP, Python, shell scripts and AppleScript. Pretty cool. Simple concept.

Informationen zur Zahlendarstellung im Rechner.

|

Informationen zur Zahlendarstellung im Rechner. Relevant für Azubis.

Dependency Inversion Principle. How to

|

Dependency Inversion Principle. How to structure your design to minimize dependencies.

Martin Fowler on Continuous Integration.

|

Martin Fowler on Continuous Integration. There's also an interesting variation of the article targeted towards C++ development.

Exploring with Wiki. A Conversation

|

Exploring with Wiki. A Conversation with Ward Cunningham, Part I by Bill Venners.

Martin Fowler talks about Refactoring

|

Martin Fowler talks about Refactoring for the C language and points to some interesting resarch projects.

Free CVS Book, 2nd edition.

|

Free CVS Book, 2nd edition.

More on exceptions and status

|

There's lots of good stuff

|

There's lots of good stuff on Ned Batchelder's site:

Plus, an interesting Blog. Subscribed.

In favor of exceptions.

|

In favor of exceptions.

Looks like a promising blog

|

Looks like a promising blog about HI-related issues. And the comic is cool, too: http://www.ok-cancel.com/index.html. Subscribed.

Strings, some practical advice. Now

|

Strings, some practical advice. Now that I've gone off a bit about the structure of strings, you're probably wondering what exactly good is it all? Knowing how things work doesn't necessarily translate to any sort of utility, at least not immediately. (I think it's essential for real understanding, but real understanding is in short supply on so many things...) But some good advice is in order. Like so many things I go on about, keep in mind that this is from the standpoint of a VM designer/implementor--I understand and do infrastructure. I have precious little experience implementing applications, unless you consider something like Parrot... [Squawks of the Parrot]

What the heck is: A

|

What the heck is: A string. And no, it's not nearly as stupid a question as it may seem. This time out, we're going to talk about string data, what it means, how its interpreted, and odds are how much stuff you've never had to think about with it. Strings are remarkably complex things. Remarkably confusing, too, if you're mono-lingual in a language with a simple base writing system. (Like, say, me) A "string", for our purposes, is a series of bits that represents some piece of text in a human language. What you're reading now is text, as is the stuff in your phone book,... [Squawks of the Parrot]

The C++ Style Sweet Spot

|

The Absolute Minimum Every Software

|

Robert Scoble asks lots of

|

Robert Scoble asks lots of great questions regarding the upcoming OS technology from both Microsoft and Apple.

98-page refactoring example by Martin

|

98-page refactoring example by Martin Fowler.

Agile testing directions: Testers on

|

Martin Fowler talks about TechnicalDebt.

|

Martin Fowler talks about TechnicalDebt.

You have a piece of functionality that you need to add to your system. You see two ways to do it, one is quick to do but is messy -
you are sure that it will make further changes harder in the future. The other results in a cleaner design, but will take longer to put in
place...

'dftb' Resources oder "Der grüne

|

'dftb' Resources oder "Der grüne Knödel".

Dialoge werden unter MacOS Carbon durch eine Vielzahl von Resourcen beschrieben:

  • 'DLOG' - Der eigentliche Dialog
  • 'DITL' - Die Liste der Controls im Dialog
  • 'CNTL' - Definition von Controls im Dialog (für nicht-triviale (Reiter) oder "moderne" Controls (Bevel-Buttons))
  • 'dctb' - Farbinformationen zum Dialog
  • 'dlgx' - Erweiterte Informationen zum Dialog, wie z.B. Verwendung von Hintergründen, Embedding Hierarchy etc.
  • 'dftb' - Fontinformationen zu den einzelnen Controls im Dialog

Insbesondere zu jedem Static-Text sollte ein entsprechender Eintrag in der 'dftb' Resource vorhanden sein. Resorcerer pflegt die 'dftb' Resource beim Bearbeiten der 'DLOG'/'DITL' Resource nicht immer korrekt mit, so daß teilweise Controls im Dialog ohne 'dftb' Eintrag existieren. Dies führt zur Laufzeit zu nicht reproduzierbaren Effekten wie dem plötzlichen Formatieren eines Texts im Dialog mit zufälligen Informationen. Wieder was auf die harte Tour gelernt.

Anticipating Builds. Everytime I make

|

Anticipating Builds.

Everytime I make changes to a header file, I immediately save it and start a build. Meanwhile, I continue working on the corresponding source code. This strategy cuts down the build time substantially, because all dependent files are getting build while still working on the source code.

Yea, probably not the world's most advanced strategy, but it works well.

Wichtig. Niemals $log cvs-makros in

|

Wichtig.

Niemals $log cvs-makros in header-files einbauen, sonst darf man nach einem cvs commit gleich nochmal einen Full-Build machen. Mal abgesehen davon, daß sich mir der Sinn der $log Makros sowieso nicht erschließt und ich diese sukzessive rauswerfe.

Ted Leung on Computers, monocultures,

|

Ted Leung on Computers, monocultures, and history.

Today's computing environment is far more monocultural than is being discussed. It's not only the monoculture of Microsoft operating systems. It's a monoculture of statically typed languages derived from a C base. It's an operating systems monoculture where most of the ideas are derived or recycled from Unix. It's a hardware monoculture that results in hardware that is optimized to run C programs.

Agile testing directions: technology-facing product

|