lainchan / λ
OOP vs FP thread
setq · 2017-09-27 02:47
I think we have covered some interesting ground on other threads about comparing OOP to FP. I think its a worthwhile discussion that deserves its own thread. Whether or not we can merge discussions from other threads I'll leave up to the mod. For now I will just start with a clean slate and allow anyone to bring ideas on this topic. So rather than me start the discussion I'll wait for someone to get the ball rolling and we can go from there.
Sabo Engle · 2017-09-27 05:08
That's fair enough. I've not until now participated in this discussion, but I do have some thoughts of mine to add.
From what I've seen, the argument is that OO and functional programming are reasonably isomorphic, but I'm not necessarily convinced by this. The other main argument is that this is a matter of syntax, but I vehemently disagree with this.
I'm led to believe that this is mostly due to muddied definitions, so you should clearly define what you mean by OO and functional programming, first. I'll provide my own thoughts on this.
In, say, Common Lisp, methods are defined as generic functions, which are a special case of normal functions, functions being simple procedures. Objects are also exposed to the type system as types. There's no visual distinction between a function and a generic function in Common Lisp in usage.
As for my definitions, a functional language (generally) defines functions as mappings between data, at least conceptually, and the data itself isn't necessarily important; an object oriented language defines (or should define) everything as objects, which is data that can be manipulated by other objects. Functional addition is a mapping between two numbers to a third number. Object oriented addition is an object that dispatches on two number objects and returns a third number object. Function mappings generally use case logic when necessary, whereas an object will simply only dispatch on certain objects and so achieve the same, with either approach being arguably more elegant than the other.
While you can do the same in either, they both make different general decisions and so I'm not inclined to believe they're one in the same by any measure.
Torvalds · 2017-09-27 09:09
OOP and FP are not isomorphic, they are orthogonal. You can program OOP in both imperative and functional paradigms.
OOP is clearly superior to the procedural paradigm in terms of code reuse and extensibility of programs. In a procedural program, if you want to extend a program beyond the initial functionalities, you must to create a polymorphism scheme with some sort of table of function pointers, and this is far more difficult and prone to errors than relying on the capabilities of a OOP language.
Great advances and great software and frameworks were made in OOP style (namely GUI and MVC web frameworks), that would be a pain in the ass to create and use in a procedural style.
For me it's clear that OOP has its worth in the imperative world. FP, however, it's powerful enough on it's own, turning the OOP concepts less valuable. But, from my experience from Scala, I think that they work nice together, it's fun to program in Scala indeed.
Unspecified · 2017-09-27 09:29
>>3780
OP here, thanks for your response. I think OO has been clouded by C++'s version of OO and people have forgotten about 'pure OO languages" like Smalltalk and Eiffel. In C++ classes and structs are the same thing. Then you have Java which sort of moves in the direction of Smalltalk by making everything except primitive types objects and having all the objects inherit from a generic object. Moving further still toward Smalltalk you have Ruby where even primitive types like numbers are objects and and there is extremely rigid scoping to make sure that objects can only respond to messages. So objects in Ruby can not see global data and internal data in objects can not be seen from outside. Now I dont know Smalltalk so I cant comment on how far Smalltalk has taken this concept but Ive heard the reason that Smalltalk failed was its object system was so closed it was impossible to use the language in anything outside its own ecosystem. So all that to say that OO is a lot more than connecting functions to structs so as to become methods.
Now more to the point about what a class/object is. To take Javascript as an example, Javascript objects are very much universal storage types. They are sort of like hashtables but they are also like structs (aka named records) and they can hold functions which can be called on the object as methods. So the difference here to functional languages is that the data type holds methods. But you could make a function that takes certain kinds of objects. Because Javascript is a dynamically typed language often we are not even aware that we are connecting functions to objects, but we will obviously get an error if we pass the wrong kind of object to a function in Javascript.
So I think you can see the differences in OO and FP are a lot more superficial then people are aware of.
Nanashi No Gombe · 2017-09-27 09:41
I think the traditional object orientation that is the focus of the discussion is needlessly complex.
Prototypes are the simplest objects I can think of. They reify the concept of inheritance by making it part of the object data structure rather than some declarative syntax. With this simple building block I can build complex class hierarchies... But I can also have a simple chain of objects, for example a user configuration object that inherits from a default configuration object and thereby overrides default settings. Less is more!
Many people also confuse object-oriented code with imperative code. Sure, they're often found together, but not necessarily. Who said you can't implement single dispatch through a functional interface? Who said functional data structures can't be linked to each other?
Sipho Nkosi · 2017-09-27 18:57
Imho, I think a more descriptive classification would be dynamic vs static and modular vs monolithic.
OO usually seems to refers to some vague mixture of modular and dynamic features. Languages that try to emulate smalltalk or (even more so) prototypical OO languages are inherently dynamic and that is a natural design choice if you want to have objects interact with each other nontrivially.
Languages like Haskell on the other hand are modular but also very static and get their expressiveness from well designed type systems with type inference and static dispatch.
Both are viable points in the design space. Dynamic languages tend to give more freedom regarding abstractions, while static languages make it harder to make a mistakes. Good languages try to amplify these benefits while minimizing the downsides of those design choices.
Modular is pretty much always good though, because it is directly connected to code reuse. It is often directly enabled by dispatch, and code that can generate new subroutines that do what you want as you go, while eliminating repetition and "filling in the blanks".
Old procedural languages that are not OO or FP tend to be neither particularly static or dynamic, and inherently lead to more monolithic code. OO or FP gives you ways to modularize the code, basically. OO does it in a more dynamic way by separating the code into objects that can interact and sometimes create new objects, while FP tends to be more based around generating the code that you want based on a more static, equational type of reasoning.
Von Neumann · 2017-09-27 20:09
>>3785
Complementing my post. What's better than talking about nebulous concepts that everyone understands differently? Talking about concrete implementations. What exactly do these object-oriented programs become when they're compiled? This developer implemented classical object orientation on top of prototypes:
http://journal.stuffwithstuff.com/2010/08/01/class-in-the-front-proto-in-the-back/
It's very simple.
>>3793
I'd like to point out that functional programming is not necessarily static. Haskell's flavor of functional programming is static, just like Java's object orientation was designed to be static.
t · 2017-09-27 22:48
>>3793
>Languages like Haskell on the other hand are modular but also very static and get their expressiveness from well designed type systems with type inference and static dispatch.
OP here, yes yes, this is exactly the point about Haskell and other static FP languages like Ocaml that people miss, its all about the type system that makes Haskell such a powerful language. People get fixated on the idea of immutable data and referential transparency of functions when that is not at all what sets Haskell apart from other FP languages. A function in Haskell is no different than functions in other languages, it doesnt know if its data is mutable or immutable. And the fact is that data is mutable in Haskell in that data in its environment is constantly changing as the program runs so that data will get changed in one part of the program, but the original data is still accessible higher up above before where it was changed.
But the main thing about Haskell is its type system, its data types work very much like OO classes in fact the the types in Haskell are called type classes. These type classes can be subclassed, they can be polymorphic. You can even have parametrized types which is just like constructors/initializers in OO languages. And since you can have a group of functions that work on these type classes means these functions really form a group that works on just this type class and so in a sense are methods to the type class. Things like high order functions, closures and currying are all really secondary features that Haskell could still function well without.
Roy Batty · 2017-09-28 18:12
>>3796
Common Lisp also apparently has an implementation (https://github.com/guicho271828/inlined-generic-function)?
Not sure if the Scheme implementations with useful type-hints have such. In theory nothing prevents it.
Mentat · 2017-09-28 18:35
personally, I find the functional style to be more intuitive, but deep down there's not much of a difference between the two styles.
car · 2017-09-29 08:28
OP here, this is very interesting that they are going to embed static data types into Lisp as Lisp is highly dynamic in nature due to its deeply nested homoiconic syntax where code holds data that can transform back and forth to code and data and be in states of partial compilation. This results in code contains code that is in a constant state of compilation extending from precompilation to runtime. So I'll be curious how far they can go with putting statically typed code into Lisp.
Sabo Engle · 2017-09-29 14:29
Wow, Turing complete languages can express the same things?
That's fascinating...
Crash Override · 2017-09-29 18:16
>>3783
I don't see why a cumbersome half-baked OOP system is needed for polymorphic behavior. Macros, and C++ style template systems can allow for very versatile code reuse in most systems that need it.
queue · 2017-09-30 23:09
>>3794
>> True, but statically typed OOP implementations end up requiring subtyping and interface types, where the actual type of those objects is somewhat restricted statically, but is actually determined at runtime (in theory, though a good compiler can eliminate the overhead in many special cases).
This is a good example of dynamic vs static not being completely mutually exclusive of each other though. Many languages with dynamic features that see heavy use end up adding more and more static typing features as time passes (Python's type annotations, and Typescript or Flow for Javascript, are also good example).
Of course, you can do dynamically typed functional, which typically just uses duck typing for polymorphism. Often it just means that the language basically lacks type system features in the core language entirely though, rather than having them available but static.
Duck typing feels a bit more like an OOP-ish feature that dispatches at runtime but doesn't force you to think in terms of classes specifically. However since it is very unstructured it often ends up being used in actual applications with a mental model that could be statically typed if you wanted to, so it ends up having a functional feel to it.
Another interesting case study would be Go's interfaces which sort of take Duck typing and tries to make it more static. Sadly Go's type system is too simplified to let you do anything nontrivial with it, so this doesn't really give it any extra expressiveness.
Cereal Killer · 2017-10-01 13:55
>>3882
Oops, accidentally greentexted the first row. Ignore that.
DEBUG-CONTENTS · 2017-10-02 09:03
>>3825
>Macros, and C++ style template systems
There's a lot of techniques that can labelled as "polymorphism", but what you mentioned doesn't replace OOP polymorphism. What replaces it is function pointers. When you plug a new device, load its drivers, and this works nicely even the device being created after the development of the operating system that you are using, is because its driver provides some functionality that can be attached in some table of the I/O management system of the OS. Without this mechanism, it would be necessary to recompile the I/O system every time that a different device is installed.
The same is valid for event based programming. In a procedural paradigm, function pointers will be needed for event handlers, and in the OOP paradigm, overriding abstract classes is the way to accomplish this.
But programming with function pointers is not for everyone. OS programmers have godlike skills, so, this is nothing for them. Most companies cannot afford using such complicated technique, because it's too prone to errors, and the code created would be difficult do understand. OOP polymorphism, in the other hand, makes such flexibility degree affordable for such companies. That's what makes OOP imperative programming more convenient than procedural imperative programming.
Unsigned · 2018-01-01 04:17
Somebody please elaborate why there's constant bickering between the two camps. OOP and FP are not mutually exclusive, and most of the time the best code just uses both paradigms depending on which methodology is simpler for a given task
Bobby Newmark · 2018-01-02 00:18
>>5944
>Somebody please elaborate why there's constant bickering between the two camps
I don't see any bickering. Languages like Scala and C++ and proof that these paradigms are not mutually exclusive. This thread was actually started by a confused newbie who thinks that OO and FP are the same thing and wants to let everyone else know how wrong you are if you think there is any difference (I'm pretty sure he wasn't trolling). Lets not revive this.
Tyrell Wellick · 2018-01-02 07:47
>>5953
OP here. I normally ignore trolls, but when trolling becomes so common that you have to sift through troll posts to find a serious post, then ignoring trolls no longer works.
The amount of C++ spamming is so prevalent that anyone who tries to ignore it is just making a fool of themselves by trying to pretend everything is normal.
You cant have an intelligent conversation with a schill who does nothing but parrot unintelligent babble like this:
>Languages like Scala and C++ and proof that these paradigms are not mutually exclusive.
This is the last time I respond to a C++ troll, this is probably going to be the last time I post on lainchan, Ive removed my bookmarks. I hope you all have fun pretending you are having intelligent conversations when half the posts are just bullsoykaf C++ memeing
Jim Hilger · 2018-01-02 11:27
>>5956
see you next week
over · 2018-01-02 19:06
>>5956
Replace C++ with OCaml if you want. It doesn't change the post in any way.
Sipho Nkosi · 2018-01-05 18:51
>>5956
>grrr I hate C++, stop talking about what I don't like!
Only 4 posts before yours in this thread even contain the word C++. Get a grip.