IntelliJ’s Serial Code Transformations

Our integrated development environment has introduced user interface improvements that may have profound impact and opportunity in the way we code. We will call these serial code transformations.


As I was chatting on Workplace with our SVP of Engineering about his new post on Kotlin, our conversation shifted from his trials as a young engineer to how terrifyingly awesome the recently integrated development environment (IDE) experience has become. With thirty plus years under his belt, he had seen many IDE environments from visual to textual and back again.

It goes without saying the IDE has and still is the extension of the developer’s hands. The IDE and its tooling is what make developers productive. From the individual to the collective, IDE’s have the power to cradle and support larger team efforts. One of the many great examples is what transformed over at Uber. The IDE played a key role to that success.

While there are many environments to choose from my focus will revolve around Jetbrain’s IntelliJ. I chose IntelliJ because there is an interesting improvement trend unfolding that I’d like to explore in its user interface. We will discuss two of these recent additions added to IntelliJ 2016.2 and 2016.3. There could be more to come in the 2017 version series.

We will review these user interface improvements with the perceived pros of readability, proper labeling and discoverability. We will also review the cons of visual noise, code quality consequences and nondeterministic code.

I’ll label these additions as serial code transformations (SECTAs). Before we focus on the transformations, let us next explore IntelliJ’s historical origin and then tooling strengths.

A Brief History On IntelliJ

IntelliJ’s strength has been in supporting Java. Since IntelliJ’s inception in the new Millenia and the rise of Java, IntelliJ had entered to compete in the IDE space against NetBeans and JBuilder.

The story on JBuilder is long. However in the end it had been swallowed by Eclipse. As Eclipse took over JBuilder, NetBeans began jockeying as the preferred IDE for Java.

Over the years major domains controlled by Java rose. This ensued power popularity struggles. One such major case was when Jetbrains paired with Google and Android development transitioned from Eclipse to IntelliJ. There are many reasons why this happened. Gradle support was absent.

With IntelliJ’s rise, NetBeans popularity had waned with the transition from Sun to Oracle. With recent problems such as NetBeans parent abandoning them, the future of NetBeans now remains in Apache’s hands.

NetBeans still holds a slice of Java server side development. IntelliJ is now the popular go to for most Java, Scala, Groovy and Kotlin ideation. A new chunk of engagement had been from Android and some Java server sided development in its ultimate edition. Jetbrains has also started the route of supporting iOS development.

With IntelliJ pulling ahead above all IDE’s in the space, Jetbrains continues to improve. IntelliJ’s implementation of clever code completion, build system plugin integrations, code and flow control analysis, and other major integration points like version control and testing, it is difficult to find a developer who hasn’t used it. Most praise the software.

IntelliJ’s North Star

Historically IntelliJ has had a very public north star. IntelliJ’s authors want engineers to “develop with pleasure”. This pleasure had a lot to do with their development of refactoring tooling since their inception. Without question the refactor tooling has been improved mercifully in the past ten years.

Their terrifying advanced hotkeys are also true to that pleasure. This is a highly welcomed addition to all the incrementing intelligent code completion now dubbed “deep intelligence”.

One of my earlier experiences with IntelliJ’s pleasure was in the refactoring tooling. I was a witness to those like Robert Martin (Uncle Bob) and his blazingly fast refactors in such videos like the bowling game kata. The IDE was essentially doing all the work. Extracting, rearranging, abstracting, all with keyed shortcuts. Simply memorize the shortcuts and where to place the cursor and let the tooling refactor with pleasure.

As with all tools in the IDE, the refactoring tooling changes code that we commit for the better as long as it is steered with engineering principles. Coupled that with great lint tooling, code analysis and now flow control, it gives the power to modify code intelligently and with speed.

In the past few iterations of IntelliJ, Jetbrains had introduced new under-the-radar improvements to further the pleasure. Jetbrains has labeled them under their “User Interface” improvements section, but I’ll label these as serial code transformations. The first few have been added within the past six to nine months.

What are SECTAs? Let’s review some examples next.

Our First SECTA

One of the more recent code reviews that came up at camp was the use of booleans as parameters in methods.

Of course, we know that adding a boolean parameter to method could be considered a code smell. It signals that this method may have two distinct options and thus violates the SRP rule.

It can be difficult to understand the usage of a primitive boolean type. As the boolean is being passed through method calls the developer has to dig to see the signature and the parameter name to understand the usage at a distance. In many cases this breaks mental concentration.

The decision to disallow a boolean parameter could be dogmatic if the codebase already has other methods using a similar pattern. Also, it depends on the usage. A method that uses a boolean without splitting fundamental two paths way could be acceptable.

Lets say we agreed to add the boolean. How do we fix the developer visibility through the method calls? The answer here is that we do not. IntelliJ solved this problem with a SECTA.

Our first SECTA is called a parameter hint. IntelliJ adds visible labeled metadata that doesn’t exist in code. However it appears to be inline code.

As a visual example, notice the gray non-monospaced label “append” next to true below. This is a parameter hint.

“append” is an example of IntelliJ’s parameter hints.

When I first saw these parameter hints some months ago I thought a special debug mode had inadvertently been turned on.

IntelliJ now ships with parameter hints on by default so many developers are becoming familiar with the style. They are continuing to improve it with expansion of hints to other parts of the code and filtering of hints where restraint is required.

Our Second SECTA

Sometime ago, Uncle Bob took on the quest to define a final programming language. In his exploration he brought on many thought provoking ideas and concepts. When he described what ideal language attributes should be, he questioned if there would be a better way to declare inequality as !=.

Now there is. A recent example was introduced at Google I/O this year at the Intro To Kotlin session. Enter code ligatures also known as font ligatures.

Hadi Hariri, the host of the I/O session, had been known in the community to introduce the use of code ligatures at previous Kotlin demos. He had now done so at a major developer conference.

Code ligatures have been around for a few years with many IDEs supporting them in some way. Many require the use of plugins. However none have adopted the ligature to the point of mass popularity and few have direct support for them. This trend is changing and it’s coming to a IDE near you.

Code ligatures are different and radical as this new tool transforms code as a developer types code.

At the moment, code ligatures are off by default in IntelliJ. However, I believe that IntelliJ is about to change this at scale so that it becomes popular. Hadi is on a mission to do this.

Code ligatures are shocking to those that have developed for some time. See the example below.

Live demonstration by Hadi Hariri of a code ligature in Kotlin.

As an example the code ligature changes != into ≠. There are many other replacement examples. The goal of code ligature is readability. To see more examples, see FiraCode. IntelliJ has implemented FiraCode as the preferred font ligature.

When Hadi demoed the code ligature above, I was in the audience. I looked over to one of the engineers and I lipped “WTF?”. The session had an audible shock when it first appeared on the screen.

Hadi did not use a unicode trick nor a shortcut to a new symbol. IntelliJ performed the glyph exchange automatically.

Now that we have a good understand of the two transformations, lets analyze the pros and then the cons.

The Pros Of SECTAs

The pros of SECTAs are straight forward and clear.

Method parameter and operator readability
The developer can lean on the IDE to see clearly the intent of the parameters and operator statements. This also is true for boolean parameters as they are by themselves as values not self describing.

Method discoverability
Parameter hints can help with quick discovery on how to use the method calls if the parameter names are highly described. The hints give natural discovery on how to use the method.

Encourages self evident parameter names
Since parameter labels are prefixed throughout all uses of the method calls, it behooves the developer to properly name each parameter.

Potential for something wonderful
What is so wonderful about SECTAs is that there is a possibility to build upon them visually. Serially transforming the code underneath the developer helps with readability. I will discuss more of the wonderful potential in the final section.

The Cons Of SECTAs

SECTAs may have very impactful cons. Lets discuss them.

Visual noise and clutter
Having parameter hints throughout the code may make concentration difficult for authors who already have the mental model of the areas of code that are are currently working in. It may visually clutter the workspace to make development less pleasurable.

For that have been trained to read the usual character combinations for equality, assignment, indirection and other operators, the use of the code ligatures could be initially awkward. Some will continue to prefer the traditional usage.

Code quality consequences
One could argue that the use of parameter hints is a route to bike-shedding. Whereas we no longer debate about the architecture or the use of a boolean as we once did. It is because the readability of the boolean is no longer a concern. The IDE simply handles a transformation. It’s making a possible poor design decision expressive and clear.

Nondeterministic code concerns
By their nature, SECTAs are virtual and depend on the IDE software version. This is difficult for version control as it can not capture the IDE environment context effectively. Code that was once the truth in the environment may not read the same with an IDE upgrade. When the IDE is upgraded or changed, there could be impacts to shifting or missing implementation of the transformations.

For code ligatures, IDE’s are beginning their way toward transforming operational symbols. These symbols also do not exist in code. They are glyph transformations on the code to make it more expressive based on a font. Even if the font is changing the symbol, it’s changing the truth of the code.

A very recent and public mistake on nondeterministic tooling was recently discovered with Gradle’s variant versions. It has been suggested by the community not to use variant versions.

The Future

When we see and use SECTAs, we should question and explore them. Watch closely for new transformations. I’m sure more will be introduced over the next versions of IntelliJ.

It’s worth mentioning that these SECTAs are in-fact serial. I named them such because textual code is by nature serially imperative. We expect to read from top to bottom and expect something to happen as we read.

With the cons in mind, are serial code transformations a slippery slope to something more insidious?

I’m not sure. In many ways we are moving into the world of “mixed reality” in our code editors and this is the start. Metadata is laid over text to help us navigate and read transformative expressive code that may have not be on it’s own or through a language limitation. What’s more, it’s not breakpoints, bread crumbing or code folding that we should question. What we should question is direct assistance on the visual readability and understandability of what we write in real time.

We may be fine with serial code transformations if IDE’s standardize.

If the IDE authors continually add transformations do the nuances between languages begin to disappear? It’s way too early to say, but it would be highly interesting and fun if the tooling could make language dialect boundaries blend. Layering SECTAs could prove very powerful.

However to balance the excitement, these code transformations may not allow us to say that the code we have committed is the truth. Maybe there could be a way where to make the transformations deterministic. An answer could be a major discovery in our craft.

Should we allow these tools to add to or transform what is actually in the code? Maybe. In a lot of ways tools do this visually and in fact some languages are visual. However, it’s something profound to layer visually over serially textual code that we all love to write.

More fundamentally, if the IDE continues to iterate on these SECTAs, does our language selection matter less? This is an interesting thought provoking question that I’d be very curious to see where it shakes out of the next few years. Hopefully IntelliJ can take that step to help every single developer to better express their creative desire to make code work well.