Looking for different languages
With the never-ending supply and constant evolution of programming languages and their ecosystems in the market, there is no shortage of options to pick from. Various languages serve various purposes. Which one should we choose? We started by looking at 4 candidates: C#, Scala, Java and Kotlin.
C# and .NET
The .NET ecosystem has evolved rapidly in recent years and its community is one of the most influential in DDD, with a depth of source codes with examples, libs, and literature about it. The Entity Framework had the closest implementation to what we were looking for, as implementing repository pattern with it is fairly simple, allowing for the use of fluent mappers and the complete decoupling of domain classes from persistence concerns. While these qualities caught our attention, we were in the process of starting to migrate our more of our activity to a microservice architecture style. We also noticed that, in terms of libraries and knowledge, the stack was still behind compared to other players. As .NET Core became more advanced, companies began to use more containerization (dockers) and a range of DevOps practices, but this was still somewhat recent for a stack that had long focused solely on Windows environments.
The JVM Ecosystem
You may have noticed something in common between the other 3 languages mentioned: they all belong to the JVM ecosystem.
The JVM ecosystem contributes to a number of well-known frameworks such as Spring and Hibernate; as well as libraries that integrate with many of the tools we use, such as Camunda, Consul, and Vault.
This caught our attention and reassured us: if we make a mistake and want to switch between these languages, we have interoperability between existing and new code. Depending on the frameworks chosen we could also reuse their knowledge (taking them to another stack). Another point of interest is the “omnipresence” of the JVM ecosystem, such as some “.jars” that are provided by the Brazilian government to validate files for integration with the Central Bank (BACEN). Anyways, let’s get back to languages.
We decided to take a look at this language because it is highly consolidated in the functional world.
Scala would apparently solve our problems upon first glance, but again a dormant risk appeared. We were coming from the object-oriented paradigm with Ruby, meaning most of our developers had no experience with the functional paradigm.
It would indeed be quite a learning curve for the team: in addition to a new language with all its ecosystem and frameworks, it would also be a new paradigm.
The number of existing libraries running in the JVM ecosystem is impressive, most of which are written in Java. It appeared Java could be a safe choice for us, but with a brief dive into the language we noticed that it could also bring us new problems. Java, aside from being an older language than the others, maintained backwards compatibility for a long time. This slowed its evolution. Java was a great language when it was released in 1995, but when compared to modern languages, its syntax, verbosity and lack of features make it a precarious choice.
With more frequent evolutions starting after Java 9, the language gained some syntactic sugar, but it still did not compare to the readability offered by other languages. This made us somewhat apathetic to the language. Checked and unchecked exceptions, poor type inference, getters and setters, and its inability to overload operators and to create extension functions are just some examples of features that didn’t appeal to us…
But what about a whole library ecosystem built on top of Java and JVM? How could we take advantage of this? It was then, at the 2018 QCon event that we saw a great talk about Kotlin. Furthermore, the talk featured examples of Kotlin within DDD and Event Sourcing. Quite a fabulous coincidence. A language with elegant and modern syntax, which ran on a secure, far-reaching platform within the market (JVM, though it also compiles for other platforms); and which would also meet our DDD needs, fell into our laps. We needed to test it.
As previously stated, we have a very complex domain. We wanted to devote our time to solving business problems, not boilerplate coding to fulfill everyday tasks that frameworks could perform for us. Jeff Atwood once wrote in his blog that the best code is the one we don’t write (“The best code is no code at all”), because the less written code, the less testing needs to be written and the less maintenance problems we face in our day-to-day.
Null Safety and Data Class features, for example, eliminate the necessity to test these types of tasks. Did the code compile correctly? Then the behavior has already been validated! All this, completely abstracted by the features of Kotlin. Null Safety, in particular, is a feature that wasn’t offered by any of the other languages mentioned, at the time (C # recently implemented it in version 8). Data Class existed only in Scala, and was also implemented in C # 8.
On the official Kotlin website, exclusively regarding Java, is the “comparison to Java” page which has a list dedicated to comparing the functionality of both languages. We note that there are several features that do not appear there and that we consider Kotlin’s advantages in a direct comparison, largely because of the results derived from some features already mentioned above (such as weak type inference and verbosity). For example, the list manipulation interfaces detailed in this Stack Overflow thread.
But OK… Kotlin looked like a great option and got us very excited, but what should our next step be? Should we simply migrate to Kotlin with JVM? Check it out in our next post.
Our goal in Product Technology is to create the best solution to our customers’ needs by offering the most complete and innovative portfolio of financial products from financing to investing. We’re here to build a fully automated and intelligent digital platform and we’re looking for people who’ll join us on that: https://boards.greenhouse.io/creditas