Functional obfuscation

Brian Duff
2 min readFeb 10, 2020

--

Since lambdas and function objects were introduced back in Java 8, it’s become terribly trendy in Java land to use chained functional expressions / streams.

There are some pretty cool things you can do with streams. For simple programs where you don’t want to think too much about executors and thread pools, and just want to do a bunch of work in parallel, the parallelStream() method is very cool. For example, I was curious about write throughput to my SSD when using parallel vs. sequential writes. I wrote a simple program to test it, and this cute expression made it easy:

At Google, we had an excellent set of Java best practices, which as far as I can tell, haven’t been published externally unfortunately. They served as a sort of more detailed addendum to the coding standards, with lots of recommendations for writing very readable, consistent code.

One of the items in the Best Practices doc covered functional-style expressions, and was originally written in a time when these involved anonymous inner classes, and were hence verbose, slightly evil, and unwieldy. Despite this the various functional-like APIs in Guava had made them popular within Google, sometimes to the extent that people would craft excruciating expressions with them that could be written more simply in a linear way. The guidance was to use them with caution, and consider readability when doing so.

At some point after Java 8 became prevalent at Google, someone forked the Best Practices functional expression guidelines in two, removing all the warnings about using them with caution in the Java 8 version. After encountering seventeen-too-many stream().filter().forEach()’s that could be expressed in loops and if statements that were frankly much easier to read, I updated the guide to restore the previous guidance about exercising caution. It kicked up a minor shit-storm and made me realize that a whole generation of Java programmers love the mind-puzzle mathematical beauty of functional expressions, and prefer to write code this way.

Since then, this style of programming has become thoroughly dominant in the Java world. I’ve recently seen a lot of examples of these kinds of expressions:

Look, I appreciate the mathematical beauty of this as much as anyone. So functional, it’s so elegant. But the part of my psyche that deeply cares about code being readable shrinks every time I see this kind of thing. It’s also kind of fugly to reason about in the debugger or profiler, because of all the synthetic nonsense involved in desugaring this into bytecode. But when I see this kind of code, my oh-aren’t-i-so-clever Functional Obfuscation Compiler kicks off in my brain and translates it to what it actually does:

I guess I wonder if all of this human brain translation for code is really good and or necessary for the supposed functional purity that it costs. It’s always really interesting to me how there are sort of fashions in coding style that come and go over time.

--

--

Brian Duff

I like building software, being a daddy, and occasionally singing things. https://twitter.com/brianduff