My Stuff
My Amps

Add this feed to a running copy of BottomFeeder

Linux World 2006 Speaker

Thursday, April 13, 2006

Nintendo and Casual Gamers

James Robertson talks about the market that Nintendo is after and it's the causal gamer. I must admit they get all of my gaming money (which isn't much). I'm probably what they consider a casual gamer. I don't play that much and when I do it's just to have some mad fun to clear the mind. Nintendo has the best "fun" games. Bar none, my favorite games ever are the Mario and Donkey Kong off-shoots (Donkey Kong Country, Mario Kart, Mario Bros, Wario, Yoshi, etc). Plus, I like carrying my games with me. The PSP peeked my interest when it came out, but I really don't enjoy racing real cars, shooting people, or robbing people. I want escape. Nintendo gives me that and fun in spades. Besides, the DS touch screen and on-line play is awesome. I dare anyone not to get addicted to Mario Kart.


Wednesday, April 12, 2006


From Blabbermouth comes this funny bit of news about MiniKiss vs. TinyKiss. It does't get much stranger:
Robert W. Welkos of the Los Angeles Times is reporting that Joey Fatale, the 4-foot, 4-inch New Yorker who heads the all-dwarf KISS tribute band MINIKISS, is denying published reports that he tried to sneak past security last month at the Hard Rock Hotel and Casino in Las Vegas to confront a rival band leader, 4-foot "Little" Tim Loomis of TINY KISS, for allegedly ripping off his idea for such a group.

Loomis, a former drummer for MINIKISS, was performing with TINY KISS, which includes three little people and a 350-pound woman, on St. Patrick's Day at Beacher's Madhouse, a Las Vegas variety show, when the incident occurred.

Show host Jeff Beacher told The Times on Monday that Fatale "tried to sneak in saying he was TINY KISS" and had to be escorted from the premises. According to the New York Post, Fatale's lawyers sent a legal cease-and-desist letter to the show trying to shut down the act.

Loomis told the Post: "[Fatale] came out here [to Las Vegas] and tried to cause trouble, so I had him 86'd from the Hard Rock. The impression I got was that he was looking for a fight. He'd been threatening me over the phone."

But Fatale disputed the accusation, telling The Times: "This whole thing about me going to the Hard Rock with my gang — that didn't happen. What happened was, I went there because somebody told me [TINY KISS was] doing the show that night…. Nobody escorted me out of there. I went there by myself to approach them as a gentleman."

Fatale says he has "nothing to say" about Loomis, except, "He's a nice guy." And, he added, "This is all a big publicity act for the guy at Beacher's."


Sunday, April 02, 2006

Revisiting Old Code And Private

I've been looking through old code as of late and well, it''s...EMBARASSING! There I said it. Does anyone else do this? I was looking at my Thesaurus project (my Squeak version and soon-to-be Java version) and was appalled at a lot of the code. So, I spent sometime refactoring and getting the code back into shape. My Thesaurus project in Squeak was a quick excursion into writing Morphs and that code was fine. What made me crinch was my parsing code! For one thing, I put all of the code for parsing into one class. It was doing all sorts of stuff with the HTML elements that it had no business doing. The first order of business was to move all of the low-level HTML traversal code into a new class. This made the parser much more readable and took away the noise inside of it. The next order of business was the actual traversal code. I made some huge blunders in my implementation of the depth-first/breadth-first algorithm. I knew the first problem was when I couldn't even understand what I was doing!

Here's the original code:
elementsIn: anElement do: aOneArgBlock depthFirst: aBoolean
| left children |
left := OrderedCollection with: anElement.
[left isEmpty]
[| next |
next := aBoolean ifTrue: [left removeLast] ifFalse: [left removeFirst].
(aOneArgBlock value: next) == false
ifFalse: [children := OrderedCollection new.
next elementsDo: [:each | aBoolean ifTrue: [children addFirst: each] ifFalse: [children addLast: each]].
left addAll: children]]

YUCK! What was I thinking with two checks for depthFirst or not? Here's the new code (which is a new class by the way!):
pvtDo: doBlock depthFirst: isDepthFirst 
| searchQueue dyadic |
dyadic := self pvtCurryForContinue: doBlock.
searchQueue := OrderedCollection withAll: self pvtChildren.
[searchQueue isEmpty] whileFalse:
[| next continue |
next := self class on: searchQueue removeFirst.
continue := [next addChildrenTo: searchQueue depthFirst: isDepthFirst].
dyadic value: next value: continue]

Now, you might notice some weirdness like the #pvtCurryForContinue:. All it does is to call the continue block by default if the block only accepts one argument. Otherwise, it let's the block continue through. Here's it's implementation:
pvtCurryForContinue: doBlock 
^doBlock numArgs == 1
[[:each :continue |
doBlock value: each.
continue value]]
ifFalse: [doBlock]

This is my functional programming training shining through. This code is much cleaner and easier to read than the one before.

This was just one simple example. I used the Thesaurus project to refactor to see how enforcing private members in Smalltalk would feel. So far, I found a lot of breaches of encapsulation that I had not noticed in the heat of development. Even with categorizing methods as private and with comments, I still broke the boundaries. The pvt at the beginning makes it obvious and Squeak's compiler tells me immediately when I have done something wrong.

After the refactoring, I felt my design was much cleaner overall. So far, I'm enjoying using pvt at the beginning of my private methods. It makes me get into the habit of "telling" my objects instead of "asking" which I generally do well. But, it helps when I'm weak in the rush to get something done or simply not as focused as I should be. The public protocol is obvious and minimal. Plus, if I have too many pvt methods, I start looking through my methods to break the object down further.

  • For even less conditionals and such, check out the packages Distinctions and ReferenceFinder in Cincom's public repository...

    By Andres, at 11:54 PM   

Wednesday, March 29, 2006

Omaha Dynamic User's Group

It's time for the most exciting user's group in Omaha to have another explosive meeting! Brent Adkisson will be blessing us again with another of his great presentations. This time he will be presenting Advanced Javascript and AJAX. If you've ever wondered how to get your mind around Javascript, Brent is going to show you! It's guaranteed to expose features of Javascript that you might not have known existed. I hope to see everyone there!

WhenApril 4, 2006, 7pm-9pm
WhereCafe Gelato

156th & Dodge



Thursday, March 23, 2006

Re: Block Thoughts

Alan Knight posted about More Block Thoughts. He made some excellent points. I particularly loved adding the #collecting:, #selecting, etc protocols on streams.

The funny thing is that the method that I used as an example was part of a larger object that actually was a stream. The stream, named WordStream, wrapped a character stream and returned a Word object on each invocation of #next. Alan mentions that my Word object is "a little bit messier" than strings. And in the context of the single method, I think he is right. But, in the larger context it makes sense. The Word object has a protocol to answer things about the itself like "am I common (the,a,is)?" for example. It's just not a simple wrapper around a String. It's much more.

I love Alan's views on streams, I'm a fan of pipe-filter designs for transformation. The WordStream was simply being fed a character stream to get more meaningful objects out. The users of WordStream only needed to know that it gave them Word objects via the stream protocol. I hate dealing with primitives and the minute I can transform something into a tangible domain object the better.

I feel like I should have given a more thorough example and not one out of context. It would have made the design decision a little more clear. And I could have shown off an example of the pipe-filter pattern. But, I was too thrilled with my new use for blocks.


Tuesday, March 21, 2006

Thoughts on James McGovern

Everyone else has posted their opinions on James McGovern's Thoughts on Ruby and the Enterprise. I figured, "what the hell? Why not post mine too". James McGovern lists some problems for the Ruby community to address, but stumbles from the mistakes. So, I'll start out with a nice quote:
Many folks haven't figured out that I too am a fan of Ruby.

OK, I can buy this, but when it comes to the list, he makes these mistakes:
Does anyone agree that the notion of packages / namespaces should be a part of every modern language?

Ruby has these things called Modules that fullfill that role.
I also couldn't find the equivalent of instance variables. Wouldn't that make reuse at an enterprise-level somewhat problematic?

Uh, Read the chapter "Classes, Objects, and Variables" in the pickaxe book. If you were a fan, you'd know this. Right?
Shouldn't the notion of methods being public, private and protected also be a part of every modern language?

Same chapter as the first one.
Does anyone in the community acknowledge that software vendors and even many large enterprises don't build on top of scripting languages because they don't want their intellectual property so discoverable?

Um, if you write your code on the server, why does that matter? Ruby shines on the server-side. Do we need to protect ourselves from ourselves? Wasn't that a problem with the Y2K problem? Didn't they have issues finding the original code and developers had to search through assembly language. Sounds fun to me...
But, my favorite is...
Ruby seems to be missing something that is otherwise fundamental in other languages which is support for Regular Expressions.

It's built in. But, you know Java didn't have Regular Expressions until 1.4 if memory serves me correctly. I remember Java was useful without it, but boy it does make somethings easier. But, if you heavily depend on regular expressions in your code, I hope never have to maintain it.
And this one took me over the deep edge:
Ruby folks as another predictor (different from guarantee) tend to not design (Yes, I know the agile party line here) and are successful in getting applications to work quickly but tend to skip out on long term maintainability. Maybe the best thing that Java folks can do for the Ruby community is to bring more of a software engineering mindset to development.

This one got my blood boiling. I love design; I think about design; and I live for design. I get angry when people do not think before they code. I know some in the agile community think you should sit at the terminal all of the time. But, I think it's important to know how the components of your application are going to fit together before you start. You might not have all of the details, but you should know what the interfaces and what their purpose are.

Thought does not mean "Big Upfront Design". Coding right away is gross negligence. CRC cards are still an excellent tool. Hell, simple message send and class diagrams still help my thought process.

To lump all of us together and call us hacks is disturbing. Ruby takes a lot from Smalltalk . Just remember all of the GoF Patterns come from examples in every Smalltalk-80 image. Don't damn all of us for the few who don't think. Besides, I've seen my fair share of poor designs in all languages including Java. Good design goes beyond language. Period. End of story. Languages are simply amplifiers that aid in the implementation of design.

Most of the critism has been overly harsh and I think his intention was to advise. But, when you get so much wrong, it's hard to take it seriously. Ruby has a lot of senergy behind it and the thing that has shocked me is the fanaticism. We need to take some advice from "The Pragmatic Programmer's" book and show everyone how cool are toolset is and not attack them. But, by the same token, we should correct those that are mistaken. It's a thin line.


More Block Thoughts

So, I whipped out the following code to get words from a character stream (input). I read the next word (all alpha-numeric characters) and return it or nil if none were found. Simple, huh? Here's my implementation:
| wordString |
wordStream := String new writeStream.
input do:
[:next |
next isAlphaNumeric
ifTrue: [wordStream nextPut: next]
[wordString := wordStream contents.
wordString isEmpty ifFalse: [^Word on: wordString]].
wordString := wordStream contents.
^wordString isEmpty
ifTrue: [nil]
ifFalse: [Word on: wordString]

Simple, but the duplication in it was bugging me. So, I thought, "If I made a block that did the duplicated code, what would that look like?" I quickly made my changes and it looked like this:
| return |
wordStream := String new writeStream.
return := [| wordString |
wordString := wordStream contents.
wordString isEmpty ifFalse: [^Word on: wordString]].
input do:
[:next |
next isAlphaNumeric
ifTrue: [wordStream nextPut: next]
ifFalse: [return value]].
return value.

Even simpler! This has a distinctive functional programming style to it. I'm using the block to return from the method which is unusual to be used liked this. But, it was in the spirit of "saying it only once". You might think the return could be moved out of the block, but I only want to return if wordStream contents are empty.

I could have done the same thing with exceptions, but it would been cumbersome in such a small method. The duplication is gone and the meat of the method is clear. Exceptions are useful when returns need to happen in nested method calls.

The fun thing about this example is that you could use blocks with return to bail out of searches instead of using Exceptions. Of course, you can do the same thing in Ruby. This is the first opportunity to explore this and like all tricks you should think about its use before you do it. I thought it fit perfectly for this method.

Blocks and closures are too cool. They can help in so many ways. But, they need to be cheap.

  • I agree that closures need to be cheap. But not just resource-wise: syntactically cheap too. Macros are used a lot in Common Lisp I believe to avoid typing #'(lambda (x) ...) all the time. Since in Smalltalk closures are about as succint as they can be, they tend to be used more than in other languages.

    Another language that uses blocks a lot is Ruby, and that's thanks to the yield keyword and being able to send a block to a method without the whole {} (done by prefixing the block argument with a &).

    When you make it short and sweet to type blocks, people will use them all the time. And that's a good thing, of course, blocks rule!

    By Vincent Foley, at 10:31 PM   

Thursday, March 16, 2006

Unknown Features

I was reading a paper entitled, "Objectoriented Encapsulation for Dynamically Typed Languages", and came across an interesting piece of information.
Some Smalltalk dialects attempt to solve this problem by using a special naming convention to specify internal methods. In the Squeak dialect, for example, methods whose names begin with pvt are effectively private: the compiler ensures that these messages can be sent only to self. However, this approach not only prevents accesses to such internal methods from outside of their class but also from other objects of the same class. Thus, the pvt convention is a form
of object encapsulation: in practice it is often too strict, because it prevents many commonly used data structures and patterns from being implemented. As with Python’s double underscore, this approach is clumsy because changing the access attributes of a method requires renaming it.

Huh? I've been using Squeak for a little while now and never knew of this feature. I even asked my good friend and fellow Squeaker, Steve Wessels, about it. He told me that he had never heard of it. The paper continues with this nugget:
The utility of the pvt feature is reflected in the Squeak image: although this feature has been available for years, only 9 out of about 40,000 methods in the latest Squeak image use it.

OK, I had to go check this out, so I fired up my trusy 3.8 image and did the following:
| result |
result := OrderedCollection new.
RTCriteria new
[:each |
each beginsWith: 'pvt'];
[:eachClass :eachMethod |
result add: (eachClass -> eachMethod)].

I got a result of 31 methods. Some of those come from Komanche and Celeste which are not part of the base image. Still, how come I never found about this? Squeak is just full of little nuggets. I'm constantly uncovering little things like this.

It's something new for me to try out and see how I like it. I've been an extreme encapsulation kick as of late and this is just adding fuel to my fire. I don't like adding pvt to the front, but it makes it painfully obvious when I'm breaking the rules and things like the refactoring browser help when I decide to change my mind.

So, I wonder what other little surprises are out there still waiting for me? Squeak is a surprise a minute! Oh yeah, the paper is an excellent read and I highly recommend it. I'm going to have to try out the stuff in it as well.


Saturday, March 11, 2006

Omaha Dynamic Language Meeting

It just keeps getting better and I'm not saying that because I'm the organizer. Last week, we had representives from several dynamic language camps (PHP, Ruby, Smalltalk, Groovy, Lisp/Scheme, and Javascript), plus a lot of curious folks. The attendance was diverse and it was fun to give a previous of my STS talk. It was a practice run and I have several things to improve on. I appreciated everyone's patience and we had a fun discussion afterwards regarding "eliminating pain" via unit testing. It was great showing off Smalltalk. I can't wait to give my "Introduction To Seaside" talk which I hope to include some of the new libraries like Seashore and the new AJAX stuff.

Next month, we have a talk on advanced Javascript by Brent Adkisson. Trust me, it's not to be missed. Brent gave a great talk last time on DynAPI and this one promises to be even better! After that, we have several great talks coming on the following topics: Lisp, Ruby On Rails, Groovy, and Seaside! Everyone is invited, let's keep the momentum going!


Wednesday, March 01, 2006

Omaha Dynamic Language User's Group

Controlling Pain: Augmenting Unit Testing
Smalltalk has a highly reflective and lively environment that can be used to augment traditional unit testing. It allows us to do things that are only dreamed about in other environments. We can easily question and interrogate code or any aspect of the system. It is not hard to implement tests to ensure code correctness, enforce metrics, and scrutinize resource allocations. You can be creative and take the stance of using tests to stop and minimize the cost of change. There is a large variety of characteristics that can be tested, from run-time correctness to code quality. This presentation will give real world concrete examples in Smalltalk.

I will be presenting the talk that I will be presenting at Smalltalk Solutions. I hope to see everyone there for the sneak preview!

WhenMarch 7, 2006, 7pm-9pm
WhereCafe Gelato

156th & Dodge



I Have Reinforcements


Tuesday, February 28, 2006

String: How I Loathe Thee

There I said it! I hate strings. I really do. Nothing screams, "BROKEN WINDOW!" louder than unnecessary abuse of strings. But, you say, "Blaine, you can't be serious! We need strings! How else would we represent names and labels?" OK, you got me. We need strings, perhaps it's the abuse that I loathe. I think an example would be good here. Let's say we had a client who wanted to keep track of his albums and group them by artist. So, we quickly come up with the following class definition:
class Album {
String title;
String artist;

//Assume the usual getters/setters and general behavior

public static Album[] byArtist(String anArtistName) {

This looks pretty harmless doesn't it? You might even say that it is "the simplest possible thing that could work". You would be right. Most of our methods would in the Album model object. But, what we're missing here is the power of objects and spreading behavior out amongst cooperating objects. We would also have methods on Album that really shouldn't be Album's responsibility. Basically with just strings, we miss out on the power of objects. The obvious solution might be to use:
class Album {
String title;
Artist artist;
class Artist {
String name;
Album[] albums;

At least, we could put that search method from above into an instance method of Artist and it would be easier to traverse the object model. We wouldn't have to worry about Album validating the artist name. Oour behavior would be spread out amongst several objects and closer to the data . We will be programming closer to the language of my user which is always should be the goal. Can you sit your client down and have them understand your code? If not, there's too much geek string talk going on.

But, you say, "Blaine, the first class is SO EASY TO MAP TO OUR PERSISTENCE FRAMEWORK! Surely, it should be the way to go!" Yeah, let's make our whole model pay the unreadable tax simply because we want to make one aspect of our system easy to implement. A model that speaks the language of the user is easier to maintain and increases understanding of the domain. It's always easier to read the message directly than deciphering what you did six months ago. Strings allow behavior to be ill-placed and meaning to be lost or worse obfuscated. It's the slippery slope to design smell and broken windows.

"OK, Blaine, you're going off the deep end here! The example you gave sucks! I don't see your point. Strings are simple. Objects are more complicated. Why go through the extra hurdle if my model doesn't demand it?" Alright, alright, alright! Strings are primitives like numbers and dates. They should be treated as such. It's a matter of taste, but I believe you should use atrings only for primitive things. You might see artist as simply a String, but what happens when your client wants to know more about an artist? We could easily add this new information to an Artist object for little cost.

In the first example, what really is the instance variable "artist"? Is it the name of the artist? It could be and that would be the assumption. But, it could be anything. Hell, someone might even stick XML into the artist variable. Nothing stops them. Our intention is not specific. An Artist objects reveals exactly what we want and adds little complexity, but gains us the ability to be more agile to our client. Our readability is increased. We also have lower cognitive friction because behavior is in the right place. Strings force behavior to be placed in unnatural spots if abused.

I've seen too many examples where strings are overused and make refactorings difficult. The reason is that meaning is generally lost and it's hard to know what the String is truly representing in spaghetti code. I've even seen people hack around them (like putting XML in a field and parsing it in methods). I've seen it all. The point here is not to avoid Strings, but look at them for what they are. Primitives. Sure, the above example could have stayed like the first. And it might have enjoyed a nice happy life. The minute the client needs additional information is when we should make an Artist object and refactor. Use common sense. Overuse of strings makes me take out my code reviewer magnifying glass because generally there's sinister bugs lying underneath. They are used too often by lazy modelers who don't want to create an extra class because it wasn't "the easiest possible thing", oops, I meant, "simplest" (yes, there is a HUGE difference, one makes the answer on thought, the other on laziness). Now, don't get me started on strings in test cases as short-cuts to comparing objects. That's another blog entry...


Sunday, February 26, 2006

Morphic: What a Strange Cool World

One of the things that I love about Squeak is its environment. Once you get past the beginner stage, it offers a wealth of exploration goodness. One of my favorite tricks is when I want to learn how something is done, I simply go through the menu options of a morph while it's on screen (you can get a menu on any morph via the halos). I find the option I want to know about and then alt-click twice. This brings up the halos for the menu item. I then simply debug it (since the menu item is a morph as well). The inspector shows you all the information for the menu item including what it calls when clicked. It's a great way to learn how morphs are put together.

It might not seem like much, but I love the fact that everything in morphic is inspectable and changeable. It makes playing a lot of fun. Morphic can be frustrating sometimes, but I love how easy it is to find out how things are put together with it.

I can't wait to start playing around with Tweak and see how it is.


Friday, February 24, 2006

Update: Collecting Seashells

We discussed an article, "Collecting Seashells" a while back at the local Smalltalk User's Group. The author, Stan Silver, graced me with an updated version along with a few other things. Enjoy! If you haven't read them, then do so. It's a collection of bits of advice. Good stuff.


Ken Pugh Answers His Critics

I need to go buy "Prefactoring" by Ken Pugh. I've read a little bit in the store and it's on my wish list. It looks like a common sense approach (like much of the agile techniques), but he has been getting some heat in his Amazon reviews. I think that's silly because I think what he says is right on the money:
There is no “big design up front” in prefactoring. The “Think About the Big Picture.” guideline is not about big design. It suggests that you spend a little bit of time investigating the environment in which you are going to create your software. The environment (e.g. a corporate infrastructure, J2EE, or web services) may provide numerous services (e.g. security or error handling) that you don’t need to develop or it may suggest ways for structuring your code to fit into the framework.

Following the prefactoring guidelines does not mean you don’t refactor your code. The guidelines can help keep the smells out. But when code starts to smell, refactor it. As you go through development, you gain more knowledge about the total project, which can generate new ideas. Performing a retrospective after every release, as one guideline states, can help direct this generation of new ideas. Agility is about delivering working software to the customer. Iterative and incremental development and customer communication, as shown in the example in the book, are key principles to enable that delivery. You can use multiple tools to achieve the goal – refactoring – performing transformations on created code is one tool; prefactoring – thinking about things before coding is another.

Read his complete answer. He explains very well that being agile requires thought and not mindless mantras. Sometimes I think XP zealots get too carried away with themselves.

Thinking about your solution before you code it does not mean big upfront design. No craftsman in his right mind would start carving a piece of wood before some initial planning. Thought is cheap and if it can save refactoring later, then let's do it! Think, it ain't illegal yet.


Refactoring and Agile

Dave Thomas (of OTI fame, if you don't know who he is, go to his website now and start reading) wrote a great article entitled "Agile Programming: Design to Accommodate Change". In it, he discusses the oft forgotten table-driven design technique. But, the thing that I found most striking was his take on agile:
Refactoring improves code, usually increasing the function while reducing code bulk. However, such refactoring or restructuring often forces the application to undergo a complete development cycle, including unit, acceptance, and regression testing, followed by subsequent redeployment. In a large IT or engineering production system, this can be time consuming and error prone.

Agile programming is design for change, without refactoring and rebuilding. Its objective is to design programs that are receptive to, indeed expect, change. Ideally, agile programming lets changes be applied in a simple, localized way to avoid or substantially reduce major refactorings, retesting, and system builds.

There in a nutshell is what agile is to me. The goal is not to refactor, but to try to avoid it. Let's face it, refactoring happens because understanding changes and cruft naturally builds. But, our goal should be to avoid it at all costs. Refactoring should be used for unforeseen obstacles. We shouldn't knowingly put opportunities of refactoring into our code base from the start. Let's take Dave's advice and design to accomodate change!


Quotes on Testing

Can you guess where the following quote came from?
I think that's wht good programmers do - they test continously and at every opportunity. "Test early and often" is their motto. It's not that they have fewer bugs, but that the habit of continual testing has kept their bugs private, and consequently cheaper.

Hint: It's not from any XP book. Give up? OK, I'll tell you: "Software Testing Techniques" by Boris Beizer. What a fabulous book. I bought it because it discusses at length what the brunt of my talk at Linux World is on. He calls it structural testing (testing the code and design instead of the functional correctness). I highly recommend it. Did I mention it was written in 1983? Why do I keep unearthing these long lost tomes?! If anyone knows of any more, let me know!

I'll leave you with another quote from the book that I just loved:
There are some persons who claim that they can write bug-free programs. There's a saying among sailors on the Chesapeake River, who sandy, shifting bottom outdates charts before they're printed, "If you haven't run aground on the Chesapeake, you haven't sailed the Chesapeake much." So it is with programming and bugs: I have them, you have them, we all have them - and the point is to do what we can to prevent them and discover them but not feel guilty about them. Programmers! Cast out your guilt! Spend half of your time in joyous testing and debugging! Thrill to the excitement of the chase! Stalk bugs with care, and with method, and with reason. Build traps for them. Be more artful than those devious bugs and taste the joys of guiltless programming!

Oh, did I mention that these lovely quotes were from the introduction? It gets better! Sure, some of the book is outdated, but there are several great nuggets of information to be had. I'm going to go run off and do some guiltless programming right now.


Thursday, February 23, 2006

Squeak 3.9

I'll admit it. I'm getting excited about the new release of Squeak 3.9. It will have Traits built it in (this alone should make any Smalltalker giggle in delight), but we will also get pragmas! VisualWorks has had support for pragmas for quite sometime and they are great for adding meta-data to your methods and classes. They make a lot of things nice (like marking methods private, adding various bits to your methods, etc) and they work a lot like Java's Annotations in 1.5.

In a normal world that would be enough, but nope the awesome folks comin up with the next version have packed into tons of new playthings. The UI has changed a bit for the better and everything seems a bit more snappy (of course, this could just be my perception).

Squeak on!


Saturday, February 18, 2006

Live at Planet of Sound

My good friends in Connecticut love to rub in how cool the Northeast truly is. A mysterious package landed in my mailbox recently containing a CD called "WCCC Live at Planet of Sound". It's a collection of acoustic numbers from well known rock acts played live. The production is excellent and I've been blasting it in my car recently. But, in the end, I know it's just a ploy by my friends to make me long for the days past when I lived there. The amount of talent that foes through Connecticut is unbelievable. I make a yearly trek up there just to experience it and laugh with my good friends. The CD was a great gift and I miss my buds! =) And one more thought, it has finally replaced Coheed and Cambria in my car. My wife thanks them.


Metalheads Against Racism

This page is powered by Blogger. Isn't yours?