Posted on May 11, 2021 by Denis Redozubov

How We Choose Programming Languages at Typeable

Demystifying the way we choose technologies for development

I’ve been asked several times why I prefer using such programming languages as Haskell and Rust, since they are not the most widely used and popular tools. So, I’ve written this post to demystify what goes on in my head when I consider the selection of technologies.

Developing software that needs to meet the requirements for long-term operation and a defined reliability level is, in a sense, similar to a chess game. In both cases, it’s rather difficult for the human brain to comprehend full scenarios. Experience is of great importance, and every move/choice can be critical. Further comparison suggests that, just like in chess, development is very much positional, i.e. a whole set of moves can be deployed in preparation for a maneuver which results in winning a single pawn. It might appear that it’s merely about one pawn but, in a serious game, it may become a considerable advantage. Similar to a positional game on a chess board, the development and evolution of large-scale projects involve constant decision making focused on solving major tasks or implementing project requirements. The effect of all, even minor, solutions tends to accumulate by the endgame, or by the moment the software product is in operation. However, the difference complicating the situation is that, unlike in chess, software development cannot be solved by using a computer. You can’t find the best moves just by running a computer engine. That is why it is necessary to make many decisions incrementally, leading us to the goal, and all means of improving our position are worth using.

Developing software that needs to meet the requirements for long-term operation and a defined reliability level is, in a sense, similar to a chess game

In a nutshell, solutions can be divided into several categories: architectural, procedural, and instrumental. Architectural solutions show the way we structure the project. Procedures define how we organize the work process and assure the implementation quality and correctness. Instruments, in turn, determine what the development team should use to achieve the goal. Today, end-to-end software development is carried out using a large number of tools: you need to formalize the requirements and the development process, write the software code and test it, assemble the release, etc. Despite this flow of tasks, selection of a programming language can be of the greatest importance because this choice determines the following set of parameters:

  1. Performance baseline.
  2. Peculiarities of software distribution and operation, for example, the interpreter’s requirements or static linking ability.
  3. Ecosystem of reusable libraries and components. I’d like to note that it is not only the number of libraries that matters, but also the quality of those relevant for you.
  4. Possibilities of parallel/concurrent/asynchronous operation of the programs, which may be important for many systems.
  5. The difficulty people face when learning the technology, which significantly influences both the language community and developer retraining.
  6. Language expressiveness which is somewhat subjective, but still being felt by developers. Additionally, the selection of programming language can have a strong influence on the structure of development. For instance, the language ecosystem tools may determine the way unit tests are written and the tests scope. A good infrastructure for property tests can give a boost to move in this direction, while the lack of good infrastructure for unit tests can make their development and support more challenging.

The tools also influence architecture-related issues – reuse of system modules is linked to how easy it is, from a conceptual viewpoint, to divide the units and structure the code. For instance, explicit work with the effect systems enables better code generalization and ensures that the software code unit doesn’t perform any input/output operations, such as network and disk operations. This makes it possible to consider safety and software architecture-related questions.

Considering this, you should be aware that the correct selection of a programming language for your project and team may have far-reaching implications. Keeping in mind the chess analogy, we remember that every minor advantage contributes a point in favor of the language, and can play a significant role in a large-scale development. It should also be noted that I’m talking about selecting development tools in situations which set no strict constraints on technology selection relating, for instance, to a large ecosystem already written in a certain language. At Typeable, we are guided by the following motives for general-purpose languages:

  1. The programming language should support static typing. This allows the developer to reduce the duration of each iteration of the code modification and its validation. This also results in a significant reduction in the number of bugs, both in terms of functional requirements and software security.
  2. Algebraic data types – it’s difficult to overestimate the influence of this feature when you start using it. This is a simple feature, absolutely necessary for invariant modeling. Sum types are also so essential that selecting a language where you need to simulate them using other constructs means creating obstacles at the outset.
  3. Flexibility of support and execution of multithreaded programs. Languages with GIL (Global Interpreter Lock) fail to meet this requirement from the very beginning. It’s desirable to be able to maximize hardware utilization and work with sufficiently high-level abstractions.
  4. A sufficient ecosystem of libraries. We also subjectively assess their quality. We don’t think it necessary to connect everything in the form of libraries, but such basic things as bindings to popular databases should be available.
  5. Clear minds in the community of developers who work with this language. A developer we would like to see in our team should be interested in CS and development. This in contrast to “easy-to-learn” technologies tempting people to get into IT for the sake of easy money, which greatly dilutes the workforce.
  6. We should have programming languages in our toolbox that allow creating software that meets strict time and memory requirements.

Considering all of the above, our toolbox should allow us to hold a steady position in any project coming our way. Going back to the chess analogy, these are the principles that let us play a highly positional game. A positional game one aimed at creating a long-term position that opens up possibilities for the player, minimizing the weaknesses. This as opposed to an attack-oriented game, i.e. “sharp game” associated with higher risks. The attacking player strives to end the game before the opponent is able to take up a strong defense. Sharp development includes programming contests, MVP for marketing experiments, several data science tasks and, in many cases, software development for Computer Science publications. They are similar in that they usually don’t require any long-term support, as they just have to work for a definite period of time. On the other hand, a positional game means long-term play where maintainability and updateability are the key characteristics. This is exactly what we do, and we need a solid foundation to be sure that the software we write and update can operate for a long time. Though such projects can also start as MVP, they are based on quite different assumptions.

Looking for a proper technology to use

So why do we select a technology based on precisely these considerations? Multiple reasons can be given. First of all, it’s a good idea to exclude the issues of technology fashion and trendiness to improve predictability over a large timespan. Even though a time-proven compiler with an active community is a conservative option, this choice is reliable in contrast to new fancy options that pop up each year. Surely, some of them will move from the last category to the first, but we will know this only later, probably after several years. Instead of the fashion trends, we strive to use fundamental Computer Science and the great number of research works devoted to this topic that have been applied to the programming languages we use. For example, type theory is a discipline close to both mathematics and CS, that deals with the fundamental issues of requirements formalization. This is exactly what we need to write software. Besides, this is the combined experience of other people engaged in “exact” sciences, and I believe it would be absurd to ignore this experience. It makes more sense to take such discipline as a basis rather than use nothing, or to use a subjective opinion based on the personal experience of a particular individual.

Secondly, we are looking for programming languages and compilers embracing the largest possible number of our principles. This is why, in addition to our favorite Haskell, we’ve added Rust into our toolbox. For real-time requirements and strict constraints on memory utilization, we need something rather low-level. The typing strictness in C is still far from perfect, so if we can use Rust for such tasks, we’d prefer to use it.

The third reason is that we create software primarily for our clients, and we’d like to protect them from our biases. That’s why we mustn’t exceed a certain risk level agreed with the client when we select a tool. But, even under these conditions, we use rather marginal technologies such as GHCJS, because the complex analysis of pros and cons still produce an attractive picture for us and our clients. We’ve already written about how we arrived at this decision: Elm vs. Reflex and Why Do We Need Transpilation into JavaScript?.

All means and theoretical justifications are worth considering when you work with large code bases and complex software; you need to somehow keep this complexity in check. Our idea of a correct approach is to protect every pawn, improve our position gradually and carefully, so that the project can exist in a good and stable state until the moment it will play a pivotal role in our clients’ businesses.

Recommended

You may also like

Want to know more?
Get in touch with us!
Contact Us

Privacy policy

Last updated: 1 September 2021

Typeable OU ("us", "we", or "our") operates https://typeable.io (the "Site"). This page informs you of our policies regarding the collection, use and disclosure of Personal Information we receive from users of the Site.

We use your Personal Information only for providing and improving the Site. By using the Site, you agree to the collection and use of information in accordance with this policy.

Information Collection And Use

While using our Site, we may ask you to provide us with certain personally identifiable information that can be used to contact or identify you. Personally identifiable information may include, but is not limited to your name ("Personal Information").

Log Data

Like many site operators, we collect information that your browser sends whenever you visit our Site ("Log Data").

This Log Data may include information such as your computer's Internet Protocol ("IP") address, browser type, browser version, the pages of our Site that you visit, the time and date of your visit, the time spent on those pages and other statistics.

In addition, we may use third party services such as Google Analytics that collect, monitor and analyze this ...

Cookies

Cookies are files with small amount of data, which may include an anonymous unique identifier. Cookies are sent to your browser from a web site and stored on your computer's hard drive.

Like many sites, we use "cookies" to collect information. You can instruct your browser to refuse all cookies or to indicate when a cookie is being sent. However, if you do not accept cookies, you may not be able to use some portions of our Site.

Security

The security of your Personal Information is important to us, so we don't store any personal information and use third-party GDPR-compliant services to store contact data supplied with a "Contact Us" form and job applications data, suplied via "Careers" page.

Changes To This Privacy Policy

This Privacy Policy is effective as of @@privacePolicyDate​ and will remain in effect except with respect to any changes in its provisions in the future, which will be in effect immediately after being posted on this page.

We reserve the right to update or change our Privacy Policy at any time and you should check this Privacy Policy periodically. Your continued use of the Service after we post any modifications to the Privacy Policy on this page will constitute your acknowledgment of the modifications and your consent to abide and be bound by the modified Privacy Policy.

If we make any material changes to this Privacy Policy, we will notify you either through the email address you have provided us, or by placing a prominent notice on our website.

Contact Us

If you have any questions about this Privacy Policy, please contact us.