Wednesday, November 28, 2007

Some Metrics

LanguageAvg Methods/ClassMax Methods/ClassAvg Params/MethodMax Params/MethodAvg Fields/ClassMax Fields/Class

I ran the metrics, that I talked about in my last post, in three environments and the results are above. Nothing really shocking, but the maxes did surprise me. I was mainly interested in the averages and the maxes were there just to see how huge the big boys really are.

I wonder what developers would think of a language that restricted the number of things that they could define. What if by looking at the numbers of above, I designed a language that didn't allow more than 256 methods/class, 8 parameters/method, and 16 fields/class. It would force the developer to write smaller entities, but would it annoy more than help?

Where I'm going with this is simply, what if the language enforced certain hard restrictions instead of allowing any incredibly large number of possibilties? If elements were kept to a certain size, would it make programming in the system more pleasurable since it would be difficult to create a god object? Objects would not get out of hand before refactoring thus making maintenance easier.

My gut instinct is that constraints would annoy and ugly code would still live. Developers would just figure out ways around them. I would love to think that by adding constraints, we could get better code. But, no matter what you measure quality by, there will be developers that will figure out how to get around it. Pessimistic, I know. But, it's simply human nature.

Still, I wouldn't mind if the language did have some limits, so that individual items stayed small. If the constraints were not dogmatic, it would make the need to get around them less attractive. Of course, with smaller things comes naming them and that would still be a problem. But, that's a problem with mammoth sized objects as well. I'll keep thinking on this. There's got to be a way to have flexibility to dream the impossible and yet gently nudge us into more maintainable programs at the same time. The problem with balls of glue is that slowly become that way. It would be nice to not allow them to become Godzilla.

Tuesday, November 27, 2007

Limitations Of The JVM

  • The maximum number of local variables in a method is limited to 65,535.

  • The maximum number of fields in a class or interface is limited to 65,535.

  • The maximum number of methods in a class or interface is limited to 65,535.

  • The maximum number of direct superinterfaces of a class or interface is limited to 65,535.

  • The maximum number of method parameters is limited to 255.

What's the point of the list above? Sure, those numbers are reduced by various factors (like this reduces the number of method parameters by 1). But, that is not the point, my friends. The point is all of the above numbers are HUGE! I was reading my trusty copy of "The Java Virtual Machine Specification Second Edition" when I got to Section 4.10 and read some of the above bullet points. In Java, I live in the land of the plenty.

I know it's all two byte boundaries and all, but what if they left some of these at one byte or 4 bits? I can hear it now: "But, we have all the space in the world! Why constrain ourselves in such a way!" True. But, when was the last time you looked at a method with 80 parameters and thought: "DAMN! Now, that's some beautiful code." Exactly. You never have and you never will. The point is not to constrain on a byte boundary, but on a good coding boundary.

Arbitrary numbers are awful to use as metrics (like you must have less than 3 arguments to each method and so on). Metrics are useful in relation to something else. You pick what seems reasonable to you (which might not be reasonable for someone else). There is a boundary where any reasonable programmer starts to hurl at bad code though. Metrics are set below that for each team. I hope I never see the interface with 16,000 superinterfaces. I really do. The cool thing is we have a huge library in Java to look at to see what is reasonable. We have tons of open source projects to feed our reason as well. What if...What if we picked what was reasonable from these code bases by using averages and everything else in our numerical power? Then, we doubled it to make it unreasonable. I wonder what the numbers would look like?

My next experiment is to run some code reflecting over both Java, Ruby, and Smalltalk code. I wonder what the averages for each would be (number of method parameters, number of methods per class, number of fields, and number of local variables). I'm curious. I have a guess at what the numbers will be. But, the raw numbers could be telling. I would like to see them for all three of the above languages. It should be interesting. I know there's probably someone out there that has done the same thing, but I want to run the tests on my own. For now, I will do it with the base libraries of all three. My guess is that they will be roughly around the same for each of the metrics that are comparable in each of the languages.

What's the point? By reading and then thinking of the worst, it got me thinking. Our languages constrain us in ways that they shouldn't, but don't in what would make our code better. Would it be such a bad thing having to split a method up because you ran over a rather large (let's say 256) number of local variables? I want to find the number where it seems unreasonable and grotesque and make that my limit. I know 65,535 is absurd for the number of local variables, but so is 256. What about 16? My answer is "HELL YES IT IS!", but there are those that would argue that sometime you need that many. 16 is not hideous, but is still in poor taste.

I'm off to see the wizard. I'll let you know what he says.

Sunday, November 11, 2007

A Happy Diversion

I was smitten with my quick snippet of code for my Monticello window in a flap. As with all little things in Squeak, it's hard to just stop. You're always thinking of little things or tools that would be nice. Everything in Squeak is easily explorable and changeable. It's too much fun to search and see the results of your labor instantly. Addictions are not pretty.

Another idea came to me. The tab for my Monticello flap was boringly called "Monticello". What a waste of real estate. My second problem was that I'm always getting confused at which project I'm in. I normally use different background colors to make it easy. But, I still get confused. I was blessed with a small brain. I curse it everyday. What is a poor little Squeaker to do? I thought I could put the name of the current project on the Monticello tab instead of the one it has. I wondered how hard would that be? And off I went...

How can I do that? I could change the tab name when the project changes. Eureka! That's what I will do. I remembered I wrote a little utility to change background images and I had to know when the current project changed. I started my hunt there and event handlers are available via the morphic world to know when a project is entered or exited. We only care about when a world is left. Why? The event handlers has to be registered on the world itself and we don't want to have to keep track of every project and world. It's easier to put a handler on the current project and know when it is left.

Let's start with this method for setting the world we're currently in:
world: aMorph 
world == aMorph ifTrue: [^ self].
world ifNotNil: [world removeActionsWithReceiver: self].
world := aMorph.
world ifNotNil:
[self changeTextOnTab.
when: #aboutToLeaveWorld
send: #leavingWorld
to: self]

Basically, this method removes all events from the old world since we will not care about it any longer. Then, we change the text on our tab and add our event handler. Next, how do we change the text on the tab? In the menu for a tab, is an item to change the name of the tab. Using the handy morphic handles, I inspect the menu item itself and find the method it will call when it is invoked. Here's the code I came up with:
self monticelloFlapTab ifNotNilDo: [:tab | tab changeTabText: Project current name]

The simple method changeTabText: does all of the magic. We just get the name of the current project. I haven't showed you how to get the tab itself. I look through the methods on the class side of Flaps to reveal its magic:

^Flaps globalFlapTab: 'Monticello'

The good news is that it will always find the flap this way no matter the name. The only thing left is to what to do during the handling of leaving the current world. The dilemma now is how do we know the next world? Some more digging and we can be ask ed to be called later. Perfect. Here's the code for the handler:
WorldState addDeferredUIMessage: [self world: Project current world]

And that's it! The same method can be called to seed our initial world as well. Now, a quick glimpse to the bottom of the screen gives my project name. Easy. Now, I can get back to updating my Seaside presentation.

Why I Love Squeak

| newTab monticelloBrowser |
newTab := Flaps newFlapTitled: 'Monticello' onEdge: #bottom.
self currentWorld addMorphFront: newTab.
newTab adaptToWorld: self currentWorld.
Flaps addGlobalFlap: newTab.
newTab showFlap.
monticelloBrowser := MCWorkingCopyBrowser new.
(monticelloBrowser window)
openInWorld: newTab referent extent: monticelloBrowser defaultExtent;
topLeft: newTab referent topLeft + (10 @ 10).
newTab referent height: monticelloBrowser window height + 20.
newTab hideFlap

The above code snippet adds a new global flap to the Squeak environment. Inside the flap is the Monticello browser. I've been doing this in my Squeak images for a long time, but doing the above by hand for each image. I went into the system and figured out what each of the menu items did to create the above. This is simple in Squeak because everything in Morphic is inspectable. It allowed me to create the script you see.

The reason for having a Monticello browser in a global flap is so that you can always have it open in every project and easily accessible. I like to have a Squeak project for everything I do and like having one Monticello browser.

The above was not much effort and took little time to figure out. Love is.

Saturday, November 10, 2007

Seaside Presentation

I updated my Seaside Presentation available on SqueakMap to Seaside version 2.8. Make sure you update your SqueakMap. The new version is 1.70. I plan on reworking it completely soon. As I upgraded the code, I was unhappy with what I saw. It needs to be refactored heavily. I want to add more code that shows off the cool new add-ons for Seaside as well. Enjoy!

Thursday, November 08, 2007

Bug Finder

Two of my favorite tools to use in coding are: a code checker and a code beautifier. The first points to sloppy and rushed code. I find sloppy code to be a vital protein for bugs to grow. The second shows me a consistent view of the code. It's amazing how many bugs you can pick out by just running a code beautifier and glancing over the code. I'm always amazed what I find with a code beautifier. What's even more shocking to me is that a lot of developers hate them. Even if the formatting is less than to my liking, I still use it. Why? It catches so many moments of unclarity. It also points to code that should be broken up into smaller bits. If the code beautifier formats my code to be ugly, then I need to refactor. It's a rule of thumb that has served me well.

Of course, I usually run the code beautifier to get a lay of the land on new code and roll back when I'm done. Why? There's nothing more annoying than searching through tons of code changes to find out that the code was only reformatted. Now, if it's my code, I don't check it in until a code beautifier has been ran on it. I find studying my code after running it is just a good habit to get into before check-in. Reading code that's normalized makes it easier to spot patterns of inelegance.

I'll write more about the code checker, also known as Lint in some circles, in another post.

Friday, November 02, 2007

Omaha Dynamic Language Group

You wanted the best. You got the best. The hottest presenter in the land...Ben Heath! What could be better than a Kiss concert, a talk on PHP of course. This month Ben has offered to show us what we have been missing in PHP. The language itself is loved by web programmers all over. If you have ever been curious, now's the time to find what the fuss about PHP is all about.

ProKarma is sponsoring this presentation. They will be providing the food and drinks. So, what do you have to lose? You get to learn something new, hang with the smartest people in Omaha, and free food. My friends, it just doesn't get any better!

TopicPHP: Practical Web Programming
SpeakerBen Heath
TimeNovember 6, 7-9pm
LocationUNO's Peter Kiewit Institute (PKI) building
1110 South 67th Street
Omaha, NE