There are many qualities that serve to contrast traditional OOP with FP (e.g, first-class functions, (im)mutability, side effects vs. purity, declarative vs. imperative style, etc.), but I’d like to focus on how logic is shared/reused within applications. OOP paradigms tend to share logic by explicitly pushing it out to objects through inheritance, composition, and/or mixins. In contrast, FP tends to push the data to the logic. FP makes this possible because functions typically act on data values rather than from within them.
The general idea behind haven.js is to ensure that all of the values passed into and out of functions are structurally compatible with the function’s expectations. It works by replacing function calls with wrapper functions that test the parameter and return types explicitly declared as object fields on the functions themselves. If type compatibilities are identified, the details are logged to the console (although the console is used by default, you can tell haven to throw exceptions instead, as you may wish to do when integrating results into unit tests.) I tend to turn off the type checking (i.e., simple don’t call the function haven.typeCheck) in code that’s released in production to avoid the performance hit.
So far, haven.js has greatly facilitated my work, and I hope you’ll get some benefit, too.