Wednesday, October 04, 2006
Thursday, September 14, 2006
Monday, September 11, 2006
Liskov Substitution in Dynamic Languages
A nice discussion on Michael S. Feathers blog.
Jim Weirich observes:
The original LSP is defined in terms of types and subtypes, not classes and subclasses. In Ruby, we try to remind people that type is not related to class. It seems to me that LSP still applies to dynamic languages, even if there is no direct language construct for type.
Also a link to dynamic/static type contracts (interfaces).
Thursday, September 07, 2006
Gmail Tricks
found here:
Gmail has an interesting quirk where you can add a plus sign (+) after your Gmail address, and it'll still get to your inbox. It's called plus-addressing, and it essentially gives you an unlimited number of e-mail addresses to play with. Here's how it works: say your address is pinkyrocks@gmail.com, and you want to automatically label all work e-mails. Add a plus sign and a phrase to make it pinkyrocks+work@gmail.com and set up a filter to label it work (to access your filters go to Settings->Filters and create a filter for messages addressed to pinkyrocks+work@gmail.com. Then add the label work).
More real world examples:
Find out who is spamming you: Be sure to use plus-addressing for every form you fill out online and give each site a different plus address.
Example: You could use
pinkyrocks+nytimes@gmail.com for nytimes.com
pinkyrocks+freestuff@gmail.com for freestuff.com
Then you can tell which site has given your e-mail address to spammers, and automatically send them to the trash.
Automatically label your incoming mail: I've talked about that above.
Archive your mail: If you receive periodic updates about your bank account balance or are subscribed to a lot of mailing lists that you don't check often, then you can send that sort of mail to the archives and bypass your Inbox.
Example: For the mailing list, you could give pinkyrocks+mailinglist1@gmail.com as your address, and assign a filter that will archive mail to that address automatically. Then you can just check in once in a while on the archive if you want to catch up.
Wednesday, September 06, 2006
Software Development as Turkey
from Darren Hobbs entry:
You can't achieve the same effect when roasting a turkey by doubling the temperatuire and halving the cooking time. Similarly a project cannot have the number of people doubled and the duration halved and get the same result. The rate of knowledge crunching is not increased by adding more people.
Closures in Java
Another post with links.
From Debasish blog, a link to Gilad Bracha's blog entry (with some nice comments)
Pick from post:
One question that naturally arises is "what took you so long?".
...
Since the late 90s, I've brought the topic up now and again. At times, even I have reluctantly been convinced that it is too late, because we've done so many things that would have been easy with closures in different ways. This means the benefits aren't as high as in a language like Scheme, or Self, or Smalltalk. The cost is non-trivial, to be sure.
Pick from the comments:
SUN never cared to implement Closures in Java.The reason why they are caring about now is Microsoft introduced them in C#.
So the funda is IF YOU WANT A NEW FEATURE IN JAVA DONT ASK SUN,(ITS TIME WASTE), BETTER ASK MICROSOFT, ONCE MS IMPLEMENTS THAT FEATURE IN THEIR LANGUAGE, THE NEXT YEAR SUN WILL CONSIDER THAT FEATURE. (This is also the quickest way of getting your favourite feature in JAVA).
(1st enums, support for dynamic languages, now closures...) :D
And a link to jaggregate examples.
Thursday, July 27, 2006
Wednesday, July 26, 2006
Comments in code
from wiki: 'to need comments' and 'too much documentation'
Class comments - OK.
Method comments - NO
Comments in code - NO
If you need a comment to specify the behaviour of an object/method, specify that behaviour in some unit-tests. In that way you get runnable, automatic, one-click behaviour testing. If your test cases have good names, than you won't need to actually read the code in the tests, a brief look at the method names should say how an object/method reacts.
Tim Ottinger writes here:
A comment is an apology for not choosing a more clear name, or a more reasonable set of parameters, or for the failure to use explanatory variables and explanatory functions. Apologies for making the code unmaintainable, apologies for not using well-known algorithms, apologies for writing 'clever' code, apologies for not having a good version control system, apologies for not having finished the job of writing the code, or for leaving vulnerabilities or flaws in the code, apologies for hand-optimizing C code in ugly ways. And documentation comments are no better. In fact, I have my doubts about docstrings.
If something is hard to understand or inobvious, then someone *ought* to apologize for not fixing it. That's the worst kind of coding misstep. It's okay if I don't really get how something works so long as I know how to use it, and it really does work. But if it's too easy to misuse, you had better start writing. And if you write more comment than code, it serves you right. This stuff is supposed to be useful and maintainable, you know?
Is there any use of comments that are not apologies? I don't think so. I can't think of one. Is there any good reason to write a comment? Only if you've done something "wrong".
Tuesday, July 25, 2006
no null
I've seen too many NullPointerExceptions.
Apparently I am not the only, see the post from Michael Feathers:
Passing null in production code is a very bad idea. It’s an example of what I call offensive programming – programming in way that encourages defensive programming. The better way to code is to deal with nulls as soon as they happen and translate them to null objects or exceptions. Unfortunately, this isn’t common knowledge.
Keith Ray explains how it is done in Objective-C:
In Cocoa / Objective-C programming, I still prefer an empty string over a null pointer, or an empty container-object over a null object, but the language does have a key difference: calling object methods on null-pointers does not normally crash! (But sometimes method parameters being null can cause a crash.)
Foo* aFoo = nil;
Bar* aResult = [aFoo someMethod: anArgument ];
calling someMethod (as above) on a nil object DOES NOTHING (it does not crash or throw an exception) and returns nil.
The Cocoa UI frameworks take advantage of this. For example, the objects that implements a Button or a Menu item would have two members variables: a pointer to an object, and a "selector" that identifies what method to call on the object. The method that handles a click (or whatever) would be written something like this:
[ targetObject performSelector: actionSelector withArgument: self ];
instead of like this:
if ( targetObject != nil ) {
[ targetObject performSelector: actionSelector withArgument: self ];
}
No need to check for a null targetObject. There would be a need to check for a null-selector (in the performSelector:withArgument: method), since the selector isn't actually an object.
People have objected that null acting like the "null object pattern" hides bugs, but too many times have I gotten web-apps sending me messages that a "null pointer exception has occurred" so I assert that null-pointer exceptions are not helping people find bugs as well as test-driven development, or thorough code-reviews and testing, would do. I expect that if null had the "null object" behavior, the web-app would have returned an partial or empty result rather than a crashing message, and that would be fine for a most users.
If the "null = null object pattern" behavior is an expected and documented part of the language, it can work quite well. Cocoa and NextStep programmers are, and have been, very productive using a language with this behavior.
Achileas Margaritis makes a very good point:
No, the problem with nulls is not their existence, but that there are not separate types.
This is the real problem: null is no object, you cannot send any message to it (you cannot call any method on it). So if I declare a function: doSomethingWith(Object somethingElse), than it is clear that I expect an object (and null is no object !!!) as argument for the method. (the same goes for the result of a function: object provideSomething()).
A colleague said that null is like a "joker" when playing cards. Nice metaphor, but null is an "evil" jocker.
Monday, July 24, 2006
Wednesday, July 12, 2006
Java "new" for non-static iinner classes
By (over) using non-static inner-classes, I came to the following code:
InnerClass created = outer_class_instance.new InnerClass(...);
The "new" operator is completely misleading: is no method(message) of the OuterClass.
It just couples the creation to the outer_class_instance scope.
strange...
Functional Programming
Peter Norvig's "Python for Lisp Programmers"
Another "comparison of Python and Lisp"
James Edward Gray "Higher Order Ruby"
Lisp Scripting for .Net
F# ML/OCaml variant for .Net (nice sample here)
First feelings:
- Python is more functional than object oriented (watch-out for lambdas cannot contain statements)
- Ruby is more smalltalk-ish (I found it easier to use than Python)
- Lisp is more readble than ML/OCaml
Friday, June 23, 2006
Java 4s
Try this in java:
(4 == 4)
(new Integer(4) == new Integer(4))
well the first one is true, the second one is false. Why do I need 2 instances of the number (integer) 4 in java I don't know. I couldn't find any example (excuse). After all 4 is immutable, I cannot change it's state, I cannot make a 5 out of it.
I could say that in Smalltalk, or ruby, where everything is an object, yada, yada.... But Sun owns Java,
they own the Integer class, so when I call the constructor I should always get the same instance.
and we have the same symptoms (changed behaviour) with booleans:
(false == false)
(new Boolean(false) == new Boolean(false))
WTF !? I can have a million false objects in java. And for What? To be garbage collected, from autoboxing/unboxing? How hard is it to create a pool inside the Boolean class and to return always the FALSE object for Boolean(false) ?
Finally, there is another guy who feels my pain: "Java's new Considered Harmful . The problem stems from memory allocation and polymorphsim". Well actually he feels more pain, but that's his problem :D
Thursday, June 08, 2006
Java Generics Aren't
Via Steve Dekorte, from Bruce Eckel:
So [java] generics are really "autocasting."
Tuesday, June 06, 2006
NUllObject and Visitor
I have a problem with nulls: they are not objects. I cannot handle a null like any other object: I have to stop, check if it is null or not, and only after that, go on.
The problem is partially solved by throwing (checked) exception: now I have to handle an exception, instead of a null, which might have been propagated, unseen, unheard, through the stack, god-knows-where.
To the rescue comes NullObject: special object, implements the interface, does nothing.
But how do we close the implementation, but still we leave room from improvements: the Visitor: "Visitor lets you define a new operation without changing the classes of the elements on which it operates." (Actually the NullObject should be provided, in my case, by an O/R mapping layer, but I want to extend this object, for my needs). In this case, every "normal" object should do the double dispatching:
accept(Visitor v) { v.visit(this); }
only the NullObject should do nothing:
NullObject.accept(Visitor v) { }
And in C# where we have delegates, the Visitor could be a function/delegate.
-- apparently I am not the first one which thought of NullObject and Visitor.
Monday, May 29, 2006
No Pain, No Gain
jmockit is cool, but if "hacking" around a clean solution is so easy, when are we going to learn to avoid final classes, and API calls ("My Application Is All API Calls"), when are we going to refactor our code to a clean OO solution: objects represent roles/responsabilities (one-to-one relationship).
If you are climber, you take care of your equipment, you don't ducktape your cord !!!