Norbert Wójtowicz's main-stage wroclove.rb 2022 talk, based on Eric Normand's book 'Grokking Simplicity'. Argues that the textbook definition of functional programming ('programming with pure functions without side effects') is the worst possible explanation. Introduces three terms — data, calculations, and actions — and two visualization techniques — call graphs and timeline diagrams — with zero discussion of monads. Data is information at rest, meaningful without a computer (Potter Stewart's 'I know it when I see it'), with multiple future interpretations (Sumerian IOU clay tablet as 5000-year-old JSON). A calculation is a function whose output depends only on its input (the Enigma machine as a real-world example). An action is a computation that depends on when or how many times it is run (shipment APIs, the Fermilab HotBits radioactive-decay random-number service). Composition rule: data + data = data; introduce a calculation anywhere and the result becomes a calculation; introduce an action and everything that touches it becomes an action (the contaminated swimming pool analogy). Re-frames 'side effects' as actions and argues functional programming is really about identifying these three in your own system. Applies call graphs to Rails' historical evolution: views-touching-models, concerns (hide complexity, don't fix it — arrows still point the wrong way), decorators (arrow pointing up from controller = something went wrong), modularized helpers like a date-to-humanized-string library (legitimate simplification), move-everything-to-controller, fat-models, service objects (a real but incomplete step). Proposes stratified design — thinking in layers, with no upward arrows, and splits based on legitimate abstraction, not just file splitting. Demonstrates method-scope stratified design by refactoring a 'most unpopular book sold' function: instead of the blog-post refactor (extract_method, each_with_object), introduce a named 'frequencies' abstraction with a minimum-value method, isolating all the 'spidey-sense' stateful code behind one abstraction barrier. Four practical tools: straightforward implementation, abstraction barrier (draw a fat line you never have to look under, e.g. Ruby's collection), minimal interface (as Nick Sutterer did splitting Reform's overloaded form class into separate presentation/validation/mutations classes), and comfort with layers (don't blindly accept Trailblazer's 20 000 layers or DHH's zero layers — question both). Ideas apply at function, class, app, microservice and layer scale. Second visualization: a timeline diagram for an event-sourced shopping cart with a 'max 3 items' rule and a 'free gift on add 2 items' policy, showing how moving reactions onto separate workers doesn't prove a race condition but tells you that you must analyze for one, because tests alone won't find it. Closes with a subtlety: a calculation that caches results in Redis with a swallowed error is a calculation in your system's context even though it does I/O; a pure function that is expensive enough that you want to control when it runs is an action. Purity vs side-effects is the wrong lens; dependency on when/how-many-times is the right one. Maps the relational-Rails stack to 'everything is an action' and shows Krzywda's previous-day talk effectively drew a fat line between application and domain — turn that line into concentric circles and you have the onion architecture. Q&A covers how to read arrow direction in call graphs (views iterating over models = dependency pointing up, even without mutation), and how the 'frequencies' abstraction turns a hash-map into a weaker but more cohesive frequency-map with a minimal API (min/max value only).