Since Functional Programming treats Data and Behavior separately, and behavior is not supposed to mutate the the state of an Instance, does FP recommend not having instance methods at all for Domain Objects? Or should I always declare all the fields final? I am asking more in the context of Object oriented languages like Java.
3 Answers
Since Functional Programming treats Data and Behavior separately,
I heard that said a lot, but it is not necessarily true. Yes, syntactically they are different, but encapsulation is a thing in FP too. You don't really want your data structures exposed for the same reason you don't want it in OOP, you want to evolve it later. You want to add features, or optimize it. Once you gave direct access to the data you've essentially lost control of that data.
For example in haskell, there are modules, which are actually the data + behavior in a single unit. Normally the "constructors" of data (i.e. the direct access to "fields") are not available for outside functions. (There are exceptions as always.)
does FP recommends not having instance methods at all for Domain Objects
FP is a paradigm which says that software should be build using a (mathematical) composition of (mathematical) functions. That is essentially it. Now if you squint enough, you could call a method a function, with just one additional parameter this
. Provided everything is immutable.
So I would say no, "FP" does not explicitly define syntax and it can be compatible with objects under certain conditions.
I am asking more in the context of Object oriented languages like Java.
This is where it kind-of gets hazy. Java is not well suited to do functional programming. Keep in mind, that it may have borrowed certain syntax from traditional FP languages, but that doesn't make it suitable for FP.
For example immutability, pure functions, function composition are all things that you should have to do FP, Java has none of those. I mean you can write code to "pretend", but you would be swimming against the tide.

- 7,514
- 1
- 20
- 38
-
How can I achieve Immutable encapsulation with Instance methods? I can be 'carefull', but that is not strict enough in a shared code-base, we got to have rules that can't be broken. I may have instance methods, if all my variables are final of course, but otherwise aren't instance methods gateways to immutable violations? – Gopal S Akshintala Sep 18 '19 at 11:24
-
2@GopalSAkshintala an instance method is a method not declared `static`. It doesn’t imply that the method makes modifications. To name a simple example, `java.lang.String` has tons of instance methods, still, does not offer any way to modify the encapsulated (mutable) array, so strings still are immutable. – Holger Sep 18 '19 at 14:00
-
As @Holger said, you can create small immutable objects and have all methods that need to change state just return a new object with that state instead of in-place modifying it. *However* as you accurately pointed out, there is really nothing in a shared codebase to prevent others from messing up your carefully constructed functional code. Even just by accepting lambdas or other 3rd party objects you have no control over, you might introduce unforeseen side-effects. In a proper FP language that can't happen, but in Java there is really no way to prevent it other than in small isolated classes. – Robert Bräutigam Sep 18 '19 at 14:45
does FP recommends not having instance methods at all for Domain Objects?
In the Domain Driven Design book, Eric Evans discusses modeling your domain with Entities, and Value Objects.
The Value Object pattern calls for immutable private data; once you initialize the value object, it does not change. In the language of Command Query Separation, we would say that the interface of a Value Object supports queries, but not commands.
So an instance method on a value object is very similar to a closure, with the immutable private state of the object playing the role of the captured variables.

- 52,766
- 5
- 49
- 91
Your fields should be final, but functional code and instance methods are not mutually exclusive.
Take a look at the BigDecimal class for example:
BigDecimal x = new BigDecimal(1);
BigDecimal y = new BigDecimal(2);
BigDecimal z = a.add(b);
x and y are immutable and the add method leaves them unchanged and creates a new BigDecimal.

- 401
- 3
- 7