Tuesday, February 28, 2012

Day In Review

I continued wrapping the payment processing API today. I ran into come issues with my integration test post-refactoring which lead me down a small rabbit-hole. Thankfully, I was able to pull myself back out before I lost too much sanity. Afterwards, it felt good to end the day totally green (specifically with unit and integration tests). Tomorrow, there is an iteration meeting and I am excited to introduce myself to the team by showing some of the functionality I have been working on.

Since the team uses JRuby, I've been running my test suite against JRuby before commits. I would develop in JRuby but it feels too slow for quick feedback loops (MRI, however, is blazingly fast). I feel as though clojure can evaluate at a quicker pace than JRuby and I'm curious to benchmark this to see if my feeling is true. If it is true it might be worthwhile to investigate the differences and see how they utilize to the JVM (I've been interested in the JVM lately for a variety of reasons).

Monday, February 27, 2012

Ruby's Functional Programming

Ruby is a fully object oriented language and is, in fact, so dedicated to objects that every entity in the language is an object. After hearing that statement it might seem a little weird that ruby also has functional support. Ruby's functional aspects are powerful and complete which makes it worthwhile to learn. We can invoke operations such as reduce and filter with the use of code blocks. We can also pass functions around directly with the use of lambda and Proc objects. In this post I'll show you some of the more powerful tricks, show their potential pitfalls, and document the experience with code to play with.

Each method call can be given an additional code block. If you don't believe me then put a block on the end of every method call that currently does not have one and watch as (almost) everything still works as intended (please don't really do that). I'll introduce code to show this, but first let's see a straight forward imaginary workflow:

Now get_name just returns the name attribute of an object, as you might guess. If we wanted to use this to get the name of an employee we would first find the employee and then pass it in here as a parameter as we have done above. Let's show the same workflow, but this time let's allow the code block to give use the name:

Cool right? We can build any employee interaction we want off of get_employee using code blocks. This is an imaginary case, however, and code blocks aren't always the best option so use them wisely.

Code blocks are a part of some of the standard library's methods. It allows us to make use of functional ideas in ruby code. For example, let's look at an inject that sums all of the elements given multiplied by two.

These are powerful expressions because the intermediary steps (i.e. the summations and a single element's multiplication by two) are stateless. We simply put data into the inject and a single answer comes out with no side effects. Other such functional actions include (but are not limited to) reduce, collect, and reject. Ruby's Enumerable has lots of functional methods.

The last functional item I want to share is the use of closures. In Ruby we can make use of lambda, Proc, and method(:name) to create closures. They all appear to be very similar, but have subtle differences. For the sake of learning we will ignore the subtle differences and use Proc to explain the concept. Procs are objects that encapsulate executable code. With a Proc we can bundle up some code and pass a Proc object around until we are ready to call it. For a simple example let's look at the following:

This should feel very similar to the code blocks we had discussed earlier. This is because code blocks are a type of closure! Think of Proc's as a code block that can be held for later use. Let's explore closures a little more:

What happened here? We invoked gen_bar in the Example::Bar object and therefore Bar.new should invoke a new Example::Bar, right? Wrong! Procs are always evaluated in their declared scope. That means that in this case the Proc was executed in the context of module Foo even though it was called in module Example. This is something to keep in mind as closures are passed between classes and modules.

Functional concepts in Ruby can make coding easier, cleaner, and more expressive. It's important to understand the concepts in order to use them correctly when a problem being faced could use a functional solution.

Day In Review

I began implementing an API wrapper around a payment processing and verification service. The workflow involved building up the required xml, shipping it off, and then making assertions based upon the return values. The code can get overly complicated if one is not careful to separate concerns and build out modular pieces. The code itself is meant to abstract the API away from the main app in order to assure loose coupling.

I generated integrations tests when building. Thankfully, the service offers a sandbox server to test against. This meant that as I built the functionality I could fill in steps for the integration test to follow up to and including the interaction with the sandbox server.

Sunday, February 26, 2012

(Retro) Day In Review

I've been without internet this weekend since I moved to a new apartment and am yet to have the cable guy visit. Before I start I need to give a quick shoutout to the Starbucks on Broadway and Sheridan for their wifi :) .

Friday morning I put some more time into the new internal 8th Light application I have started. The start of this project is exciting because there are many new idea that run counter to the canonical rails development. I've enjoying playing with some ideas and letting them fall into place with a red/green building and refactor cycle. Some of the abstractions took two or three attempts to feel right, but I am starting to finish up some of the beginning features and pass acceptance tests. Moving forward I will be finishing the first iteration's features and take a little bit of time to put a polish on the UI so it is not bland html.

Friday evening I had the opportunity to visit the University of Chicago for a hack night. It was a great experience because myself and two other 8th Lighters were able to share ideas with the students. I enjoy any opportunity where both parties are excited to share ideas two-ways and this was one such opportunity.

Thursday, February 23, 2012

Day In Review

I continued working on the interactions between columns on the story board. There are many server and client side modules that all serve these interactions so the change I want to make alongside the decoupling I am doing as I go is getting tough. Fortunately, I was able to leverage the power or prototypes to add metadata to objects that were subclasses of backbone objects. This means that I can retain the inheritance and those benefits with attached metadata that lives outside of that child-parent object structure.

I also paired with Paul on an autocomplete feature. We ran into some walls in development, but I believe we were on the right track. One takeaway I had was to select your dependencies carefully. If you include a dependency that itself is a collection of dependencies don't then include a single dependency that clobbers what exists in the collection. It's important to be cognizant of the ramifications of included dependencies.

Wednesday, February 22, 2012

Day In Review

Interactions between story board columns is rough and I am beginning to think that the architecture is going to need to change for the story board backbone views. Instead of having 5 story collections it will all be condensed into one collection that each of the five column views shares. Then, we can attach some meta-data (that will not synchronize with the server) to each story and let the column views use the meta-data to decide which stories to accept and reject when rendering. Although I liked the five ignorant collections with one per view it is not useful for multi-view interaction and every spiked solution I have attempted so far has felt very hacky.

I also planned the beginning iteration for Abbacus today. I spoke with craftsmen and apprentices about the architecture of the application and what they thought would be good practice when starting.

Monday, February 20, 2012

Decision Deferment

We have all seen the carnival ride where the riders are in a circle and the ride spins them around incessantly. The riders see the same distorted, blurred images flash past them over and over again. By the end of the ride the images are familiar, even in their blurred state. Eventually, the experience takes its toll and the riders begin to feel nauseous. Some riders feel this discomfort more than others, but all riders are aware of the feeling. Code can feel this way as well. We pass one test only to see another test fail. We type quickly and powerfully until the test is green. We run the suite and something else has broken. It begins to feel like a maddening experience where the test passes and failures blur together yet we can clearly distinguish a circular pattern. This is a smell and the smell should make us nauseous. It smells of needless complexity. We are hacking our way blindly through the code trying to pin down the one correct answer to the problem while leaving a tightly-coupled, complex, and unreadable wake. Code does not have to be this way. When we build our application out from the top down and defer hard decisions we can let the complexity come to us in small, manageable waves.

The top down development approach tells us that we can, and should, start at the top level of our application. We should express our intent in high level algorithms and relationships that are simple and easy to understand. If there is a hard high level decision to be made, we ought to make it now independent of the lower levels of implementation. We simply write low level interactions as if they existed in the system so that we are uninterrupted in the task at hand. When we feel comfortable with our design we move one level deeper. We view the current state and make decisions, once again, as if lower level implementation were available. Eventually, we reach the bottom and the implementation is agnostic to the higher levels. It simply does what it is told and we have avoided complex coupling between layers of abstraction.

Part of getting the top down approach right is to simply write what we say. If we have employees in our system and we want to aggregate the names of all of our employees we simply do that, exactly as if we were stating it verbally.
What is all_employees? It might not even be in the system! Right, it might not be, but we need it to get the names of all employees. Getting all the employees from some data store or central location is a detail that is outside of this algorithm's scope. Once we have finished with this algorithm we can move downward and collect all employees, again just translating spoken features into code. Coupling the idea of doing what you say with top down development is a powerful remedy to the typical complexity of systems.

If we have taken these two approaches to system building we have set ourselves up for the benefits of decision deferment. Why decide something before it is absolutely essential? After all, if we make the decision later we will be better informed about our system since more of the system will be built out. As the system falls into place we begin to find patterns. These patterns drive abstractions. As our system takes shape these abstractions allow additions to become simpler and better managed. Deferring decisions allow decisions to seemingly fall into place or, at the very least, help pin down a solution set to solve our problem. For example, I was recently pairing on a 'like' algorithm for a music playing application. If users like a song it would play more often. My pair and I spent a long time figuring out important ratios, playing with variables to establish good weights, ect. In the end, we sat down to code and realized that what we really needed was a workflow for the user to like a song and for the system to record and aggregate the user's likes. Thankfully, we did not dive straight into hacking up some weighting algorithm for an attribute that we did not have a familiarity with. Instead, we build the like aggregation first and moved on from there.

When we start to fall into the trap of chasing a solution we leave a trail of nested nasty garbage in our code. This garbage is a smell and we should avoid the chore of cleaning it up later if at all possible. Top down development and writing what we say allow us to realize the opportunities of decision deferment. Remember next time you feel as if you are on spinning ride of failure repetition to step back and avoid needless complexity.