5 ms·
There is an interesting trend where things with a strong mathematical definition tend to have the advantage. "Functional Programming" doesn't have a precise def
by roenxi 2y ago
There is an interesting trend where things with a strong mathematical definition tend to have the advantage. "Functional Programming" doesn't have a precise definition at all as far as I know, so it is likely it doesn't refer to a real thing. Most of the paradigms are similar as they don't seem to actually mean anything. People seem to want to describe something (in today's article, data flow) but they don't quite have the language to do it.
If you go to https://en.wikipedia.org/wiki/Functional_programming https://en.wikipedia.org/wiki/Functional_programming right now you will see "functional programming is a programming paradigm where programs are constructed by applying and composing functions" which is a bit of a ... it is quite hard to program without doing that. Even SQL is basically applying and composing functions. There are languages that are branded together because they have similar communities or techniques, but the brand isn't describing something beyond people thinking that things belong in a basket together.
- culi 2y agoIt's funny you say that because I'd say FP has a much more well defined mathematical foundation compared to OOP. In fact, before it became as dominant as it is today, it was often criticized as being too scholarly and theoretical. It's built mostly on the foundations of Lambda Calculus (and maybe some Type Theory). I don't think OOP ever had nearly as strong of a mathematical/scholarly foundation as FP has
- roenxi 2y ago> It's built mostly on the foundations of Lambda Calculus (and maybe some Type Theory). Can you describe a programming language that isn't based on lambda calculus? It is a universal model of computation.
- LegionMammal978 2y agoIn that sense, every programming language (as well as lambda calculus) is based on Java, since Java is a universal model of computation. So I don't think it's very useful to take "is based on" to be as broad as "is interpretable using".
- roenxi 2y agoConspicuously absent in that thought is an alternative way to interpret "is based on". Because I suspect that in most senses that FP is based on lambda calculus we probably can claim it is also based on a subset of Java. Everything useful is multi-paradigm these days, programming paradigms turned out to not be a useful lens for developing useful programming languages.
- LegionMammal978 2y ago> Conspicuously absent in that thought is an alternative way to interpret "is based on". "Has designers who consciously adopted significant ideas from" seems good enough for me.
- roenxi 2y agoThat is a path-dependent property though. So if we interpret it that way we can't tell if a language is based on lambda calculus without interviewing the author. Indeed, the definition admits that we could have two almost identical languages but only one of them is based on lambda calculus. I don't think it is a reasonable way to interpret "is based on", it requires too much knowledge of history. It is more proper to have a technical definition that is rooted in the language itself.
- LegionMammal978 2y agoC'est la vie: it's always going to be a very fuzzy concept when applied, short of broadening it until it's unrecognizable. Not every property of a thing needs to be perfectly decidable with no room for guesswork. To put it pithily, "This popular notion is provided 'as is', without warranty of any kind, express or implied, including but not limited to fitness for a particular purpose." If you really want a property that's fully intrinsic, I'd suggest disregarding fuzzy 'based on'-ness and instead considering some particular aspect you care about, e.g., "How difficult is it to express such-and-such a technique in this language?"
- ninetyninenine 2y agoFP is math. There's not much distinction. The language of math is FP.
- ryandv 2y agoIt's arguable that SQL is "basically applying and composing functions," given that its mathematical underpinnings lie in the relational algebra (hence relational databases). Further, while it's maybe technically correct to make statements such as, all programming languages are based on lambda calculus, a universal model of computation [1], this is about as precise a statement as saying that all mathematics is based on set theory. While it may be true, it may be too low a level of abstraction, and there are probably higher-order constructs or machinery that get closer to your actual domain of study or application (e.g. real numbers, functions, vectors). I have mentioned downthread [0] a few characteristics that distinguish FP from other paradigms - namely, first-class functions and higher-order functions (the ability to pass functions to functions); referential transparency, "pure functions" without side effect, and equational reasoning (the ability to replace expressions with their value and keep the behaviour of the program identical); and a tendency to prefer parametric and ad-hoc polymorphism (generics and trait/typeclass bounds) to subtype polymorphism, the "inheritance" boogeyman of OOP. Again as mentioned in [0] the "expression problem" [2] is a good model for discussing the ergonomics and tradeoffs of FP vs. OOP. [0] https://news.ycombinator.com/item?id=41450851 https://news.ycombinator.com/item?id=41450851 [1] https://news.ycombinator.com/item?id=41452258 https://news.ycombinator.com/item?id=41452258 [2] https://wiki.c2.com/?ExpressionProblem https://wiki.c2.com/?ExpressionProblem
- roenxi 2y agoThe distinguishing characteristics don't distinguish FP from anything. Those are features like first class functions that I would expect to find support for in Python or C++, for example. And it isn't possible to write a useful program that doesn't have side effects because there would be no IO. It is a case of the paradigm not really meaning anything. It is an arbitrary bunching of language features and code properties that doesn't provide a particularly useful guide. Anything that is a good idea in one paradigm is also a good idea in any other paradigm too.
- ryandv 2y agoIt's worth noting that both languages cited (Python, C++) are multi-paradigm and therefore contain aspects of both OOP and FP; there are very few languages that are exclusively object-oriented or functional. The naming of the functools [0] stdlib package for Python's higher-order functions is illustrative in this respect, and there is an entire HOWTO for "implementing programs in a functional style" [1] in the Python docs. If you want to see object-orientation taken to the extreme, and how it makes writing programs in a functional style extremely unergonomic, you can read old-school Guava code from Java 6 and try to decipher all the line noise; there is even a caveat in its official documentation [2] that states, functional programming without Java 8+ requires awkward and verbose use of anonymous classes. Excessive use of Guava's functional programming idioms can lead to verbose, confusing, unreadable, and inefficient code. These are by far the most easily (and most commonly) abused parts of Guava, and when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps. > It is a case of the paradigm not really meaning anything. It is an arbitrary bunching This is a case of throwing the baby out with the bathwater; just because we can't come up with a perfectly precise definition doesn't mean that we should dispense with rough heuristics and (perhaps crudely drawn) boundaries that serve as a useful clustering of related features. Try asking a machine learning or computer vision algorithm for the criteria it uses to categorize something as a "dog;" it's unlikely that you'll come up with something as precise as the definition of the Platonic ideal of a dog, but we can still use its model to recognize dogs with a reasonable degree of accuracy. [0] https://docs.python.org/3/library/functools.html https://docs.python.org/3/library/functools.html [1] https://docs.python.org/3/howto/functional.html#small-functions-and-the-lambda-expression https://docs.python.org/3/howto/functional.html#small-functi... [2] https://github.com/google/guava/wiki/FunctionalExplained https://github.com/google/guava/wiki/FunctionalExplained
- ahf8Aithaex7Nai 2y ago> Functional Programming” doesn't have a precise definition at all It may be that different people mean different things when they talk about FP. I come from the Haskell corner and from my point of view that's a completely insane claim, at least when it comes to pure FP. [ ] Are you writing a procedure that just processes its arguments into a return value? [ ] Does the procedure also operate on a non-static context? [ ] Does the procedure generate additional side effects? If you answer yes|no|no, you are programming purely functionally. The formal litmus test is the question of whether your procedure actually fulfills the definition of a mathematical function with regard to the relationship between the arguments and the return value. If it also does not generate any side effects, it is a purely functional procedure! Then you can apply the principles of mathematical composition of functions to the construction of programs. Purely functional languages force you to program this way by default and to use special constructs for everything that has to do with side effects: IO monad, algebraic effects, The Elm Architecture. How are you supposed to program like this? This is where (in addition to the concepts mentioned above) the higher-order functions that everyone knows come into play: map, fold, filter, flatMap, ... If you only know these and their use in impure languages, as if this were nothing formally thought through, but just a programming style for hipsters, then I can understand how the impression arises that there are no precise definitions here. In practice, the concepts are often very distorted or not understood at all. For many programmers, OOP mainly seems to mean that you get the drop-down list with completions in Rider when you press “.”.
- tome 2y agoI also come from the Haskell corner and I agree with roenxi. I don't think that FP is a well-defined concept, nor do I understand your characterization of pure FP. Let's take a simple program main = do v <- newIORef 0 let procedure = do n <- readIORef v print n modifyIORef v (+ 1) ... and have a look at the conditions you laid out * Are you writing a procedure that just processes its arguments into a return value? No, it has no arguments and its return value is just (), but it does more besides. * Does the procedure also operate on a non-static context? Yes, it operates v * Does the procedure generate additional side effects? Yes, it prints to the terminal. So I have answered no | yes | yes, the exact opposite of what I should have to be classed as doing pure functional programming. You might say "Ah, but the return value of `procedure` is not (), it's IO ()", but I don't see that that changes anything. I can write my entire program in IO if I want, in a way that's hard to distinguish from having written it in, say, Python. Is that not pure functional programming, despite the fact that it's being carried out in Haskell? Then you might say "Ah, but the difference is that you could have written your program purely, without IO". But again I fail to see how that differs from Python. I can write programs that don't do any IO in Python too. So what is it that makes Haskell a pure functional language and Python not? My response to all this is that the notion of "pure" is very unhelpful and the correct way to describe this property that Haskell has is "referential transparency", that is let x = rhs in ... x ... x ... has the same result as ... rhs ... rhs ... regardless of how many times (or zero) x occurs.
- mrkeen 2y agoHere's a good enough definition: "The same input yields the same output". > "functional programming is a programming paradigm where programs are constructed by applying and composing functions" This is only seems like a useless truism if you take 'function' to mean 'method' or 'procedure'. If you nail down 'function' to sameinput->sameoutput then it starts to make more sense.
- ninetyninenine 2y agoNo. You missed it the meaning. The paradigm is referring to the fact that the ENTIRE program must be constructed this way. So let's say you have this in your code: x = 1 b = x + 2 x = b + x You have composed three procedures here in order. This is illegal. You must ONLY construct the programs via composing functions there can be no other way.
- hollerith 2y agoNot so fast. This next is legal Haskell: let x = 1 b = x + 2 x = b + x in <do something with b and x> The third line creates a second binding of x which shadows the first binding, and shadowing is considered by most people to be within the functional paradigm. What is not considered functional by most people is assigning a variable in a loop although even here you can do it in Haskell. Specifically, you can call readIORef and writeIORef every loop iteration, but last time I tried, that was about 1000 times less efficient than in an imperative language.
- ninetyninenine 2y agoThe intent of my syntax is to show mutation and procedures not variable shadowing and let in.
- mrkeen 2y agoI don't think I missed anything. You presented non-functional code as an example of code which isn't functional. There's no contradiction. And good riddance, too! I'm so sick of seeing this anti-pattern at $DAYJOB: First, create a thing which isn't what you called it (e.g. 'result'), and then mutate it in place until it is what you called it.