- Create more than one line. I would divide them up by flexibility of travel plans. I notice a lot of time is spent with just a few passengers. You could use one line to determine what the needs are and then pass them on to more dedicated lines. This would speed things up for everyone on the whole.
- Updated information on the boards. Most of the problem is that you don't know what's going and there's no confirmation that you're doing the right thing. It's chaos. Some road signs would answer most people's questions (flight delayed - for how long - and yep, it's canceled and with the reason!).
- Send flight information to your cell phone for each of your flights. If it gets canceled and they automatically rebook, then notify me. If the default is unacceptable, then I'll wait in line. But, give me options. I'm thinking the default would the best for most people and reduce the line size.
- "Feed" the line. People are generally tired, cranky, and hungry. Pass out refreshments while they wait in long lines. It will keep the natives peaceful.
- Workout a deal with a local taxi company to pick up the slack to take people to the hotel. I waited an hour tonight just to get to the hotel.
- Workout a deal with the tourism department to show around town if their flight is canceled. They have time to waste and might want to venture out.
- Have shuttles from the hotel that take people to malls or Wal-Mart. Why? Because you don't have your luggage and might want a fresh set of clothes.
- Have private areas in the airport. I would spend money just to have a small place to prop up my feet and take off my shoes. I'm thinking something with walls and a Laz-E-Boy chair.
- Better food. Airport food is expensive and junky. Sometimes I would give anything for some vegetables and something healthy. How hard can that be?
Saturday, February 24, 2007
Stuck in Memphis
Sunday, February 04, 2007
Books on Design
- Designing Object-Oriented Software : THE book on OO design and analysis. This one keeps it simple and is awesome. Mrs. Wirfs-Brock will always be one of my heroes that I aspire to.
- Domain Driven Design: And I'm not saying this because of my involvement with TimeAndMoney. Eric is not a great mentor, but an awesome author. If you want to learn how to write REAL DSLs, this is the book. Learn to talk through your domain. Read this cover to cover. There is not one paragraph not to be savored. I went to the first Smalltalk Solutions just to meet him. Seriously...
- The Design Patterns Smalltalk Companion: This is the book where you learn a lot of the hidden secrets in Smalltalk and that all of the design patterns started there. This is an awesome book and reads better than the original. Buy this even if you don't know Smalltalk. It's that good.
- Structure and Interpretation of Computer Programs: I don't know one person who has read this and not have had the way they look at software be different. Learn to be a magician. This opened a lot of possibilities for me. It made me much more creative in my solutions.
- Prefactoring: A lot of Agile enthusiasts got upset with this book because they didn't read it. This book dares to followers to do what they say: Think about their designs. This is also a great book if you want to learn more about DSLs. All good OO models are DSLs. If you're not doing a language with your models, you are doing something wrong.
- Agile Software Development: Robert Martin hits a home run with this book. This is what people who think Agile is about no design, should read this. Being agile is about thinking. I know a lot of Agilists get that, but I have come across many who think it's all about coding and no thought. This book goes beyond Agile and talks about good ole great design.
- Software Fundamentals: These articles were written before I even knew what a computer was and they are still relevant today as they were then. You'll either walk away from this bewildered at what we keep rediscovering or notice how a lot of stuff that seems new is really rebranded. This book is just an awesome tomb of software experience from one of the early innovators. His views on encapsulation really changed the way I look at design. Awesome book.
- A functional pattern system for object-oriented design: Functional programming for object-oriented programmers. I love functional programming and by studying it. My thoughts on development and design have changed. This book shows that they both can share ideas from each other and become stronger. This is a fantastic book that should get more accolades. It shows what great things can be done if OO and functional programmers put their powers together for good.
- Every single book that Martin Fowler has had his name on or associated with. They all rock. Analysis patterns is really the crowning jewel (again, if you want to do DSLs, learn from the master). But, all of his books are easy to read and will teach you volumes.
Wednesday, January 31, 2007
Dynamic Language User Group Is Back!
Room PKI 269 is nice because it has about 25 machines, each connected to the Internet, and a large screen projector at the front of the room. A laptop may be connected to the projector or you can just use the PC at the front of the room. Almost every room in PKI has a large screen projector at the front of the room with a PC and a laptop connection. All of the rooms have white boards.
WOW! I would like to give extra special thanks to Heather Blockovich of Tek Systems for all of her help. So, when are we meeting at our bright new shiny place? February 6 is the date usual time of 7-9pm. Of course, I'm always up for a little chit chat before.
Now, for the most important announcement (drum roll please): the speaker! Ben Heath will be providing a special evening of discussion on Common Lisp and his Netflix project. Ben is a passionate programmer with years of experience and is a Lisp and dynamic language lover. It's going to be an exciting talk for sure! I can't wait.
And if that wasn't all, Tek Systems will be joining us with food, refreshments, and maybe a few suprises! Yes, we have sponsorship for this meeting. Now, I have to ask what better way to spend an evening with free food, great place, great people, and awesome Lisp coding?! It's just too good! I look forward to seeing everyone.
| Topic | Lisp and Netflix |
| Speaker | Ben Heath |
| Time | February 6, 7-9pm |
| Location | UNO's Peter Kiewit Institute (PKI) building 1110 South 67th Street Omaha, NE |
Sunday, January 28, 2007
Some Self Philosophy
In short, to maximize the opportunities for code reuse, the programmer should:
- avoid reflection when possible,
- avoid depending on object identity except as a hint, and
- use mirrors to make reflection explicit when it is necessary.
This is the summary to a portion of the chapter entitled, "Behaviorism versus Reflection". It's best explained in this three paragraphs:
One of the central principles of SELF is that an object is completely defined by its behavior: that is, how it responds to messages. This idea, which is sometimes called behaviorism, allows one object to be substituted for another without ill effect—provided, of course, that the new object’s behavior is similar enough to the old object’s behavior. For example, a program that plots points in a plane should not care whether the points being plotted are represented internally in cartesian or polar coordinates as long as their external behavior is the same. Another example arises in program animation. One way to animate a sorting algorithm is to replace the collection being sorted with an object that behaves like the original collection but, as a side effect, updates a picture of itself on the screen each time two elements are swapped. behaviorism makes it easier to extend and reuse programs, perhaps even in ways that were not anticipated by the program’s author.
It is possible, however, to write non-behavioral programs in SELF. For example, a program that examines and manipulates the slots of an object directly, rather than via messages, is not behavioral since it is sensitive to the internal representation of the object. Such programs are called reflective, because they are reflecting on the objects and using them as data, rather than using the objects to represent something else in the world. Reflection is used to talk about an object rather that talking to it. In SELF, this is done with objects called mirrors. There are times when reflection is unavoidable. For example, the SELF programming environment is reflective, since its purpose is to let the programmer examine the structure of objects, an inherently reflective activity. Whenever possible, however, reflective techniques should be avoided as a matter of style, since a reflective program may fail if the internal structure of its objects changes. This places constraints on the situations in which the reflective program can be reused, limiting opportunities for reuse and making program evolution more difficult. Furthermore, reflective programs are not as amenable to automatic analysis tools such as application extractors or type inferencers.
Programs that depend on object identity are also reflective, although this may not be entirely obvious. For example, a program that tests to see if an object is identical to the object true may not behave as expected if the system is later extended to include fuzzy logic objects. Thus, like reflection, it is best to avoid using object identity. One exception to this guideline is worth mentioning. When testing to see if two collections are equal, observing that the collections are actually the same object can save a tedious element-by-element comparison. This trick is used in several places in the SELF world. Note, however, that object identity is used only as a hint; the correct result will still be computed, albeit more slowly, if the collections are equal but not identical.
Basically, the above is basically placing more value on "duck typing" (the new word for behaviorism) than reflection. I've always placed myself in the "behaviorist" camp and anyone that knows me rolls their eyes when I rip into my "@#$%^& not another data structures and controllers architecture!" It's because I place more value on the behavior than I do the data. It has a lot to do with my mentors enlightening me to the teachings of the brilliant Rebecca Wirfs-Brock (yes, she is still my hero).
Sorry for my digression, but why did I quote all of this? First off, I always thought of duck typing and reflection as tools in my bag. I have never thought about why I would pick one over the other. I do tend to pick non-reflective solutions where I can (It seems Joshua Bloch does the same from his Effective Java book as well). The reason being that most people understand behavior, but reflection is not so obvious.
OK, enough background, and on to my real point. This all got me thinking about why I've always been squeamish with reflective GUI, persistence, and rule engine frameworks. Now, before I begin, I love my OO-relational mapping tools and rules engines, but somehow they have always seemed like they were breaking encapsulation. And in fact, they are for great benefit (which outweighs the encapsulation violations). They are going underneath the covers of your objects and exposing them to a privileged few. Now, this gives us great power and takes a lot of things out of our hands. These frameworks do a lot of heavy lifting and breaking encapsulation has always seemed like a small price to pay. But, how could we do it without reflection? Ah, there's an interesting question, no?
Is this mental aerobics going to get us anywhere? I don't know. But, I bet the journey will be fun. So, what do we have in our arsenal right now? Well, off hand you can name the Memento pattern and we could have a simple hash table object that we get values in and out of the object. This could work for all of the frameworks I listed. But, it seems cumbersome and still prone to major changes in the object topology. We're still depending on data, just putting a common interface on an object. Perhaps, this is the point of "Mirrors" in Self is to provide this type of functionality, albeit consistently. It's also slow because we have to keep taking snapshots if we want to track changes (which means we have to ask for the data and then do compares). But, we could use the Observer pattern and trigger events on any change to an object at the end of some change transaction.
Another tool can be found in Allen Holub'sexcellent article about alternatives to getters/setters in GUIs using the Builder pattern. Now, the solution is very specific, but it's a turn on the Memento pattern. I like that fact that it's more about behavior where I have to send an object that understands the messages and reacts to those messages instead of being passive. But, it still seems the Memento pattern wins because it can be more generic (at its simplest: get(key) and put(key, value)).
I'll leave this article as a point to ponder. There might not be an answer. But, I think a pure behavior approach is more understandable and simple than a reflective one. If anyone has any thoughts, please send them to me. I'll post any further thoughts as I have them. I'm always thinking of ways to preserve encapsulation in my designs. Just remember, Alan Kay wished he had called object-oriented programming, "message-oriented programming". It enforces the black box nature of objects and strong communication semantics. It keeps designs simple and easily reasoned about. Now, don't get me wrong, I don't hate reflection. I just feel like we should always seek alternatives, like inheritance it holds awesome power. But, in the wrong context can cause maintenance issues. Just because you have a tool doesn't mean you have to use it. Besides, forcing constraints on yourself, can cause interesting thoughts on your future designs.
Saturday, January 27, 2007
Smaller Is Better
"The smaller the object, the more forgiving we can be when it misbehaves." -John Maeda, "The Laws of Simplicity"
This quote was talking about real world objects, but I think it's doubly true for software objects. If we keep our objects small in our design (single responsbility), we will be more forgiving when errors arise. Why? Small objects are easy to test, debug, and well, fix. In fact, the fix is obvious because the object is so small. It's time to make our objects small and build layers of domain specific languages on top where each layer is simple to comprehend and understand. It would make our designs "more forgiving" to the ones who have to maintain it.
Magnetic Fields Metaphor
Magnetic Fields:
Find a central metaphor that's so good that everything aligns to it. Design meetings are no longer necessary, it designs itself. The metaphor should be crisp and fun.
Metaphors are a hotly debated topic in XP/Agile circles and I've never understood why. Alan Kay's quote resonates with me because when you have a good metaphor for your system, you can easily make design decisions as they arise. It keeps your design cohesive and simple. Of course, if your metaphor doesn't fit, it can have the opposite effect. I don't force metaphors, but when one pops that fits...I grab it whole-heartedly. But, I will take the time to brainstorm for one. The metaphor should be your compass that helps you navigate through your design decisions.
Language Of The Year
Sunday, January 21, 2007
Feed Change
I did make a few changes to where index.rdf will now still be updated from atom.xml in the meantime. Again, thanks for everyone's patience on this matter.
Wednesday, January 17, 2007
Java And Simplicity
I believe, simplicity of language is VERY UNDERESTIMATED asset.See, I worked for years with c++. I liked templates, they were
giving me a 'mental satisfaction'. I liked to check generated
assembler, emmited own instructions when not satisfied.But that's not way how programs should be made.
Once switched to java, I apprecitated simplicity of java.
Java followed KISS principle, provided simple language,
simple tools (javac, javadoc, javah ... ).Now, we are loosing this important asset.
Converted c++ programmers ask their templates and operators.
Converted c# programmers ask their properties and closures.
Coverted script programmers want their dose of language sugar.Java creators made java simple - and not simpler then it should be.
We should apprecitate and preserve it (in rational way).
OK, I'm sure that some of the Smalltalkers and Lispers out there either have their jaws on the floor or hurt bellies from laughing so hard. I know I did at first and then it struck me. We have failed. We have failed to educate on what simple can truly be. When I think of simplicity in language design, I think of Self, Smalltalk, Forth, and Scheme. Java wouldn't even come close. But, there's an army of developers out there that haven't seen better and that is sad.
Sure, we could easily laugh at the uneducated, but it's our fault. Instead we should be sharing and telling. I spent time at RubyConf showing off Squeak and have been known to hang out at the local Java user's groups talking all things dynamic. I enjoy showing people the power that's out there and the great thoughts that have preceded us. It's exciting to see Java getting some of these capabilities and programmers demanding them! The future is bright, but there are still some we haven't reached.
Next time, you hear someone call Java simple, don't snicker. Show them something simple. Who knows maybe someday I'll be able to program in Self because it will be the defacto standard. A boy can dream can't he?
Wednesday, January 10, 2007
Favorites Of 2006
- Unexpect-In a Flesh Aquarium
- Muse-Black Holes And Revelations
- Into Eternity-Scattering Of Ashes
- Pure Reason Revolution-The Dark Third
- Peeping Tom-Peeping Tom
- Axamenta-Ever-Arch-I-Tech-Ture
- Hammers Of Misfortune-The Locust Years
- Die Apokalyptischen Reiter - Riders On The Storm
- OSI-Free
- Ghoul-Splatterthrash
- Frost*-Milliontown
- AFI-December Underground
- Strapping Young Lad-New Black
- Mars Volta-Amputechture
- Dragonforce-Inhuman Rampage
- Estradasphere-Palace of Mirrors
- Cradle of Filth-Thornography
- Black Stone Cherry-Black Stone Cherry
- Trivium-The Crusade
- The Faceless-Akeldama
Tuesday, January 09, 2007
Zero Mass Design
He has a little book called "Zero Mass Design", the premise of which is that if you're going to work on something - for instance, you're going to write a book, or you want to write some software, or you are about to embark on any project that requires planning -- start with a simple design. But it's more extreme than just keeping it simple; you start with a design so simple that it won't work. That requires a great deal of discipline because you go into the project with the premise that you will fail; until you've tried something and actually seen it fail, yoiu don't know how simple you can get.
Does it sound familiar? Sounds sort of agile doesn't it? The explanation that he gives next is the best I've read for "Do The Simplest Thing Possible" mantra of XP. Read on:
Dave Thornburg's example, from James Adams' book "Conceptual Blockbusting", is the Mariner IV spacecraft. It had large solar-cell panels that unfolded. The problem, as stated, was to have a mechanism that slowed down the panels as they unfolded so that they wouldn't break when deployed. So, they tried oil, but that was sort of messy, and they tried springs; they did all sorts of things. The day for the launch was coming nearer and nearer. What were they going to do? Remember, the problem as stated was to find a way to slow down the panels, or to find a braking mechanism. Finally, somebody had the brilliant idea to try it with nothing, so they tried it and the panels shook and shivered but nothing broke. If you state the problem with assumptions, you're going to get them. You're got to pare back and pare back and pare back. Starting with a very simple design has wonderful advantages, but it requires a pyschological twist; you have to expect that it will fail and enjoy that.
I like to get requirements stated in goals which is a trick I learned from use cases. Get the problem stated as a goal and a lot of assumptions can be removed. You'd be surprised how well it helps. The point is not only to "Do The Simplest Possible Thing That Will Work", but state the problem as "Simply As Possible". It removes assumptions and thus, doesn't color your design with needless complexity. Those words slapped me in the face and it seemed everything came together. Wow.
How To Make Sure Your Fans Don't Find You
"Riders of Apocalypse". Why the name change? Oh well, who cares? One of my favorite bands are back and I got two new albums by them this year. I should be happy and I am! I just would have liked to been listening to one of them now for 3 years....I got a lot of time to make up!
Great Post On Smalltalk and Parsers
tangent: No Virginia, Smalltalk does not have operator overloading. It simply allows method names using non-alphanumeric characters. These are always infix and all have the same fixed precedence. How can it be so simple? It’s called minimalism, and it’s not for everyone. Like Mies van der Rohe vs. Rococo.
He makes more and it's a great read. I almost got diet pepsi all over my new Mac while reading it. I tend to stand on the same fence that thinks functional and object-oriented programming compliment each other well. I'll even go as far and say they need each other. I ran across this blog because of my recent interest in Self and Factor. Fun stuff!
Monday, January 08, 2007
Don't You Want To Own a Lisp?
Sunday, January 07, 2007
The First Week With Mac
I love the quickness of putting it to sleep! Wow! Booting it up from scratch is slow, but I've only had to do that once so far. I just put it to sleep. Nice.
I'm enjoying Dashboard and I've already gone a little nuts with it. I think I have something like 8 widgets. I have a weather one, two quotes of the day, inspiration for the day, word of the day, unix command lookup, ruby documentation, and a thesaurus.
Switching between applications is nice. It took me a little time to get into the multiple windows per application way of thought. In Windows, everything is a window with no grouping by application. Mac groups windows by applications and makes it super easy to switch between.
The only problem I've had is re-learning key mappings for Eclipse and Squeak. They are generally the same, but it's the apple key versus alt key on Windows. The keyboard is a laid out a little differently too, but I'm not complaining. It's just taking a little to get used to.
I'm loving Self. It makes the whole reason for getting the Mac worthwhile. I've been going through the tutorials and I've only scratched the surface. But, language-wise I'm so impressed with Self. They take their simplicity seriously!
On more thing, I can now read postscript files directly! Yippee! They get converted automatically to PDF and that is wonderful. I can see I'm going to go super crazy with academic papers. Mac will be my pipe for my crack.
My Mac didn't come with an AirPort card and the battery lasts 1 minutes. I'm missing my wireless and I got to have battery power. All in all, I'm having fun with it. Right now, I'll be staying in both Windows and Mac. But, there's a lot of cool things on the Mac that I still need to explore like XCode. I'll keep you posted!
Theme Song For The Year
One Way
Most computer designers, for some reason, delight in providing many ways of doing something. If there are fifteen ways to do something, they think it gives you freedom. The fact is that most users don't use the majority of the commands on their word processors. There are a few that everyone uses. And even though they've read the manual and know it might be a little more efficient to use a special technique, they don't bother. They use the same ones every time.
I've seen this time and time again. I know I've even fallen for the "flexibility" fallacy where I should have been simple. The above can apply to not only user interfaces, but APIs and languages. It made me immediately think of Ruby.
Ruby falls prey to the "flexibility" vulture and it's even touted as one of its greatest strengths by some (Reason #7). You have two ways to define blocks ({}, do), various ways of constructing arrays (new Array, %w), and other things to make various programmers from other languages feel comfortable. I think Ruby itself needs to become more opinionated.
There's a lot of great things about Ruby that I'm proud that are finally getting into mainstream minds like dynamic typing, closures, and meta-programming. It's cool seeing all of the excitement. But, I think if Ruby wants to go further, it needs to trim some of the fat. Now, this fat might have made programmers from other languages more comfortable, but we need to lose it. I would like to see Ruby more lightweight, easier to parse (it's a nightmare), and of course more opinionated. But, I worry that with all of the activity that bad habits will continue. I'm worried about the future of Ruby because all of the forking and lack of a clear direction.
With all of the battles that Ruby has won, I would hate to see it fail because of sins to gain more acceptance. It's won that, now, let's make Ruby the best it can be.
Wednesday, January 03, 2007
More On Nulls
Empty Collections instead of null.
The easiest way to prevent null pointer exceptions when using collections is to use empty ones. The Java collections library in fact includes empty versions of all the collection interfaces. Use them. It takes a little more typing, but it prevents one more check. And usually, most collection code can be written to be size agnostic.
Use meaningful defaults.
This one is really simple. Instead of being lazy, think about good defaults for your objects or at least ones that will be easy to spot when debugging. One of the problems that I have with nulls is that when I have to debug code, they tell me nothing about the intention. A default can give some sort of clue. If defaults can not be used, then...
Throw an exception.
But, if you must insist on using nulls, then please don't use them for incorrect usages of your API. In other words, if I pass you bad parameter, don't return null because your API can't handle it. Signal an exception and tell me what the problem is. Sadly, the Java collection API falls into this trap. The implementation of Map returns a null if it doesn't find the key and null is ambiguous in this case because it can be the key was not found or that null was stored as the value. I think an exception for the first case would prevent that. It would also make it easier to spot an incorrect usage of the API with a good message to tell me what to correct. Good designs are easy to debug and require little to no detective work. Be nice to your users.
Use small objects.
Wrap primitives into something more meaningful. You can then use the interface for both the implementation of real values and another one for true Undefined scenarios. Small objects are easy to debug because they can give much more meaningful information and you don't have to deal with all knowing objects that are 300+ lines of code. Small objects make dealing with nulls easier because...
Null object Pattern.
This pattern described in "Pattern Languages 3" by Bobby Wolfe. Go read it now if you haven't. Basically, implement a different implementation of your interface that either deals with the undefined case more gracefully. Now, by that, I mean, either throw an exception detailing why the request could not be completed, ignore the request, or forward it on to someone else. There could even be more options, but the first two are the most commonly used which of course, brings me to...
Deaf object pattern.
This is the Null object pattern where the implementation of the interface ignores all exceptions. This is used throughout Dolphin Smalltalk to great effect. This is a dangerous pattern, but when used right can make life easier. Dolphin uses it as a placeholder for objects that are not fully instantiated yet and requests would not make sense. It does this external resources where the object is instantiated, but they have not yet allocated the proper resources yet to make it fully functional. It helps them avoid timing issues. Again, I would caution the overzealous use of this pattern because it can mask bugs which brings me to...
Undefined object pattern.
Yet another popular variant of the Null object pattern, this version throws an exception with a meaningful message (be creative, but put something better than "undefined object<>
In closing, the one point I want to make is relying less on null requires thought in your design. Too many times, I see use of nulls as absence of caring for the users of your code. Nulls are just lazy and you can replace most of the them in your code using the above arsenal. Plus, the techniques above can make your code more readable, easier to debug, and more fun to extend.
Amen
I’ve also been reading a lot of the relevant academic literature published since the 1970s; for instance, the Lambda Papers and the myriad works of Henry Baker have been particularly inspiring. I continue to be struck by the harsh reality of the often-asserted, but seldom-accepted, truth that most of the great work in software was indeed done very early on, with virtually no further fundamental progress having been made during the past couple of decades.
I'm in the same boat. I'm just so much in awe of early computer science. I've been reading David Parnas's old papers and they are inspiring. It's amazing how much of the old papers we are reinventing. It's fun and mind blowing reading, but depressing that we haven't push the envelopes further. I think it's time to stop being sad and just do it.
Here's my call to arms. Let's take it further and stop whining! Who's with me?! CHARGE! The next generation of computer science starts NOW!
Superfluous Parentheses
of course, I can’t help but admire what the Smalltalkers have built with Squeak. (I suppose once you’ve reached the Source, being a polyglot becomes second nature.)
and...
The Lisp machines seem to have been the apex of Lisp, a brilliant achievement still unequalled (except by the Smalltalkers, as always). These wonderous machines have been followed by two decades of standstill, or even retrograde, progress.
It's funny, but I chose Scheme as well for slightly different reasons. I like the simplicity and elegance of Scheme which barely edges out Common Lisp. And the debugger is really great. It's also weird when he mentioned Forth and Factor. I just downloaded the Factor implementation recently. Weird. Forth is something that I like the elegance and enjoyed Brodie's book immensely. But, haven't played around enough with stack-based languages yet to know whether I like them or not. So much cool stuff!
Anyway, it's a great read. One of these days, I need to do one of these for why I choose Smalltalk. I think the above article was frank about Lisp and we need to be the same about Smalltalk.
I noticed he had a few books that he was planning on reading and are still on my reading list. I wonder if a virtual book club might be in order?
Monday, January 01, 2007
More Having Headaches Over Null
Sunday, December 31, 2006
Dipping My Foot In The Mac Waters
Friday, December 15, 2006
L'Atomium
You are missed, Dawn
Power lines,
Steel webs confine,
Violating the brownish sky.
Hard grey smothers,
Earth, like cancer.
Cracks revealing,
Ground below.
Broken and bleeding,
every seed, every stone.
One of my favorite albums of all time, Fear of God's "Within The Veil" began with the above quote and you knew it wasn't going to be a cheery album. It's been ten years since Dawn passed and this has to be the darkest week in metal. We lost three great musicians all of which released albums that I cherish and love. So, today I raise my glass and listen to my metal brothers and sisters that are no longer with us. You all are missed dearly.
Are We Worrying About The Wrong Things?
I agree whole-heartily with him. After awhile, I get tired of the same old language wars (pick your tools, know them well, and kick booty). We all need to know our tools better.
The core of the article is the message: Get better at your craft and mentor others on what you learn. It's up to us to make our community better. The time of being smug is over. We're in the same boat, let's help each other out.
I love Smalltalk, but I'm not afraid to use other tools. And I really don't mind Java that much (most of my rants come looking at poorly written Java). Good design is good design no matter what language. Yet, I see under-abundance of talk on design. I'm still shocked at meeting people who have never read Rebecca Wirfs-Brock's excellent "Object Oriented Design" or "Structure and Interpretation of Computer Programming". Both excellent books on design that transcend language. If you don't have them, buy them now and get "Code Complete" as well.
Anyway, the article is awesome and is a good wake-up call to us to look at the bigger picture.
Wednesday, December 13, 2006
Thought And Readable Code
No tool solves every problem. Put down the damned hammer and pick up a screw-driver once in a while.I agree with the above sentiment. I love a lot of different languages for various reasons. I often say that everyday I get closer to becoming a functional programmer because that style keeps rearing its head in my code. But, like anything it needs to be tempered.
It's all about balance and simplicity. I think the functional guidelines of trying to make most objects stateless and composition to the smallest and simplest are wonderful. The code you write reads well and if you try to restrict the places where you change, then it's easier to find bugs when problems arise.
The point is don't go overboard with your ideology. The end goal should always be readable code. Readable code changes information in few places. Readable code is easier to maintain. Readable code performs well. Readable code cares about the programmer that has to pick up the pieces once you're on to something else. Readable code is small. And finally, readable code is simple.
But, readable code takes thought. Design takes thought. Most of the zealotry that I witness is from people who want to remove thought. They think great code comes from restriction. It does not. It comes from freedom to have choice. Sure, you can make a bad choice, but sometimes the bad choice might be the good choice in certain situations. But, the choice requires thought. Any hard and fast rules should be looked upon with suspension. In the wise words of George Clinton:
Think! It Ain't Illegal Yet!
Oh, and if someone still wants to make religion and dogma out of anything technical (like the functional and XP evangelists), tell them to:
Go Wiggle
I'm going to think about making better code and designs.
Shallow are words from those who starve...
...For a dream not their own to slash and scar.
Chuck you are missed, bud. Thank you for enlightening us with such great music before your untimely death. Let the metal flow!
Friday, December 08, 2006
Thinking And Sharing Ain't It Cool?!
Then, it occurred to me. I should just make my collection of objects it's own domain specific object that I can then send the proper messages to. Thus, instead of a Collection object, you have an AccountCollection object that wraps around an ordinary collection. And this is where I can stick the "active" method. It's not static and reads so much better.
But, what about being able to combine predicates, transformers, and closures? I didn't discuss that in the original post. My post was inspired by a problem at work where I needed to combine different predicates on in-memory objects. So, it would be nice to have a "where" method that selects a subset of my new AccountCollection. I could even make the "where" functionality available in an abstract collection so that future domain specific collections could enjoy its benefits. But, to combine predicates, it's still ugly with all of the static utility method calls. Yuck. OK, what if I write my own abstract predicates, closures, and transformers that can chain themselves? For instance, you could have "and" and "or" methods to predicate; "then" for closures; and "as" method for transformers. Underneath the covers, could simply call all of the static utility methods. I get readability back (getUser().getAccounts().active() and getUser().getAccounts().where(Account.BY.olderThan(DAYS_90).and(Account.BY.active())).
I like this approach better and it keeps the knowledge shared. You could put the most frequent queries in the the domain specific collection, but still leave it open for future extension of less used queries or transformations.
Yet, again, this approves the more you move functionality down and spread responsibilities around, the easier your code becomes to read. Thanks to Jeff for making me thinking of where my solution was ugly.
Case Statements...They're Still Used?! Say it Ain't So!
Of course, I'm surprised the minds at Sun let such mistakes go by. Both auto-boxing and enumerations allow null pointer exceptions that most coders will not catch because typically you don't expect them (because of the expansion of the real code). I think this is going to catch a lot of unsuspecting developers. Java has trained our eyes and minds to where potential null pointer exceptions could lie. Ouch. The rules have now changed.
Again, nulls rears its ugly head to smash down all of that compile type checking non-sense. It all compiles, but will it run? How much do you want to pay for safety that's not guaranteed? I'd rather not fight monsters with blankeys, but with a real sword (unit tests).
Getcha Pull
Thursday, December 07, 2006
Agile Religion
I thought Patton's definition of "software success" (taken from the blog post) was interesting:
'We knew we?d delivered successfully not when the ?EAR file as uploaded to the server,? but when we saw end users successfully working with the software on a daily basis.'
Depends on the scope of a project I suppose, but for me, I would add to that sentence "and in 5 years' time".
That draws in concerns such as flexibility of design, level and quality of documentation, ability to accomodate increasing volumes, anticipation of change, etc.
A lot of these things are anathema to the Agile dogmatist mindset (you ain't gonna need it!), and, dare I say it, the typical consultancy mindset (I've used my glorious methodology, now the maintenance guys can take over and I'll move on to the next gig - but first I'll blog about how great I feel about it.)
Given the investment in money, people and time for software of any real significance, just having something that is good enough today is, not, well, good enough.
The point that 'Agile' is now an overused cliche is well made. As is the use of 'Waterfall' to paint any project that doesn't call themselves 'Agile'. They're just labels that lazy people use to pigeonhole - kind of like music genres!
All I can add is, "AMEN BROTHER!" I totally agree.
Sunday, December 03, 2006
Apparently, I like bad music
Metal
Jakarta Commons: Collections
Collection activeAccounts=CollectionUtils.select(someAccounts, new Predicate() {
public boolean evaluate(Object object) {
return ((Account)each).isActive();
}
});Wouldn't this be nicer:Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY_ACTIVE);One, it's lot less typing and reads much better in your logic. I've put the Predicate on the Account class. I really liked doing it this way and made my code read much more cleanly. Also, by having the Predicates defined on the objects that they were operating on, it made it easier to find which Predicates had already been defined. Everyone wins right? Well, no, I started using the same technique for Closures and Transformers too. My objects started to get crowded because I look putting my public static declarations at the top. Now, what to do?
Well, I was speaking to Matt Secoske one morning, we naturally started to discuss my dilemma of growing predicates and he had a simple answer: Put them in inner classes. At first, I scoffed at the idea, but after thinking about it, I came up with the following code:
public class Account {
public static final Predicates BY=new Predicates();
//Class stuff...
//Put this at the bottom of the class
static class Predicates {
public Predicate active() {
return new Predicate() {
public boolean evaluate(Object each) {
return ((Account)each).status.isActive();
}
};
}
}
}I have no idea why I didn't like the idea at first. But now, my client code looks like this:Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY.active());The client reads the same, but now, I've gotten the implementation of the predicates out of the way. Everyone wins. I also put my transformers in their inner class named AS and one for closures called EACH. The important thing is that I keep meaningful information at the top and my client code reads well. Another thing to note is that now I can hide more information and expose less. You would be amazed at how much data is exposed in predicates. Yet, another nice side effect.
You will also notice that in the resulting code that I used a status instance variable to figure out if it was active so that I didn't have to duplicate the protocol of the status object through the Account object. My code has been getting simpler and it's been shocking me.
The point should always be to make the clients that use your objects life easier and more readable.
Wednesday, November 29, 2006
To Closure or Not
Both of the extreme cases seem comical. One takes the position of nothing but objects and the other nothing but blocks. It seems that pure object-oriented programming is at odds with functional programming. But, it's not. They need each other. I think Smalltalk and Ruby strike a good balance in this area. Blocks are used as lightweight objects (ala syntactically cheap) where a full object definition would be cumbersome. But, having nothing but blocks would also be problematic. For bigger things, we use full objects. It's the balance of having both that allows us to choose the one that allows us to more succinctly express our solution.
I don't know why people argue these things. There are problems that are better expressed in objects and others in closures (blocks). Why do I have to choose one over the other? I want both! There's also a lot that object-oriented programmers can learn from functional programmers and visa-versa. In fact, I'm always shocked how much functional programming is in pure object-oriented languages like Smalltalk and Ruby.
I'm going to go message something.
Tuesday, November 28, 2006
Notes From One of Alan Kay's Talks
"interactive LISP -- a metainvention, the Maxwell's Equations of programming. Today is the 40th aniversary of the first interactive implementation by a 16-year-old Peter Deutsch. It was the first time a programming language became an operating system."
WOW! Really, that's all I can say. Peter does correct the above quote. But, I'll leave that to you to discover. Makes me wish I would have asked more questions when I met Peter at Camp Smalltalk. Darn it!
Prefactoring Hate
Friday, November 24, 2006
After A Rough Day, This Made Me Laugh.
Thursday, November 23, 2006
About Time
Commands are not Text-based
Unlike traditional command-line interface commands, Windows PowerShell cmdlets are designed to deal with objects - structured information that is more than just a string of characters appearing on the screen. Command output always carries along extra information that you can use if you need it. We will discuss this topic in depth in this document.
If you have used text-processing tools to process command-line data in the past, you will find that they behave differently if you try to use them in Windows PowerShell. In most cases, you do not need text-processing tools to extract specific information. You can access portions of the data directly by using standard Windows PowerShell object manipulation commands.
This was taken from the documentation for Microsoft's PowerShell. All I can say is: FINALLY! Tools like grep have their place, but man, working with objects is so much nicer. I just started to look into this, but I'm liking it thus far. I've been waiting forever for a command line environment that dealt with objects instead of dumb old text.
Wednesday, November 22, 2006
Compile Time Reflection
Class someClass=MyObject.class
But, I wish it went further. If you're going to make me go through the pain of verifying everything at compile-time, then make my life easier for example:
try {
Method method=MyObject.class.getDeclaredMethod("doSomethingCool", AnotherObject.class, String.class);
} catch(NoSuchMethodException problem) {
//handle reflection exception that could have been caught at compile-time
} catch(SecurityException problem) {
//handle reflection exception that could have been caught at compile-time
}Right now, if I mis-typed "doSomethingCool" then it wouldn't get caught until run-time.Now, we don't want to make the baby Gosling cry, do we? How about this:
Method method=MyObject.class.doSomethingCool(AnotherObject,String);
For one, it's more succint and no need for any try/catch blocks because the compiler did all of the work. Another nice side effect is that you can check regular visibility constraints (if I call the above in MyObject and doSomethingCool is private, then all is good. Otherwise, don't allow it if outside of MyObject). Now, I don't have to set the setAccessible() method on Method and no security check. Now, of course, you can also use this for fields as well. In fact, it's simpler.
Now, I ask since they gave us ".class", why didn't they finish the job? Java reflection has always seemed half way there to me.
Just don't get me started on JavaBeans (where are the collections?).
Beauty. Remember that word.
In 1958, John McCarthy was thinking about a symbolic differentiation program in a programming language that was later to become Lisp. He was concerned about the “erasure problem”: no-longer-needed list structure needs to be recycled for future use. In subsequent languages, such problems were handled either by the structure of the program being restricted to trees (stack allocation of data and its trivially automatic deallocation through stack popping) or by explicit allocation and deallocation (malloc/free). His comment on erasure / explicit deallocation:
The recursive definition of differentiation made no provision
for erasure of abandoned list structure. No solution
was apparent at the time, but the idea of complicating
the elegant definition of differentiation with explicit
erasure was unattractive.-John McCarthy
It’s worth a pause to notice the style of research described. McCarthy and his colleagues were trying to design a programming language. Part of their methodology was to write the program they thought should be able to do the job and not the program that a compiler or execution system would require to make the program run well. In fact, the beauty of the program was foremost in their minds, not correctness down to the last detail. Beauty. Remember that word.
Eventually the first Lisp implementers decided to ignore the bug—the fault of not explicitly erasing abandoned list cells, causing the error of unreachable cells accumulating in memory, leading to a failure to locate a free cell when one is expected—until the failure occurred and to repair it then. This avoided the problem of entangling a common set of functionality (keeping available all the memory that should be) with a pure and clear program (symbolic differentiation). The failure the fault eventually caused was repaired, along with a lot of other similar errors in a process named at the time and still called garbage collection.
What are you waiting for read the whole thing. It's awesome and will make you think about how we can write better software. The garbage collection story put a smile on my face. "Beauty. Remember that word." I couldn't have said it better. We should always strive for beauty in our designs.
I Am Object
"I should calculate the total when given a new line item"
"...that is not my responsibility..."
I act like I am the object. It's so natural to me that I don't even think about it. Now, this is very common when designing with other Smalltalkers as well. Are we the only ones that do this? And if so why? Is it because we are behavior-ists (ala Wirfs-Brock) and not data-ists? I don't know, but I think it's funny and it's what makes being a Smalltalker a joy.
Fate Is Weird
Well, I am pleased to announce that I will be returning (once again) to the land of messages and freedom. I can't wait to start. I will be working with some scary smart folks and doing outrageously cool feats of programming acrobatics. And it can only be done in Smalltalk. How lovely.
The railroad was awesome in retrospect and I had a blast. It was short-lived and I wish I could have stayed longer because I was just getting some steam on my project. Oh well, this new opportunity was just too good to pass up. The railroad has some cool aspects that I never thought about and the shipping industry is an interesting domain.
ROCK! Pass the messages and hold the data. I'm back to writing elegant code unhampered by a stuffy old compiler!
Tuesday, November 21, 2006
Why Lisp Has The Parentheses
Null: The Runtime Error Generator
if (something != null) {
something.doWhatYouWereBornToDo()
}You know what I mean. It's inevitable in legacy java applications. Now, I generally only do null checks on my inputs and avoid null conditions at all cost. But, the other day it got me thinking:
Null gets around all static type checking at compile time.
It's not a real type. It can be ANYTHING. At compile time, it slips under the radar because it only exists at runtime. So, what is my typing system doing for me? I find NullPointerExceptions tend do great damage on lazy (bad, whatever you want to call it) code. And let's face it, we've all had those days where we weren't exactly on the ball. NullPointerExceptions are sitting there to wake us up.
I really don't mind static typing. But, let's not kid ourselves. Allowing nulls throws out the safety of the compiler catching our dumb mistakes because most of mine are of the null variety (the dumb ones that is).
Of course, we could just reference everything by their interface and do the Null Object pattern and be smart about messages to ignore and which ones to worry about. But, it's a lot of typing without much gain.
Now, you might be saying to me, "But, Blaine, you imbecile! Don't you have nulls in Smalltalk, Ruby, and Lisp?" Yes, we do and it's called nil. But, we don't pretend to catch all of our dumb mistakes up front. And our nil is an ordinary object which we can add messages to. Nil, our null, is a little bit more powerful. Does it still sting when we make a programming mistake? You bet it does.
Enough on that, just don't get me started on primitive arrays in java. They are even sneakier and there's a plethora of stuff that the compiler doesn't catch.
Till next rant, keep your objects small and your messages plenty. AMEN!
Sunday, November 05, 2006
Worst Web Site Ever?
Wednesday, November 01, 2006
Happy Belated Halloween
How cool is that? So, you might guess what I might have done. I was thinking carving either Alice Cooper or this:
And of course, my wife, Michelle had to quickly take a snapshot of me in all of my techy glory.
Now, I must ask the question, am I knight now or what? I even used Squeak to edit the pictures.
By the way, I used Melissa Winger's "Powered By Smalltalk" logo. Thanks! It was a blast to carve!
Tuesday, October 31, 2006
Ruby and Continuations
Monday, October 30, 2006
I didn't say it, honestly!
Smalltalk
All your concepts belong to us.
Lisp
(no ‘they all belong to (us))
MOHAHAHAHA! Ok, I'll stop the diabolical laughter now.
Saturday, October 28, 2006
Welcome To World, Duncan Manning
Rebol in Omaha
Here's the location specifics:
Creighton University
2500 California Plaza
Omaha, NE 68178
Parking
Additional Information:
Enter the west end of the Old Gym.
Go up the elevator to the fourth floor.
You're there.
Restrooms are on the 2nd floor, unfortunately.
Vending machines are on the 1st floor, around the wall to the right of the elevator.
Anyone asks, you are attending the Omaha Dynamic Users Group meeting on the fourth floor of the Old Gym or ODUG.
PropertyDescriptor in JavaBeans
OK, it's time for an example. Spring is all of the rage (and rightfully so) and injects by the exposed writer methods in an object. But, wouldn't be nice not to expose them, but give Spring priviledged access to these fields and basically disallow ordinary access. What if I could have a custom PropertyDescriptor for just those fields. Well....
Right now, I could have a private writer and have a custom PropertyDecsriptor to grant access to it. But, what if I didn't want to add unnecessary noise to my class? Besides, it seems like a lot of trouble. Let's dream for a bit shall we?
What if instead of having getReaderMethod() and getWriterMethod(), we had getPropertyAccessor()? What would this new method return? How about this:
public interface PropertyAccessor {
Object get(Object receiver);
void set(Object receiver, Object newValue);
}And this would be the default implementation:
public class MethodPropertyAccessor implements PropertyAccessor {
private Method reader;
private Method writer;
public MethodPropertyAccessor(Method reader, Method writer) {
this.reader=reader;
this.writer=writer;
}
public Object get(Object receiver) {
try {
return reader.invoke(object, null);
} catch(...PlethoraOfReflectionExceptions) {
throw new RuntimeException(reflectionException);
}
}
public void set(Object receiver, Object newValue) {
try {
writer.invoke(object, new Object[] {newValue});
} catch(...PlethoraOfReflectionExceptions...) {
throw new RuntimeException(reflectionException);
}
}
}More of the knowledge in how to get/set properties in the object are known to the PropertyAccessor. We could then provide our own PropertyAccessors like we could have one built by giving it the Field itself. Like this:
public class DirectAccessPropertyAccessor implements PropertyAccessor {
private Field property;
public DirectAccessPropertyAccessor(Field property) {
this.property=property;
this.property.setAccessible(true);
}
public Object get(Object receiver) {
try {
return property.get(receiver);
} catch(...PlethoraOfReflectionExceptions...) {
throw new RuntimeException(reflectionException);
}
}
public void set(Object receiver, Object newValue) {
try {
property.set(receiver, newValue);
} catch(...PlethoraOfReflectionExceptions...) {
throw new RuntimeException(reflectionException);
}
}
}Users of the PropertyAccessor would not have to know how the field is accessed (whether via methods or direct access or by going through other objects). By hard-wiring to always use methods, the JavaBeans framework has exposed too much of its internal implementation to the outside world. If they would have hidden more, it would have been more flexible. Of course, the examples need more fleshing out to handle things like primitives (but, you're not using those anymore are you since you have autoboxing, right?).
I wanted to show this as a simple example of why encapsulation is good. I've made the code more flexbile, simpler, and easier to test even. The PropertyAccessor is simply a facade around the business of accessing a field. Pretty simple stuff.
Just think if you had this with so many java frameworks that use JavaBeans. Wouldn't it be nice?
Monday, October 23, 2006
RubyConf 2006
The Gospel Of Closures
Saturday, October 14, 2006
Tour Updates
Next up, I'll be attending this year's Ruby Conference in Denver October 20-22. I can't wait. It's going to be so much fun! New people to meet and exchange ideas with.
Wednesday, October 11, 2006
Eclipse Mylar
Basically, it keeps the context of what you're working on. You create tasks and it pays attention to what you're editing. The cool thing is when you start switching tasks. It switches out the editors to exactly where you were and it creates a custom working set with only the files you were working on (you can also show everything and it greys out the least interesting items). I'm impressed and it works great with Eclipse 3.2. Finally, I have Squeak projects for Java and a whole lot more.
Now, I need to get Bugzilla installed...
Strings suck
Saturday, October 07, 2006
What Makes Ruby Roll
Kevlin Henney said...
Someone will have rewritten it by then. Yes, will succeed where Smalltalk failed because it's not bound up in the smalltalk environment (you can open up Ruby files in Notepad). Also, do not underestimate how important a 'normal' if statement is. The biggest problem with Smalltalk is Smalltalkers.
The first part of the quote is right. Smalltalk is too much change for most developers to accept. You have a new syntax to learn, a new environment to learn, and a completely different way of thinking. It's too much for a lot of developers. It's human nature. An image-less Smalltalk would have a nicer entry point since developers love their editors (you spend a lot of time there and well, when you learn one well, you don't want to leave it). The last part of the quote really hurt. I see myself as a lot of things. I see myself as rubyist, a smalltalker, a java programmer, and a bunch more. But, I can see where the arrogance of certain Smalltalkers can detract from the true message. It makes me sad. Smalltalk is a cool language to program in and I love talking about it. But, I know it has warts like anything else. I hope no one ever sees me as an arrogant Smalltalker. I want them to see me as passionate and thoughtful.
Dave Thomas said...
As long as the people who have big checks are running on the CLR and JVM Ruby will have to crossover to those platforms to succeed. Business and economics were the downfall of Smalltalk, not natural selection. The "arrogance of the smalltalk communities sealed the lid".
Another quote right on the money, but stings me in the heart. It's true. Marketing killed Smalltalk and the arrogance that their product was better. The sad fact was yes, Smalltalk was better than C++ and Java, but having a better product doesn't win. Java had a lower cost of entry (familiar syntax, could use any text editor, and a familiar work flow) and it was good enough. Maybe if Smalltalk had been marketed correctly, maybe the story would be different. And one more thing, yeah, the arrogance of some Smalltalkers didn't help our cause.
It's always interesting to see how the rest of the developer commounities see us. I feel like we get lumped in with the grumpy Lispers. We both have great languages with communities that can be intimidating. I hope that never happens with Ruby because right now their community is inviting.
Wednesday, October 04, 2006
Seaside Presentation
Sunday, October 01, 2006
Six Weird Things/Habits/Facts About Me
- I own lots of music (enough to fill an 80 gig MP3 if they made one), but I do not own a stereo. I prefer to listen to music on headphones.
- Territorial. I do not like anyone to be in my space when I'm not around. And I do not like it when neighbors park in front of my house.
- I loathe cigarette smoke even though I'm an ex-smoker.
- I love high fiber cereal. The higher the better.
- I carry Equal and a pen wherever I go. I'm freakishly prepared for anything.
- Encyclopedic knowledge of heavy metal that stems from being a rabid fan (I love a lot of other genres, but metal is my favorite). I can name not only the song, but the artist, album, side (remember records?), year, producer, and my first impression when I first heard it.
Seaside and Smalltalk in Omaha
Here's the location specifics:
Creighton University
2500 California Plaza
Omaha, NE 68178
Parking
Additional Information:
Enter the west end of the Old Gym.
Go up the elevator to the fourth floor.
You're there.
Restrooms are on the 2nd floor, unfortunately.
Vending machines are on the 1st floor, around the wall to the right of the elevator.
Anyone asks, you are attending the Omaha Dynamic Users Group meeting on the fourth floor of the Old Gym or ODUG.
Thursday, September 28, 2006
XP Youth
Truth is, pair programming is one of the only effective ways that a lot of us have ever witnessed keeping average developers from pissing away 95% of their productivity engaging in non-work such as reading and writing blogs, instant messaging, personal email, shopping online and otherwise wasting time on bullshit.
So, we need the XP youth to keep us inline? If I'm not doing my job, I should be fired. Period. End of story. We all can't be above average, but we all need mental breaks (I doubt most developers spend 95% of their time shopping online).
Pair programming has pluses and minuses. It takes a certain personality to be good at it. I've had very few good pairs in my career. Nothing can match the creativity of two minds locked in a common crusade. It's great. BUT, I have found it takes a person that can take constructive critism of their ideas, is vocal, loves programming, and the most important: listens. Your average developer if he's browsing the net for 95% of his time probably doens't "love" what he/she is doing. I found while pairing can give the illusion of productivity, it's easy for one part of pair to be asleep at the wheel to speak. If you don't love what you do, you will find ways to avoid doing it no matter what hurdles managers throw at you.
I love pairing with passionate yet humble programmers (the greatest minds I have met have been this way). But, I hate pairing with ego maniacs. I love short bursts where we colloborate intensely and then go program solo for a short while. Get back together and show each other what we did. Rinse, repeat. I find it keeps the creativity spark alive (because you can experiment without the sucritiny of another to verify if the idea is good) and the interaction rich. It allows the feeling of working together, as well as ownership of a piece of it.
Pairing should be something that is not mandatory. It should be up to the programmers. Anything forced is going to cause people to find ways around your dogmatic rules. It's human nature. XP should be agreed upon, not enforced.
Confession Time
"A wise man changes his mind, a fool never" - Spanish Proverb
Well, at least it makes me feel better right? Well, I have a confession to make. In the past, I have argued for the use of accessors on instance variables. I liked accessors because they looked the same in the code as a method call and the flexibility. But, several months ago, I tried writing code without accessors. I was shocked by what I found about myself. First, it was hard after programming with accessors for so long and it didn't feel natural. But, I got over that in the first month or so. Second, I noticed that I broke encapsulation of my objects less. In fact, if I felt the need to access an instance variable outside of my class, I questioned myself thoroughly and generally tried to find another way.
I thought I was writing good code, but I was making little sins that added up. Forcing myself to use accessors only when necessary caused my objects to be more self-contained. I started writing smaller objects. My code got way better. So good in fact, that I find myself on the other side of the accessors debate.
Yes, I now frown upon the use of accessors by default. It leads to data structures (not objects) and controllers (not objects). The funny thing is the road to breaking encapsulation is one paved with small sins along the way. Besides, with today's tools, it's easy to switch the accessors if needed.
Oh well, I had to get that off my chest.
Wednesday, September 27, 2006
Too Many Toys?
There's one thing that hasn't changed. Good design and thought. Frameworks are only amplifiers in this regard much like languages. They can make our life easier if we apply them to good sound design principles. But, I think that's what is missing in our field. Go to any Border's and Barnes and Noble bookstore. Hell, go to any coder's shop and what you will find are rows and rows of books on the latest "cool" frameworks and languages. It's all vocational. You might find a little section on design if that. And it's not like we don't have great books on design. Hell, I can list several and still have more to recommend! These are the books that will stay on my shelf long after the latest framework fad or language has gone to the legacy island of old technology. It amazes me how many developers are up on the latest technology, but have never read a book on design (or maybe just one).
It shocks me. Knowledge is our most treasured asset. I strive to understand the core concepts and to go beyond. I'm always trying to learn from anything I can find (even non-software books) if it can give me a glimmer of understanding more about our field. Sometimes, I think though, we get so caught up in the flavor of the month, that we neglect the knowledge that will survive after the fads are dead.
Do we have too many toys? We're spending all of our time playing with them and not learning the core concepts that's behind them. I think that's sad. I love solving hard problems, but I want to spend my learning the problem domain. I want to learn the business of my users so I can solve their problems in elegant ways. The world of business is one of the most fun beasts to tame. I don't get excited anymore about applying the latest technology to a problem, but by solving it period. The tools needed are in your head. The frameworks only amplify what is at the core. When push comes to shove, it's still takes thought to do a good design.
So, here's my solution: read one non-vocational technical book per year. Understand it. Become it. Or at least be able to argue why you hate it. I read more books about design that any other every year. It's time well spent and it only makes you a stronger developer. Rock on, brothers!
Wednesday, September 13, 2006
Design Patterns of 1972
Now, let's roll up our sleeves and take our industry further!
Sunday, September 10, 2006
I miss Zappa
PINE: I guess your long hair makes you a girl.
ZAPPA: I guess your wooden leg makes you a table.
Made me laugh. Time to fire up "Grand Wazoo".
Thursday, September 07, 2006
Working On The Railroad
Time And Money Library
Monday, September 04, 2006
Updated: Comment Unit Tests For Ruby
Here's a simple example:
### >>> 3 + 4
### >>= 7
You can even use variables:
### >>> a='i'
### >>> b=' love '
### >>> c='michelle'
### >>> a + b + c
### >>= 'i love michelle'
And if they are part of the same comment, it will keep the variable bindings active, so you can do this:
### >>> a + ', robot will never die'
### >>= 'i, robot will never die'
And finally, if comparing two objects bores you, then you can create your own equality check like this (notice the >>>?):
### >>> a = 5
### >>> b = 4 + 1
### >>? a == b
Enjoy and Ruby on!