Category Archives: Sone

Sone Is Being Kotlinized

About a year ago Jetbrains released Kotlin 1.0, a new JVM-based programming language. I took a short look at it and pretty much immediately fell in love with it: it is very similar to Java, uses considerably less boiler-plate, has properties, improved collection interfaces (while using all the known java.util stuff under the hood), and lambdas.

I started to introduce it in the company I currently work for and nobody who has used it for more than two lines wants to go back to writing Java code.

Needless to say, I started using it for my private projects, too. One of the good things about Kotlin is that it integrates with existing Java code very nicely. Compiling Java and Kotlin source code with Gradle with both parts depending on the other works out of the box. Java code can use Kotlin classes and the other way around with pretty much no restriction. This makes it very easy to update existing projects: write new code in Kotlin, continue using the old Java code until it’s time to replace it.

So far, Sone profitted from Kotlin most of all: as I am in the process of writing lots and lots of tests for everything that Sone does (and it is amazing how many bugs you find once you actually unit test your code) the news tests will – of course – be written in Kotlin. I also already added some new features to Sone, again using Kotlin.

Several places in Sone collect elements (such as posts) from all over the place, filter them, sort them, all using Guava and Java 1.6-compatible syntax only. This requires a lot of extra code to be written. Take a look at this:

Collection<Post> posts = new ArrayList<>(sone.getPosts());
for (String friend : sone.getFriends()) {
    Optional<Sone> friendSone = core.getSone(friend);
    if (!friendSone.isPresent()) {
        continue;
    }
    posts.addAll(friendSone.get().getPosts());
}
posts.addAll(core.getDirectedPosts(sone));
posts = Collections.filter(posts, Post.FUTURE_FILTER);
posts = Collections.sort(posts, Post.DESCENDING_BY_TIME);

Code very similar to this exists in several places in Sone. Now take a look at the equivalent Kotlin code:

val posts = (sone.posts +
        sone.friends.mapNotNull { core.getSone(it) }.map { it.posts } +
        core.getDirectedPosts(sone))
        .filter { it.time <= System.currentTimeMillis() }
        .sortedByDescending { it.time }

Now go ahead and tell me that this isn’t better (this even works for almost arbitrary definitions of “better.” Yes, Kotlin is just that good).

In addition to actually making me want to work on Sone again it will also reduce the amount of production code in Sone, making it easier to review. However, as I don’t expect any review activity to take place before 2030 (and probably not even before the Great Singularity™) this was not a criterium which played any role in my decision to gradually convert Sone to Kotlin.

Simply put: Kotlin makes programming fun again.

Biznis iz gettin’ siriuz

It is amazing how often I manage to code myself into a corner, or at least halfway there, before realizing my mistake. In order to prepare Sone for a persistent database, i.e. the situation that it starts up and everything is already there, I thought I had to make the current in-memory database persistent.

But I think I actually don’t have to do that. Nothing in Sone really assumes that the initial database is empty; everything is cleared when new data arrives, i.e. all data of a Sone is dropped when a new edition is loaded, anyway. This means that it should be perfectly fine to simply start with the new database (yes, it’s finally getting serious!) and see how that works out.

We Are Getting Closer

So, I finally managed to get the beast Core.java below 2000 lines of code. I have extracted various parts from it and put them into their own classes, with their own unit tests, and I have been pulling almost all Sone-related storing out of there, too. I’m still not done with it, there’s a lot more that will have to go because it shouldn’t have been there in the first place. However, it will probably not take too long anymore until I can start using a real database to store Sone data which I am really looking forward to.

So, We Meet Again…

The day has finally come! My decision to keep all objects (Sones, posts, replies, etc.) in memory and never re-create them is finally coming back to bite me in the ass. And even though I knew for a long time that it was coming I was kind of surprised and relieved this morning when I realized why I even did that in the first place: because I thought I had to create Sone (and post and reply) objects before I ever had any real data for them!

Now that I finally rediscovered the reason behind this ancient decision I should be able to rework the parts in question to fit in better with the database changes. Just having discovered this makes me have a much more positive outlook on the whole database topic than I had before. :)

Why Sone Is Stalling Again…

At work we started watching “Clean Code” by Robert C. Martin (“Uncle Bob”) a couple of weeks ago. While some colleagues are of the opinion that these videos are unbearably stupid (and they do have a point: the way all the knowledge is presented is… uhm… questionable, at least) I have grown quite fond of some of the things Uncle Bob has shown us.

Two points that have especially struck home for me: keeping methods short and test-driven development. While the former is (more or less) easy to implement the latter requires more discipline and is also difficult to work with when a sufficiently large codebase already exists.

So lately I have been writing tests. Thousands and thousands of lines of test code have been added to Sone; in the process I was able to eliminate almost the same amount of lines from the production code because it proved to be unnecessary after various refactorings have performed.

However, one of the targets of the current refactoring still has not been achieved: storing everything in a database. I am a lot closer to finishing this task, though: most objects and their relationships are already managed by a non-persisted, in-memory database. Persisting the database will be a second step that follows later.

I will continue writing tests and increasing coverage to make it easier to finish the big refactoring. Unfortunately that will mean that there won’t be a new Sone version in the near future.