Complex Type System and the Asymmetry in Tooling

By Tanin | 8 July 2019

Since Lilit recently added support for type info, I want to write about how it helps solve the asymmetry in tooling to some degree.

The asymmetry in tooling happens when an IDE is so advanced that it enables us to write highly complex code, which is only comprehensible when reading with the IDE. In a situation where we can’t use IDE, reading code becomes challenging.

This asymmetry gets worse when a language offers complex type system. Java, Kotlin, and Scala are prime examples. This might apply to Haskell as well, since I’ve heard that Haskell is an inspiration to Scala. But I’m not sure because I never work with Haskell (anyone help?).

In Java, for example, programmers almost always use a proper IDE, which supports code navigation, resolving types, and many other helpful capabilities. These capabilities turbo-charges the writing skill and helps us manage higher complexity in our codebase.

But when we read and review code on Github, we don’t have the same richness of tooling. See the ridiculously complex toy example below:

The example is an adaptation of java.util.stream.Collectors.groupingBy(...)

Deciphering which next() is invoked in our heads wastes our valuable mental effort.

Using IntelliJ/Eclipse, we can figure out this code instantly. This makes the writers unaware that this piece of code is too difficult to comprehend without code intelligence.

In contrast, a dynamically typed language doesn’t suffer from the asymmetry in tooling since we mostly write code in a text editor. We might use somewhat-inaccurate auto-completion here and there. But programmers never truly depend on code intelligence. Therefore, we tend to simplify code to the point that it can be understood without external assistance.

Some statically typed languages avoid the asymmetry in tooling by not offering complex type system. C and Golang are the prime examples. The languages are simple enough that we can comfortably use a text editor to write them. Therefore, the code is often simple enough to read with a mere syntax highlighting.

Whether or not a complex type system is needed to capture our complex reality is a discussion for another day, and I’d love to hear thoughts on this topic.

However, for Java and some other languages, that ship has sailed. The complex type systems are there, and we need powerful tooling to help us navigate that kind of complexity.

Improving the reading tool

This is why we are building Lilit. We want to solve the asymmetry in tooling. We want a “true” code intelligence that is ubiquitous and as good as your local IDE.

As an example, we recently launched type info, which resolves the concrete type of a symbol. For the code example above, you can simply hover your mouse cursor over next() to see the concrete return type (AnotherThing) and the method's location (line 29):

Lilit is currently accepting private beta users, who are on Github. Your team will review code on Github faster with Lilit, and you can help give us feedback.

Let’s achieve a better future together. Click here to try Lilit today.

If you would like to use Lilit on another platform (e.g. Gitlab, Bitbucket, or on-premises), please send a message to us. We'll notify you when we support the platform you're on.