Static Typing – the dangers of incomplete info

Ok, so I’m going to use this post – Making Illegal States Unrepresentable – and I’ll add my experience to it. For people that don’t know F# (or that don’t want to check all the post to see what’s the point), the idea is that he’s trying to construct a type that will only be valid if a user does at least an e-mail address or a postal contact. Then, he ends with the following type (I’m “inventing” a way to represent this type that’s close to Scala, but easier to read for people that don’t know Scala or Haskell or F#):

type Contact {
  Name: String
  AND Contact: ContactInfo

type ContactInfo {
  EmailOnly: EmailInfo
  OR PostOnly: PostalInfo
  OR EmailAndPost: EmailInfo with PostalInfo

// Types EmailInfo and PostalInfo have to be defined also

Then, he uses 13 lines to construct a ContactInfo, and another 12 to update a contact info. He ends up concluding that these complicated types are necessary because the logic is complicated. And that’s where we start to disagree.

Object-oriented after working with functional programming

Sometimes I need to divide my knowledge in phases: when I started to program, I felt that C/C++ were the best languages to make a software. Then, I’ve began to work with Ruby and learned Test-Driven Development. I divide my knowledge “before TDD” and “after TDD”, because it literally changed the way I could think about software and tests in general. Now, I’ll probably make the same division: “before functional programming” and “after FP”, and I only discovered that things have changed this week: I just discovered I don’t know how to do object oriented programming anymore – and to be honest, it’s not really a bad thing: I also saw in practice how object-oriented programming expects you to write lots of boilerplate in most situations.

This realization came to me when I was working in a peculiar kind of problem – it’s basically a ruby code that needs to connect on messaging system and, when it receives a message, needs to persist it in a relational database. The problem is that this specific system have a strong consistency requirement, so the message could only be updated on DB before a specific event happens: after that, we can’t change it anymore, except for some specific fields. Also, as we’re working with messaging, we can receive the message multiple times, out of order, and all of those strange things that happens on Internet-land. So, to summarize:

  1. The system will receive a message
  2. It’ll UPSERT a record on DB, just with some identification fields (they’ll never change, and if they do, they characterize another message to be persisted – think about an external id)
  3. It’ll BEGIN a transaction and SELECT ... FOR UPDATE my just upserted message
  4. It’ll find, on another table, the rest of the fields on the message
    1. If this record doesn’t exist, we’ll create it (and log)
    2. If it does exist, we’ll check additional info, and decide: or we ignore it (and log), or we upsert (and log), or raise an error

Now, for the implementation. Because consistency is a must have on this system, I don’t want to expose for future programmers (be it myself or some of my friends) some code that’ll induce me to errors: after all, who wants to do with_consistency_check(msg) { Message.upsert!(msg) } when I can just do Message.upsert!(msg), right? So, I don’t want to allow people to be able to modify, find, update, or anything else outside of the with_consistency_check (or whatever name I decide). So, how to do it?

Understanding Ruby’s Awesome Nested Set

Recently, I saw people migrating from Awesome Nested Set to Ancestry. The reasons are simple – Ancestry is very simple, it just need a new string field in your table, and it’s easier to reason about. So, why should I even consider to use an alternative?

The answer is simple, and I’m going to quote H. L. Mencken: For every complex problem there is an answer that is clear, simple, and wrong.

And the reason that using Ancestry is a bad idea is simple: it doesn’t reflect good design. It treats a single field as a multi-valored column that keeps the ancestry of your object. This means that there’s no way to fetch all records AND their parents in a single query, or fetch all records AND their children, because we need to split the string (ruby-side) and then create a query (also ruby-side). So, in this post, I’ll show some tricks of what we can do with Awesome Nested Set, or even beter, how does it implements the tree pattern (and why it calls it a “set”, not a “tree”).

First, when we think about categories and sub-categories, we think like this:

But this is, in fact, a terrible way of representing trees in SQL. So, the alternative, is to transform it in a group of sets: Parent 1 (P1, for short), is a super-set containing subsets C1 and C2 (Children 1 and Children 2, for short). Each of the children have its own grandchildren, so C1 is a super-set containing G1, and C2 is a super-set containing G2 and G3.


Don’t be a Copperfield

After a year and a half working in other languages, I’m back to Ruby. And, one of the things that I was amazed at Clojure is how simple things were.

Back to Ruby, I’m really surprised on how people overcomplicate things.

There’s no perfect language, nor perfect community of languages. In Clojure, there are fewer abstractions, which is not exactly a good thing – if you, let’s say, just want to create a simple page to show data from a database, you’ll find it extremely tedious to do it in Clojure, where in Ruby/Rails it’s just a few lines of code away. Ruby’s moto is “programmer happiness”, and this reflects in every library that they write.

But this kind of higher abstraction pays off with time. At least where I live, working with Ruby means working with Rails almost all the time. There are no “big competitions” for Rails or ActiveRecord (Sequel is a close one, but at the time of this post, AR have 10 times more downloads than Sequel), and other web frameworks are mostly “Rails-like”. But what bugs me most is “magic”.