Summary
The Rubico library classifies several JavaScript classes as monads, including Array, String, Set, Generator, AsyncGenerator, and objects with flatMap or chain methods. This postmortem evaluates whether this classification is accurate and explores the implications of treating these constructs as monads.
Root Cause
The root cause of the confusion lies in the loose interpretation of monad laws in JavaScript. While some classes exhibit monad-like behavior, they do not strictly adhere to the three monad laws:
- Left identity:
unit(a).flatMap(f) ≡ f(a) - Right identity:
m.flatMap(unit) ≡ m - Associativity:
m.flatMap(f).flatMap(g) ≡ m.flatMap(x => f(x).flatMap(g))
Why This Happens in Real Systems
- JavaScript’s dynamic nature allows for flexible interpretations of functional programming concepts.
- Lack of strict type enforcement enables monad-like behavior without full compliance with monad laws.
- Practical utility often prioritizes convenience over theoretical correctness.
Real-World Impact
- Misunderstanding of monads: Developers may incorrectly assume these classes are true monads.
- Unexpected behavior: Code relying on monad laws may break in edge cases.
- Library inconsistencies: Libraries like Rubico may introduce confusion or bugs if not used carefully.
Example or Code (if necessary and relevant)
// Example of Array as a "monad"
const arr = [1, 2, 3];
const doubled = arr.flatMap(x => [x * 2]); // [2, 4, 6]
// Example of Object as a "monad"
const obj = { a: 1, b: 2 };
const mappedObj = Object.entries(obj)
.flatMap(([key, value]) => [{ [key]: value * 2 }])
.reduce((acc, curr) => ({ ...acc, ...curr }), {}); // { a: 2, b: 4 }
How Senior Engineers Fix It
- Educate on monad laws: Emphasize strict adherence to monad laws in functional programming.
- Use proper monad implementations: Leverage libraries like
folktaleorramdafor true monads. - Document limitations: Clearly state when a class only mimics monad behavior.
Why Juniors Miss It
- Lack of formal FP knowledge: Juniors may not be familiar with monad laws.
- Overreliance on libraries: Assuming library classifications are always correct.
- Focus on functionality: Prioritizing code that “works” over theoretical correctness.
Key Takeaway: While some JavaScript classes exhibit monad-like behavior, they are not true monads unless they strictly adhere to monad laws. Always verify compliance before treating them as such.