OO says: "State is hard—let's hide it!" (er, sorry, "encapsulate it") FP says: "State is hard—let's isolate it!"
OO says: "State is hard—let's hide it!" (er, sorry, "encapsulate it") FP says: "State is hard—let's isolate it!"
I like F#’s stance on functional-first programming. There are times in which you want to expose the underlying types and there are times you do not. When I recently started a ray tracer implementation, it was a good example of this. The vector, color, point, transform, world, camera, etc. types where all readily implemented by records and discriminated unions which properly isolated but exposed the types. However, for the matrix library, I chose to use F#’s Array.Parallel library and thus a 1D array as the underlying implementation, and this was a perfect use case for using a class. I wanted to hide the implementation of the matrices from the user of the type and encapsulate the internal behavior, only exposing a clean API. Even in that case, the matrix type was immutable because the operations on matrices would simply return new matrices. I think F#’s acceptance of multiple paradigms is really the way to go.