Daniel Westheide
October 26, 2018
720

# The Complexity Trap: Think Before You Leap

Recently, many people in the functional programming community, and specifically in the Scala community, seem to follow the trend of solving their programming problems with more and more fancy abstractions and techniques. If in doubt, we throw a monad at the problem, and if that’s not good enough, we’ll make it free. Naturally, to top it off, we have to sprinkle the whole thing with some type-level programming, because this is common courtesy these days.
LAMBDA WORLD 2018, Cádiz

In this talk I want to challenge some of the fundamental assumptions of how we think and work. With all our sophisticated engineering, are we actually solving the right problems? Are we rushing towards technologically exciting solutions too quickly? How much of the complexity in our software is inherent in the problem domain, and how much of it is of our own making? We may have honorable intentions, but do our solutions come at an acceptable price? Maybe it’s time to slow down, think about what the problems we have to solve actually are, and how to do so in the simplest way possible.

October 26, 2018

## Transcript

1. ### LAMBDA WORLD CADIZ 2018 The Complexity Trap: Think Before You

Leap Daniel Westheide @kaffeecoder

Unsplash
3. ### Agenda • What is complexity? • The complexity trap &

how to escape it – Neglecting the costs – Embracing industry standards – Maximum zoom • Conclusions

7. ### Metrics or it didn‘t happen! // Cyclomatic complexity = 1

def squared(x: Int): Int = x * x // Cyclomatic complexity = 2 def max(x: Int, y: Int): Int = if (x >= y) x else y
8. ### Cognitive complexity public static int sumOfPrimes(int max) { int total

= 0; OUT: for (int i = 1; i <= max; ++i) { for (int j = 2; j < i; ++j) { if (i % j == 0) { continue OUT; } } total += i; } return total; } def sumOfPrimes(max: Int): Int = Stream .range(1, max + 1) .filter(i => (2 until i).forall(j => i % j != 0)) .sum Java version taken from: https://blog.sonarsource.com/cognitive-complexity-because-testability-understandability

11. ### The sound of poison has gone off Our traps aren't

malleable, beware! No dogma or deterrent can dissuade us from our torment path Said path has run nigh on eight years Dark skills in trade, we hone and sharpen arrow blade The trap is laid While we await and wait and wait Laying Traps Crippled Black Phoenix 2012 Photo by Mario Azzi on Unsplash

on Unsplash

23. ### Functional core, imperative shell // imperative shell: def showArticlePage(id: Long):

Task[ArticlePage] = for { article <- fetchArticle(id) comments <- commentingAllowed(article) .fold(_ => Task.now(Seq.empty), _ => fetchComments(id)) } yield ArticlePage(article, comments) // functional core: def commentingAllowed(article: Article): Either[String, Unit] = { if (article.commentingAllowed) Right(()) else Left("Commenting not allowed") }
24. ### Discourse • Focuses on how instead of why (or why

not) • Emphasis on more and more advanced techniques

30. ### aim42 • Architecture improvement method • Iteratively in three phases:

– Analyse – Evaluate – Improve • https://aim42.org/

32. ### … applied to the latency problem • Why is our

overall request latency so high? • Why do we need to make so many requests? • Why are our microservices designed around a single entity? • What if … ?

34. ### … applied to the JSON codecs • Why do we

provide a JSON API? • Why do we have a single page app?
35. ### What if … • we did server-side rendering of HTML?

– No JSON API – No duplicated business logic – Much simpler frontend JS code https://medium.com/@jmanrubia/escaping-the-spa-rabbit-hole-with-turbolinks-903f942bf52c

39. ### Conclusions • Leave your programmer comfort zone • Consider costs

• Talk about trade-offs • Don’t ignore boring solutions • Slow down & stop meddling with symptoms