A value at a moment in time. This could be UI status, data from endpoints, configuration, user input, or any number of other variables.
As complexity grows, so does shared state. Design patterns like OOP and FP are a way to manage that complexity.
Object-Oriented Programming segregates shared state into object instances with interface methods, allowing each object to manage state independently.
Functional Programming seeks to minimize state and restrict it to carefully controlled portions of your application.
It embraces strategies from category theory to enable compositional programming. Complex abstractions are built up from smaller, pure operations that can be combined in solid and predictable ways.
In practice, runtime errors and unpredictable side effects are much less of an issue. Complexity remains a constant foe, however, especially in languages with terse syntax and user-defined operators.
Functional programming was introduced in the 1950s with LISP. It actually came before OOP!
At the time, memory was very expensive. OOP required less memory.
Even today, mutation gives Object-Oriented code a performance advantage while sacrificing predictability.
"Codify" your domain knowledge as custom types, and use a switch statement to make decisions based on them.
Exhaustive checking ensures you don't miss a case. Type arguments allow you to pass additional data with a variety of uses.
Custom, flexible types that don't have to be defined and imported in order to be used. The types can be used interchangeably in many situations.
The sound type system allows for powerful abstractions based on category theory.
Allows you to pre-process your OCaml code, transforming it before it is compiled.