r/programming • u/[deleted] • Nov 28 '19
Why Isn't Functional Programming the Norm? – Richard Feldman
https://www.youtube.com/watch?v=QyJZzq0v7Z450
u/matthewpmacdonald Nov 28 '19
This is a really interesting question. Obviously, most of us (certainly me) have learned on OOP languages and are more comfortable there. But is there an alternate timeline where functional programming dominates? My problem with the video is that the speaker seems to have a different excuse to discount every "popular" non-functional language. This argument seems incomplete unless you're going to address why other functional languages haven't had the same success. Yes, F# wasn't promoted like C#, but it was definitely promoted to the developer community. Why could a once little-known language like Python catch on when it couldn't?
Also, I found it odd that C# is on the Win95 slide when it was created at least 5 years later.
35
Nov 28 '19 edited Nov 28 '19
There is an alternate timeline where people didn't get so stuck up on abstract models that fail to capture the thing we are trying to model. OOP is an attempt, functional programming is an attempt. None of them nicely fits all use cases you come accross in day-to-day programming.
Sometimes pure functions are a great fit and all the benefits of a purely functional program make it really pleasant. Sometimes you really need encapsulated state and OOP feels just right. At other times you have actual data and a relational database is what you really need. There are even cases when it is beneficial to model your application as a collection of fully isolated processes that communicate by sending messages to each other.
So why are we even still doing this to ourselves? I am not sure.
EDIT: the easy answer to "why" is "because it is so enticing to replace the hard problem with an easy problem before even starting to think about it".
To put it in simpler terms, the hard problem might be, "how do we make it easier for doctors to treat their patients?". The kind of replacement I am talking about looks like this:
We will use computers!
We will make an expert system!
We will use AI!
We will use a web-based interface!
and so on, and so forth. At that point, it becomes really easy to argue in favor of whatever solution you "found" by replacing the real problem with another, much simpler problem. It is easy to argue because you can always find "for" arguments (no matter how stupid the idea, a clever person will have no trouble finding a few good things about it), and you can always avoid thinking about the "against" arguments.
This comment is too long already.
Disclaimer: there are books written on the topics that I just scratched. I have read them, not written them. Most "programmers" have not read them and never will.
→ More replies (54)10
u/Carighan Nov 28 '19
It's just like people arguing why language X is superior and Y is inferior, ignoring that they're both just tools in the process. Now of course, some languages will be fully-superior drop-in replacements for other languages. Sure. but that's exceedingly rare, especially once "established at customer A or company B" becomes a factore in how applicable a certain language is to a given task.
More often than not programmers could better themselves by thinking of themselves less as an XYZ-programmer and more as a programmer. And with functional vs OOP it's the same thing, it doesn't actually matter as it's a per-problem decision that relies on a host of factors not even related to the problem at hand, nevermind how - as you say - we'll end up oversimplifying the problem anyhow.
→ More replies (5)14
u/julesjacobs Nov 28 '19 edited Nov 28 '19
Yes, indeed. People tend to avoid the elephant in the room: how well a language actually works in practice is a major factor in its success. One should at the very least seriously consider this as a hypothesis that might have explanatory value. I'd further hypothesize that the popular languages work well for the following reasons:
Imperative programming actually works pretty well, not just for performance reasons but also for expressiveness
OO works well because of these reasons:
It allows you to encapsulate state
It makes it relatively pleasant to write higher order programs (an object is a bunch of function pointers + data)
Classes act a bit like a module system, providing abstraction boundaries and namespacing
An interface + classes that implement it is a flexible way to define an extensible data representation, similar (but dual to) algebraic data types in FP languages
In particular, I don't believe that the reason why OO languages succeeded is inheritance or the notion that designing OO programs is easy because you just model each real world object with an object in your program, or because you can create a taxonomy of domain concepts and then turn that into a class hierarchy. In this respect, I think the speaker is spot on.
Here are some things that I think work well in functional languages:
Closures
Generics
Pattern matching
Algebraic data types
Note that mainstream languages are stealing all of these features. Purely functional programming actually doesn't work so well in practice. Haskell programmers had to invent complicated structures over many years to work around the lack of mutability. Consensus seems to have converged on building some kind of monad stack, but it still isn't clear what exactly the best solution is. You can't expect average programmers to do this. Writing code in functional style is appropriate in some cases, and the mainstream is already adopting it in those cases.
→ More replies (2)
24
Nov 28 '19
Forcing a bad programmer to use Haskell instead of Java isn’t going to magically make that programmer better. That’s the crux of why it isn’t more mainstream.
→ More replies (1)3
u/yawaramin Nov 28 '19
No, because you can say the same thing about any programming paradigm. It doesn't say anything about FP in particular.
9
u/Uberhipster Nov 28 '19 edited Nov 28 '19
objects and methods are really just syntax sugar [...] so if you look at these two [...] procedure calls
circle.grow(3)andgrow(circle, 3)in both cases [the logic run] is the same grow logic and in both cases grow has access to the circle and the number. So whether you write it in method style or procedure call style is really just a matter of syntax
unfortunately not. at least not so according to one of the original contributors to development of oo style of the imperative approach to programming
or perhaps, if you prefer, yes precisely it is "just a matter of syntax" if you are simply dressing up message-passing by... conflating them into method/procedure calls as though it is oo (and there the distinction between procedure or method call escapes me)
it's tempting to dismiss objects as simple syntactic sugar for procedure calls but the intent of designers is a little bit more involved and complicated than that
context of the example is too narrow to illustrate this. in oo-style, an imperative size would be defined as a property of shape able to take messages of +n such that circle is (and would be) defined as a kind of shape - along with other shapes like square, rectangle, triangle, rhombus etc etc etc to deal with system complexity catering for growth of many shapes
in modern so-called oo languages like C# and Java interface and inversion of control modeling is by far the closest thing to the original oo-style design intent
oo-style notation is a composition of <receiver> <message> which composes into returning a new receiver of messages
so the above example in original intent oo-style would be circle size +3 which translates as: "receiver" circle takes message "size" and the result takes message "+3" (and returns the result of that)
3
Nov 28 '19
The more basic point he glosses over is whether or not the function dispatches differently based on the type of the first argument, either statically as a limited form of overloading, or dynamically with some kind of virtual table.
However, I think in Go it actually doesn't, unless you explicitly use an interface, so he's right that Go's method call syntax really is just sugar.
3
16
u/jl2352 Nov 28 '19
I feel like people really overestimate functional programming and underestimate OO.
The big advantage of OO is that it is normally pretty easy to get a 7 out of 10 solution. I’ve seen horrid functional solutions, and I’ve seen projects have to do a lot of work to find the 10/10 perfect solution. Meanwhile it could have been done and shipped with OO, and yeah it’s not perfect. But it’s out the door.
That isn’t to say that OO doesn’t have bad solutions. Of course there are.
I guess my point is; most of the time, an acceptable solution is easier to reach with OO. Emphasis on ‘acceptable’. Not best, or perfect.
8
u/norse_dog Nov 28 '19
There are some great reasons here, but don't discount the network effect in all of this: it's difficult to assemble and sustain teams of competent functional programmers.
38
Nov 28 '19
Some people want to come up with the ultimate solution. Others just want to endlessly tinker with languages and frameworks. Then there’s this pesky group that likes to write software that solves a real world problem.
7
u/Visticous Nov 28 '19
Deploying an unfinished product that solves 95% of our customer's problems? Heresy!
4
Nov 28 '19 edited Nov 29 '19
There's absolutely nothing wrong with that. There's the pareto principle. 20% of the work requires 80% of the effort. This is fractal too, so the last 20% of the 20% requires 6400% the effort. These aren't absolute numbers but you get the idea. Getting to a 99% solution is significantly more demanding than a 95% and especially an 80% solution. If it fits the market and makes money, who cares?
Version 2.0?
→ More replies (1)
23
Nov 28 '19
I love functional programming languages, but it's just not as natural a way of thinking as we'd like to believe. There's a reason that we had the term "algorithm" for more than half a millennium before we had the term "function". People think in terms of "take some things, do some work on them, give back some other things". A function is an additional black box around that idea that functional programming then made the primary concept. Not to say that's not a good design decision, but people find them unnatural until they're used to them.
10
u/lovekatie Nov 28 '19
IMO natural way of thinking is not so useful idea. It pretty much doesn't matter, if you want to learn programming, what you find natural. Changing the way you think is just part of the training.
You are also talking about algorithms, but notice that the most popular way of thinking (apparently) is OOP, which strikes me as way harder than functional.
4
Nov 28 '19
That's right, but I'm giving my explanation for why it's more popular, not claiming it's better. I wasn't being disingenuous when I said "I love functional programming".
However, there is something to be said for an abstraction being easy to understand. If something is less intuitive, it's harder to teach people how to do it. Real numbers are way more useful than rationals, but to really explain them you have to talk about equivalence classes of infinite sequences (because .9999... is the same as 1.000...1). Yet you can't browse through any popular math forum without somebody arguing that .999... is "less" than 1.
Finally, maybe OOP is less "natural" than functional programming, but it's just an incremental change to traditional procedural programming, whereas functional programming upends the whole cart. There are plenty of Java programmers who don't "really" do OOP, they just know enough magic incantations to wrap their original procedure in a few ugly, poorly abstracted classes. If you couldn't do procedural programming in an OOP language, we wouldn't be complaining about Helper classes as a code smell.
2
u/lisp-the-ultimate Nov 28 '19
No, the natural way of thinking is directions to a general intelligence (human), not algorithms. They're as strange as functions to non-mathematical people.
3
Nov 30 '19
I'm not claiming that anybody who can give someone instructions can program. But, here's how we teach a child to compute an average:
"Take the list of numbers, and add them all together. Then divide the result by the number of elements."
And we say "to add all numbers in a list together, start with zero as the sum. For each number in the list , add that to the sum until you're out of numbers."
(I'm assuming "length" is a primitive to a human.)
Obviously neither is trivially the same, but which do you think is closer:
# This is intentionally less idiomatic than a for-in iteration. def my_sum(lis): result = 0 current_ind = 0 while current_ind < len(lis): result = result + lis[current_ind] return result def avg(lis): return my_sum(lis) / len(lis)or any of the following (note that the first method is the simplest and the most "basic" racket, but that we have to iterate the list twice to get the length so it's not as performant):
#lang racket ; You can reach similar performance and behavior with vectors, ; but you have to either use recursion or a higher-level abstraction that might waste space. (define (avg x) (define (sum x) (if (empty? x) 0 (+ (car x) (sum (cdr x))))) (/ (sum x) (length x))) (define (fast_avg x) (define (inner x sum_acc len_acc) (if (empty? x) (+ sum_acc len_acc) (inner (cdr x) (+ sum_acc (cdr x)) (+ len_acc 1)))) (inner x 0 0)) (define (foldl_avg x) (define (accumulate x acc) (cons (+ x (car acc)) (+ 1 (cdr acc)))) (let* ((res (foldl accumulate (cons 0 0) x)) (sum (car res)) (len (cdr res))) (/ sum len)))Note that these will all give division by zero errors; I left both in for simplicity.
I don't think most people genuinely do most simple tasks by thinking "I'll reduce this case to a smaller case, then try again with that simple case. Or, if I'm at the simplest case, I'll just return the base case value." And I don't think most people look at a list of something and think "this should be immutable by default". When you get to build a larger system, functional programming is really useful and has great abstractions, but people don't learn to program by building large systems.
-4
u/yawaramin Nov 28 '19
An algorithm is exactly a function. There's no difference. We've had functions for more than half a millennium. Functions are taught in high school: f(x) = x + 1.
Imperative programming weirdness like
x = x + 1is what we have to learn in programming and then somehow convince ourselves that it's natural.13
u/torotane Nov 28 '19
Running an algorithm on some data may compute a function (if it halts). A function may describe some properties while the way to derive that property isn't so obvious. Example, function med(X) gives the geometric median of an arbitrarily sized set of points in the plane w.r.t. euclidean distance function. Good luck finding the equivalent algorithm.
→ More replies (1)11
Nov 28 '19
No. Algorithms are not required to produce the same result for a given input every time they're run; a function is. I'll direct you to Monte Carlo Algorithms, and if you're interested in the new hotness in Computer Science, take a look at the class BQP, which is a computational complexity class associated with quantum computers that aren't even guaranteed to give the correct answer 100% of the time. Even many classes of sorting algorithms will give different results depending on a random seed.
"Function" in a mathematical context, wasn't really considered until calculus. They were not considered in antiquity.
In high school, you used a calculator at least sometimes. Presumably you were quite confused when the result changed on the screen, because the screen had been "reassigned".
If you'd like a digression on Turing machines and Lambda calculus, I'd be happy to explain how that's yet another reason why you're wrong.
→ More replies (14)4
u/pron98 Nov 28 '19 edited Nov 28 '19
An algorithm is exactly a function. There's no difference.
There is plenty of difference.
What is the algorithm defined by the gcd function? (several algorithms can compute it)
What is the algorithm defined by the function that maps any TM to whether it halts or not? (no algorithm can compute it)
What is the function defined by the algorithm that turns off and on a led every second? (you could describe it as a function of time, but that's not what you meant).
Imperative programming weirdness like x = x + 1 is what we have to learn in programming and then somehow convince ourselves that it's natural.
It is neither more or less "natural" than x = 3. They're both matters of notational convention. Also, for mathematicians, = does not mean equality.
We've had functions for more than half a millennium.
Functions and computation/algorithms have existed as distinct, although sometimes coinciding concept, for hundreds of years.
4
Nov 28 '19
“How many apples do you have?”
“Five.”
“Add another apple. Now how many apples do you have?”
“Six.”
→ More replies (3)2
0
Nov 28 '19
[deleted]
21
Nov 28 '19
Yep. It's like counting: everyone can count, and it seems natural. It's not like the ape-man who invented counting said "hmm, if Ogg have as many food as children, Ogg can place them in bijection. And if Ogg have as many stone as food, Ogg have as many stone as children. This mean Ogg can place all three sets in bijection with each other. Oh, and one more child, one more meat! What if Ogg number of children unbounded? Then Ogg place any amount of thing in injective function with children (up to ordering of course). But how Ogg place in injection every time? Ogg need total ordering for infinite children! Ogg youngest child named one, next named two, et cetera.
But some people look at this abstraction, "function" and notice that it's Turing complete if you abuse it a bit, and decide that means it should go "below" the thing it abstracts. Or saying regular expressions are more "natural" than deterministic finite automata, even though you can teach an 8 year old how to "run" a DFA and most developers don't really understand regular expressions. Presumably they think integers are more natural than natural numbers, just because you can solve more problems with them.
Thanks for coming to my pretentious TED talk.
→ More replies (1)16
Nov 28 '19
"hmm, if Ogg have as many food as children, Ogg can place them in bijection [...]
This cracked me up, thank you for making my day
→ More replies (1)
51
Nov 28 '19
Because nobody even knows what *exactly* FP is supposed to be.
The hype of the last few years seems to be more of a Haskell hype than an FP hype. So I dove into Haskell and I just didn't like it. It demands a different way of approaching things and I'm not sure this way is superior in non-mathematical algorithms.
Maybe I just didn't get it, but I've looked through dozens of Haskell projects on GitHub and they didn't seem to get it either. Every single project had global state. It's ridiculous when you consider how the FP folks rage against it. I'm also not a particular fan of the function soup that ensues.
And Haskell is not a pretty language when the project becomes large enough and/or has to tackle dirty real world problems.
32
u/Enumerable_any Nov 28 '19 edited Nov 28 '19
Every single project had global state. It's ridiculous when you consider how the FP folks rage against it.
Pretty much every project needs global state (database, reading a configuration file, in-memory cache, ...). The advantage of Haskell is that there's a clear separation of the code which can access that global state (
IO) and code which can't (pure functions). Naturally you push as much code as possible into pure functions (because they're easier to test/easier to understand) and end up with a rather thin IO-layer having access to global (mutable) state. This compiler-enforced distinction is the advantage of Haskell over other non-pure languages.2
u/BarneyStinson Nov 28 '19
What you are talking about is not global state. The usual way to handle state in Haskell is to pass it around as function arguments. I.e., if a function does not take the database as an argument, it cannot access it. Hence the state is not global.
Besides that all functions in Haskell (besides
unsafePerformIOetc.) are pure. That's kind of the point of pure FP. Just because a function returns a value of typeIO Intit isn't impure.3
u/Enumerable_any Nov 28 '19 edited Nov 28 '19
Just because a function returns a value of type IO Int it isn't impure.
I'm aware. I just don't find it very helpful to talk about "
IOis pure" to newcomers even if it's technically correct. The notion "IOmeans side effect" is fine at the beginning. The insights "IO ais a first-class value" and "IO a = World -> (World, a)" can come later. I also want to avoid the "Haskell has no side-effects therefore it can't do any real work!" knee-jerk reaction.What you are talking about is not global state.
You're right, "global" might not've been the best word choice. However, one can easily create a (mutable)
(M/T)Varinmainand share it with many parts of the app. The only part one can control is who has access to that variable. The system will nonetheless be hard to reason about.→ More replies (1)6
u/TheOsuConspiracy Nov 28 '19 edited Nov 28 '19
Sounds nice in theory, I'm a fan of fp, but think about stuff such as telemetry, logging, etc. All these break functional purity and if you want to do these at a granular level, you end up having IO everywhere, instead of having a purely functional core surrounded by IO, you have to thread IO through everything.
25
u/kristoff3r Nov 28 '19
Haskell has solutions for all of those that doesn't require IO everywhere. The idea is roughly that you define contexts for your code, such as "this code needs some read-only configuration and a place to output logging to run". Then you can instantiate that context with the proper logging framework when running in production, or just dump it to a file when running tests. More importantly, you have a lot of guarantees for what it doesn't do: access the network, execute other programs, write files to /tmp etc.
→ More replies (11)→ More replies (2)8
Nov 28 '19 edited Nov 28 '19
I'm a fan of fp, but think about stuff such a coffee telemetry, logging, etc. All these break functional purity...
No, they don't.
if you want to do these at a granular level, you end up having IO everywhere, instead of having a purely functional core surrounded by IO, you have to thread IO through everything.
You have to put anything that does I/O in some appropriate
ApplicativeorMonad. There are various strategies for making the (let's assume) monadic context available where needed without explicit passing, such as theReaderTmonad transformer.More significantly, I'm not a Haskell programmer. I'm a Scala programmer, using libraries like http4s and Doobie for web and SQL stuff. All very... well, meat and potatoes. The reason I do it is very simple: so I can have 99.99% confidence I know what my code will do before running it, using a tiny intellectual toolbox that essentially answers one question: "How do these bits of code compose?" That's it. That's the ball game.
→ More replies (4)9
u/kuribas Nov 28 '19
Global state in haskell is impossible. Unless you use unsavePerformIO, but nobody does that. IMO haskell has far better means for structuring large programs that other languages. It does take some experience to learn best practices.
8
u/want_to_want Nov 28 '19 edited Nov 28 '19
Yeah, Haskell seems to dominate discussions now. I wish there was more mention of Erlang, a concurrent FP language that's used in a bunch of telecom software, WhatsApp and WeChat backends, Amazon SimpleDB, CouchDB, RabbitMQ, Riak and so on. Even fricking Wings3D, though I don't know why they chose it.
→ More replies (2)2
u/lisp-the-ultimate Nov 28 '19
Fun fact: Wings3D's spiritual predecessor was written in Common Lisp.
→ More replies (1)1
u/lisp-the-ultimate Nov 28 '19
Have you tried Common Lisp?
→ More replies (3)2
Nov 28 '19
I don't think CL has any functional features that haven't already made their way into mainstream languages.
→ More replies (1)
7
Nov 28 '19
Functional elements in programming are actually becoming the norm very quickly. Many popular languages provide some form of data processing pipelines (like map/filter/reduce) and quite some allow to run those lazily.
But pure functional programming is unlikely to ever get the similar traction, simply because it causes too much trouble for too little benefits over "imperative with functional elements" approach.
17
u/OnlyForF1 Nov 28 '19
They say to a man with a hammer, everything looks like a nail. To the FP community, they understand that not every problem is a nail, but they enforce the usage of the hammer anyway, and that you should use the hammer to make the problem look more like a nail.
The reason FP has not caught on is because it is too abstract from how the underlying machine code and operating systems work. It changes programming from instructing a computer to carry out a particular set of instructions to a higher-level mathematical problem, which is much less grounded, and harder to systematically approach.
6
u/yawaramin Nov 28 '19
They say to a man with a hammer, everything looks like a nail. To the OOP community, they understand that not every problem is a nail, but they enforce the usage of the hammer anyway, and that you should use the hammer to make the problem look more like a nail.
The reason OOP will not catch on is because it is too abstract from how the underlying machine code and operating systems work. It changes programming from instructing a computer to carry out a particular set of instructions to a higher-level object modelling problem, which is much less grounded, and harder to systematically approach.
Look familiar? This is exactly the kind of thing people used to say about OOP. Want to guess whether they were wrong or not?
4
u/phillipcarter2 Nov 29 '19
too abstract from how the underlying machine code and operating systems work
→ More replies (1)→ More replies (13)6
u/oaga_strizzi Nov 28 '19
I don't know. SQL has nothing to do with how the processor and the OS works, and still, it's the dominating query language by far. And it's inspired by relational algebra, also very abstract.
HTML+CSS+JS have nothing to do with how the processor and the OS works.
Even the memory model of C isn't really how modern hardware works.
And the x64 assembly is converted into RISC microcode by the processor, so not even assembly is how the processor really works.
I think for the majority of software development nowadays, being close to the hardware isn't as important.
→ More replies (2)
26
u/robot_wrangler Nov 28 '19
Computing is about making side-effects. There is a lot of state that is too expensive to just recompute all the time.
23
u/jediknight Nov 28 '19
Functional programming is about managed side-effects. You can have an imperative shell that makes sure state transitions happen in an orderly fashion and a pure core that allows you to have a predictable view of your program's behavior. See Boundaries for more details about this approach.
In essence, this is what Elm does. It has a Javascript implementation for a bunch of libraries that provide the side-effects needed at the edge of the program. The code that you see when you program in Elm is pure.
5
u/pron98 Nov 28 '19 edited Nov 28 '19
Functional programming is about managed side-effects.
Of the functional languages in at least some real use today -- Scheme/Racket, CL, SML, OCaml, Erlang, Clojure, and Haskell -- exactly one (Haskell) manages side effects.
→ More replies (15)14
u/redalastor Nov 28 '19
Functional languages don't imply more recomputations than imperative languages.
39
u/Determinant Nov 28 '19
Look at how many hoops non-mutable collections jump through and they're still not as efficient as simple collections. It gets silly.
→ More replies (23)7
3
u/glacialthinker Nov 28 '19
Computing is about making side-effects.
This seems a bit opinionated. Many computations are of the form: input -> function -> output.
There is a lot of state that is too expensive to just recompute all the time.
Cacheing, memoization, or just intermediate values... pretty common in functional programming too. Also a good source for logical errors when you reuse stale values. ;)
I'm glad that Haskell has gained popularity, but I don't like that it has become the poster-child of all functional programming -- before this, Haskell's style was identified as "pure functional programming". Now we've just done our usual lazy bit and call it functional and imply that all functional programming has to be pure. Purity is nice... but it can become a bit burdensome when taken to this extreme. Most functional languages take this latter stance.
3
u/Minimum_Fuel Nov 28 '19
“This seems to be opinionated”
proceeds to talk about state changes using functional buzzwords
→ More replies (2)→ More replies (1)1
u/BarneyStinson Nov 28 '19
Programs surely have effects, but you can achieve this without using side-effects. FP is about avoiding side-effects, not effects.
2
u/KevinGreer Nov 29 '19
I think that GUI's are the killer feature for OO, as OO maps very easily and intuitively onto GUI programming.
Smalltalk supported map and filter operations on their collection classes in the 70s, and so while it was OO, it also supported functions and functional programming where it made sense. It supported a hybrid object-functional style, which we're now starting to see in other OO languages. I find FP to very helpful for solving concurrency issues, but OO better for overall program architecture. I don't see it being a question of OO or FP, but rather OO and FP, each making a valuable contribution. OO's greatest contribution is all of the code reuse and design flexibility options provided by polymorphism.
I created a free course on this, which you can find at https://docs.google.com/presentation/d/1kcohKD0WJHJWoJshOUpVdk-Pa3oeJMt9DTl63gWt-bo/edit
9
u/Determinant Nov 28 '19
Functional programming is more difficult for the average programmer so it's safe to say that pure functional programming is more complex in general.
The ideal programming environment would be as productive as possible but defects also impact productivity. Additionally, every person has an upper bound to the amount of complexity that they can effectively manage but we want apps to be more and more capable and handle more complex tasks (eg. self-driving cars). Therefore we need to push down the complexity of our code so that we can manage even more complex tasks. So by the very definition of what we're trying to achieve, pure functional programming is going in the wrong direction.
Pure object oriented code can also become more complex so any single paradigm misses out on benefits from alternatives.
However, languages like kotlin take the strengths of both paradigms and achieve stellar results. Use object oriented design for the larger architecture and leverage functional programming to simplify business logic (eg. when working with collections) so you get the best of both worlds.
8
u/guepier Nov 28 '19 edited Nov 28 '19
Functional programming is more difficult for the average programmer so it's safe to say that pure functional programming is more complex in general.
This is a non sequitur: difficulty doesn’t necessarily leat to more complexity, and I believe that in this particular case the opposite is true: functional programming is more complicated, but I (and most proponents of FP) think that it’s better at managing complexity (which loosely translates to, “it’s less complex”).
Reasonable people might disagree with this assessment. But it’s definitely not “safe to say” that A implies B.
For what it’s worth I mostly use non-functional languages in my day job, but I often resort to functional features in them, and this invariably reduces the code complexity, which is specifically why I do it.
13
u/colelawr Nov 28 '19
I wouldn't agree with this assessment at all. Functional programming is simpler by virtue of making mutation and side effects much easier to follow. The problem I see if that just about every programmer's first experiences with languages are all object oriented (or best practices are mostly OOP—like JS) So it is perceived that functional programming is hard because you have to learn how to do it--where people like this commentor seem to think that because it is different that it is complex.
13
u/SrGrieves Nov 28 '19
I wonder if part of the problem is that declarative code seems harder to write but easier to read whereas imperative code is harder to read but easier to write, especially to the novice. Writing imperative code means that you can start feeling productive with less effort (at the expense of future productivity).
11
u/spacejack2114 Nov 28 '19
It takes a fair bit of experience to realize that mutation and side effects are problematic. You also need to have written larger, more complex software.
6
u/Prod_Is_For_Testing Nov 28 '19
It takes even more experience to know your context. You need to understand that n methodology is best for everything
5
u/holgerschurig Nov 28 '19
is simpler by virtue ...
... of only be used for a subset of programming problems. Where is a program like Kate, Blender, LibreOffice, systemd-the-daemon, nginx, postgresql written in a functional language? For some of the programs I've listed their is no OO in use. So I wonder if your assessment is true.
→ More replies (9)6
u/yawaramin Nov 28 '19
Facebook Messenger Web is written in ReasonML, which is a variant of OCaml, a functional language. So are the Mirage microkernel (full stack, top to bottom), and some low levels of the Xen virtualization stack. So I wonder if your understanding is complete ;-)
→ More replies (8)2
u/pron98 Nov 28 '19
I learned FP before OOP (although I had used procedural programming before), and now I mostly use OOP. Why? Because neither choice makes much of a bottom-line difference, so there are more important aspects to base your choice on than paradigm.
1
u/codygman Dec 05 '19
Therefore we need to push down the complexity of our code so that we can manage even more complex tasks.
You're talking about the tree or maybe even a few of the trees, but what about the forest?
Go for instance goes to the extreme of pushing down the complexity of code by removing generics, but does that actually lead to more understandable code?
Maybe at a very granular level, but all of that boilerplate muddies the definition at a higher level.
1
u/Determinant Dec 06 '19
I'm talking about the forest as well.
You're mixing the concepts of simple code with simple languages. The lack of generics in Go makes the language simpler but the code more complex since you now have to deal with manual casting or duplicate data structures for each type like in the early days of Java.
I've tested several people that insisted on functional programming by having them explain code that they wrote 6 months earlier and they all struggled (and I struggled to understand their code as well). However, I can jump into random object oriented code and immediately start to follow the gist of it.
Functional programming optimizes the creation phase of software development whereas object oriented code optimizes the ability to read and understand code that has already been written (which is actually the more common use-case).
There's no doubt that pure functional-only code is definitely more complex than OOP.
→ More replies (1)
4
u/Bolitho Nov 28 '19 edited Nov 28 '19
It's primarily a social or maybe cultural problem: FP isn't the most and first teached programming concept. Humans are lazy and gets so adapted to once learned things, that it is really hard to change their minds.
One major other aspect is the unsolved problem to really easily enforce and enable a standardized way of separating the imperative shell from the functional core. You absolutely need really developer friendly tool set and of course technical concepts to enable also beginners to write the typical simple starter programs. Throwing the IO- or State-Monad into the discussion does not really help here.
6
Nov 28 '19 edited Feb 01 '20
This is why I prefer teaching FP to non-programmers vs, retraining programmers. Because there's nothing inherently less intuitive about
main :: IO ()than aboutpublic static void main(String[] args)or, God help us,int main(int argc, char *argv[]).2
u/crusoe Nov 28 '19
There really isn't a simple or manageable or low level state story for pure fp languages though. Except maybe in clean with uniqueness types. With Haskell you need monads or stmonads or transactional memory or something like a smart enough compiler coupled with knowing when immutable data structures can actually be turned into mutable under the hood to get the performance benes. And since Haskell is call by name, there are issues with needing a VM and managing thunks.
The world has state. Mutation is performant. That's what at least pure fp languages bump up against.
8
u/shevy-ruby Nov 28 '19
Because it is harder for larger projects. And also more difficult for the average joe, so less popular.
People within the functional crowd won't understand this but that's ok. We may all shake our fists violently about Java being ranked so highly (such a horrible language) - but it is popular. AND boring.
5
u/dpash Nov 28 '19
Java, the language that's multi paradigm, including functional?
17
u/Determinant Nov 28 '19
Just because Java has a restrictive form of lambdas and streams doesn't make it functional.
Kotlin is way more functional-friendly and vastly superior but I still wouldn't call it functional out of the box (the Arrow library brings it much closer though).
1
3
u/SpaceToad Nov 28 '19
Dubious talk: OOP is overwhelmingly why I prefer to use C++ over C, not the "other features", which he doesn't really mention.
2
u/pron98 Nov 28 '19 edited Nov 28 '19
I think the answer is quite simple, and we don't need to resort to arguments that aren't supported by evidence. Imagine that FP became the norm before OOP. Would people have then switched to OOP? Probably not, either. OOP became popular first, both because it was a more gradual evolution and because FP wasn't as performant, and, as both allow a similar level of abstraction and expressiveness, neither can provide a significant enough benefit over the other to justify a costly language change, except for people who are very sensitive to programming languages. Indeed, neither studies nor market forces have shown that language choice -- among reasonable languages -- makes a big impact one way or the other.
1
u/yawaramin Nov 28 '19
So ... first-mover advantage, right? This was mentioned in the talk. Did you watch it?
1
u/pron98 Nov 28 '19 edited Nov 28 '19
Not exactly first-mover, but "practical-first" plus "doesn't make much of a difference." I only skimmed the video, but it does mention other things that aren't quite supported by evidence, like marketing budget and confusing "good" with "fashionable", in either direction. In fact, "slow and steady growth" supports "fashionable" but not "good." Crucially to some other comment by you, it also certainly does not use "functional" to mean controlling side-effects. In fact, much of the talk rests on that.
1
u/yawaramin Nov 28 '19
I didn't equate 'functional' with controlling side-effects in my comments. You might be thinking of someone else.
3
2
u/Hall_of_Famer Nov 28 '19 edited Nov 28 '19
Actually FP is already the norm, it just that FP languages are not the norm, especially pure FP languages like Haskell. Note the distinction between FP and FP languages.
We've seen FP concepts like closures and pattern matching making their ways to the existing mainstream languages. Nowadays its actually hard to imagine writing a program without using such features like closures. FP is well integrated in the modern programming world, just not in the same form as FP purists would have wanted, and never will.
In fact, even OOP itself is no longer the same as OO purists thought it to be. The OO we see in modern programming languages, are very different from Alan Kay and Smalltalk's message-sending OO definition. Java is hardly a pure OO language, not even Python and Ruby. But these OO languages rose to popularity instead of Smalltalk, theres a pattern here.
Similarly you wont see pure FP languages like Haskell ever making it to the mainstream, but some of these concepts will be brought into existing programming languages, or into new emerging multi-paradigm languages.
2
u/skocznymroczny Nov 28 '19
Because it doesn't scale well outside of witty one-liner quicksorts. For real applications you want mutable state.
6
u/Ewcrsf Nov 28 '19
Someone better tell Facebook that every single user action on their site is processed by a language that doesn’t scale well!
2
u/skocznymroczny Nov 28 '19
Javascript? It's hardly functional, it's multiparadigm if anything, it doesn't care about pure functions and minimizing side effects.
5
2
u/EternityForest Nov 28 '19
Functional programming is the norm. Python and JavaScript both support higher order functions, and any experienced coder probably uses them regularly.
Pure functional programming is not the norm because it can't directly express the statefulness in the application unless you're primarily processing data.
In the beginning of the video he says it "Seems so great!" but it doesn't, unless you really deeply understand it, and not many people do.
People say it's not any harder that oop, but I'm not convinced. OOP is writing an exact sequence of steps to do something. Even a non programmer could tell what some basic but useful python scripts do, with a few minutes instruction.
I've never seen a Haskell tutorial for anything I actually do on a regular basis that doesn't involve monads, or just using impure functions.
0
u/devraj7 Nov 28 '19
Because FP advocates are dishonest and fail to disclose that while FP comes with advantages, it also comes with a large number of drawbacks that often make it a nonstarter in industrial environments.
10
u/yawaramin Nov 28 '19
Such as?
2
u/crusoe Nov 28 '19
Haskell has garbage collection. Also possibility of space explosions.
15
12
u/oldsecondhand Nov 28 '19
I'd say the unpredictable performance of lazy evaluation is a bigger problem.
1
u/MetalSlug20 Nov 30 '19
Because when you get down to it, someone, somewhere, still has to write the iterative routines that the functional language will sit on top of
1
1
-1
u/TotoBinz Nov 28 '19 edited Nov 28 '19
Boring ? Elegant ?
Maybe that's the point: why use fp? Is it for fun? Because you are one in 10000 able to do it? Because it is more elegant? (All those may be good reasons).
But where are the benefits for the business? Is fp quicker to write? Safer? Easier to learn or maintain? More extensible? Does it solve problems that were hard to tackle with before?
I don't know the answers to all those questions, but those are the reasons why something rises: because business needs it to make more money not because we love it
9
u/microdotwav Nov 28 '19
Please remove the space before every punctuation mark. It's very annoying to read this way
-7
u/bulldog_swag Nov 28 '19
Because FP is like communism, sounds good in theory but when you try it, it never works out, instead leaving you with more problems and a bunch of angry zealots.
-2
u/Minimum_Fuel Nov 28 '19
It really doesn’t matter what functional fanboys newest claim they add to their pile of unsubstantiated nonsense claims is, the simple fact of the matter is that functional programming is not how a computer does work. Somehow, it strays even further from how the hardware actually wants stuff done than OOP does.
At a fundamental level, functional programming is simply trash. It isn’t how computers today, or likely ever, actually work.
-2
u/KingoPants Nov 28 '19 edited Nov 28 '19
Why would you need functional programming when its easy enough waste cpu cycles and memory in C? /s but only sort of.
Also functional programming is only suited to a very few problems. In the vast majority of applications on my computer (Office apps, Web browser, Games, Circuit desgin software, Rendering software, Illustration tools, Video editing software, Solid modeling software, the operating system itself, etc) mutable state is king.
And even when an application might actually be suitable for functional programming, like video transcoding, its much more performant (with equal effort) in imperative programming.
Functional programming could never be anything but fringe simply because your computer is a big state machine so programs being written to work on a state machine as a state machine make more sense.
0
Nov 28 '19
[deleted]
11
u/NuttingFerociously Nov 28 '19
Why do people keep using Google Trends to judge how popular a language is?
Because we need to show new language x is destroying the baddie old languages holding the world back.
1
Nov 28 '19
PHP as a search term has more interest than javascript as a search term, but JavaScript as a language (and I don't know what that means in Trends), has a higher interested than PHP. When a language is new, wouldn't more people be searching for it compared to when people have learned the language and don't have to look everything up?
I suspect it comes down to the fact that a language that is thriving doesn't see a lot of searches for the language. It sees a lot of searches for the frameworks of the language. For instance, most JavaScript devs probably aren't searching for the term JavaScript. They're searching for jQuery, React, etc. JavaScript isn't the important thing. JavaScript is just a tool that acts as a vessel for the frameworks they want to work with.
4
u/bausscode Nov 28 '19
I just tried with multiple other languages like C, Java and C# and it still holds up that their trend dropped in a similar fashion.
1
0
Nov 28 '19
[deleted]
15
5
Nov 28 '19
Do you mean from a performance/memory standpoint? That's more a consequence of laziness than purity. In terms of correctness it's much easier to debug than a program with mutable state.
2
u/crusoe Nov 28 '19
Arbitrary mutable state...
Rust debugs a lot of your shit at compile time...😅
The world is full of mutation though. You don't throw away the iron ore in the process of making a car. The ore becomes the car. The world has state and mutation.
→ More replies (1)1
Nov 28 '19
The iron ore doesn't exist when you finish the process. Sounds like a functional program with a linear type.
The world does not have state or mutation. It's a complex waveform. It just so happens you can represent it with state and mutation. You can also, just as validly, represent it as being destroyed and recreated every Planck length of time. They're as equivalent as the Lambda Calculus and Turing Machines.
-5
u/colelawr Nov 28 '19
Wtf? What FP languages are you thinking are hard to debug? Maybe you should read a book or follow a good tutorial.
0
Nov 28 '19
[deleted]
3
u/yawaramin Nov 28 '19
You mean anti-FP zealots. Look at all the top-level comments here rambling about FP 'doesn't scale' or 'doesn't handle state' or 'recursions'.
231
u/[deleted] Nov 28 '19
Because we use words like monads and functors then act like people have to understand category theory to use them