Our Languages

January 4, 2022

Throughout Symbol's development, we've used a large number of different languages. As part of regrouping and turning the ship, we've decided to cut back on the number of primary languages. Some choices will be less surprising than others. We hope this will facilitate hiring and improve intra-organizational mobility. We want to tear down those walls, Mr. Gorbachev!

C++

catapult-client is the Symbol reference client and will continue to be developed and maintained in C++.

We like C++ because it is a deterministic destruction language, which gives us fine grained control over memory usage. This allows us to optimize performance more easily.

C++ before and after 0x are almost different languages. Using RAII patterns, memory problems are almost almost a thing of the past. We're currently using standard version 17 because we find it has good cross platform support, which allows us to support all major operating systems and compilers.

Rust

We hope to build an alternative client in Rust one day. A secondary client will improve the resilience of the network because no longer will a single client bug threaten the entire network.

We like Rust because it has many of the same advantages of C++. In addition, it makes it somewhat more difficult to make memory management mistakes.

JavaScript

Catapult REST was our first Symbol application. We chose JavaScript then and we're doubling down on it now.

We plan on slowly converting our browser based applications - wallets, explorers, etc - into JavaScript.

Python

For scripting, tooling and E2E tests, we're choosing to use Python.

An interpreted language like Python is well suited for management tasks like these. Performance is not paramount and the Python ecosystem is strong.

SDKs

We plan on supporting a lite-SDK - in the model of the Python SDK - for JavaScript and Python.

Any other SDKs can be created by the community.

Appendix: Why We are Choosing JavaScript over TypeScript

Throughout Symbol's development, we've mostly chosen TypeScript over JavaScript even though we started with JavaScript (Catapult REST). Upon reflection, this reliance on TypeScript has probably been detrimental.

JavaScript is a far more common language than TypeScript. Among both our small developer community and the world at large.

When first introduced in 2012, TypeScript was intended primarily to:

  1. Add type checking to JavaScript
  2. Introduce the "future" of JavaScript

The "future" that TypeScript presaged mostly arrived as part of ECMAScript 6 in 2015. At that point, TypeScript devolved into simply adding type checking to JavaScript.

Unfortunately, TypeScript doesn't perform any type checking at runtime so the "safety" it provides is incomplete at best. For example, objects received from calls aren't checked. Neither are the objects used to interact with libraries without TypeScript bindings.

In JavaScript, it's clear there's no magic type checking. So, if the type of an object is important, it needs to be checked explicitly. This also crystallizes the intent in the code.

TypeScript is incredibly verbose. It can change a few lines of JavaScript:

public static runImageUsingExec(logger, options) {
    const { catapultAppFolder, image, userId, workdir, cmds, binds } = options;

into something a bit less readable:

public static runImageUsingExec(
    logger: Logger,
    {
        catapultAppFolder,
        image,
        userId,
        workdir,
        cmds,
        binds,
    }: {
        catapultAppFolder?: string;
        image: string;
        userId?: string;
        workdir?: string;
        cmds: string[];
        binds: string[];
    },
): Promise<{ stdout: string; stderr: string }> {

Yes, that code really is equivalent!

TypeScript always needs transpiled into JavaScript before running. By definition, it only exposes a subset of JavaScript. Why not take full advantage of JavaScript's features instead of hiding them?

In addition, the transpliation process adds an extra step in the edit, build, test loop and requires code maps when debugging. Why not just get rid of all that and write JavaScript in the first place?

TLDR: If you want to write better JavaScript: use eslint, not TypeScript.