Chasten - Rationale

Despite a recent surge in conceptual popularity, functional programming in the Node.js ecosystem remains fundamentally unsupported. Sure, there are some excellent utility libraries like ramda and sanctuary, but the fundamentals of serving HTTP requests are still left to mutation, statefulness, and other abject misery. What are those fundamentals, exactly?

Some subset of these are sporadically supported by a few of the popular Node.js frameworks, but what if you want all of them? I couldn't find anything to help me out so I wrote Chasten.

What follows is a brief recap of why functional programming is preferable in general, and no attempt has been made to sugar-coat my strong opinions on the matter. If you find yourself disagreeing with much of the below, Chasten might not be a good match for you.

Prefer Functional Programming to OOP

Functional programming is a fundamentally good idea.

On the other hand, object-oriented programming is a major source of headache.

  • Functions that mutate their arguments and cause observable side effects are fundamentally unpleasant to reason about, test, or compose with each other.
  • Performing mutative actions like I/O or state changes all over your application code with no clear boundary between pure and impure sections sets you up for a terrible time when you need to test your code.
  • The rich objects of the OOP world tend to result in programs where each object has its own internal, specific, one-off API and everything is stateful. This unerringly result in a reduced ability to compose the basic building blocks of applications, which should be simple data, because this data is hidden or inconveniently accessed due to data hiding.
  • When application code is just pure functions and dumb data, the need to reason about how the world changed in response to previous function calls disappears entirely; the world didn't change. This is a huge relief for test code authors, who no longer have to be careful what they effect by using the functions of the domain they're testing.

    When there is no state, the mental gymnastics required to understand a section of code tend to abate in difficulty. This also means there is no state to mock in testing, lessening the testing hassle.

    Simple is not always Easy

    Contrary to widespread belief, simple does not guarantee easy, and simple is more important than easy. If the two are in conflict, Chasten prefers to be simple by splitting interfaces into their constituent parts. When separate concerns are decomplected like that, reasoning about the system becomes easier, and assembling the system precisely as desired becomes possible. This is always desirable, even if it means applications now have to put more pieces together to work. Chasten goes a long way to keep you in control.

    No surprises

    It should be possible to read the source code and correctly infer the behavior of the program. Surprises are usually bad surprises in the context of programming. "Magic", as some people take to call the weird things you never asked your program to do, but it did anyway, has no place in serious programming. A core tenet of a good code base is its readers' ability to know what it does - even after a year-long hiatus working on other code bases. These surprises tend to creep in with the best of intentions, and HTTP in particular has a great number of common practices and conventions that a web library tends to handle for you. Chastens chooses not to in the general case.