Corda: Kotlin
- Transfer
When someone looks at the Corda code , they immediately notice that it is written in Kotlin, a new programming language from JetBrains, which can be compiled under JVM and in Javascript. It was an unusual choice, and in this article I want to share some of the reasons for this decision and the experience of our "year with Kotlin in production".
Why Kotlin?
This solution can be divided into two parts:
- What platform to use? JVM, .NET, Node, Python / Ruby, Go, Haskell or something compiled (in machine code)?
- What language should I use if I chose JVM? Java? If not, then why? And if not, then which is different: Scala, Ceylon, Clojure, Kotlin, Python, Ruby, Javascript, or Haskell (because they all have a JVM implementation).
The reasons for choosing JVM as a platform are well known in the enterprise application environment and there is little point in stopping there. Suffice it to say that if you need a scalable, thread-safe, cross-platform runtime environment with garbage collection , and with a lot of well-documented libraries that solve basic business problems, then the choice is reduced only to JVM and .NET.
At the beginning of work on Corda, the project had no name and it was difficult to imagine that it would develop into a product in the future. In fact, when the project, which became Corda, began in December 2015 (on my first day at work), the plans were not to create a new corporate distributed accounting system. Corda began as a set of prototypes to explore new ideas and requirements, which was interested Architecture Working Group ( Architecture Working Group is ) consortium, in particular related to limited data visibility and data model provides scalability "array of unspent transaction output (UTXO set)" along with the programmability of the imperative smart contracts of Ethereum as a whole.
Due to the fact that it was not clear whether these prototypes would turn into something, or simply serve as information for other products on the market, we had a difficult choice. On the one hand, we wanted to quickly and efficiently explore algorithms and data structures. On the other hand, there must remain the potential for creating a large corporate product and quickly hiring people for it.
Java definitely met these requirements, but the lack of modern features in the language significantly reduces productivity, and, more hiddenly, the morale of the developers.
Dynamic typing was not considered - the benefits of correctness, development tools and performance provided by static typing are too great to be neglected.
Languages that are fundamentally different from the most popular ones were also not considered, since we wanted to be able to hire financial experts. And, although creating a team around a Haskell-like language is quite possible , the search for a person with serious banking experience and lazy (pure) functional languages from a random London resident seemed risky. In addition, the very nature of the product implied that our “users” were in fact plug-in developers and applications that use the platform, and there is no point in requiring them to learn completely new paradigms and tools. Our choice of language should not limit users too much.
As a result, these requirements left us with Kotlin, Scala and Ceylon. These languages are quite similar and quite interesting. We chose Kotlin for the following reasons:
- Virtually seamless integration with Java
- In particular, Kotlin programs use an enhanced (compiler-enhanced) version of standard JDK collections, thus ensuring no integration problems due to the use of other collection libraries. We send and receive collections to and from Java libraries everywhere , so it’s important that this doesn’t cause any problems.
- From the Kotlin-classes, the usual-looking Java API with the methods
get
/set
/is
according to types is obtained . No special annotations or other actions are required for this. For the reason that Corda provides for transparent use by Java developers, the API is a great advantage: from ordinary code, an API is obtained that cannot be distinguished from the Java API with only a few reservations (for example, to be able to intercept checked exceptions from Java annotation of methods)
- Inlining small functions like
map
/filter
/fold
/groupBy
(instead of hoping that the JVM will do it itself) is done by the compiler. Unfortunately, the JIT JVM compiler, although excellent in general, does not in all cases eliminate the overhead of abundant use of higher-order functions. Using Kotlin compensates for this, in addition allowing you to control the execution of the program from within the lambda functions (note: for example, non-local return). This is one of the little-known, but at the same time, useful features. Since we write code everywhere in such a functional style, then if it was poorly translated into machine code, we could create performance problems for ourselves. - Due to the fact that the code on Kotlin is translated into quite similar Java code, almost all existing Java-oriented tools work out of the box . This is not always true in the case of other languages. For example, Quasar hardly instruments Scala code because it needs method annotations, and Scala translates lambdas into methods that cannot be annotated. Kotlin lambda are usually embedded (see above), or may be annotated otherwise.
- Excellent documentation and a tiny standard library make it very fast to learn. We did not indicate in our vacancies the need for experience at Kotlin, and hired people without his knowledge, giving it a swing for 1-3 days after which the new team member was able to write idiomatic code.
- Based on the choice of candidates who passed our interviews, IntelliJ is the most popular IDE (they had a free choice of tools). Among the post-Java languages, IntelliJ supports Kotlin better than anyone.
- I already had a satisfactory experience with him, and therefore, I was sure that his new colleagues would also like it.
If it were not for Kotlin, we probably chose Scala: Kotlin was inspired in many ways and both are good languages.
Our year with Kotlin
What is the year of working with a new language in the context of a corporate application?
The most important thing was, no doubt, to hear from colleagues that they really enjoyed working with him. The programming language is a personal matter, and people usually have a definite opinion on this matter. If you, as the first task in the new job, ask someone to learn a new language and do not even warn about it in advance, then there is always the risk that a colleague will simply hate him and rather find him annoying rather than increasing his productivity. But this is not the case.
Below are some of the problems that often emerge in a post-Java / C # corporate development environment, and which we ourselves have encountered:
- The code looks different depending on who wrote it. In general, not such a big problem. Unlike Go, which requires a certain style, the Kotlin-code of different authors may look different. But IntelliJ has a formatting tool that unifies the codebase style. It is more limited than for Java, but that's enough. A more subtle problem, especially with Scala code, is the confrontation of Java-OOP and Haskell-OP coding style. Scala code that uses such libraries as scalaz can be difficult to read for developers who expect to see improved Java. In this dispute, Kotlin stands firmly on the improved side.Java And, although functional programming, in a certain form, perhaps at Kotlin, the community (at least for now) has not split into camps. We had cases when the code was written as if it was Haskell, but it was worked out on codereview.
- Libraries. At Corda, we use more than 50 open source libraries and there were no problems with any. We never wrote wrappers or layers of adapters. Maven or Gradle are usually used as build systems in Kotlin projects - there is no official Kotlin-specific replacement for these tools (although Gradle introduced Kotlin support as a new scripting language!).
- DSL and SQL. C # has LINQ, Java has JOOQ, and Kotlin has Exposed . This is one of the areas where Kotlin is somewhat weaker than its competitors - Exposed is an excellent example of using Kotlin's capabilities for building DSL, but the library itself has an unstable API and is a minor project. JOOQ, of course, can also be used with Kotlin, and, in retrospect, this seems like the preferred option.
- IDE / toolkit. The Kotlin plugin for IntelliJ is, of course, written by JetBrains and, overall, great. However, it is less sophisticated compared to Java support. New features of the editor, such as the parameter hint , must be manually ported to Kotlin, and support itself, as such, usually lags behind much older Java plug-ins. We also noticed that the IDE plugin quite often notifies about internal errors, although the frequency of IDE exceptions during the year has decreased significantly (and it seems that they do not affect anything). The use of other tools also does not cause problems, because what is written for java usually works out of the box. Exceptions are tools that work with source code instead of bytecode, and which, obviously, cannot be reused. At the same time, the Kotlin compiler and the IDE plugin are not as debugged as in the case of Java, even a year after the 1.0 release. Most likely you will never encounter internal errors in
javac
, but, although very rarely, we still encounter them in Kotlin. - User acceptance.Corda users are, most often, large and conservative financial structures. Such companies prefer to use common, well-established languages. Kotlin, without being either, clearly caused some surprise at the time when we started. "Why Kotlin?" - this is a question that, over the past year, has practically disappeared, because people looked closer and realized that it was not so risky as it usually happens with new programming languages. We also tried to facilitate adoption by providing code examples demonstrating that building applications using the platform does not require Kotlin knowledge. The results of this were not so successful - many developers, working for the first time with Corda, still begin with an introduction to Kotlin. It is not very clear whether this is the result of that we have provided insufficient Java-oriented use cases and documentation, or is it just a good excuse for learning a new cool tool. We were also helped by the growing acceptance of Kotlin inside large investment banks. Over the past year, we have heard from several members of the consortium that their internal development teams have begun to seriously look at Kotlin for their own products: often stimulated by the availability of tools that convert Java to Kotlin, which provide significantly less painful integration into the existing code base.
- Commercial support. The risk of using obscure languages is that they can stop developing, or have goals that are not consistent with the needs formed around the product, the user community (for example, in the case of research languages, the main goal of the developers is to create scientific articles). The main reason why we feel confident with Kotlin is that JetBrains is a stable, profitable company that has been on the market for over 15 years. JetBrains quickly began to tasteown tool introducing Kotlin in the code of the main products. Thus, the risk of discontinuing support is rather small. In addition, JetBrains is already a middle-aged company, and its target market (IDE and tools for developers) has ceased to be new or especially fashionable, which reduces the risk of a possible takeover of the company, which can lead to unpredictable strategic changes. And, despite the lack of a commercial support package for Kotlin, in practice the team rather quickly fixes known problems. At the moment, JetBrains intend to release the next language update after a year from release 1.0. Such a release cycle is quite similar to the development cycle in a corporate environment.
Findings?
We do not regret: the choice of a young language at the start of this project was at least a risk, but balanced. He did a good job for us and we would not change our choice.