DEV Community

Discussion on: Function vs Object

Collapse
 
wiktorwandachowicz profile image
Wiktor Wandachowicz

Ok, just three silly questions.
1) How do you model and use in FP relations between domain "things", like orders, clients, suppliers, goods, invoices, organizational units, etc.?
2) How do you handle in FP graphical user interfaces with widgets?
3) Are there easy to follow FP frameworks based on MVC patterns, for example?

Collapse
 
stereobooster profile image
stereobooster

This is kind of out of the scope of the post. I didn't try to compare the whole FP vs OOP. I simply presented a small slice of FP and OOP that has similarities (closures and objects as value).

1) How do you model and use in FP relations between domain "things", like orders, clients, suppliers, goods, invoices, organizational units, etc.?

There are different approaches, but I guess simple data structures would work - lists, trees, graphs? The question is too broad.

2) How do you handle in FP graphical user interfaces with widgets?

Broad question. It can be interpreted in different ways, for example, take a look at how they do it in Elm. ¯\_(ツ)_/¯

3) Are there easy to follow FP frameworks based on MVC patterns, for example?

In FP they don't use design patterns. Read the next post in the series for details.

Collapse
 
wiktorwandachowicz profile image
Wiktor Wandachowicz

1) How do you model and use in FP relations between domain "things", like orders, clients, suppliers, goods, invoices, organizational units, etc.?

There are different approaches, but I guess simple data structures would work - lists, trees, graphs? The question is too broad.

Ok then, perfectly understood: simple data structures and set of functions (possibly pure functions in FP). Then is it me, or is this similar to procedural programming with ADT (abstract data types)? Say, a C or Pascal program with user-defined data types that match domain concepts?

If the latter, then there are problems with scale of systems. The bigger the system grows, the more functions are introduced in global namespace, or possibly in nested namespaces. Given that, in OOP languages there are not only namespaces (or modules), but classes that are typically used to encapsulate and solve sub-problems.
Good example is a class that implements some calculation algorithm: pass parameters to constructor, store them in private fields and call one or more public methods to get the result. Self-contained piece of code, that can be easily unit-tested, inherited and extended. No need to pass many parameters from one function to another.

But again, in FP the notion of a function went way futher than in other imperative languages. To the point where it might blend with math and formal proof of correctness. Is this the "true way" (TM) to follow from now on?

2) How do you handle in FP graphical user interfaces with widgets?

Broad question. It can be interpreted in different ways, for example, take a look at how they do it in Elm.

I know Elm and I really like it :) Any other real-world examples?

In object frameworks like: C#/XAML/MVVM, Delphi/VCL, Delphi/FireMonkey, C++/Qt, JS/React, TS/Angular - there is a notion of model and data binding. Such frameworks are relatively easy to understand, use and extend. And the knowledge of one of these can be directly or indirectly applied to other OOP languages / frameworks.
From this perspective, how much time does one have to invest to understand Functional Programming approach? And what are the benefits?

Finally here is my fourth simple question:

4) Is Functional Programming suited well enough to rewrite existing programs (websites, mobile apps, Line-Of-Business apps, etc.) using this paradigm, or are there areas where FP seems to suit best?

Thread Thread
 
stereobooster profile image
stereobooster • Edited

Then is it me, or is this similar to procedural programming with ADT (abstract data types)?

In the real world, a lot of time people would mix paradigms, because separation in paradigms is arbitrary in the first place (this is not a science, this is closer to the art). For example, see this article about if, or for example, you can use .map in the OOP-ish language.

The big difference (at least one which first comes to my mind) with procedural programming is "functions as values". Which doesn't seem like a lot, but allows to do a lot of neat tricks. If you add lazy evaluation it will allow to do even more tricks (pure FP needs lazy evaluation, in Lisp they don't have it by default, but they have macros). This is a broad area it would take me N posts to cover. To show all the tricks and why it matters.

If the latter, then there are problems with scale of systems.

Why? Do you have any empirical evidence for this? I know people deliver 100k codebases to production (LoC is not the same as "scale", but we don't have another fair measure for this).

The bigger the system grows, the more functions are introduced in global namespace, or possibly in nested namespaces.

What the difference between namespacing with objects and namespacing with modules?

Self-contained piece of code, that can be easily unit-tested, inherited and extended. No need to pass many parameters from one function to another.

I don't know how to respond to this. What can be more unit testable than pure function? You always get the same output for the same input, which is not always true for objects. As well in FP they typically use plain data structures, so you don't need a special mocking library.

To the point where it might blend with math and formal proof of correctness.

There is a difference between proving the correctness of the program and the formalism of FP. This is an urban legend that FP programs are formally proved to be correct right away. No, they are not. You need to write additional verification for it, the same way as you would do for any other paradigm. See this post for details.

Any other real-world examples?

I don't know. Search the internet for examples. Haskell, F#, Scala, Kotlin.

From this perspective, how much time does one have to invest to understand Functional Programming approach?

There are patterns in FP as well, which you can learn and then reuse across languages. For example, map, reduce, functions as values, monads (option-monad, either-monad, futures - similar to promises, but not the same, etc.)

4) Is Functional Programming suited well enough to rewrite existing programs (websites, mobile apps, Line-Of-Business apps, etc.) using this paradigm, or are there areas where FP seems to suit best?

FP the same way as OOP as procedural style is general programming paradigms (for example, logic programming is not general), so they suitable almost for anything (95% of use-cases ?), most of the time is just a matter of taste. There are some edge cases for which you need something else, for example, I would not use FP languages (as far as I know most of them are garbage collected) to write Memcached (key-value storage). To write key-value storage you need not a garbage-collected language or non-stop garbage collection as they have in Pony.

Thread Thread
 
wiktorwandachowicz profile image
Wiktor Wandachowicz

Regarding "scale of systems" I was mostly thinking about number of names (be it functions, classes, etc.) that might collide with one another. Namespaces of course solve part of the problem, in the meaning that functions have some "prefixes" before their names (like name of namespace or module for example).

What [is] the difference between namespacing with objects and namespacing with modules?

I didn't give an example here, sorry. I had in mind Java 9 modules, and upcoming C++20 modules. They solve different problems than just namespaces in these languages.

Regarding testability. I was thinking rather about a set of functions (methods) enclosed in a class. It's rare to do everything in just one function, typically one function uses other functions to express the result. I was never trying to imply that functional programs are difficult to be unit-tested ;)

You always get the same output for the same input, which is not always true for objects. [emphasis added]

Now I don't know how to respond to this... Seems like a serious bug to me. There's not a problem to create objects with immutable state, where the results of method calls are always the same. Plus such immutable objects can easily be shared between threads. It depends on the style and/or necessity.

There are patterns in FP as well, which you can learn and then reuse across languages. For example, map, reduce, functions as values, monads (option-monad, either-monad, futures - similar to promises, but not the same, etc.)

Very true. Just a different set of concepts. By the way, combination of map and reduce is one of my favourites (!) I learned long ago.

Thank you very much for your time and interesting discussion. I will keep coming to your blog and occasionally ask some more questions :)