Yes? No? If yes, how/in what way?
Yes, now I see no difference between closure and object
I’ve been a Java web programmer for ~20 years and learning about functional languages (first Scala, then Clojure, then Elixir) has definitely changed my approach over the years.
Granted, it’s still Java so getting away from mutable values can feel like swimming against the current. Most of the libraries I use (e.g., DB access, JSP) assume the JavaBean spec (getters and setters) so it’s easier to go with flow at those boundaries.
Aside from that, I try my best to write most of my code as pure functions, which to my eyes offers code clarity and ease of unit testing. These days, my Java is less OOP and more structs and functions.
The introduction of streams (think enumerables) and lambdas in Java 8 was really exciting for me thanks to my exposure to functional languages. Helping my colleagues at work understand the benefits and rationale was challenging but the eventual ah ha moments were very rewarding.
Absolutely. Ultimately both OOP and FP can get great work done, but I’ve found that a functional style helps clarify my thinking. Separating the data structures from the functions brings a tremendous clarity to my designs.
These days, I actually use classes for dependency injection containers - the meat of the program still tends to be highly functional.
My biggest takeaways while learning and now preferring FP that have changed my perspective on OOP languages is the following (some of them are not good):
- Quarantine side effects. This has help a lot with reducing bugs and making unit testing easier since it means that my pure functions aren’t intermingled with all of the effectful code.
- It made me realize how much harder OOP is to get the same result. Mutability adds complexity that most of us don’t even notice: Time. When a value changes over time you pretty much have to us a debugger to see it change and why it’s changing. In FP it’s just a new binding. Also, coupling behavior with data makes it even harder to manage because you end up with temporal coupling when one property or method changes a value and a method was depending on the value of a member var to be in a certain state. In FP, new state changes are very explicit (and far simpler). State (data) goes in… and new state comes out.
- The bad part is that FP has made me realize that is so much simpler to program in so I get annoyed in OOP languages when I have to do something simple like create a class just to add behavior to my program when a simple function will do.
FP really drove home the message to me that I was doing programming wrong my entire life before that.
…Namely “data structures > code”. If you know the shape of your data and can think in data then the code kind of comes naturally after – LISP is an excellent demonstration of this approach but Elixir is quite close with its metaprogramming abilities as well.
So I am looking into getting more into the math foundations of FP and then learn a ton of data structures and algorithms.
FP taught me that the programming language syntax, 99.9% of the time, doesn’t matter one bit. What’s important is the data. And having an excellent runtime like the BEAM VM.
I learned both around the same time. Scheme and Java, in school. While due to knowing C before them both, and more learning materials geared towards C-style languages, I gained abilities with Java faster, but my appreciation for functional programming happened quicker (also, thanks to a few articles on Charming Python series back in 2002). Appreciation dominated (and as a by-product, turned into) ability. With time, my OOP language codes resembled as functional as syntactically possible (i.e. smaller composition, no void returns/mutations, avoidance of classes if the language allowed it), it’s funny how your OOP code doesn’t look/feel bad if written in functional style but not so much the other way round.
So, early exposure to functional language had me do most my OOP language adventures done in more functional style, sent me on guilt trips whenever I did mutations (
void sort versus
List<T> sort), avoided statics, classes etc, and jump ship to a more functional language shop the moment I got a chance! And I was lucky enough make that chance for myself in the place I worked at fairly early on!