Cymen Vig

Software Craftsman

Day 23: Looking back at one month with 8th Light

Doug and I sat down today to look back at my progress over the past month. Over the past month, I have done the following projects:

  1. Tic-tac-toe in Ruby

  2. Take #1 and put a web-interface on it using Sinatra (Ruby)

  3. HTTP server in Clojure (working but needs another couple days before ready for review)

Other things done during this time include the Ruby and Clojure koans and reading from a number of books:

  1. Agile Software Development, Principles, Patterns, and Practices

  2. Clean Code

  3. Side track: The Joy of Clojure

It took me a little while to get comfortable working in the open office environment at the 8th Light downtown office. I came from a very quiet office where I shared an office with one other developer looking right out the window on the 9th floor of a building in the loop. The 8th Light office is very different. The current office has a large room with a lot of tables, about 8-9 large LCDs with keyboards and mice (for pairing or individual work) and a large number of random office chairs. We’re on the top (5th) floor of a building so we have skylights. One end of the office has windows but nobody sits right next to them. For the most part, everyone grabs a chair wherever they want however most people do tend to sit in the same area.

But I digress – the point was that working in a loud open office is a bit of a change and I think this slowed down my first project. My second and third were much quicker. Doug has told me a couple of times that the apprenticeship has no fixed pace so it is up to the individual to go at the speed they are comfortable with. I think this makes a lot of sense and now that I’ve adjusted I’m working at a pace I’m happy with.

In short the last month has been a lot of fun. I’ve gotten to know everyone by name at 8th Light. Some I work with almost every day while others are typically off at client sites during the week. It takes longer to get to know these people but that is what Friday is for. I have felt very welcome here and am happy with how things are going!

Comments and Reactions

Day 22: Attempting to retrofit testing

As mentioned previously, I didn’t manage to do all of these things with my Clojure HTTP server project:

  1. develop test-driven using spec testing

  2. learn clojure

  3. implement HTTP protocol

  4. learn intricate details of Java-Closure interop for reading/writing string lines, characters and bytes to input/output streams

Everything went well except #1. So now I’m faced with refactoring my code to be more testable and learning how to write Clojure in a test-driven approach. This isn’t fun. I can now see clearly why Doug was suggesting I get going with the testing approach. The biggest problem is that it simply isn’t attractive to write spec tests after the fact because it will require refactoring and the code already “works”. No doubt there are some bugs in the implementation. But of course the proper thing to do is to do spec tests as they force one to:

  • write code in a more separable approach to make testing easier which also has the wonderful effect of decoupling your implementation quite a bit more than the non-testing approach

  • document how the system works by writing spec code which is functional: if the specs fail the system is not working as expected and the failing point is (hopefully) clearly evident

  • avoid having to litter your code with distracting safety checks because your spec tests can be referenced more easily to figure out how the code is supposed to be used instead of reading a method definition and hoping for the best

So I spent more time today splitting up my code. This was relatively straight forward except for a few things:

  1. Using multimethods in Clojure with the defmulti in one namespace and each defmethod in a separate namespace is tricky. I ended up having to do this:
1
2
3
4
5
6
7
1. Parent namespace - has a :use line for the defmulti namespace and each defmethod namespace


2. Namespace for function definition - defmulti


3. Namespace for each function implementation - defmethod

Then I could :use the parent namespace to pull everything into the project. Without the parent namespace I would end up with circular :use that would cause a compilation error. This seems very strange. I wonder if there is a better way or if I should really have my defmethod in the same namespace as my defmulti and keep them short by separating out code into additional short functions.

  1. The before and before-every function in speclj didn’t seem to work and the spec runner isn’t nice like the Ruby one – if you are comparing to items say string “a” should equal the output of mymethod() the Ruby spec runner prints out the differing result. This is most excellent as it makes resolving things quick. As far as I can tell, speclj can’t do this and it is a shame. Particularly because Clojure is functional so you can’t easily toss in a print statement like you can in an imperative language. It’s not that hard to do but it certainly requires more jiggling around (I usually wrap the part I want to print in a do and then use a let to save the result to a variable and then print the result – so that  is at least three things to change and you have to watch your brackets plus the next thing…).

  2. Clojure on the JVM is just slow enough to start that it makes debugging painful. I saw news of an implementation of Clojure on top of python/pypy which is not as fast as the JVM but has very fast startup times compared to the JVM. I don’t think they have solved the Java interop issue though so it isn’t useful for everyone (and indeed isn’t for me on this project). The other option is to look more closely at the Emacs integration however I’ve always avoided learning Emacs primarily because I like the more minimal world of vim. But I would definitely look into Emacs integration more closely if I was using Clojure regularly. Update: I found VimClojure which might be a solution for vim lovers!

I am very much in love with Clojure so while some things are annoying it is very fun to work with. I have briefly looked at other functional languages in the past and found that the interaction outside of the core lisp “world” looked very painful. The way Clojure ties into the JVM and allows dropping down to Java is awesome.

Comments and Reactions

Day 21: Splitting up Clojure HTTP server into multiple namespaces, PUT, etc

Spec testing is lacking in my Clojure HTTP server project. In order to facilitate testing, I split up the “all in one” core.clj file (and namespace) into a bunch of files (and namespaces). While doing this, it became clearer that some things shared between the functions needed to be separated out in order to be reused in multiple namespaces.

So the original project was basically:

  • core.js with namespace of clojure-http.core

This is now split up (and refactored where appropriate) into:

I wasn’t sure if it would work to put the defmethod implementations into separate namespaces but it worked out well. A blog post by Colin Jones named Clojure Libs and Namespaces: require, use, import, and ns was helpful for understanding the options in Clojure for working with namespaces.

On the testing front, I read through the speclj tutorial and tried some of the tutorial tests. It looks good! Now that the code is separated nicely I can write tests by namespace and look for more violations of the single responsibility principle (in Clojure, this seems to be by namespaces in lieu of classes).

Finally, the server is passing the FitNesse-based cob_spec test suite. I’m still slightly confused on exactly how FitNesse works. I think my issue is that it is a bit clunky and some of the test code is (at least in this case) in Ruby code. So the implementation is hidden from the wiki view and you can’t really tell what the test is doing unless the test names and other names are crystal clear. It is at least starting to make sense. The final part of my Clojure HTTP project is to add a test to this suite so I’m mulling over what to do.

Oh, and my Clojure HTTP server is named clip-clop because I like it and it’s sort of like the HTTP request-response cycle: a request (clip) always has a response (a clop). Maybe it should be cliplj-clopjl but that is ridiculous!

Comments and Reactions

Days 19 and 20: HTTP server in Clojure

I spent yesterday and today working on my clojure-http project. These features work but are still rough:

  • HTTP GET - can respond with text or binary files, directory listings and sort of 404

  • HTTP POST - can process body for text (“url encoded”) data but still rough

The hardest part so far has been IO. Reading lines of text and characters from input streams can be tricky.

Comments and Reactions

Day 18: 8LU, the Interactor pattern and automapper

Today at 8LU, Myles Megyesi, another resident apprentice, gave a talk on abstracting the business logic away from a Rails application by using an Interator (sample application used in talk). An Interactor is basically a controller but in the more common use of the term not quite as it is used in MVC. The abstraction provided by an Interactor is putting the business logic (which the presentation pointed to as being in the models for a typical Rails application) in another area separate from the concerns of Rails.

Coming from an ASP.NET MVC viewpoint, the talk was revealing in that some of the benefit of Rails is seen as a weakness. ASP.NET MVC doesn’t have a standard data store interface like ActiveRecord. Instead, it is left up to the developer to choose whatever data store interface they would like and it is up to them to design and/or create the models. This is of course a bit of a weakness as a the usual Rails example of a blog in 15 minutes may take a while longer while connecting to a database is figured out (or later on when attempting to figure out how to actual interact with the database instead of Visual Studio “magic”).

The key point of the presentation was that the abstraction makes it possible to separate the concerns enough that additions to the system would result in the addition of new classes instead of having to modify the existing classes (Models in this case). During the second half of my time with ASP.NET MVC I started to use AutoMapper and occasional use View Models. AutoMapper was created specifically to map between similar objects with one object coming from the data store and another object being created or having been updated by the application. The way AutoMapper works is it checks for the presence of the same properties on the two objects and if the types are the same it maps them over.

The reason AutoMapper is interesting in this case is that the Interactor implementation in Myles presentation ended up doing mapping between the model from the data store (an ActiveRecord object) and the model being passed by the Interactor to Rails (a simple object). AutoMapper was created to automate this exact thing and it is quite handy to have. Unfortunately, AutoMapper requires the creation of a map and has some limitations that are surprising if one isn’t very familiar with how it works. For some of my work, I ended up using reflection as the speed hit from AutoMapper was too large and I didn’t need the majority of the features. Because of the loose type in Ruby, I’m left wondering how useful a tool like AutoMapper would be in the Interactor pattern. It looks like the same people that created the C# AutoMapper made one for ruby automapper.

Comments and Reactions

Day 17: Finished Clojure Koans, brought Joy of Clojure, got echo server running

I finished the Clojure Koans. These were quite a bit trickier than the Ruby Koans in that they required doing at least some research for some of the questions. But it certainly works well to focus and keep you going and at least seeing some code in passing that will look familiar in another context at a later point.

I took the example of using server-socket from stack overflow and created a leiningen project for it and then put it up on github:

github.com/cymen/clojure-socket-echo

This is possible to run with a simple “lein run” (after perhaps doing “lein deps” and “lein compile” – I separate these as the “line deps, compile” seems to not work for me).

I brought a copy of the Joy of Clojure in order to try to get a bit more into the why of using Clojure and to get more familiar with the idioms.

Comments and Reactions

Day 16: New project -- HTTP server in Clojure

My next project is an HTTP server in clojure. I can use sockets. A quick search revealed clojure-contrib that has server-socket. The project needs to pass the cob_spec web server test suite from 8th Light. The test suite is built on top of FitNesse which is another project from 8th Light: a sort of mashup of wiki, requirements and testing.

While mulling this over I’m continuing to work on the Clojure Koans and attempting to do a Kata. I asked Doug and he said it’s normal to feel really weird trying to do a Kata but you basically just need to do it just like brushing your teeth.

Comments and Reactions

Day 15: Starting the Clojure Koans

I finished the HTTP version of my tic-tac-toe ruby game in about two days instead of 1.5 weeks so I was out of things to do. In the morning I spent some time looking at how ASP.NET MVC compares to Ruby on Rails and spent some time moping about katas. I just don’t get them to be honest. I’m guessing you have to “taste” them to get them but I have a hard time getting started. It may be that I don’t like the idea of performing code in public. It may also be that so far I’ve gotten nothing out of attempting to observe katas at 8LU due to the projector resolution, contrast and sitting distance. I’ve tried to move closer but then the kata was in clojure which I wasn’t familiar with so it was going too fast… I’ll need to bite the bullet and just start doing a kata at the start and end of every day.

I started the Clojure Koans in the afternoon. I’m using leiningen which was very quick to get setup on Ubuntu 11.10. So far, I like it… The initial reaction is that the syntax is a bit terse and it’s harder to break it into chunks but time with the REPL is helping.

I forgot my wallet at home but thankfully I also forgot half of my lunch so that worked out. Speaking of lunch there is another rant there. The 8th Light tradition is for everyone to eat lunch together every day. I like it but not every single day. Of course it is only for the duration of the apprenticeship but being limited this much at lunch time really cuts lunch options, the occasional socializing with people outside of 8th Light, and taking a bit of mental time to oneself. Maybe it’s okay to break the lunch rule every once in a rare while? It is important to note that overall the office experience is very nice and this is a minor complaint.

Update: Doug clarified it is fine to leave for lunch. It’s just a general idea to avoid having everyone eating at their computer if they are going to eat in the office. I’m all for avoiding that and I’m glad it was just a misunderstanding on my end!

Comments and Reactions

Day 14: Reviewed HTTP-based tic-tac-toe with Doug

Doug reviewed my tic-tac-toe project to see the progress I’d made on the HTTP implementation. We discussed some of the aspects of testing that were difficult. He is going to return with the next challenge but in the mean time I’ll work on making sure my HTTP-based tic-tac-toe using Sinatra is completely tested. I split my state interactions off to a TicTacToeStorageSession class which made testing easier as I could inject the session as a hash instead of a Rack session (the Ruby hash has the same interface as the session for my purposes).

I added more testing of to the project. Testing the “actions” in my Sinatra-based tic-tac-toe application was straight forward and thankfully there are few of them. I also added more testing to other parts of the application where prior refactoring exposed methods to use to set values for testing of functions that use those values (typically, along with other input).

Comments and Reactions

Day 13: Working HTTP-based tic-tac-toe

I worked on my HTTP-based tic-tac-toe project. I can now play the game on the console with:

1
ruby play_console.rb

Or via HTTP (using Sinatra) with:

1
ruby play_http.rb

I am still figuring out how to do testing with Sinatra. It looks fairly straight forward but the part I remain unclear about is redirects. So I’m looking into that next. The game uses POST when the human/HTTP player makes a move but uses a GET when choosing if the human/HTTP player would like to be X or O. That should probably be a POST but doing a nice clean prompt for X or O and submitting the result with a POST is not as clean as I’d like. Maybe another attempt or two will result in something that is cleaner.

For more details, see the TicTacToeHttp class

Comments and Reactions

Day 12: HTTP-based tic-tac-toe

I spent some time reading about Sinatra today and yesterday in order to put an HTTP interface on my Ruby-based tic-tac-toe game. By early afternoon, I had a board that was fetched via HTTP with a URL to GET to play a space. I hooked up an instance of the ComputerPlayer class (which uses a Negamax solver) and had the player on the HTTP side always be first (so X in tic-tac-toe). I used Rack::Session::Pool so that I could keep the game state on the server side (instead of the default session which would put it in a cookie). I saved the Board object into a session variable by using Marshal.dump() on it to serialize it to a string.

This worked out well! However it is untested and the Scorer hasn’t been hooked up yet nor the prompt to choose if human/HTTP player wants to be X or O. So those are the next steps…

Comments and Reactions

Day 11: Review of tic-tac-toe and the next thing

Doug reviewed my console-based tic-tac-toe solution in ruby. We discussed some of the areas that I had problems testing and some ruby patterns that could make some of my work more elegant. The next challenge is to make the project work with both a console and HTTP interface.

Comments and Reactions