Skip to content

Instantly share code, notes, and snippets.

@noullet
Last active October 25, 2017 12:17
Show Gist options
  • Save noullet/c97e15ed2bfa3f277ebfb0e6e482b4b1 to your computer and use it in GitHub Desktop.
Save noullet/c97e15ed2bfa3f277ebfb0e6e482b4b1 to your computer and use it in GitHub Desktop.
Typed FP and function cognitive overhead

Here is an elaboration for three properties which I think enable replacing flat code by functions without adding cognitive overhead for the person who reads the code:

Expressive type signatures

  • Benefits: if type signatures convey a lot of meaning and if such signatures can be trusted, then they may be sufficient. In some cases, you may not need to know more about a function than the fact that it safely converts a value from type A to type B.
  • Tooling opportunities: an editor can show type signatures at hand, e.g. on hover or even by inlining them.
  • Without it: if the function signature is Int -> Void or even Int -> Int, you must look at its definition to know what it does.

Absence of side effects

  • Benefits: the only "effect" of functions is what they return. Just by looking at what happens to the return value of a function in the calling code thus allows knowing all the consequences of the function call.
  • Tooling opportunities: referential transparency allows replacing a function by its value, meaning that when you read code, an editor could expand function calls and replace them by their body as many levels as you want down the stack.
  • Without it: with side effects, you need to look at the definition of every single function to know what it does in addition to returning a value.

Good abstractions

  • Benefits: good abstractions allow reasoning at a higher level (to quote Dijkstra, they "create a new semantic level in which one can be absolutely precise"). A good abstraction comes with precise laws constraining how it behaves and it should not leak internal details. Abstractions come with a cost that you have to pay upfront: learning their purpose, their use and their laws. Some fundamental abstractions can be used in lots of places, meaning that once you know them, code using them becomes familiar and can be "reasoned about", which in the long run outweights the initial cost.
  • Without it: there are two cases, bad abstractions and no abstractions. Bad abstractions require looking at the internals to use them safely because there are no clear laws to trust when trying to reason at a higher level. No abstraction at all requires re-implementing the details again and again, maybe with mistakes or a subtle changes.

Every without it section shows how the lack of the corresponding property lead to a significant cognitive / memory overhead of replacing code by functions. OO code often suffers from these shortcomings, while typed FP negates them.

I think that tooling could definitely be improved to better assist the reader, and that typed FP is a great foundation to build such tools. The Unison semantic editor and isomorƒ seem to be good examples of such work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment