Sunday, October 30, 2005

New Me

Well, I cut my hair off recently and everyone that I know has been curious as to what I look like now. So, for the curious, here is my post-metal locks:




My wife was kind enough to take the pictures and touch them up! I must admit I love it. Rock on!

Saturday, October 29, 2005

Early Binding Gotchas

I recently ran into code like this:

public class MyType {
public boolean equals(Object other) {
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof MyType)) return false;
return equals((MyType)other);
}
public boolean equals(MyType other) {
return someValue == other.someValue;
}
}

Nothing really stands out as being WRONG, does it? It's making clever use of overridden methods and it looks like it might even save us some time if we know the object ahead of time (equals(MyType)). And that is where the "gotcha" is! Let's look at a test shall we?

public void testEquals() {
MyType myType=createExampleMyType();
MyType otherType=createAnotherExampleMyType();
MyType nullMyType=null;
Object nullObject=null;

assertTrue(myType.equals(myType)); //correct
assertFalse(myType.equals(null)); //correct
assertFalse(myType.equals(otherType)); //correct
assertFalse(myType.equals(nullObject)); //correct
assertFalse(myType.equals(nullMyType)); //This thows anException! WHAT THE @#$%^&!!
}

OK, let's break this down shall we? The first test binds to equals(MyType) because the java compiler early binds its arguments in message sends. It figures out the argument types from the variable types used and finds the appropriate message to call at run-time (basically, it early binds the arguments and late binds the receiver). The second test binds to equals(Object) because it finds the most generic method it can. Since, we didn't say what type of null to use, the compiler picked Object for us. Next up, the third test binds just like the first, since we know the types of arguments. The fourth test is now trivial to us, right? Which leads us to the final and most troublesome test. Bascially, equals(MyType) got bound because the compiler doesn't know that we left that good ole null in there! So, where we thought we were safe, we are not. We just bypassed all our null checking code. Oh poo...

So, what can you do?

public class MyType {
public boolean equals(Object other) {
if (other == this) return true;
if (!(other instanceof MyType)) return false;
return equals((MyType)other);
}
public boolean equals(MyType other) {
if (other == null) return false;
return someValue == other.someValue;
}
}

The simple answer is to move your null check into your equals(MyType) method and be done with it. Just remember that null and early binding are gotchas not to be taken lightly when using overridden methods.

Great Idea

I was checking out Fall Of Troy's website and clicked on the tour dates. Uninterestingly enough, it shows a list of tour dates. I saw that they were going to be in Iowa and I thought, "Wow, that would be a cool show!" So, I click on the link and it takes me an info page telling me all the usual stuff (venue, address, time, ticket prices, etc), but with one small difference. You can add yourself to the list of attendees! What a cool idea! It allows you to exchange emails with people before the show and talk music. I wish the internet had been bigger when I was in college. We used to just get to the show early and hang outside to meet new folks. It was a blast. Anyway, I thought it was a great way to meet people wo are interested in the same things and who doesn't need more friends?

CD Extra Tracks

I hate added silence to get to the bonus tracks of a CD. I don't mind a 3 second delay, but when you make it more than that: You're testing my patience! And most of the time, the extra song was not even worth the wait. So please, I plead with record companies to stop adding silence to wait on the impending bonus track that will not rock my world. Thank you.

Friday, October 28, 2005

Cute And Fun

Why do the Lisp dudes have the best cute ideas? First, it was Schememonster and now, a cool alien logo. I love the idea behind it too. It's kind of poking fun at themselves and at the same time, letting the world know that we are DIFFERENT and that's GOOD! It's inviting in a "Jump on in, the water's fine!" kind of way. It's anazing how much the Lisp and Smalltalk inventors just got it right. It's even still amazing people are still discovering things that you can do with both. Rock on!

Wednesday, October 26, 2005

Being Sick Sucks

I've been ill for this week and I'm aggravated with it now. Nebraska has killer viruses that knock me out for a week at a time. I've been sleeping all of the time and I'm only conscience for only a few hours everyday. It's viral and the only thing to do is medicate and sleep it off. I hate being sick. I was excited about this week at work too. Grrr. I can't even read an article without spacing into neverland. Oh well, it's back to bed for me. And there is so much good material to read from OOPSLA 2005. Grrr. I hate illness!!!

Sunday, October 16, 2005

Some Days Are Meant For Play

I read Michael Lucas-Smith's blog this morning and immediately downloaded his Higher Order Methods package in my VW image and read the documentation on it. I thought to myself, "WOW! This would be a nice addition to my Lazy Collections framework!" So, instead of working on Needle in VW, I update the Lazy Collections framework in Squeak. Shame on me! But, it was SO MUCH FUN! The implementation is different from Micheal's, but I used a similiar implementation to the internal's of Lazy Collections. Basically, this is just me playing around. I made a few additions like prepending each to common methods (like #printString is #eachPrintString). It cleaned up my test a lot! Just download it and compare the #test method with #testIterator. The iterator version uses Higher Order Methods. I like the shortened syntax.

It was a fun exercise in blocks and doesNotUnderstand! OK, I'm going back to my regularly scheduled program. I would like to thank Michael Lucas-Smith and Travis Griggs for the inspiration. Your code as always is a lot of fun to read and study.

You can get the new version of LazyCollections on SqueakMap.

Saturday, October 15, 2005

Poor Interface

You know you have a bad interface when there are store fronts to sale stuff on your site. I don't know, but I would be embarrassed if I was the head of Ebay. There's a whole niche maket springing up simply because your user interface is so hard to use. So, people will take their stuff to someone else to deal with it. I know I've seen at least two of these stores around my neighborhood and they've even been spotted in movies (in 40-year Virgin, it was a part of the story!)

Monday, October 10, 2005

Re: Re: Dolphin's Command Framework

I got the following comment from Günther regarding this previous discussion:
Blaine,

I tried to get this to work with Menus and ContextMenus in the ViewComposer, without success.

Could you give us a for dummies description how to do that?

Thanks,

Günther, guenni

OK,
I've been writing a little utility for myself to manage my Mp3s in Dolphin and here's the code that I use to add commands to a context menu (when you right-click on a model object in a tree view):
setContextMenuFor: aModel 
| menu |
menu := aModel isNil
ifTrue: [nil]
ifFalse:
[| contextMenu |
contextMenu := Menu description: 'IRiver'.
aModel actionItemDescriptions do:
[:each | | command description |
command := each key.
description := each value.
contextMenu
addCommand: command
description: description].
contextMenu].
self tree view contextMenu: menu

The interesting bit of this method happens in #addCommand:description:. The command argument can be anything that understands the protocol #queryCommand: and #value. Symbol and MessageSend both do as well as my CommandMessageSend that I discussed earlier (since it is a subclass of MessageSend). Here's some examples of #actionItemDescriptions implementations that are called on the model in the above code:
Mp3Respository>>actionItemDescriptions
| result |
result := super actionItemDescriptions.
result
add: (CommandMessageSend receiver: self selector: #syncBackup) -> 'Sync Backup'.
^result

Mp3Root>>actionItemDescriptions
| result |
result := super actionItemDescriptions.
result
add: (MessageSend receiver: self selector: #save) -> 'Save'.
^result

I tried doing it through the ViewComposer and it can be done, but it's more trouble than it's worth. I decided to generate the code dynamically if I needed it. It's just as easy to add it through the code as it is to add it via the ViewComposer. I hope this explanation helps. I was trying out to see how I liked the model answering the things that it could do without knowing about the GUI. This was a cut at what it would feel like. Feel free to email me! =) I'll try to get on the IRC discussion more often.

Application vs. Data

Ravi Venkataraman wrote:
It is unfortunate that many people in the software industry do not understand that applications come and go, while data remains for much longer.

Is it that really true? I've been in the business for now over 10 years. And I've never seen the lights turned off ANY application. In fact, I've seen many mainframes persist when they should have been replaced. The application and the data is the whole picture. The application has the business logic and knows what to do with the data. I know our experiences will be different and our mileages will vary.
If, as you are suggesting, every application defined its own terms and essentially created its own data model, how can the enterprise ever know anything? Say, for example, every department and system defined "customer" in its own way, then how can you answer the simple question, "How many customers do we have?"

I think we're looking at the same problem through different lenses. I think applications should have access points to get information that's inside of them. I believe in encapsulation. It's the classic black box vs. white box. I see the problems in both and I wonder if we could come up with a mutual solution. A common database makes it easier to find "how many customers do I have?", but what if all applications had common access points and you could answer the same question? They both require expertise in different areas. Is one better over the other? The more I think about it, I come to the same conclusion: Both require planning and thought. You can certainly paint yourself into a corner with both. Maybe we should have a mixture of both. Can we have a mixture of both? What would that look like? I would love to discuss this further...
The fact that data modellers create unchangeable, unmaintainable data models is a reflection on their lack of competence. Most data modellers know zilch about data modelling. Just like the vast majority of Java developers know nothing about OO concepts.

I think if you look at any human endeavor, you will find a bell curve. Few will be awful, few with be great, and most will be average. I think a lot of times data modeling gets into discussions of performance way too early (much like getting into performance issues too early in OO design causes problems). Good data models are hard much like OO models are hard. I think I'm a pretty good data modeller, but I could be wrong. Do you have any good books that I could read? I'm always into bettering my craft.
The right approach is to build the data model from an enterprise point of view, then use database views to show the application specific representation. That insulates the application developers from the actual implementation of the data model; and takes care of all the problems you mention.

I believe this is a slippery slope. Common OO models to reuse across enterprises have been tried and I've seen them get stumped on "simple" questions. What seems straightforward for one part of the enterprise might not be for another. It's the difference in context between organizations. Vague language is the main culprit. Common terms might mean different things to different parts. To get them to agree and use them consistently is another matter. RDMS answers the problems of making sure my tables have integrity, but what about values in fields? For example, what about ranges? Most business rules are complex beasts and they usually go beyond the integrity constraints of RDMS. And to get different parts of a large organization to agree on the business rules for each segment is a hard problem. Like I said before, maybe we can discuss this to come up with a better solution.

The main purpose of a RDBMS is to enforce data integrity. Applications used to enforce integrity, but that failed more than three decades ago. That is why the shift to RDBMS occurred. The network model and the hierachic model, along with using files for storing data, rather than a higher level abstraction, created many problems.

Oh, I'm glad we don't store things in files anymore! I just think applications should have access layers that allow outside applications to intergate their information. Allowing an outside application access a public object model is powerful stuff. It allows the outside application to even update my system because I can enforce my business rules while keeping my data encapsulated properly. Anyway, thanks for the history lesson, but I know the reasons why RDMS came into being.
You seem to be suggesting that we should go back to the 1970s and try things that were known to have failed at that time. Why do you feel it should succeed this tme?

I am in no way suggesting we go back to the 70's. Most mainframe system provided no way for outside system to access their internal data. Most of the mechanisms have been added afterward. I'm suggesting a layer of abstraction above the database. It takes a little more effort to add a component layer to an application, but it's absolutely needed in enterprise settings. But, let's discuss and not give history lessons or bad assumptions:
The original weblog article is flawed in so many respects that one is filled with despair.

If the suggestion is that each application develop its own data model, then what happens to data integrity? How are the common integrity and business rules expected to be applied across all applications? Duplication? What if one application modifies the code in a manner inconsistent with the business rules?

I suggest that you learn a little bit about RDBMS before talking about them.

I suggest you don't assume what my background is. But, let's talk like educated and intelligent beings. I believe applciations should manage their internal data integrity and provide a model to the outside world. I believe in encapsulation at the application component level as well as the object level. I'm opening up the discussion. You make a lot of valid comments and I think we can come up with a cool solutioon if we concentrate on our goal and not tearing each other down.

Sunday, October 09, 2005

Omaha Smalltalk User's Group Meeting

This month I will be presenting Seaside, Avi Bryant and company's brilliant continuation-based web framework. People have been requesting it again so I thought it was time to do it again. It should be a lot of fun as always!

Here's all of the details:

When: October 11, 2005, 7pm - 9pm
Where: Offices of Northern Natural Gas
1111 S 103rd Street
Omaha Nebraska 68154

Office is at 103rd & Pacific. Guests can park in the Northern visitors parking area back of building, or across the street at the mall. Enter in front door, we'll greet you at the door at 7:00pm. If you arrive a bit later, just tell the guard at the reception desk you're here for the Smalltalk user meeting in the 1st floor training room.

Saturday, October 08, 2005

Tacky

This should be filed under Tacky. I can't believe they would actually sell this t-shirt. I was shocked and saddenned. And we wonder why more women do not get into our industry?! We are not inviting with crap like this.

Get Up

Need apparel on the positive side? What a cool and nefty idea. T-shirts with positive messages. How fun. Now, I wish someone would put all of the funk phrases on t-shirts (from P-funk, Graham Central Station, and EW&F). Nothing really more to say, I just really liked this idea.

Sunday, October 02, 2005

Shared vs. Mobile Data

Alex Bunardzic writes about "Shared Data and Mobile Data" in response to his article on "Should Database Manage The Meaning?" He makes an important distinction in the debate. There's people who think the database should be the central point and then, there's those of us who think data should be mobile (not centralized). I think the folks that believe in centralized databases should read William Kent's "Data And Reality" book to see the problems with that view. It basically boils down to meaning. Different projects will view what might seem to be the same data differently. We might even use the same terms, but have slightly different meanings. It's the slight difference that kills the shared database model. Not to mention, that over time shared database models become unchangeable and unmaintainable because of the massive amounts of coordination it takes to make a change (even with volumous documentation which is usually out of date anyway). Who wants to make a change and be held accountable for every system they break? It becomes a "let's just hack this field that only we use so we don't have to go pull teeth". Ouch. It's easier to just change your code than burden evryone else (who may not want to make ANY changes to their code at all...it's not in their budget) I've seen this scenario more times than I care to count.

Mr. Kent's book exposes these problems and lays them out. The book is great for exposing the problems that basically boil down to humans having ambigous language. Even though our computer languages are strict, our meaning still is king and that's the disconnect. It's the same reason that common business objects that cross enterprise divisions are problematic as well. They each have their own meaning of various words used to label things. It's best to have each system to have their own database and have distinct boundaries where they exchange information. Everyone keeps their definitions (which makes sense to their users) and makes conversions on the boundaries.

Eric Evans' excellent "Domain-Driven Design" offers the solutions to the problem. In fact, he has an example in the beginning of Chapter 14 (Maintaining Model Integrity) that explains it. Different systems might be working on what seems to be the same model, but they are looking at it from different contexts. Each system should have its own "bounded context" of the model. Here's an excerpt from "Domain-Driven Design" that explains it clearly:
Explicity define the context within which a model applies. Explicity set boundaries in terms of team organization, usage within specific parts of the application, and physical manifestations such as code bases and database schemas. Keep the model strictly consistent within these bounds, but don't be distracted or confused by issues outside.

He continues to make a point of keeping the boundaries distinct (don't allow them to blur) and be explicit in communication with outside systems (by using "context maps" for conversion to/from outside systems).

The bottom line is keep your systems distinct and avoid the allure of sharing common domain/data models. Keep the boundaries distinct and exchange information with outside systems. I wouldn't even allow common exchange formats across systems (It runs into the same exact meaning problems). Define the exchange for each system (A different DTD for each one if you use XML, I'm not saying to not use standards, just don't define a common DTD for all system exchanges across the enterprise). Don't be lazy. Let your system keep the meaning and don't let it get watered down. Sharing allows meaning to be blurred (and misused) and this lets the bugs in. Data warehouses sound like good ideas, but really your duplicating the meaning to pull everything together. An agent system would be a better answer where it gathers the information from each of the systems at their boundaries. Since the agent would be its own system. It's a harder path to follow, but it's the one that allows your systems to continue to grow and not stagnate. The minute you buckle a system together with another, the stagnation will begin and the cost curve will start to rise.

Firefly: Huh?

I was excited to see Serenity until I saw my first episode of Firefly. I can see why the Fox executives killed it. I know I would have. Which brings up the question: What am I missing? The show I saw was little more than take offs of previous Star Trek (original series) episodes, bad scripting, bad acting, and over-worked sci-fi cliches. It basically killed my desire to see the movie. I saw the previews again and the poor scripting came up in it as well ("Do you want to captain this ship?" "YEAH!" "Well, you can't!"...That's GOOD?). I don't know I'm just tired of Star Trek sci-fi. It's been done to death. Give me Planet of The Apes, new Battlestar Galactic, Logan's Run, Philip K. Dick, and 2001 any day. Give me sci-fi that makes me think (as you can tell, I like sci-fi with political themes). Am I truly missing something? Am I not supposed to take it so seriously? Is it meant to be so bad that it's good? I'm at a loss here.