5 ms·
I think most people miss the philosophy of FP; even practitioners of FP. A good chunk of React and Javascript developers just don't get it. They harp on about i
by crimsonalucard 7y ago
I think most people miss the philosophy of FP; even practitioners of FP. A good chunk of React and Javascript developers just don't get it. They harp on about immutability but really the statement is meaningless to them as it is essentially a buzzword.
I feel to really see the full picture you need to be able to do point free programming with a language that supports the point free style as a first class feature.
Functional programming is about function composition. If you haven't picked up on this notion, than you haven't fully understood FP.
- sfvisser 7y ago> function composition Yes! But more broadly about composition in general. Also datatype composition. Building DSLs that allow you to compose small constructs into larger ones preserving the same type so you can compose even further. Maybe even inhibiting some algebraic properties so you can reason about your compositions. About identity, reflexivity, associativity, transitivity etc. So many real world problems can be tackled this way and getting this right can make you so extraordinarily productive!
- crimsonalucard 7y ago>Yes! But more broadly about composition in general. Functional programming in general is not about data composition. There is a difference between function composition and data composition in FP. Function composition produces a new type given two separate types. In your example the type is the same. In Haskell if you wanted to do data composition, you would need something like dependent types or some rudimentary form of it. If such a thing was invented, it may look something like this: a -> b -> (a * b) where a and b can be records or "structs" and (a + b) is the composed record. This type signature preserves the notion of parametric polymorphism in function composition which looks like this: (a -> b) -> (c -> a) -> (c -> b) I'm no expert but as far as I know, in Haskell a new type must be defined manually when composing data but not when composing functions. The tuple type actually shares an isomorphism with the concepts I am describing above. However it ascribes a sort of "order" on the types and feels more like a container of two types than it does a composition of types. I will illustrate below: a -> b -> (a,b) != a -> b -> (b,a) a -> b -> (a * b) == a -> b -> (b * a) The ECS pattern among gaming focuses on the data problem you describe but largely suffers from the same issue as it is limited by the type system.
- sfvisser 7y agoIt's very easy to compose data in Haskell. data Expr = Const Int | Add Expr Expr | Mul Expr Expr myExpr = Mul (Add (Const 1 2)) 4 > There is a difference between function composition and data composition in FP. The difference is rather blurry, because data constructors are very much like functions. > Function composition produces a new type given two separate types. Yes and no. The type might look different, but it's still a function! You can change the function domain to something else (like a DB query) to better see how this is actually type-preserving in a meaningful way: Query a b -> Query c a -> Query c b Yes, the parameter types are different, but that's what makes this so powerful.
- crimsonalucard 7y ago>Yes and no. The type might look different, but it's still a function! The type is different. Functions are a class of types. The output of function composition is absolutely a different type but within the class of function types. >It's very easy to compose data in Haskell. I suggest you reread my post, I do not believe you fully understood it. You can compose data in ALL languages. >Query a b -> Query c a -> Query c b I mentioned the tuple type in my post which is essentially the same thing as what you're doing sans the constructor. In type theory these things are called "Product types." Products are commutative, but in Haskell Data composition does not hold this property. See below: (a,b) != (b,a) Query a b != Query b a while (a * b) == (b * a) I am saying there is limited power in Data composition in Haskell, it is not as "complete" as function composition. It also brings nothing new to the table as the data compositional patterns are used outside of FP extensively.
- sfvisser 7y ago> The type is different. Functions are a class of types. The output of function composition is absolutely a different type but within the class of function types. I know how types and type constructors work, it's completely irrelevant in the context of what I was trying to say about composition in FP. It seems to me you're probably talking about a very specific technical form of composition. I'm not. To me a simple function like `vertically :: [Ui] -> Ui` is also about composition. The input and output types of the `vertically` function are not the same no, but informally we're still composing UIs into UIs. Which is exactly the level of detail I care for in this discussion.
- hopia 7y ago> Functional programming is about function composition. If you haven't picked up on this notion, than you haven't fully understood FP. Maybe that's exactly why the likes of Elixir feel so much less functional than some other FP langs. You don't usually compose functions, merely use function application (|>).
- gmfawcett 7y agoI think you've touched on an important point here, namely that functional programming is a feeling. We know it when we see it! But it's hard to get any two people -- even two domain experts -- to agree upon a common definition. To me, functional programming is the feeling that you can successfully reason about a local fragment of code, because you know what the code (and its callers, and callees) can and cannot do with the data being passed around. It's functional in the mathematical sense -- i.e., the output is a pure function of the input, no matter how convoluted the definition -- and knowing this helps us to reason more clearly, mainly because we don't have to worry about unseen effects at a distance. So, functional programming is a feeling of confidence achieved by making data transformations as local and as pure as possible.
- crimsonalucard 7y agoTry to not just stick to feelings. Feelings often indicate a lack of understanding. The ultimate goal is to coalesce that feeling into total understanding. The definition of FP is fuzzy and it feels like a "feeling." However, as humans we can formally define the word with an exact definition that fits the "feeling." We've already done it with mathematics and it improved our understanding by a huge margin.
- gmfawcett 7y agoI agree in general that fuzziness isn't desirable. :) But the lack of a proper and widely accepted definition of FP is a perennial issue, and I don't see a resolution in sight. It's not a lack of clear understanding in my opinion, but rather a lack of consensus, and I'm not confident that FP will ever coalesce into a singular definition. What I see in practice is that we have various tribes, using various FP languages, who each define FP in terms of the languages they use (e.g., an FP lang must have certain type-system features, or be non-strict, or etc.). To put it crudely, FP is the thing that we do in our language, and which we perceive others as not doing. I've used the term "tribe" intentionally, as I do think that tribal thinking has had a role to play in the muddying of the term. Given this, I think it's reasonable to demote FP to the level of "feeling", at least in general conversation. Discussions within a certain language community, or in the context of a book or article, are a different matter of course since a formal, contextual definition can be given there.
- throwaway17_17 7y agoFirst, I happen to strongly agree with your point-of-view/philosophical stance that composition is the essential nature of ‘functional programming’. However, and it is a big one, a vast majority (including the leading researchers and academic authorities in the area) are hopelessly and willingly tied to applicative programming as not only the default paradigm, but as they see it, the only paradigm. I am quite aware Backus was talking about compositional programming in his Turing Award speech, and his work backs that position up, and as I stated, I think that is the proper ground level for functional programming, but most programmers do not agree. The wide-spread and well understood meaning of functional programming is programming in an expression oriented way, with immutability of data and lack of side-effects being the tent pole rules, laziness/eagerness of evaluation becomes the pivot point between most languages, with the divergence between compositional and applicative languages being almost completely absent. With all the conflation and mass propagation of the term functional, I have to agree with Conan Elliott and recommend a more rigorous approach to terminology, I don’t whether is adopt his usage of denotational in place of functional, but some clarity in the semantic space would be a good idea. — Edited to fix autocorrected errors.
- crimsonalucard 7y agoReally? Category theory (when applied to FP) is basically the theory of function composition. I would think this point of view is huge in academia due to the prevalence of CT among academia and FP. >with the divergence between compositional and applicative languages being almost completely absent. Most FP languages have facilities to do both anyway. And the isomorphisms between the two concepts are small in distance so it doesn't matter too much if you use applicative over compositional. So really when I say you should do "point-free" to see the big picture I'm advocating that more for educational purposes rather than practical (though I'm not opposed to practical). That being said you and I are pretty much in agreement, I was just unaware of the whole academic thing.
- throwaway17_17 7y agoWith regard to the prevalent academic opinions, I was really referring to the nature of programming language syntax and semantics. I would say that Category Theory is essentially about function composition, but that then gets filtered down into so-called applicative languages. This designation is based heavily on the lambda calculus, in which application of terms to other terms is the prime mover for computation. Backus certainly wasn't talking about lambda calculus based semantics for FP, he was focused on strict compositional semantics with only non-named pipelined data being fed to compositional units. Most language researchers and writers just assume that any programming language uses function application as the basic unit of computation and so the language is naturally built in layers on this basic unit. So, 'point-free' programming in a language like Haskell is typically just considered good programming style, it is still used in a primarily applicative way. I'm not quite a no-application purist, but I really do see the algebraic beauty in avoiding named variables and skipping application as anything other than a definable operator to work on other higher-order functions. Just for reference, if you want to see the divergence between applicative (which is basically every modern language in production or in research) and compositional look at some of Manfred von Thun's papers he wrote about the Joy Programming Language. Some people strongly disagree with his stance, but I find him easy to read in any event, see the link below. Also, in several places linked from [0], Thun discusses the Categorical Abstract Machine and has a few references which served as a nice jumping off point for more reading. [1] http://joy-lang.org/papers-on-joy/joy-compared-with-other-functional-languages http://joy-lang.org/papers-on-joy/joy-compared-with-other-fu...
- zodiac 7y agoDo you have a rationale for drawing the line there? Why don't we go further and claim that (say) FP is also about laziness, if your language does not support first class laziness it's not functional. Or first class continuations, etc
- crimsonalucard 7y agoIsn't programming about using abstraction to simplify complexity? You take two primitives and compose those primitives to form a simpler abstraction. This is the whole point of programming languages, otherwise we'd just use assembly as in the end it's all isomorphic anyway. The question of how to Design things or how to abstract things in programming is thus in essence a discussion about different ways of composing things (aka different ways of abstracting things). It is the drive behind all the arguments behind different programming styles, different programming languages and different system designs. The way you compose primitives in functional programming is through function composition. The debate between functional programming and procedural programming and OOP from a "design" perspective is thus the debate between which primitive composes better: The function or the procedure or the object? It's a question of Design and at the heart of it lies composition. I think most people who love functional programming know on some level that the "design" of functional programs "feels" better. Most of them have never thought about "why" this is the case. They have never tried to answer the question of what is the true nature "design" from a programming language perspective. What is this vague thing we are optimizing for? We are constantly inventing new programming languages/patterns in attempt to answer the question and instead much of the time we move in a flat circle and come back to where we were before (see golang). I believe FP moves the ball forward in terms of design. The thing is, most people can't see why. They rely on inexact feelings, and a lot of the times they even feel the opposite. I've heard people talk about FP is just a fad similar to design patterns and OOP. Without the ability to develop an exact concrete answer why one "design" is better than the other, we will always move in circles even when we discover a "design" that is actually better. If you want an exact, concrete answer to the question of "design" the answer lies in the mechanics of composition.
- zodiac 7y ago
- gmfawcett 7y agoSurely it's about functional application as much as it's about functional composition. E.g. currying, one of the signature idioms of functional programming, doesn't involve composition at all, but is more closely related to partial application. I'm a bit skeptical of the premise that either composition or application is a high enough bar. Consider stack-based/concatenative languages such as Forth. Composition and application are foundational aspects of that language, but nobody really considers Forth to be functional. On the other hand, the concatenative language called Joy is considered functional -- by its authors at the very least -- but it also introduces purity to the mix.
- crimsonalucard 7y agoOf course it's about function application. All of programming is about transforming data. This is obvious. Some procedure must be applied to some data to transform it. There is no programming paradigm or language that avoids this and therefore it is not worth discussing. I bring up composition because this it is the most important differentiator between FP and all paradigms. I wrote about it another reply: https://news.ycombinator.com/item?id=22292105 https://news.ycombinator.com/item?id=22292105
- deleted 7y ago[deleted]
- gowld 7y agoYou ignore C++ template metaprogramming, that performs computation without applyit any functions :-)
- asdfsdgdshsdgh 7y agoImmutability may be a buzzword, but if you stick with immutable data, that does give you functional programming. The possible exception to this is that you could have certain kinds of real-world side effects in a language which only had immutable data. FP used to mean just "no side effects". (Barbara Liskov mentions this old understanding of FP here: https://www.youtube.com/watch?v=qAKrMdUycb8 https://www.youtube.com/watch?v=qAKrMdUycb8). That is a desideratum for the even bigger buzz-phrases "referential transparency" and "equational reasoning", which are the goals of the FP research programme and have yet to really materialize. As a counterpoint to your claim that understanding point-free style is a fundamental part of understanding functional programming, how about this 1998 paper by Andrew Appel, "SSA is Functional Programming" http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.3282 http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.3... which locates the essence of functional programming in the fact of immutable data (equivalent to imperative Single Static Assignment code).
- crimsonalucard 7y agoYou're not wrong. By simply making data immutable and just using function application you achieve something that's not too far off from function composition. I mostly advocate point free style for educational purposes and I believe in the end it doesn't matter too much whether you use one style or the other. I talk about the isomorphism briefly here: https://news.ycombinator.com/item?id=22299297 https://news.ycombinator.com/item?id=22299297 As to why I advocate the point free style for educational purposes and why I believe immutability is just buzz that hinders true understanding of why function composition is fundamental to FP I get into that here: https://news.ycombinator.com/item?id=22292105 https://news.ycombinator.com/item?id=22292105
- yodsanklai 7y ago> Functional programming is about function composition It sounds unnecessarily abstract. Isn't functional programming simply avoiding side effects? It forces you to use immutable datatype and write "pure" functions.
- crimsonalucard 7y agoI believe that function composition is the heart of the matter. Side effects and immutability are just the consequences of trying to create a primitive that can be used under function composition. In another post I illustrate exactly why I believe that it IS NOT necessarily abstract and in fact fundamental to FP: https://news.ycombinator.com/item?id=22292105 https://news.ycombinator.com/item?id=22292105
- yodsanklai 7y ago> Side effects and immutability are just the consequences of trying to create a primitive that can be used under function composition I think I see what you mean, but it sounds like you see function composition as the end, where I see it as a mean. To me, being side-effect free is the end because it helps me doing local reasoning which ultimately makes programs easier to reason about. That being said, I understand it may be easier to characterize formally FP using function composition.