Wednesday, August 08, 2007

Injection Doctor

We use in project X a slightly wrapped PicoContainer. The implementation of several service are registered in the container explicitely. Sometimes people forget to register it, and unfortunately the container fails with an "UnsatisfiedConstructor" error. The error appears only at run-time (we don't have test-coverage for container configuration), and it's misleading: if we need a class A which needs B,
and we forgot to register B, we get the error on class A (which is, per se, OK).

The solution (proposed) is to instantiate recursively all the services, and to build for each (failed) instantiation a histogram: the more points we get for a service, the "more" needed it is, the probability to
have there the "injection-problem" will be bigger. For the previous example A will get 1 point and B 2 points.

And here is the source:


public class Memoize {

private readonly Func _func;

public Memoize(Func func) {

_func = func;

}

private IDictionary _cache = new Dictionary();

public R Call(T value) {

R result;

if (_cache.ContainsKey(value)) {

result = _cache[value];

} else {

result = _func(value);

_cache[value] = result;

}

return result;

}

}


class InjectionExplorer {

private Func<IEnumerable<Type>, Type> _greediest_ctor_params;

public InjectionExplorer() {

_greediest_ctor_params = new Memoize<IEnumerable<Type>, Type>(GreediestConstructorParametersWorker).Call;

}

public IEnumerable<Type> RequiredTypes(Type t) {

return _greediest_ctor_params(t);

}

private ConstructorInfo Greediest(Type t) {

ConstructorInfo greediest = null;

int greediest_param_length = -1;

foreach (ConstructorInfo ctor in t.GetConstructors()) {

if (ctor.GetParameters().Length > greediest_param_length) {

greediest = ctor;

greediest_param_length = ctor.GetParameters().Length;

}

}

if (greediest == null) { throw new Exception("No ctor was found"); }

return greediest;

}

private IEnumerable<Type> GreediestConstructorParametersWorker(Type t) {

ConstructorInfo ctor = Greediest(t);

return Enumerables.Do.Map<Type, ParameterInfo>(ctor.GetParameters(), delegate(ParameterInfo info) { return info.ParameterType; });

}

}

class InjectionDoctor {

private readonly IEnumerable<Type> _types;

private readonly Func<object, Type> _instantiate;

private readonly InjectionExplorer _explorer;

private readonly IDictionary<Type, int> _failed_instantiations;

public InjectionDoctor(IEnumerable<Type> types, Func<object, Type> instantiate) {

_types = types;

_instantiate = instantiate;

_explorer = new InjectionExplorer();

_failed_instantiations = new Dictionary<Type, int>();

}

public void Examine() {

Enumerables.Do.ForEach(_types, TryInstantiate);

}

public void PrettyPrint() {

string print_format = "{0} -> {1}";

Console.WriteLine(print_format, "Type", "Failed Instatiation Count");

foreach (KeyValuePair<Type, int> failed_instantiation in SortFailedInstatiationsByFailedCount()) {

Console.WriteLine(print_format, failed_instantiation.Key, failed_instantiation.Value);

}

}

private IEnumerable<KeyValuePair<Type,int>> SortFailedInstatiationsByFailedCount() {

List<KeyValuePair<Type, int>> pairs = new List<KeyValuePair<Type, int>>();

foreach (KeyValuePair<Type, int> failed_instantiation in _failed_instantiations) {

pairs.Add(failed_instantiation);

}

pairs.Sort(delegate(KeyValuePair<Type, int> x, KeyValuePair<Type, int> y) { return y.Value.CompareTo(x.Value); });

return pairs;

}

private Type Instantiable(Type candidate) {

if (candidate.IsArray) {

return Instantiable(candidate.GetElementType());

}

return candidate;

}

private void TryInstantiate(Type candidate) {

Type instantiable = Instantiable(candidate);

if (HasFailedInstatiations(instantiable)) {

CountFailedInstantiation(instantiable);

return;

}

try {

_instantiate(instantiable);

} catch (Exception) {

CountFailedInstantiation(instantiable);

TryInstatiateRequiredTypes(instantiable);

}

}

private void TryInstatiateRequiredTypes(Type candidate) {

Enumerables.Do.ForEach(_explorer.RequiredTypes(candidate), TryInstantiate);

}

private bool HasFailedInstatiations(Type candidate) {

return _failed_instantiations.ContainsKey(candidate);

}

private void CountFailedInstantiation(Type candidate) {

if (! HasFailedInstatiations(candidate)) { _failed_instantiations[candidate] = 0; }

_failed_instantiations[candidate] += 1;

}

public int FailedInstatiations() {

if (! HasFailedInstatiations(typeof(T))) { return 0; }

return _failed_instantiations[typeof (T)];

}

}



Unit-Test sample:

class B {

private readonly C _c;

public B(C c) {

_c = c;

throw new Exception("poof");

}

}

class C {

public C() {

throw new Exception("poof");

}

}

class D {

}

class E {

private readonly C[] _cs;

public E(C[] cs) {

_cs = cs;

}

}

class A {

private readonly B _b;

private readonly D _d;

public A(B b, D d) {

_b = b;

_d = d;

}

}

[TestClass]

public class InjectionDoctorSpecifications {

private DefaultPicoContainer _container;

private InjectionDoctor _doctor;

[TestInitialize]

public void BeforeEachTest() {

_container = new DefaultPicoContainer();

}

private void Register(IEnumerable<Type> types) {

foreach (Type t in types) {

_container.RegisterComponent(new CachingComponentAdapter(new ConstructorInjectionComponentAdapter(t)));

}

}

[TestMethod]

public void should_detect_instantiation_failures() {

IEnumerable<Type> types = new Type[] {typeof (A), typeof (B), typeof (C), typeof (D), typeof(E)};

Register(types);

_doctor = new InjectionDoctor(types, _container.GetComponentInstanceOfType);

_doctor.Examine();

//_doctor.PrettyPrint();

Assert.AreEqual(1, _doctor.FailedInstatiations<A>());

Assert.AreEqual(2, _doctor.FailedInstatiations<B>());

Assert.AreEqual(3, _doctor.FailedInstatiations<C>());

Assert.AreEqual(0, _doctor.FailedInstatiations<D>());

Assert.AreEqual(1, _doctor.FailedInstatiations<E>());

}

}



The output of the PrettyPrint looks like:
Type -> Failed Instatiation Count
Tests.C -> 3
Tests.B -> 2
Tests.E -> 1
Tests.A -> 1

Additionally we could add a method bool InjectionDoctor.HaveAllInstantionsSucceded()
ps. The Blogger Code Formatter is not playing nice with the generics: the InjectionDoctor takes as parameter in constructor a function f(Type) -> object. In this way we make the InjectionDoctor container-agnostic.
pps. source-code on request.

Wednesday, August 01, 2007

Mixing Peer (extension objects in c# 2.0)

In project X we have a big hierarchy of objects/interfaces:
Eintrag
- Artikel
- NeuFormArtikel
- NormalArtikel
- AbdaArtikel
- Verweis
- AbrechnungsEintrag

(The hierarchy is bigger, but this is enough for our purpose.)
We have a case, where in a View we must display a union of fields from this hierarchy. i.e. AbdaArtikel.Preis if the object has such a property, otherwise null/string.Empty.

We have several options:
- use a visitor for the whole hierarchy
- use a PropertyMapper (reflection-fluent-interface-based machinery) (looks pretty slick, enables a very declarative way of mapping, maybe I will post about it)
- extend/pull the AbdaArtikelPreis into the Eintrag (if we need it there)
- mix in a generic visitor:

Since the objects/interfaces in the hierarchy are Nhibernate BOs, they are proxied, i.e., in our configuration, we cannot use generic methods in BOs. But we can extend the BO with an object which can:
  1. we define Eintrag.Peer() { return new EintragPeer( this ); }
  2. now we can extend the peer/mixing with generics

public class EintragPeer {

private readonly Eintrag _extended;

public EintragPeer( Eintrag extendable ) { _extended = extendable; }

public R TryMap(Func func, R otherwise_default) where T : Eintrag {

if ( _extended is T ) { return func( _extended as T ); }

return otherwise_default;

}

public void TryApply(Action action) where T : Eintrag {

if (_extended is T) { return action(_extended as T); }

}

}



  1. Now we can use it as:

Preis eintrag_preis = eintrag.Peer().TryMap(

delegate(Artikel artikel) { return artikel.Preis; },

Preis.Null);



Other variations can be build on that.

Thursday, July 19, 2007

"Agile" Process Disentanglement

How FUBAR can an "agile" process be, that this book is needed?
How deep in the jungle is the team, that we need a silver-magic-map to bring it back on the driving-road?

Wednesday, July 18, 2007

Functional idioms, Take Three

In a hypothetical project in which the Law of Demeter is completely ignored navigation through objects is allowed: we can do A.B.C.D.E.DoSomething(). This has a lot of negative effects, already spoken/written, I'm not going into details.
  • My 1st suggestion would be to play by the rules, and pull the DoSomething(...) through the hierarchy up to A, where you need it.
  • But what if you cannot do it ("it is not the way we do it in this project") ? What if, to make the matters worse, every element in the chain could be null (and not a NullObject) ? The chain would explode in a cascade of if-then-else-s to check every element for null, etc...
    • Comega has something like int? = A.B.C.GetSomeIntValue(...)
    • We (C#) could do:

created.PackungsgroessenEinheitText = Chain.On.Nullables<IArtikel, INormalArtikel, Packungsgroesse, string>(

artikel,

delegate(IArtikel x) { return x as INormalArtikel; },

delegate(INormalArtikel x) { return x.Packungsgroesse; },

delegate(Packungsgroesse x) { return string.Format("{0} {1}", x.Menge, x.Einheit); }

);

    • we navigate throught the chain with delegates. The navigation is interrupted on the 1st null hit.
    • If we watch the "chain" implementation:

public class Chain {

private Chain() {}

public static Chain On { get { return new Chain(); } }

public R Nullables(S input, Func fun_1)

where S : class

where R : class {

if (input == null) {

return null;

}

return fun_1(input);

}

public R Nullables(S input, Func fun_1, Func fun_2)

where S : class

where R1 : class

where R : class {

return Nullables(Nullables(input, fun_1), fun_2);

}

public R Nullables(S input, Func fun_1, Func fun_2, Func fun_3)

where S : class

where R1 : class

where R2 : class

where R : class {

return Nullables(Nullables(Nullables(input, fun_1), fun_2), fun_3);

}

}




Monday, July 09, 2007

Functional Idioms, Take Two

My friend Ralf has extended the Enumerating module, adding a fluent interface.
  • Since the mini-project lives, I think we should create a sourceforge acount for it.
    • I have extended the interface with IsEmpty, Count, ApplyOnce, ...
  • I really like the fluent interface. SelectThenCollect is no longer necessary, we can do Select(...).Collect(...)
    • if in the initial Enumerable we have m elements and we select n from them, SelectThenCollect is O(m). Select(...).Collect(...) will take O(m)+O(n). (in the current implementation).
  • Open Question: the current implementation does eager-evaluation: the select is computed when the method is called. Do we need a lazy-implementation? It could look like a query definition, and the code will be more declarative:
    • IEnumerating query = Enumerating.On(several_things).Select(IsEven).Collect(ItsColor);
    • IEnumerable result_items = query.Eval();
    • The solution might cache, the specified delegates, for a later (lazy), usage. This might lead to some unwanted side-effects: the garbage collector will not release the objects referenced in the delegates in the query definition, until ... (the query is released).
    • Through laziness we could work on very large (infinite) data streams.

Tuesday, July 03, 2007

Sudoku Solver: TDD or not

In this blog people are comparing Peter Norvig's solution with Ron Jeffries TDD tries. (read the post, [some] good comments, other links to reddit comments, etc.)

It is a nice problem to chew on, for me, as Unit-Test/TDD agilist: I think that a TDD approach does not lead to discover constraint satisfaction algorithms, it should lead to a clean, testable, SRP driven architecture. If I remember well, the XP books say that you should start with a "metaphor", a design starting point.

disclaimer: this an echo post, i just wanted to link to AIMA.

Thursday, June 28, 2007

Logging and Unit-Testing

Imagine the following situation:

1 public class SomeService {

2 private static ILogger _logger = new Logger<SomeService>();

3 //...

4 public void DoSomething() {

5 _logger.Debug("I log something cheap {0}", _service.DoSomething());

6 //...

7 if (_logger.IsDebugEnabled()) {

8 _logger.Debug("I log something expensive {0}", _service.DoSomethingElse());

9 }

10 }



How do we want to test that logging works in this situation?
A proposed solution was:

13 [Test]

14 public void should_log_something() {

15 using(disable_appenders_and_introduce_new_appender = new MagicStringAppender()) {

16 _service_under_test.DoSomething();

17 Assert(disable_appenders_and_introduce_new_appender.AllMessages.Contains("I log ...");

18 }

19 }



And here is what I don't like about it:
  1. Static creation of ILogger: by this we make ourselves dependent of the concrete implementation of Logger class. This will pull other dependencies (like log4net) in the environment, despite the fact that these are irrelevant for the test. The logger will be created when the class(type) is instantiated.
  2. The check-before logging for expensive log operations, is too low-level. A macro might help (TRY_LOG_DEBUG(...)), or maybe delaying the expensive operation into a lazy delegate: _logger.Debug(Func a_delayed_string_generator). The only objection might be that wrapping the costly operation in a delegate creates an extra object, making in the worst case scenario, the logging even more expensive. (From what I know, delegates & closures are pretty cheap).
  3. Maybe we don't know which operations are cheap and which are expensive, maybe in time a cheap log call will evolve to an expensive one. I would prefer a uniform lazy_delegate or macro solution.
  4. We are trying to unit-test a scope which is too big: if the service sends a message to the logger interface, if log4net (and its wrapper) receive the message, if according to the configuration, the log message is sent to the right appender, etc... Suppose that we change the config, and log4net, and the test fails. Then we have a lot of fun debugging. We will say: "why isn't working, I haven't changed anything in months". Because the scope is too big, we have no chance to do a binary chop.
  5. We have built another big machinery to manipulate log4net at the wrong end. This machinery must be maintained and support (for example when we want to switch to another log engine)
What I would do (probably better):
  1. Explicitly specify that we want to log in constructor. Either inject an ILogger or an ILoggerFactory.
  2. Test only that the service sends a message to the ILogger interface (a mock or a stub recorder)
  3. Try to use a delegate for delayed/expensive computations.
  4. Use a main logger for the critical exceptions (like OutOfMemory)
---
Update:
- the post it is not about what am I trying to log, it is about "how" I am trying to log. (suppose the expensive operation is dumping a complex object tree to a human-readable-not-xml representation)
- I am not a proponent for logging-testing, but some people would like to do that (logging gives a chill-fuzzy feeling: "I don't know what I have implemented, QA also doesn't have a clue, and now we are relying on log files, on a production-customer-machine. hmmm..."

Friday, June 15, 2007

F# FizzBuzz

I'm trying to learn F# as the "pragmatic-learn-a-new-changing-the-way-you-think-programming-language-every-year" (sorry about that, it must be the german influence).

Here are my FizzBuzz exercises, based on F# Active Patterns:

First try:

let (| fizz|_ |) x = if x % 3 = 0 then Some("fizz") else None

let (| buzz|_ |) x = if x % 5 = 0 then Some("buzz") else None

let (| fizzbuzz|_ |) x = if x % 15 = 0 then Some("fizzbuzz") else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| fizzbuzz text -> display text

| fizz text -> display text

| buzz text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done



Second try: refactor the recognizers to a single parameterized recognizer:


let (| is_multiple|_ |) n text x = if x % n = 0 then Some(text) else None

let print_fizzbuzz (x:int) =

let display text = print_string text; print_newline() in

match x with

| is_multiple 15 "fizzbuzz" text -> display text

| is_multiple 5 "fizz" text -> display text

| is_multiple 3 "buzz" text -> display text

| _ -> x.ToString() |> display

let _ = for i = 1 to 20 do print_fizzbuzz i done


(* we do get a warning that the syntax for the parameterized recognizers is under review and it might change in the future release *)

Please post or backlink for improvements :D

Tuesday, June 05, 2007

APIs, handling dependencies, agile architecture

Somebody said recently that Resharper is "not so lovely" since it cannot handle thousand of files... My argument is that the need to work simultaneously (in a solution) is a smell, and the fact that Resharper crashes at type-parsing with a "System.OutOfMemoryException" exception should amplify the smell (increase our awareness).

I think we have only two cases: inside the membrane, or outside the membrane. The core of the cell represents a service implementation, the membrane represents service definition, outside the membrane are the service consumers/users. Actually outside the membrane, is inside another membrane: the whole architecture should be splitted in components.

If we are inside we are working on the implementation of a certain service(object, component). Inside a component we have limited visibility, up to a component interface (the membrane). Maybe some other interfaces, or stand-alone components (without external dependencies, for examples enumerating). All refactorings, type-parsing should occur without problem in this component.

If we are outside, we are service consumers. But we cannot talk to the "core" of the cell, we see only the membrane: the component interface. So we are not influenced by the changes in the implementation of the service (aka the "core").

What happens if you are a producer and you need to modify service definition. If we don't have a few consumers, we could load all the required components in a solution (producer + all consumers), and refactor the whole thing. If we have many consumers, we need to use public API techniques: we declare the whole interface as obsolete, we declare and implement the new one. After x weeks we delete the old interface (the consumers are responsible for refactoring their own code).

Isolating the change, is a fundamental principle in designing maintainable architectures. In a world without membranes, we are just hurting each other.

Tuesday, April 10, 2007

Higher-Level Abstractions on Enumerations

I am not the only one missing a higher-level of abstraction in .Net.
I feel that I wrote thousand times find, select, collect as foreach ...
statement, without the clarity (declarativeness) needed.
Here is my shot
(very lightweight at it):


Thursday, February 01, 2007

Static Considered Harmfull

Let's imagine the following situation:


static class Service {
static void DoSomething(...)
}

class Client {
Client() {}

void Action() {
Service.DoSomething(...)
}
}



We have the following smells:

1. Tight-Coupling
- The client object is tight-coupled with the Service class.
- We cannot exchange, polymorphically, the Service.DoSomething(...)
with another service FunkyService?.DoSomething.


2. "Lying" Constructor
- The client's constructor doesn't declare all the dependecies.

3. Tight-Coupling Propagation
- If the class Service has dependencies to other static classes
(methods, instances, properties), than these dependencies propagate into
the client. The "inoffensive" Service.DoSomething(...) is just the tip of an iceberg of singletons.

Proposed Solution:
In an OO world, responsabilities are realized by objects.
Unfortunately in static-typed langugages classes ARE NOT objects.
(in smalltalk/ruby they are, we don't have this problem)

So let's do it right from the beginning:


interface IService {
void DoSomething(...)
}

[Inject]
class Service {
void DoSomething(...)
}

class Client {
Client(IService service) { _service = service }
void Action(service.DoSomething(...));
}



Benefits:
- we are unattached from the implementation of the IService.DoSomething
- we have explicitely defined the responsability of the client to delegate/ask a
query to the IService implementor
- We can provide different implementations to the IService
- UnitTesting is easier: if the implementation of the IService has been tested,
then in the Client's unit-tests we are only interested in the call to IService,
which we can mock.
- Instance creation is handled by dependency injection container
(if you need only one, create just only one)


An example in ruby (classes are factory objects):
http://onestepback.org/articles/depinj/

Wednesday, October 04, 2006

A bile on the the death of agile and an other post about the flip side of agile as religion vs. agility at google: Good Agile, Bad Agile

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.

Wednesday, July 26, 2006

Google Tech Talk: Cornelia Brunner - 'On Girls, Boys and IT Careers'

google video


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".




Podcast: Scott Ambler - Advanced Agile Techniques

mp3 here


Tuesday, July 25, 2006

Interview with Andy Hunt - Practices of an Agile Developer

on perlcast


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

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 !!!



Wednesday, May 24, 2006

Play And Learn

from RubyQuiz you could learn something about the use of continuations and Amb operator for Constraint Processing. This is so much fun !!!


Arc Suggestions


Paul Graham posted the collected suggestions for (his) "new Lisp" here. Some nice points: concurrency continuations, OO, macros... But I liked:

*** Dan Milstein: Concurrency

One problem which, IMHO, no popular language has come even
close to solving well is allowing a programmer to write multithreaded
code. This is particularly important in server-side programming, one of
Arc's major targets. I've written a good deal of multithreaded Java, and
the threading model is deeply, deeply wrong. As a programmer, there's
almost no one way to write the kind of abstractions which let you forget
about the details. You're always sitting there, trying to work through
complicated scenarios in your head, visualizing the run-time structure of
your program.

I didn't see another way until I read John H. Reppy's "Concurrent
Programming in ML". Instead of building his concurrency constructs around
monitored access to shared memory, he builds them around a message passing
model (both synchronous and asynchronous). What's more, he provides
powerful means of capturing a concurrent pattern in an abstraction which
hides the details.

I highly recommend giving that book a read. Here's an example of some of
what you get (not the abstraction, actually, just the basic power of
message-passing over shared memory). The abstraction facilities are
complex enough that, like Lisp macros, a small example doesn't really
capture their power. I'm in no way familiar with concurrent extensions to
Lisp, so I'm not able to provide the code for how much harder it would be
in CL or Scheme. Assuming they were augmented with a shared memory model
(as Java is), which forces the programmer to deal with synchrnoized access
to memory, I can only imagine it would be significantly more complex.

A producer/consumer buffer. You want a buffer with a finite number of
cells. If a producer tries to add an element to a full buffer, it should
block until a consumer removes an element. If a consumer tries to remove
an element from an empty buffer, it should block until a producer adds
something.

In Concurrent ML:

datatype 'a buffer = BUF of {
insCh : 'a chan,
remCh : 'a chan
}

fun buffer () = let
val insCh = channel() and remCh = channel()

fun loop [] = loop [recv inCh]
| loop buf = if (length buf > maxlen)
then (send (remCh, hd buf); loop (tl, buf))
else (select remCh!(hd buf) => loop (tl buf)
or insCh?x => loop (buf @ [x]))

in
spawn loop;
BUF{
insCh = insCh,
remCh = remCh
}
end

fun insert (BUF{insCh, ...}, v) = send (insCh, v)

fun remove (BUF{remCh, ...}) = recv remCh

---------------

Translated into a Lisp-ish syntax (very easy to do from ML), this would
look something like:

(defstruct buffer
ins-ch
rem-ch)

(defun create-buffer ()
(let ((ins-ch (make-channel))
(rem-ch (make-channel)))
(labels ((loop (buf)
(cond ((null buf)
(loop (list (recv ins-ch))))
((> (length buf) maxlen)
(send rem-ch (car buf))
(loop (cdr buf)))
(t
(select
(rem-ch ! (car buf) => (loop (cdr buf)))
(ins-ch ? x => (loop (append buf (list x)))))))))
(spawn #'loop)
(make-buffer :ins-ch ins-ch :rem-ch rem-ch))))

(defun insert (b v)
(send (buffer-ins-ch b) v))

(defun remove (b)
(recv (buffer-rem-ch b)))


Key things to notice:

1) Language features:

Communication between threads *only* occurs over channel objects, which can
be thought of as one-element queues. In CML, channels are typed, but in
Lisp they probably wouldn't be.

send/recv: synchronous (blocking) communication over the channel. A thread
can attempt to send an object over the channel, and will then block until
another thread does a recv on the channel.

Creating a new thread is done via 'spawn', which takes a function as its
argument. (I can't remember what the signature of that function is
supposed to be -- clearly, in this case it can't be a function of no
arguments, but imagine it to be something like that).

Selective communication: the call to 'select' is one of the very powerful
features. It is like a concurrent conditional -- it simultaneously blocks
on a list of send/recv calls, and executes the associated code with
whichever call returns first (and then drops the rest of the calls). The !
syntax means an attempt to send, the ? means an attempt to receieve. In
both cases, the '=>' connects the associated code to execute. (I haven't
really come up with a Lispy translation of that syntax).

I don't think select could be efficiently implemented without language
support. It requires a sort of 'partial blocking', which is tricky to
implement on top of normal blocking.


2) The Idiom

The buffer is implemented as a separate thread which has connections to two
channels and an internal list to keep track of the elements of the buffer.
This thread runs through a loop forever, taking the current state of the
buffer as its argument, and waiting on the channels in the body of its
code. It is tail-recursive.

Note the absolute lack of any code to deal with synchronization or locking.
You might notice the inefficient list mechanism (that append is going to
get costly in terms of new cons cells), and think that this is only safe
code because of the inefficient functional programming style. In fact,
that's not true! The 'loop' function could desctructively modify a list
(or array) to which only it had access. There would still be no potential
for sync'ing problems, since only that one thread has access to the
internal state of the buffer, and it automatically syncs on the sends and
receieves. It's only handling one request at a time, automatically, so it
can do whatever it wants during that time. It could even be safely
rewritten as a do loop.

What I find so enormously powerful and cool about this is that the
programmer doesn't need to worry about the run-time behavior of the system
at all. At all. The lexical structure of the system captures the run-time
behavior -- if there is mutating code inside of the 'loop' function, you
don't have to look at every other function in the file to see if it is
maybe modifying that same structure. This is akin to the power of lexical
scoping over global scoping. I have never seen concurrent code which lets
me ignore so much.

This really just scratches the surface of Concurrent ML (and doesn't touch
on the higher-level means of abstraction). But I hope it gives a sense of
how worthwhile a language it is to learn from.


3) Issues

I think that channels themselves would be fairly easy to implement on top
of the usual operating system threading constructs (without needing a
thread for each one). However, the style which this message-passing model
promotes can easily lead to a *lot* of threads -- if you have a lot of
buffers, and each of them has its own thread, things can get out of hand
quickly. I believe that Mr. Reppy has explored these very issues in his
implementation of CML.

http://cm.bell-labs.com/cm/cs/who/jhr/sml/cml/

Insofar as I have time (which, realistically, I don't) I would love nothing
more than to play around with implementing CML'ish concurrency constructs
in a new version of Lisp like Arc.



Google engEDU

A list with "all" (!?) educational videos from google


Tuesday, May 23, 2006

One More Thing

I really enjoyed the "Behaviour Driven Development" presentation which Dave Astels did at Google. And here is the "one more thing":



"I always thought that Smalltalk would beat Java, I just didn't know  it would be called 'Ruby' when it did." - Kent Beck




Monday, May 22, 2006

Speed Kills

Found an UncleBob's blog entry:



Speed is the prime destroyer of software systems. In our rush to get something to execute we make mess upon mess. We push and shove the code around in a frenzied effort to make something work. And then, once we achieve the desired behavior, we consider ourselves to be done, and move on to the next urgent task.

Of course we all realize that this is self-destructive behavior. We know that the more we rush the deeper the messes become, and the slower and slower we will go. We know that the only way to keep development going fast is to work carefully, deliberately, and slowly. We know that if we do this, we will keep our systems clean and well structured. We know that clean and well structured systems are easy to change. We know this. Yet we find it difficult to act on this knowledge.

The traditional productivity curve for software projects is a sigmoid. It starts very high, and remains high for the first few months. This is the honeymoon period when the team is cranking. They get lots of good work done, and they get it done quickly. But then the messes begin to build. Those messes slow us down. The productivity curve enters a steep and sudden decline. A few months later productivity has bottomed out and asymptotically approaches zero. This is the phase of the project where it takes forever to do even the simplest thing. This is the phase of the project in which the smallest possible estimate is 3 weeks or more.

As productivity slows to a near halt, the business responds in the only way it can - it adds more people to the project in the forlorn hope of increasing productivity. But these new people, eager to please their employers and peers, continue to rush, thereby adding even more corruption to the existing steaming pile. Productivity continues to decline as the sigmoid approaches zero at the limit.

The solution to this nearly ubiquitous problem is to act upon what we already know. That speed kills projects. Slow down. Do a good job. Keep the code clean. Write unit tests. Write acceptance tests. And watch how fast you go!




Saturday, May 20, 2006

Saturday Reading

actually watching videos, from TechTalk@Google


Peter Seibel, "Practical Common Lisp":



In the late 1920's linguists Edward Sapir and Benjamin Whorf hypothesized that the thoughts we can think are largely determined by the language we speak. In his essay "Beating the Averages" Paul Graham echoed this notion and invented a hypothetical language, Blub, to explain why it is so hard for programmers to appreciate programming language features that aren't present in their own favorite language. Does the Sapir-Whorf hypothesis hold for computer languages? Can you be a great software architect if you only speak Blub? Doesn't Turing equivalence imply that language choice is just another implementation detail? Yes, no, and no says Peter Seibel, language lawyer (admitted, at various times, to the Perl, Java, and Common Lisp bars) and author of the award-winning book _Practical Common Lisp_. In his talk, Peter will discuss how our choices of programming language influences and shapes our pattern languages and the architectures we can, or are likely to, invent. He will also discuss whether it's sufficient to merely broaden your horizons by learning different programming languages or whether you must actually use them.



Dave Astels, "Beyond Test Driven Development: Behaviour Driven Development":



Test Driven Development (TDD) has become quite well known. Many developers are getting benefit from the practice. But it is possible that we can get even more value. A new practice is getting attention these days: Behaviour Driven Development (BDD).

BDD removes all vestiges of testing and instead focuses on specifying the behaviour desired in the system being built. This talk will be focus on Ruby and will introduce a new BDD framework: rSpec. The ideas, however, are language independent



Wednesday, May 17, 2006

Architects Must Write Code

I found a blog entry here.


The comments are pretty interesting:


Bell-Labs has a pattern repository: WebInde of OrgPatterns (see ArchitectAlsoImplements, DevelopingInPairs).And my favorite:



Architecture, like war plans, do not last longer than the first minute of the battle: the architect must be in the front line, coding, spiking, re-architecturing...




Tuesday, May 16, 2006

Working Effectively with Legacy Code III

Jeremy D. Miller has some notes about the book.


Tip #1: Yes, go buy the book, and put it next to "Refactoring" (you know: beware of code smells)


Tip #2:



On most of the XP projects I've been on we've used an "Idea Wall," just a visible place to write down or post technical improvements.  Anytime we have some slack time we start pulling down tasks from the idea wall.  Occasionally we're able to outpace either testing or requirements analysis and we aren't really able to push any new code.  Whenever that happens we immediately pull things off of the idea wall.  One way to judge if your technical debt is piling up is to watch how crowded the idea wall is getting.  On the other hand, if something stays on the idea wall for a long time, it might not be that important after all.


Design never stops, not even for an older codebase





Thursday, May 11, 2006

nice

Virtual Street Reality


Martin Fowler evaluates Ruby

here:



It's still early days yet, but I now have a handful of project experiences to draw on. So far the results are firmly in favor of Ruby. When I ask the question "do you think you're significantly more productive in Ruby rather than Java/c#", each time I've got a strong 'yes'. This is enough for me to start saying that for a suitable project, you should give Ruby a spin. Which, of course, only leaves open the small question of what counts as 'suitable'.



Is Smalltalk (sorry, I meant ruby) having a coming back?


Wednesday, May 10, 2006

Lambda the Ultimate - thread

What do you believe about Programming Languages (that you can't prove (yet))?


Interesting thread.You can find some nice gems, in the flame-war dirt.


Should Mock Objects be considered harmful?

Robert Collins asks the question:



Should Mock Objects be considered harmful? As an optimisation for test suites they are convenient, but they mean you are not testing against the something which can be verified to behave as the concrete interface is meant to, which can lead to Interface Skew.



Let's says we have an object A which uses an object B. In OO A and B represent roles: object A does something in collaboration with B. A behaves "right" only if B behaves "right". So we have a behaviour contract between A and B. This normally represented by some unit-tests for the B role which specify its behaviour. Based on that, we can test A: we "mock" the B role, and see how A reacts. If we want to keep our implementation clean, A knows nothing about B implmentation, it knows only about its behaviour. (B is an interface, or A and B are implemented in a dynamic language).


Once we have tested B's behaviour and A's behaviour they "should" work together without errors. This doesn't happen: usually B is not throughly tested, the behviour contract is broken. for this case we should have integration-tests: A and B play nicely together.


Testing.Kata: unit-test role B, unit-test role A, integration test A and B.


Monday, May 08, 2006

Getters And Setters are Evil

Setters are evil because they allow you to have inconsistent objects, which they cannot work until they have set their collaborators (see PicoContainer/Good Citizen).


Getters are evil because they allow you to extract the data from the object, instead of putting the action where the data is. (see violating encapsulation, or Martin Fowler's "GetterEradicator").


So everything goes round and back to Allen Holub: "Why getter and setter methods are evil".


Thursday, May 04, 2006

Violating Encapsulation

Dave Astels blogs about it.



Something I see all the time, on every team I've been involved with, is code like the following (classes are generalized from examples):

MyThing[] things = thingManager.getThingList();
for (int i = 0; i < things.length; i++) {
MyThing thing = things[i];
if (thing.getName().equals(thingName)) {
return thingManager.delete(thing);
}
}

This code is tightly coupled to the implementation of myThing in that it gets the name property, knows that it's a string, etc. This is a classic approach from the old days or procedural programming. It is NOT OO.

How about:

MyThing[] things = thingManager.getThingList();
for (int i = 0; i < things.length; i++) {
MyThing thing = things[i];
if (thing.isNamed(thingName)) {
return thingManager.delete(thing);
}
}



I've seen this procedural approach thousand times. The problem is that a lot of developers think "procedural": they never met smalltalk/lisp with its closures. That's why learning a new programming language is good: you will think different, even if you will never get a chance to use the "newly acquired" programming language.




Startup School

Paul Graham on "the hardest lessons for startups to learn".


Wednesday, May 03, 2006

Sunday, April 30, 2006

To interface or not to interface

I've posted some comments on Troy Brumley's blog here . He liked the metaphor interface is a "firewall": we use it in order to isolate "changes": I don't want to be affected by your changes, and you don't want to be affected by my changes.


Actually an interface is a "wall", a very thin layer, which hides implementation details. And we should use is at framework, package and object level. In practice it doesn't happen: we "trust" our object within an package, or within a framework.


An interface defines a "contract": somebody understands this set of messages. Why don't we have interfaces in dynamic languages? Because we don't need this wall, we are always talking to a duck.The implementation is always hidden.The contract  resides in the UnitTests.



Qumana

I tried to download wbloggar, but the site is down. Let's see how is this working...


Powered by Qumana


Friday, April 21, 2006

Before and After Ruby

found on the "journal of jess".

Also Torsten is wondering here:
What I dont understand is that people complain about Java and start with Ruby right after it.
What if they would take the next step and directly start using Smalltalk. I'm sure they will enjoy the wonderfull world full of objects.
Well I think that Smalltalk environment is too scary for a java developer: no code files, no cvs/subversion, everything is in an image file, etc.

When a java developer plunges in Smalltalk, he has a "What now" moment: everything is there, but he does not know where to start.

Ruby is the "way" to Smalltalk: easier to learn, but OO imperfect (ruby has "syntax" and not everything is an object)

Tuesday, April 18, 2006

The Quality of Many Eyes

here:

Linux kernel development model implies that the developers can't directly add their changes to the main code branch, but publish their changes. Other developers can review and provide comments, and, more importantly, there is a dedicated person who reviews all the changes, asks for corrections or clarifications, and finally incorporates the changes into the main code branch. This model is extremely rare in producing commercial software, and in the open source software world only some projects use it. Linux kernel has been using this model from the beginning quite effectively.
Raise your hand: Who's doing code-reviews? Who's doing pair-programming?

Wednesday, April 12, 2006

Ruby and Lisp

found here:

So, Ruby was a Lisp originally, in theory.
Let's call it MatzLisp from now on. ;-)
– Matz

Larry Wall never understood Lisp
Guido Van Rossum once read a book on Lisp
Yukihiro Matsumoto once read a book on Lisp and understood some of it
– Keith Playford


Tuesday, April 11, 2006

Code Generation

Bill Veners here
Dave Thomas here

I don't like code generation. It feels to me as a step backwards and not forwards to a solution.

Instead of saying: "let's write a class/object with this functionality", we say: "let's write another class and a template, to generate a file, which compiled, gives us the needed object and functionality". Hmmm....

If the algorithm is so generic that we can express it in a template/file generator, why can't we write a class which through reflection generates the needed functionality?

How do you unit-test generated files? Do you test the output code, or do you test the new object? If you test the created object (the new functionality), than you have one additional step in unit-testing: compilation.

My point is that:
Ruby is dynamic enough to let be do what I want without leaving the language
Smalltalk is more "extreme" than ruby. There you don't have source files !!!

Java/C# should be "dynamic" too. I think they already are, through reflection and dynamic code generation, almost as flexible/generic as Ruby. But the developers are always scare of the performance loss. So they prefer an "immature" optimization, instead of a "clean" solution.

Monday, April 10, 2006

Monday, April 03, 2006

Sunday, April 02, 2006

saturday reading

Bambi Meets Godzilla
The Rise of "Worse is Better"
Jao has some good blog entries.

It's not about the content.
It's about the "sparkle which starts the engine".

Wednesday, March 29, 2006

C# 3.0 Implicitly variable types

I have previously posted about C# 3.0 new features.

The good side for
var p = new Point(1,2) is the we don't have to write that much redundant code. (like Point p = new Point(1,2))

The bad side:
The compiler won't implicitly convert to: IPoint p = new Point(2,3).
The usage of p as concrete class will lead to a lot of "concrete-class-dependency" and, eventualy, to bad design.

It is a pitty that syntax is used as a crotch to enrich the language. Look at Lisp, Smalltalk and Ruby, to see how easy is to enrich the language and to create DSLs. (ruby sample: rake, and this article)

Another entry on Code Quality

I see "broken windows" every day.

Bill Venners blogs about it here.

Andy Hunt observes the psychological impact:

If you walk into a project that's in shambles—with bugs all over, a build that doesn't quite work—you're not going to have incentive to do your best work. But, if you go onto a project where everything is pristine, do you want to be the first one to make a bug?

Singleton as anti-pattern

In 99% of the cases the singleton pattern is used as a global variable.

But as I said before, the singleton 's main problem is that it violates the Single Responsability Principle: we have a factory + an object.

But in some object-oriented languages (ruby, Smalltalk), classes are object-factories.
In these each object has it's own responsability. Clean: the class is a factory, the object is "... its responsability".

In a way, "singleton" is an antipattern, because of the language limitations.
In C++/java/C# you need to hide the constructor, and offer a static "getInstance()",
in ruby/smalltalk you need to overwrite the new message/method.

In c++/java/c# you wonder: "why can I instantiate objects from other classes, but not from this one", in ruby/smalltalk the API usage is uniform and clean.

Working Effectively with Legacy Code II

James Robertson blogs about a Michael Feather's talk here.
A 2nd entry here, about another topic.

Michael Feather's puts the finger on the wound:

"Utility classes" - ones with all static (Class) methods are a problem as well. Bottom line, the methods aren't where they belong. Preserve signatures, but create the appropriate methods in the appropriate classes.

Tuesday, March 14, 2006

More fun with ruby

Jim Weirich's presentation on Dependency Injection (in ruby).
If you are a ruby newbie, read Jim's guide for Java programmers.

And the cherry on the cake: Jim's presentation on continuations.
For more continuation goodies, see Sam Ruby's explanation, RubyGarden #1, RubyGarden #2 and IDEA Programmer's one. (or Bruce Tate article)

You might also check Seaside(Smalltalk), Borges(ruby) and DarkSide(Io) implementations. (no link, just google for them).

Reaction to James Gossling's rant about scripting languages

Very nice put together here.

Sunday, March 12, 2006

Object-Oriented

Maybe object-oriented does not mean an object based system like Smalltalk.
Maybe it means "in that direction".
When I say "my window is north-oriented", it does not mean that my windows is at the North Pole, but, somehow, strangely, points to that spot.

Maybe that's why we accept so many non-object imperfections: we are just staying at the window seeking for the real thing.

A Case against Static Calls

I don't like static calls. Why?
You cannot mock them.
You cannot apply "Inversion of Control", specifying the class (role A) as a collaborator of the user (role B), in the user's constructor.

A static function belongs to a class, and a class is not an object (in the most enterprise- object-oriented languages). This function represents a responsability which you cannot isolate, or replace (mock). This makes the testing/maintainance harder than it should be.

In an OO world, each responsability should be materialized by an object, see the Single Responsability Principle. But a class is not an object, so you cannot treat it as a an object.

The problem is that in some languages there is no uniform access, there is a discrimination between a class and an object, therefore they must be accesed in different ways.

Another issue is that a static method does not use the instance fields/methods of the class. A static method does not belong to the object, but to the class. If the class defines the behaviour of its objects, but a static method does not belong to the objects, then it should be defined somewhere else.

That's why the singleton is an anti-pattern: the class defines the object's behaviour (responsability 1), and it's creation/life-cycle (responsability 2).
A lot of other examples we can find in Michael C. Feathers book "Working Effectively With Legacy Code", where he suggests breaking the dependencies gradually: first make a method static, then move it to another class.

Closures "quote"

I found an interesting quote on lesscode.org, which expresses fully my hesitation (wondering):
Anyone that really feels Ruby closures are a critical technical factor should be wondering why they’re not develping in Smalltalk or CLisp.
Actually a lot (all !?) the things I love about Ruby come from Smalltalk (and Lisp, but Smalltalk is closer to ruby, being an OO environment): closures, named arguments (ok is a hack in ruby, but is going to be solved), continuations.
I saw a post that exception handling in Smalltalk is a library !!! Isn't that a pure thoght !?

My biggest discomfort with Smalltalk is the image-based environment.
On one side, image environment is what I need: when I develop in java, I am not looking for files, but for classes. (I do type/function navigation).
On the other side, ruby is so lightweight: you write a script, and you can check-it in, take with you, etc. In Smalltalk, I need to extract the code from the image in a text file, do some stuff, and then reintegrate it elsewhere.

hmmmm, ruby or Smalltalk, where should I digg deeper?