Recently I have been learning to program in Erlang as a long time C and C# developer. I am fairly new to functional programming. Now, I am trying to understand how do objects in languages like Scala work. I have been taught that OOP is all about changing state of given object using its public methods. Those methods change state of public properties and private members. But now I hear that in functional programming all objects should be immutable. Well, I agree that once assigned variable (in given function) should remain pointing to the same object. But does this "immutability" mean that I cannot change the internals (properties, private members) of given objects using their public methods? This makes objects just like simple data containers. It extracts all of the functionality outside of them. This makes objects act more like structures in C. It is something that is strange to me. Maybe I am missing something? Is it possible to use objects the old-fashioned-way and still consider it as functional programming?
You are mixing up three different concepts. Functional programming, mutability, and OOP are three different things.
I have been taught that OOP is all about changing state of given object using its public methods.
Yes and no. The important thing in O OP is that you have objects , which can simultaneously carry around data and code (their member methods), and that you talk to the objects using their interface , so that the object can then
this
in the method implementation) Nobody prescribes you what this method call does, or that it must modify some state.
It happens to be that OOP helps to restore some basic sanity when working with state. This is because the horrifyingly complex global state of the application can be cut up into smaller pieces and hidden inside mutable objects. Moreover, those mutable objects can additionally attempt to maintain at least some local invariants, by prohibiting direct access to their state, and providing only a restricted set of operations that can modify that state.
But now I hear that in functional programming all objects should be immutable.
They should respect referential transparency. If your objects have no mutable state and only methods without any side effects, then it is sufficient for referential transparency. Sufficient, but not necessary : the objects can have more complex inner structure, but appear completely immutable from the outside. Caching is a good example.
Furthermore, even pure functional programs are not restricted to working with immutable data structures only. There is such thing as pure mutable state . The idea is that your functional programs are used to construct something like complex action plans for dealing with mutable state. The plan itself is an immutable entity. This plan can be very complex, but thanks to the fact that it is built from pure functions, it can be still sufficiently easy to reason about. This plan, which is built using only pure functions, can then be given to a small and simple interpreter, which executes the plan on mutable memory. In this way, you reap the benefits of both worlds: you have conceptual simplicity of pure functions while you are building the plan, but you also have the performance of close-to-the-metal computations when you execute this plan on mutable data structures.
But does this "immutability" mean that I cannot change the internals (properties, private members) of given objects using their public methods?
In general, yes. However, in Scala, immutability is not enforced by default. You can decide what parts of your application are complicated enough to reason about, so that it might be worth it to restrict yourself to pure functions. Everything else can be implemented using ordinary mutable structures, if this is easier.
This makes objects just like simple data containers. It extracts all of the functionality outside of them.
No, because objects still carry their virtual dispatch table with them. You can then ask the object from the outside to invoke the method apply(integer i)
, and the object, depending on what kind of object it is, might then invoke completely different things, like
/** get i-th character */
String.apply(integer i)
or
/** get value for key `i` */
TreeMap.apply(integer i)
You cannot do this with C
structs without essentially re-implementing subclass polymorphism as a design pattern.
Is it possible to use objects the old-fashioned-way and still consider it as functional programming?
It's not an all-or-nothing game. You can start with a classical oop-language (with mutable state and all that), which supports the functional programming paradigm to some degree. You can then look at your application, and isolate those aspects of it that require more precise control over the side effects. You have to decide which side effects matter, and which are less critical. Then you can express the really critical parts using the somewhat stricter approach with pure functions (pure in the sense: as pure as you need them to be, ie not performing any critical side-effects without declaring it explicitly in their signature). The result would be a mix of classical OOP and FP in one application.
Writing programs using pure functions can be thought of as a construction of a proof in a somewhat primitive logic. It's nice if you can do it when you need it (using a stricter approach with pure functions), but it can also be nice if you can omit it when you don't need it (using the usual approach with messy side-effecty functions).
OOP is all about changing state of given object using its public methods.
It's a lie!
in functional programming all objects should be immutable
It's a lie!
But does this "immutability" mean that I cannot change the internals (properties, private members) of given objects using their public methods?
There are strict immutability and "simulated" immutability. With "simulated" immutability you can change internals, but you shouldn't produce visible changes. For example, caching of heavy computations is still acceptable.
Is it possible to use objects the old-fashioned-way and still consider it as functional programming?
It depends on how exactly you are mutating objects and how you define FP. Actually, god damn it, you can mutate objects in FP.
Maybe I am missing something?
Yes, there a lot of things you should learn.
There are several things you don't understand about immutable objects:
Here are things that you should know about OOP:
Here are things that you should know about FP:
FP doesn't requires you to use immutable data. But it's much easier to work with immutable data in FP.
If a tree falls in the woods, does it make a sound? If a pure function mutates some local data in order to produce an immutable return value, is that ok?"
Good FP languages have a lot of ways to work with mutable data to meet performance needs. FP just loves to hide mutations.
Only pure-FP languages are forcing you to use immutable data.
FP has get it's name for functions as first-class citizens. See more on wiki . You can use & pass functions just like you use & pass objects.
Well, a lot of FP is not about functions.
You should also know how OOP and FP are related:
And now, I want to explain why there a lot of people whom thinks that some paradigms can't be combined:
Just to make things clear: creators of FP-style aren't idiots. They want side-effects to be explicit & controlled. So there is a nice concept: pure function .
Summary :
But does this "immutability" mean that I cannot change the internals (properties, private members) of given objects using their public methods?
Yes.
This makes objects just like simple data containers. It extracts all of the functionality outside of them.
No. Typically much of the functionality of immutable classes is provided by their constructors. A constructor is not neccessarily just assigning values passed to it as arguments to member variables. Another part of the functionality can be found in getter-like methods that not only return the values of member variables but perform more complex transformations on them.
This makes objects act more like structures in C.
No. Structs in C are completely mutable. Anyone can access and modify their elements.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.