Archive for August, 2009

SmalltalkJVM: From dream to …

Sunday, August 23rd, 2009

 stduke*

My Smalltalk for the Java Virtual Machine is progressing and while I’m not in the home stretch yet I can see the turn that leads to that stretch ! When I reach that turn I’ll open up the github account for people to download the project.

So what is this Smalltalk for the JVM going to do:

  1. Provide a Smalltalk-80 implementation that compiles to bytecode
  2. Provide a command line interactive environment like IRB or Lisp REPL
  3. Provide debug support (breakpoints etc)
  4. Provide generators for converting Smalltalk-80 to other languages, like Ruby, Python and Javascript, and to target other VM’s like LLVM and Parrot.
  5. Provide build tools and libraries to get things done (like rspec, rake, roodi, stunit etc).
  6. Provide a port/implementation of Seaside !
  7. Provide tools for bundling your code for deployment to J2EE containers.

If you would like to know more then please drop me a line or follow smalltalkjvm on twitter.

*This image which I’m calling Saint Duke (ST Duke) was done by Tim Cuthbertson, who is not only a talented developer, but a juggler and a 3D artist.

TDD: Where to start ?

Saturday, August 8th, 2009

birds-eye *

When I do Test Driven Development and I have the choice of doing it how I like then I start from the Top-Down. I choose Top-Down because it keeps me focused on the goal and what the Business/User wants. With Top-Down I go down fewer rabbit holes looking for an elusive bug or wrestling with a tricky implementation.

I start by writing down what it is I am building and what tests must pass before I accept the work as done. For example, I am working on a Smalltalk compiler for the Java Virtual Machine and one of the deliverables is the compiler, so this is how I started the acceptance tests:

The compiler will be done when …

  • Compiling Statements made up of a single Expression
  • Compiling Methods with a Message Pattern followed by Statements

I try to write all the criteria down before starting any implementation. I do this so I can prioritize and see the scope of what I am doing. I then convert these sentences into the syntax of the language I am developing in, sometimes this makes the test method names more uniform but I try not to loose important information:

compilingStatementsWithAnExpression()
compilingMethodsWithMessagePatternAndTemporariesAndStatements()

The next and probably most important step is writing the line of code that will prove or disprove that the criteria has been met. I write this before any implementation. If I can’t form a hypothesis in code before writing implementation code then I’m usually not sure of what I am doing and I should step back and become sure with a spike. I follow the same process of writing the verification or assert statement in English and converting it to the target language.  Here are the verification steps for the above tests, assuming the use of the Java Mockito Testing framework (in my case the compiler is done when it can call the code generator with a valid abstract syntax tree):

verify(generate).receive(statementWith(expression()))
verify(generate).receive(methodWith(messagePattern(), temporaries(), statements()))

I use the features of the language or the testing framework to facilitate code that is descriptive, even if this means a little more work since the test also serves as documentation. In my case I can tick off each test against the Smalltalk grammar shown in the back of the book Smalltalk-80: The Language and its Implementation.

When I have all the tests ready I sometimes comment out all but the one I want to implement first and make a start on implementing it.  Commenting out the others means I won’t get swamped and disheartened by a flood of red-bars (failing tests). As I implement each test I leave it uncommented and move onto the next test. Eventually all the code is uncommented and passing (green-bar).

The test I implement first is driven by the Business as it is typically the feature they want first or the one that shows them or me the most important information to make decisions on moving forward.

When implementing I fake-it-until-i-make it, that is, I hard code the results output from the code under test to ensure the test passes, then I go back an remove the hard coding and implement the real logic. I do this because it provides an opportunity to see more of the requirements to get the test to pass and an opportunity to see the test is correct. There have been a few times when the test was incorrect and passing and therefore the code was not correct and I was none the wiser.  Not happy times.  While using fakes I output a message to let me know a fake is in use, so I remember to remove them all.

The above approach is the one that works best for me and I suggest you try it as I find it yields less code overall.

ADDENDUM:

I received some feedback that suggested I may not be following the failing-test-implement-pass-refactor’ cycle and the approach I use does, as I start with a test that fails because I have not yet faked it. I then implement the fake and the test passes. I then continue to fake more tests to show two important things, 1. The tests work and, 2. The commonality in tests and the potential implementation. At some point in the process I will have no fake code at all and the actual implementation will have been done after a failing test. I have seen the false-positives scenario too many times so I stop and test the test just a little more. YMMV

*  The image used here is by Cannboys and you can see his portfolio here: http://www.istockphoto.com/cannboys

East: Clean and DRY …

Saturday, August 1st, 2009

towels

Some friends of mine like to meet up regularly and discuss code and on Friday I caught up with Fredy and we discussed keeping Ruby code clean and dry by orienting it East. Fredy showed me the following Cucumber steps from his project as a starting point for a discussion:

1 Given /the Customer results table is sorted by Address/ do
2   @customer_page.results.header.address.click
3 end
4
5 Given /the Customer results table is sorted by Surname/ do
6   @customer_page.results.header.surname.click
7 end

We both liked the use of the page fixture “@customer_page” as it encapsulated the page being worked with and kept the steps focused on the business logic rather than how to interact with classes that manipulate web pages or swing apps. However, the rest of the lines were not good in my opinion, as they exposed too much information on the ‘how’.

This is how the discussion went:

James: What is line 2 meant to do ?
Fredy: It sorts the customer page results by address by clicking on the address column in the header row.
James: So why not have a method like ’sort_by_address’ and let it take care of the how by getting the results, it would be more readable* ?
Fredy: But what is there (on line 2) is readable.

James: Which of them ‘results.header.address.click’ or ’sort_by_address’ conveys the business intent?
Fredy: I guess ’sort_by_address’ does, but it is only one line and it is done.
James: Sure but it isn’t East Oriented and therefore you are missing opportunities to keep the code clean and dry. See line 6, where you repeat yourself.
Fredy: You and your East thing. (In a sarcastic tone) Ok, tell me how East will help as Im dying to know?

James: For a start you are asking the object with the information for that information rather than telling the object with the information to do the work.
Fredy: But I am using ‘Tell Don’t Ask’, I’m telling the customer_page to give me the results.
James: That isn’t ‘Tell Don’t Ask’ as I understand it, which is also why I call it East and have rules to ensure code is East Oriented. With East you can’t have a public method that returns a value like results, so you would have to ask the customer_page to do something else, maybe ’sort_by_address’ ?
Fredy: Some code has to get the results and sort them !
James: Yes, but it should not be a public method, since this leads to duplicate code like you have (lines 2 & 6) because when you ask for an object then manipulate it the chances that more than one piece of code will do the same manipulation is made higher since most people wont look through the codebase to find the same manipulation and make it common. By going East you greatly reduce this possibility and put the functionality in an Object where it can be refactored to remove duplication.
Fredy: Lets assume line 2 and 6 are East as you suggest, how is that removing duplication and besides now I have an explosion of methods on my page fixture object ?

10 Given /the Customer results table is sorted by Address/ do
11   @customer_page.sort_by_address
12 end
13
14 Given /the Customer results table is sorted by Surname/ do
15   @customer_page.sort_by_surname
16 end

James: Now the methods are all on the same object and not spread across lots of other objects making the opportunity to refactor them into a single method more obvious. For example, ’sort_by_address’ can become ’sort_by’ and take an argument indicating the sort criteria. So your code can now look like this:

20 Given /the Customer results table is sorted by (.*?)/ do |criteria|
21   @customer_page.sort_by criteria
22 end

James: Which is East, reveals the business intent and provides a generic step that can be reused wherever a Customer results table needs sorting without you adding more code. If you follow these changes through the code you should see that going East made the code more DRY and reduced the count of public methods on several objects. As a bonus if the Business decide they want to sort using a keystroke rather than a click you only have to change the code in one spot.

Fredy: I guess I could give the ‘East’ thing a try. Would you help me ?
James: Sure.

*I made a mistake here in the discussion by using a value word like ‘more’ since what is actually more readable to one person may be less readable to another. I need to remind myself not to use ‘value’ words like ‘more’ or ‘better’ in these sorts of discussions.