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