DEV Community

What is the benefit of Functional Programming?

Kasey Speakman on April 05, 2017

Posted at the suggestion of Pablo Rivera. I've seen some posts lately trying to come to grips with or warn against functional programming (FP) pat...
Collapse
 
cullophid profile image
Andreas Møller

Throwing an exception violated the contract of a function.
Take the function Number -> Number. It takes a number as input and returns a number.
If the function throws an exception it will no longer return a number and will therefor violate its contract.
That is why you use complex types for error handling in functional languages:
Number -> Either Err Number
This function now returns an Either type that can either be an error or a Number. Notice that we can now handle exceptions, but we still do not "throw".

Collapse
 
mortoray profile image
edA‑qa mort‑ora‑y

Exceptions in no way violate the contract of a function, they are merely part of the contract. There is no fundamental reason a pure function could not throw an exception.

I've covered this in my article: The exceptional myth of non-local flow

Collapse
 
kspeakman profile image
Kasey Speakman

In functional languages, pure functions depend on the function signature to be a declared contract. An exception is not declared in the signature. Some functional languages do not even have exceptions. With the examples in your article being in C, I'm not sure that our points of view are looking at the same set of circumstances. If we were talking about C, I might be swayed to your side.

Collapse
 
mortoray profile image
edA‑qa mort‑ora‑y

I'm saying that exceptions in general don't prevent something from being a pure function. I don't belive it makes a significant difference whether the error handling is explicit or implicit -- it can be considered part of the contract either way.

For example, in my language Leaf, errors are an implicit part of the signature, they can however be turned off.

Thread Thread
 
kspeakman profile image
Kasey Speakman

We will have to agree to disagree then. I think any error handling strategy could work in its own set of conditions. But to say that exceptions are the best way to handle errors across the board, I can't agree with.

Thread Thread
 
seykron profile image
seykron

In web environments you usually have one or two options to manage errors: retrying IO or returning an HTTP status code 500. There's a user in the other side waiting for a reply, and in the most common request handling model thread-per-request there's a thread bound to the current request waiting to be released. So you can either choose to handle the error flow like a special flow in your business logic (like Try's in scala), or you just can throw an exception, set up a catch-all handler and return a friendly error code so the user can retry the operation.

I really don't support error flows in web environments, it usually opens additional branches in the execution that makes harder to debug and detect errors. The easiest way I know to debug and fix errors is to throw exceptions closer to the place the error occurs.

Collapse
 
danielkun profile image
Daniel Albuschat

I second that functional is better for maintainability. Btw. now a days c# can be as functional as F# or Scala, for example. All necessary language features are available, which makes the switch for a dev (team) much easier, allowing them to focus on methodologies and mindset instead of syntax and interop.

Collapse
 
kspeakman profile image
Kasey Speakman

You can certainly write pure functions in C#. But it can be a bit awkward. Anonymous functions have overhead to setup, often requiring a type declaration in the form of Func<type1, type2, returntype>. Partial application becomes more verbose. C# makes it difficult to avoid nulls and thrown exceptions. (To be fair, .NET itself makes that latter hard to avoid in F# code too.) C# lacks the primary means that F# uses to avoid these: union types. (Union types are also a great modeling tool for business logic.) The C# alternative to this could be subclassing or marker interfaces, which also work well with the new pattern matching feature. However, it's quite verbose to setup compared to union types. Avoiding mutation is really tough to ensure in C#, and foreign to most of us coming from OO. It requires a high level of discipline (and training for new team members).

I'd say that you can do pure functions in C#, but it's not what is made easy there. And under deadline, I find that I will often go with the path of least resistance. If the goal is to write pure functions, F# makes that easier. F# is not perfect in that regard either... it's still pretty easy to introduce side effects like getting current time. I wish there was a way to mark modules "pure" so they would generate a compiler warning if a side effect was introduced. (I'm aware of Delegate.Sandbox, but I don't really want to run unoptimized code.) But in all, F# gets you a long way towards making pure functions easier to write.

Collapse
 
danielkun profile image
Daniel Albuschat

"And under deadline, I find that I will often go with the path of least resistance"

Yes, that's the point. The new C# features are all going in a functional direction, but it's still too easy to either skip or miss core elements of FP. But it's still interesting to see how virtually all languages currently add functional elements (or new languages start functional from the beginning, like Elm), so hope for FP becoming more mainstream is still there.

Thread Thread
 
kspeakman profile image
Kasey Speakman

Absolutely. As several recent languages show, there's no reason why FP can't exist alongside OO (and procedural) in the same language. I'd like to believe that FP becomes the dominant paradigm before long. I just hope people don't fall into the same trap I did and get discouraged with FP. The trap was that I focused on using match and Maybe and partial application, and all the other mechanics of FP. But disappointingly, I found they didn't provide much benefit, because I wasn't striving to make pure functions with them. Nobody really explained that to me, so I thought I would take a stab at it with this post. :) Best wishes!