27 ms·
Functional programming is not popular because it is weird (2016)
- markus_zhang 5y agoIt's probably just me, but I found loops much more intuitive than recursions for those non-recursion oriented problems. That is to say that I prefer to use recursion ONLY for those are un-intuitive to solve by loops in a trivial way.
- chongli 5y agoGenerally when you learn recursion you also learn about higher order functions. Most of the use cases of loops get replaced with map/filter/fold. What’s left are typically those “unintuitive” problems that need recursion, such as when you’re dealing with trees.
- tester756 5y ago>What’s left are typically those “unintuitive” problems that need recursion, such as when you’re dealing with trees. I always prefer to walk thru trees with e.g stack/queue because it's easier to reason about / debug it for me
- deleted 5y ago[deleted]
- garethrowlands 5y agoTrue enough but worth noting that a good tree should also have map/filter/fold-like operations.
- whateveracct 5y agoI think recursion and loops are hard to read. I rarely even use either anymore.
- jltsiren 5y agoLoops are intuitive and easy to understand, because they are concrete. They can also be cluttered and hard to read due to all the required bookkeeping. For simple loops, I prefer something like map/filter/fold when appropriate. I try to avoid chaining them, because that often turns the code impossible to understand and makes me feel stupid. If the loop can't be modeled naturally as a higher-order function, an iterator-based loop is easier to read than an index-based loop, which is better than tail recursion. With complex loops, there is no way around concrete loops with comments describing the invariants and what each part of the iteration does. Many problems can be modeled naturally with recursion. Such problems are particularly common with graphs. However, you should never use explicit language-level recursion unless you can guarantee that recursion depth will be small. It's easy to get a stack overflow, so recursion should usually mean a loop with an explicit stack of states.
- toast0 5y agoLoops are nice, but after having written enough Erlang, you get used to using foldl and map when they make sense, and recursing yourself when you need to. I can imagine starting with Erlang and learning about loops later and being weirded out. I've grown to sometimes enjoy how a recursive loop looks in code. Sometimes you put the end case first, sometimes you put the end case last, depending on which makes most sense while writing (or perhaps while editing while reading later). With languages with loops and no pattern matching, I'll always write a loop as a loop, if I used one with both, I dunno, there's probably a few loops I'd do as recursion and most would be loops. OTOH, Erlang is certainly functional, but it's very pragmatic as well, there's not a mention of monads, and one tends not to do a whole lot of weird stuff with closures (although you can). Sure, there's a good number of functions that take functions as arguements (which you can do in C anyway), and there are anonymous functions, but you get better error reporting if you use functions with names, so at least I tend to name anything with more than a few lines. I also tend to have very short functions, but that is somewhat influenced by stack traces only having function names and not line numbers when I started 10 years ago.
- Zababa 5y agoRecursion is great for recursive structures, like trees. When you say "a binary tree is either a leaf, or a node which is a value and two binary trees", it's really easy to imagine how you will use a recursive function on it.
- mamcx 5y agoI like functional code, except that because the use of lambdas is awkward to "escape" them: nums.iter().map(|x| if x > 10 break(?)) This little thing is the major problem of functional chains (this is only a toy version of the issue). Because lambdas are inside the scope is hard to make them truly part of the current execution flow. So, sometimes I change a chain of iterators to simpler loops for things like this. IF iterators where part of current scope, it will look far more natural, IMHO...
- HKH2 5y agonums.iter().take_while(|x| x <= 10)
- mamcx 5y agoYeah, I'm aware of the other options, just pointing that the use of lambdas break the flow.
- emi2k01 5y agoRust just standardized `ControlFlow` which would let you pass equivalents of `break` and `continue` as values. x.try_for_each(|y| {...; ControlFlow::Break} )
- mamcx 5y agoYeah, that is cool, and also show the problem :). Internal iterators and/or lambdas are at odds with imperative code. Some guy also yesterday ponder about this stuff: https://www.reddit.com/r/ProgrammingLanguages/comments/pno38l/what_would_a_principled_imperative_language_look/ https://www.reddit.com/r/ProgrammingLanguages/comments/pno38...
- sullyj3 5y agoHaving written Haskell for a few years, the concepts are kind of interchangeable in my mind. I think of recursion as being basically a loop, and a loop as basically the same thing as recursion. To the point where it seems natural to me to name a recursive helper function `loop`. Obviously they're not exactly the same, but with familiarity they can be translated trivially. I think it's really just a matter of prolonged exposure to make recursion seem intuitive.
- alanbernstein 5y agoFunctional Programming Is Not-Popular Because It-Is-Weird, not Functional Programming Is Not Popular-Because-It-Is-Weird. I just found the ambiguity amusing, in the title of this particular blog post.
- jjoonathan 5y agoNeeds more parentheses.
- Y_Y 5y agoNo, combinators.
- gweinberg 5y agoYeah, I thought the author might mean "some of you may be under the impression that the primary appeal of functional programming is it's weirdness. However, that is not the case." The easiest and clearest way to resolve it would be to say "unpopular" rather than "not popular", although arguably they don't mean exactly the same thing.
- evnix 5y agocan someone explain me the ambiguity, I don't get it
- jstx1 5y agoTwo ways to interpret it 1. FP isn't popular; this is because it's weird. 2. FP is popular; this isn't due to its weirdness, it's for some other reason.
- hasmanean 5y agoThe English language is popular-yet-weird. I find it’s not the most straightforward langauge for expressing precise thoughts and logic… “ The Dog Walking Ordinance * The following transcript of a Borough Council meeting in England illustrates the difficulties of expressing a simple idea in precise and unambiguous language. From the Minutes of a Borough Council Meeting: Councillor Trafford took exception to the proposed notice at the entrance of South Park: "No dogs must be brought to this Park except on a lead." He pointed out that this order would not prevent an owner from releasing his pets, or pet, from a lead when once safely inside the Park. The Chairman (Colonel Vine): What alternative wording would you propose, Councillor? Councillor Trafford: "Dogs are not allowed in this Park without leads." Councillor Hogg: Mr. Chairman, I object. The order should be addressed to the owners, not to the dogs. Councillor Trafford: That is a nice point. Very well then: "Owners of dogs are not allowed in this Park unless they keep them on leads." Councillor Hogg: Mr. Chairman, I object. Strictly speaking, this would prevent me as a dog-owner from leaving my dog in the back-garden at home and walking with Mrs. Hogg across the Park. Councillor Trafford: Mr. Chairman, I suggest that our legalistic friend be asked to redraft the notice himself. Councillor Hogg: Mr. Chairman, since Councillor Trafford finds it so difficult to improve on my original wording, I accept. "Nobody without his dog on a lead is allowed in this Park." Councillor Trafford: Mr. Chairman, I object. Strictly speaking, this notice would prevent me, as a citizen, who owns no dog, from walking in the Park without first acquiring one. Councillor Hogg (with some warmth): Very simply, then: "Dogs must be led in this Park." Councillor Trafford: Mr. Chairman, I object: this reads as if it were a general injunction to the Borough to lead their dogs into the Park. Councillor Hogg interposed a remark for which he was called to order; upon his withdrawing it, it was directed to be expunged from the Minutes. The Chairman: Councillor Trafford, Councillor Hogg has had three tries; you have had only two . . . . Councillor Trafford: "All dogs must be kept on leads in this Park." The Chairman: I see Councillor Hogg rising quite rightly to raise another objection. May I anticipate him with another amendment: "All dogs in this Park must be kept on the lead." This draft was put to the vote and carried unanimously, with two abstentions. ”
- brundolf 5y agoSomething I've wondered is why we can't have a language that looks totally procedural but uses monads under the hood to reason about state at any given point in the process. This would mostly be sugar, but I think it could make that stuff much more accessible. We get small, specialized fragments of this in Rust's borrow-checker and TypeScript's control-flow analysis, but I'm not aware of something that tries to take the whole of IO-monads and reshape them into a familiar format.
- zozbot234 5y agoRust's borrow checker (or rather its affine typing, which the borrow checker partly implements - "affine" rather than linear, b/c the compiler is free to drop() objects that are no longer used) actually gets in the way of using monads to reason about state. That's one key reason why the language still lacks a general monad construct.
- Y_Y 5y agoWhat about Haskell? do putStr "What is your first name? " first <- getLine putStr "And your last name? " last <- getLine let full = first ++ " " ++ last putStrLn ("Pleased to meet you, " ++ full ++ "!") (see: https://en.m.wikibooks.org/wiki/Haskell/do_notation https://en.m.wikibooks.org/wiki/Haskell/do_notation )
- amusedcyclist 5y agoGets a bit uglier if you use >>= instead lol
- zeugmasyllepsis 5y agoThis might work out well in practice when tracking a single effect with a monad (e.g. with Haskell's `do` notation) but I think it quickly falls apart when working with multiple effects. Monads don't have a general form of composition - at the very least the order that they're composed matters to the outcome of the program. Procedural code is generally flexible enough to allow you to mix-and-match how effects gets handled, which I think would be difficult and impractical to work out in monadic contexts.
- 6gvONxR4sf7o 5y agoSome of the weirdness is so completely avoidable that it frustrates me, but languages and libraries dig in on ‘you get used to it.’ I’m talking about the f(g(h(x))) vs x | h | g | f. Right to left chains of functions seem more popular than chains of pipes in FP, but even being someone who has drunk the kool-aid deeply, I always prefer pipes. ‘Take the pan out of the over once it’s been in for 30min, where the pan contains a folded together eggs and previously mixed flour and sugar’ isn’t more FP than ‘Mix the flour with the sugar, then combine with eggs, then fold together, then put it into the oven, then take out after 30min.’ But people new to it so often think it’s an FP thing for no good reason. It’s a new user issue that ought to be totally fixable as a community. FP has enough great ideas that I’d recommend everyone learn pure functional solutions just to put into their tool belt, but it’s absolutely true that getting up to speed is harder than it needs to be. My hot take: it won’t be really mainstream until someone figures out how to make dependent types really ergonomic, which seems a long way away.
- davidatbu 5y agoI'm relatively an FP newbie, and I have a few questions. 1. I've never seen the "pipe" notation you talk about in any lang except bash, which is not an FP right? In which languages does "|" denote function application? 2. Aren't dependent types orthogonal to whether a language is functional? Just to make sure we're on the same page on what dependent types mean, I wanna give a example (a contrived one, sorry) of dependent types in Python. from typing import overload, Literal @overload def str_if_zero(num: Literal[0]) -> str: ... @overload def str_if_zero(num: int) -> int: ... @overload def str_if_zero(num: int) -> int | str: if num == 0: return "That's a zero" return num
- lostcolony 5y agoElixir, Elm, Ocaml, Haskell, and F# all have a pipe like operator for function composition (though the actual operator varies).
- madcaptenor 5y ago
- jmfldn 5y agoFunctional programmer here. It's a different way of thinking is all, I don't see it as solving puzzles exactly. It's unfortunate if people see it as being about complexity or being clever. Done well, it should be the opposite. Once you understand the key abstractions, it can make code a lot easier to write and reason about in some cases. That's the joy of it for me. It furthers my day to day software engineering concerns of readability, maintability, testability etc. Nothing more. It's just another tool though and there are many places where it's not appropriate. It's also a personal taste thing, I get that. It's worth persisting with it on a deeper level though just for the sheer joy of those 'a-ha' moments that come. Even if you don't use it in your day job, just bending your brain with different programming paradigms is well worth it.
- mdoms 5y agoI feel like your first and second paragraphs are directly at odds. It's not about "solving puzzles" and you decry cleverness and complexity, but you also think we should persist for joyous "a-ha" moments and brain-bending?
- jmfldn 5y agoHa, yes OK that sounds a bit contradictory so let me clarify. Firstly learning ANY new paradigm is inherently brain bending. By definition right? If you didn't know logic programming or oop you'd have to bend that brain. Secondly, using FP day-to-day doesn't require any deep insight. You can use various tools, monads and whatnot, and not think too hard about it. However, when you really grok the paradigm you will get those a ha moments. The same is true of other paradigms too, but there is a particular satisfaction that comes with deep understanding in this domain that I can't explain. It's kind of beautiful to a certain mind I guess...
- zz865 5y ago> However, when you really grok the paradigm you will get those a ha moments. The same is true of other paradigms too, but there is a particular satisfaction that comes with deep understanding in this domain that I can't explain. It's kind of beautiful to a certain mind I guess... Right but you understand that 90% of developers can't bend their brain that way so does make maintaining functional code very difficult.
- ryanmarsh 5y agoI've seen a handful of articles and conference talks where the main thrust is "why isn't functional programming more popular". Apparently it works well and is "intuitive" for some people. I think the first thing we should do is recognize the amount of neurodivergence amongst programmers. The WISV-IV GAI tests for verbal comprehension and perceptual reasoning. It provides an estimate of general intellectual ability, with less emphasis on working memory and processing speed. My GAI is 124. Which means I'm fairly intelligent (sic. "superior") when it comes to understanding language and reasoning. It makes me a fairly good problem solver. I'm an ok programmer (judged against the hundreds of programmers I've paired with through my consulting work). That said, I've tried to learn Haskell three times and given up each time. The functional model of D3js kicks my ass. I cannot grok LISP. It turns out my WMI (working memory index from Wechsler Adult Intelligence Scale) is BELOW AVERAGE. This makes holding lots of recursion or abstraction in my head at once quite difficult. I also suffer from adult ADHD. I love long functions in a procedural style. I'm quite proficient working that way. There's not too much abstraction and behavior hiding (why I grew to hate OO). You can see how my neurological makeup impacts what "good" code looks like. I also understand that James Gosling has a kind of synesthesia and that impacts the structure of his code to the point of causing problems for others (see Lex Friedman interview). I said all that to say this. What makes code understandable/readable/clean is in the eye of the beholder. There's quite a bit of neurodivergence in our field and we need to account for that when deciding on how to critique code. After all shouldn't code be written first and foremost for humans to understand and only incidentally for compilers? (paraphrased from SICP)
- jmfldn 5y ago"Apparently it works well and is "intuitive" for some people. I think the first thing we should do is recognize the amount of neurodivergence amongst programmers." Yep that's it! It suits my brain quite well but I totally get that it doesn't suit everyone's. This sort of point is under-appreciated, not just with FP, but with so many things in computing and life more generally.
- matthoiland 5y agoThank you for bringing up WISV-IV – it's a fascinating way to categorize intelligence. My son (11yo) is autism spectrum and recently received a WISV-IV evaluation and found him off the charts for spacial reasoning. It immediately had me thinking about object oriented programming and conceptualizing digital processes spatially. Perhaps functional patterns are preferred by those with faster "processing speed" of thought or "working memory" – basically thinking primarily of "just before" and "just after". My anecdotal experience has shown that the coworkers who think "the fastest" prefer functional patterns, whereas those who think slower but more comprehensively prefer object oriented. Also anecdotally, functional programmers rarely leave the keyboard, whereas OOP spend a lot of time on the mouse – both are equally productive at the end of the day.
- armchairhacker 5y agoFully functional programming (e.g. Haskell) isn't popular because it isn't ideal and computers work imperatively. Even in a "functional" task (e.g. compiling) sometimes you just want an imperative algorithm. And while Haskell allows this via state monads, they're clunky. Meanwhile there's practically no tradeoff to writing functional code in an imperative language. In fact there's lots of functional code in most C++/Java/Python programs. Most "imperative" languages are actually hybrid functional and imperative, supporting "functional" constructs like lambdas and pattern matching. 99% of the time a functional program will get executed sequential and strict anyways. The other 1% of the time, in an imperative language you can explicitly encode functionality (e.g. generic stream operators which work concurrently and on lazy streams).
- cheeze 5y agoFunctional programming absolutely has its use cases, and I love a bit of functional style thrown into imperative language one hundred percent. That being said, I often end up arguing with 'pure functional programmers' at work - they can be incredibly hard to work with and married to the idea that _everything needs to be functional_ because its their preference, even though your average college student is going to be able to pick up and iterate on code that just uses a damn for loop or whatnot. I _like_ functional, I find it incredibly useful, but like everything else, its just a tool to solve a problem and there are tradeoffs. But some of the most annoying and must-do-things-academically-because-look-how-cool-monads-are this-is-the-only-proper-way people are very vocal about functional, which is a pretty big turnoff IMO. Haskell is a good example. There are totally cases where Haskell will make your life easier. But if you're trying to reinvent the wheel and redefine our architecture by injecting haskell everywhere you can because _you like it_, that drives me absolutely bonkers.
- jimmaswell 5y agoWhat are the use cases you've seen functional programming in real business?
- pharmakom 5y ago
- myWindoonn 5y agoAh, to be reminded of high school, where one could be not popular simply because they are weird. I think that they've confused functional and declarative?
- davidatbu 5y agoI'm curious, what is the difference between a declarative programming language and a functional one?
- gopiandcode 5y agoDeclarative languages are characterised by having the programmer specify _what they want_ but not _how to get it_ (i.e to get a sorted list, you would specify that the elements are in increasing order, but not the specific algorithm to use). In contrast, functional languages are characterised by treating functions as first class values (amongst other things, but these are harder to summarise). Prolog for example is a declarative language, Haskell is a functional language.
- davidatbu 5y agoSomeone can correct me on this, but I've never seen this distinction you're making anywhere else. And, it doesn't make sense to me either. The wikipedia page[0] for FP says that FP is a "declarative programming paradigm". Can you give me an examplel of a "functional" piece of code that is "not declarative"? [0] https://en.wikipedia.org/wiki/Functional_programming https://en.wikipedia.org/wiki/Functional_programming
- Jensson 5y agoProlog is a declarative language but not a functional language. Hence functional languages and declarative languages are not equivalent. Functional languages are not just defined by lacking side effects but also by using functions as first class citizens, meaning that SQL isn't a functional language either.
- pkilgore 5y agoI wonder now much C++ matters here. I rarely reach for functional patterns when the language I'm using does not provide proper constructs for readable, declarative code like pattern matching, nominative discriminated unions, and pipe operators. Sure, you can fake all that with other constructs or patterns. But then it really does feel more like a puzzle. IMO, good FP is good when it is maximally declarative and organized in the linear way in which humans reason best. Maybe the author should try F# or OCaml instead of Haskell! I love FP and have also tried and hated Haskell three or four times.
- maxbendick 5y agoSubversion: Functional programming is popular because it's intuitive! Perhaps "immanent" or "diagrammatic" is a better word than functional. I mean that a function _is_ what it does, but not so with a procedure. One cannot bake a value as one does a cake! See React's dominance. See the usefulness of declarative state machines. See async/await. Functional programming gets a bad rep. People often fail to see the functional elements in more imperative code and the imperative elements of more functional code. In fact very few language constructs are necessary to open up 99% of functional possibilities in imperative languages (functions as values) or imperative possibilities in functional code (do-notation). Any critique that dismisses one or the other misses the point. May add more explanation later.
- pharmakom 5y agoYes indeed! How many times have you heard these two statements from the same individual? “I don’t need all those functional features” “I don’t need a functional language because X has taken all the important functional features from language Y”
- TeMPOraL 5y ago> Functional programming is popular because it's intuitive! I mean that a function _is_ what it does, but not so with a procedure. One cannot bake a value as one does a cake! I suppose it really depends on what you've learned first. Myself, I started programming (C++) in my early teens, a bit before I was introduced to the concept of a function in math classes. I didn't have much problems with that part of math, but I knew something doesn't feel right about it. Only many years later I realized that I never fully internalized the concept of mathematical function being a relationship and not a procedure. And I had the same issue with "=" symbol. After being exposed to the concept of assigning values to variables in imperative programming, it took me years before my brain fully internalized the concept of equivalence relationship.
- hasmanean 5y agoMaybe the problem is that we evaluate functional programming as a way to write programs, but it’s real potential is that it gives us more ways to rewrite programs. That’s more useful long-term.
- yewenjie 5y agoThis talk by Richard Feldman is an excellent discussion about why Functional Programming is not the norm - https://www.youtube.com/watch?v=QyJZzq0v7Z4 https://www.youtube.com/watch?v=QyJZzq0v7Z4
- ur-whale 5y agoPeople always underestimate how much the aesthetics of things actually matter. Language adoption is a numbers game and good marketing matters. This is why Lisp never won. However powerful and elegant it may be, Lisp syntax is downright ugly. The exact same thing happens with Haskell. However amazing the language is, its freaking unapproachable and the syntax is - like the OP says, weird.
- Zababa 5y agoIt's impressive to have people say that Lisp is "downright ugly" and Haskell is "freaking unapproachable and the syntax is weird" on an article that includes C++ templates. It's not the "aesthetics" that matters, it's the popularity and what you're used to. Part of the reason why Rust is popular is that they didn't break too much people's habit, and even with that it constantly gets flak for its syntax.
- wudangmonk 5y agoI didn't want to comment about looks because it wouldn't add anything to the discussion but since we are talking about looks I just can't get over how ugly c++ templates are. I will even admit that the only reason I never gave Rust a chance was because it reminded me too much of this type of angle bracket monstrosity.
- math-dev 5y agoI find functional programming reasonably straightforward to learn but difficult to master. For example, this Common Lisp cheat sheets covers a large part of the language and isnt hard to follow https://github.com/ashok-khanna/lisp-notes https://github.com/ashok-khanna/lisp-notes I was doing some Haskell and Racket and I found basics not too hard to learn, but I did then too hard to master, but I think thats to do more with the complexities of the problems I tried to solve and less to do with the languages themselves
- phoe-krk 5y agoCL isn't a functional language though. It's 100% multiparadigm. The lisp-notes page that you linked shows this.
- math-dev 5y agoAh sorry, I always thought of it as a functional first language
- garethrowlands 5y agoIt's totally functional first. And it's multi-paradigm.
- ur-whale 5y agoI'm happy the author wrote this blog post, it very much reflects my take on FP. And if I had to keep one sentence from it: mutable states are very useful. FP addicts consider mutable states to be something to be banished at all cost, much like a generation of 70's academics tried to do away with goto's. The fact is, there are lots of situations in the real world where using mutable state variable is the very best way to model the problem: - easier to understand - faster to execute The same holds for goto's btw.
- scns 5y agoI like SPJs' explanation why Haskell is useless: https://www.youtube.com/watch?v=iSmkqocn0oQ https://www.youtube.com/watch?v=iSmkqocn0oQ Disclaimer: tongue in cheek
- Zababa 5y agoI think the big difficulty in trying to bake the functional cake is that the author tried to name every step, when he didn't do this for the imperative cake.
- AtlasBarfed 5y agoI am not a huge functional programmer, but the big weapon in FP's wheelhouse is that pure side-effect FP is far more suited to multicore/threading/processing, which is where all the future gains in processing will probably come from.
- 50firstthreads 5y agoDownvoted for knowing what you're talking about.
- 50firstthreads 5y agoClickbait garbage.
- dang 5y agoDiscussed at the time: Functional Programming Is Not Popular Because It Is Weird - https://news.ycombinator.com/item?id=11188570 https://news.ycombinator.com/item?id=11188570 - Feb 2016 (75 comments)
- wly_cdgr 5y agoFunctional programming isn't popular because the talent pool for experts in languages like Haskell is * tiny * composed largely of insufferable snobs who will insist on reminding you that they're smarter than you and understand computing on a deeper level Whereas the talent pool for jalopy languages like Javascript and Python is full of easygoing can do barbarian hustlers who will do everything wrong but make your prototype work well enough for you to get the next round of funding. And if you really need heavy duty people who are still pragmatic, there's always the large and deep C++ talent pool
- z5h 5y agoPure Functional programming’s cost comes up front when you are trying to solve and express your solution. Imperative programming’s cost comes after you have written code, because it is inevitably buggy and incorrect. Imperative programmers and managers don’t mind because fixing bugs feels and looks like productive work, and they don’t believe bugs are largely avoidable.
- eli_gottlieb 5y agoI think the actual problem is that a lot of the functional programming discipline is about writing code to be understood by machines (eg: compilers, theorem provers, etc) in ways that can trade off against the convenience of people reading and writing it. When I have to write a program that computes functions of programs, I always reach for my FP knowledge, first thing, and start using the more "theoretical" branches quite quickly. But program analysis and synthesis are different actual endeavors from writing some bog-standard, everyday code.
- csneeky 5y agoFact: functional programming takes more time to learn. It's not full of people that are "smarter' or "snobs" it's just full of people that have taken the time and invested in educating themselves to get to the point where they can do it well. It's not "better", it's just a useful tool for certain types of problems. I'd advise any young engineer to just learn how to do both "imperative" and "functional" programming well and avoid getting dogmatic about it. The vitriol here is in dogma here to be sure
- raspasov 5y ago“Fact: functional programming takes more time to learn” Is there evidence/studies about this?
- fiddlerwoaroof 5y agoI haven’t tracked this down, but I believe the authors of How to Design Programs did some research and basically found that whether FP or OOP is harder depends on which you learned first.
- carlmr 5y agoWhich kind of makes sense, but then again I learned OOP in college, I always found it really hard to remember all those design patterns they made us learn. Years going on in programming I never really saw any big advantage of OOP hierarchies and spreading one function into 15 different files (yay for the person debugging this). Then I found out what we call OOP is just a misunderstanding. Erlang kind of did "proper" OOP and that makes sense. Then I got to functional programming through F# (and Scott Wlaschin's amazing page F# fsharpforfunandprofit.com), and it just immediately clicked. Maybe because Scott's material is so good. But also because there's not so much non-sense boilerplate and extra complexity as you see in every "good" OOP example.
- pbourke 5y agoScott also wrote “Domain Modeling Made Functional”[0], which demonstrates functional modeling of a business system like you’d find in the real world. I found it really helpful even though I don’t work much in F#. [0] https://pragprog.com/titles/swdddf/domain-modeling-made-functional/ https://pragprog.com/titles/swdddf/domain-modeling-made-func...
- js8 5y agoHm, what about a language like Joy or Factor? It is written sequentially, as a recipe, and (in the case of Factor) can have side effects. And yet it is deeply functional, because of the compositionality of words. I really like Haskell, but I think Factor is going to be my next thing (although it needs better type system, like Kitten has attempted to), for the reason that it further simplifies Haskell's (already simple) syntax.
- deleted 5y ago[deleted]
- rg111 5y agoI recently watched this talk- Why Isn't Functional Programming the Norm? (https://youtu.be/QyJZzq0v7Z4 https://youtu.be/QyJZzq0v7Z4) Here's the HN thread- https://news.ycombinator.com/item?id=21280429 https://news.ycombinator.com/item?id=21280429 I learned in that talk, among other things that Oracle spent $500 million to promote and market Java. - https://www.theregister.com/2003/06/09/sun_preps_500m_java_brand/ https://www.theregister.com/2003/06/09/sun_preps_500m_java_b... - https://www.wsj.com/articles/SB105510454649518400 https://www.wsj.com/articles/SB105510454649518400 - https://www.techspot.com/community/topics/sun-preps-500m-java-brand-push.5852/ https://www.techspot.com/community/topics/sun-preps-500m-jav...
- shaklee3 5y agoC++ and C have spent $0 on marketing and are more popular, so I don't think this is a good indicator of success.
- bmitc 5y agoIt really isn't. Just see Racket, Clojure, Elixir, and F# for practical functional programming languages. This article is pretty terrible. There isn't even a functional implementation, with just a half hearted attempt to even understand how to do it. Functional languages excel at state machines. The example is pretty terrible too with regards to imperative programming being a good fit, because literally no one enjoys the real life statefulness and mutation when cooking. If you mess up, there's no going back. Why would you want to embrace or repeat that feature in your implementation? Functional state machines just pass explicit state around instead of mutating some random collection of variables. And god, those C++ examples make me nauseous.
- TuringTest 5y agoConcur about the C++ examples, but that's not just on the language. The author seems to be averse to whitespace to separate one chunk of code from the next.
- keithnz 5y agoI often wonder, if LOGO, which was inspired by Lisp became more popular than BASIC whether functional programming would have become popular earlier. Many Gen X kids like me were exposed to both, but basic was more broadly avaialbe and often was the OS of your computer, But LOGO was really good for its time and it made it simple to structure your program around functions and build upon functions in a semi lispy/schemey way. It instantly change the way I thought about programming and often attempted to replicate that method of programming in basic.
- ABeeSea 5y agoI don’t think so. Most programming is CRUD which is by its very nature impure. Trying to make it pure just adds a lot of overhead and baggage. I do think the stateless paradigm that serverless cloud has created is a step in the right direction. Most AWS lambdas are by their very nature impure though since you have to send the output somewhere at the final stage of the lambda.
- deleted 5y ago[deleted]
- etaioinshrdlu 5y agoOpenAI Codex is pretty good at translating code between languages. It's far from perfect - but it can get simple cases perfectly. It knows languages like Rust, Haskell, Erlang, and more. I found that I could translate Python to Haskell using Codex and get more real working Haskell code far, far quicker than I could manually. I think Codex will be a simply incredible tool for learning new programming languages, could definitely make FP easier. It may not be super "smart", but it's smart enough, it knows a ton, and it's got superhuman recall. Another idea is that you could filter Codex suggestions for those that pass the type-checker, and keep regenerating until it passes. It's so incredibly fun. It made me want to never stop coding.
- semitones 5y agoSuch strong praise, in a just tangential enough comment, reeks of marketing to me.
- etaioinshrdlu 5y agoNo, I am just a big fan, and a bit all over the place. In fact OpenAI is my NEMESIS.
- deleted 5y ago[deleted]
- vnorilo 5y agoI don't know. I don't write functional because it's hard and I'm super smart, I write functional because it's easy and I'm lazy. I'm also not sure the example in TFA is much of an argument. From a glance looks like the programmer got entangled in their own cleverness, but the slice we are shown is too small to show if there's some external reason to do it like that. story time: once did a compile time parser generator with c++ templates. "Zero-cost" abstraction and all that jazz. Turns out the binary was so large that a type-erased vtable system ran faster, for all its nonzero cost. Templates are orthogonal to functional or imperative. It's a code generator. Understand what you generate!
- tooltower 5y agoI've had this experience too. It doesn't take a lot of template use for both binary size and build time to blow up. When iterating with `make` starts taking over a couple of minutes even on a smallish-medium-sized project, it becomes a bit much. I didn't do anything fancy like compile-time parser generation. it was overuse of the standard library features, like `std::variant`.
- pharmakom 5y agoI have settled on the immutable core + imperative shell pattern, because it’s the easiest way to write robust software in my experience. It’s much easier to do this in a functional language like F# or OCaml than it is in a mainstream OOP language, even one with all the bells and whistles like C#.
- vnorilo 5y agoTrue. Especially when guiding a team C# makes life hard because so much of immutability is by convention only. I suppose it will get better once we can move to C#9 with Records, but even so, some discipline is required.
- logicchains 5y agoIt's getting much easier in C++ due to constexpr becoming more and more powerful. A constexpr function is a mathematical function, in that the compiler guarantees that its output is a deterministic function of its input.
- fnord77 5y agoI like the FP syntax in Java 16, rust and clojure. I dislike it in Scala, C++ and javascript
- Animats 5y agoHere's "clippy", Rust's style enforcement system, complaining about an insufficiently functional form. warning: manual implementation of `Option::map` --> src/viewer/regionindex.rs:265:13 | 265 | / match vlinkopt { 266 | | Some(vlink) => Some((*vlink).clone()), 267 | | None => None 268 | | } | |_____________^ help: try this: `vlinkopt.map(|vlink| (*vlink).clone())` | note: `#[warn(clippy::manual_map)]` on by default for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_map It wants a map and a closure used on a single value, to replace a simple conditional. I am told that the map and closure will all optimize out, but I haven't looked at the generated code.
- nextaccountic 5y agoThe issue here is that None => None is really a code smell, because all you are doing is mapping the internal value of Some(..). Hence, calling .map() actually makes the intent of the code more clear.
- jkelleyrtp 5y agoIn some cases I've found it impossible to use .map() - especially when needing to use "self" and dealing with lifetimes of data borrowed from "self". I really wish Rust had proper disjoint capture for private methods in these instances.
- NobodyNada 5y agoDisjoint capture in closures is coming in Rust 2021 next month: https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-capture-in-closures.html https://doc.rust-lang.org/edition-guide/rust-2021/disjoint-c...
- valzam 5y agoBecoming fluent in using all the different ways to iterate over traditional collections (map,flatMap, fold, reduce etc.) already takes some time. Extending that to things that programmers don't normaly think of when they think "loop over something" is definitely a hurdle. It doesn't help that these operations have very generic names. That being said, once you get used to it it is extremely convenient to just map over any sort of "container" and focus on business logic. The above concept even extends to async programming. You can do things like iterating over a Future and let the runtime handle waiting for the value. Functions returning a Future or a Promise can be composed just like you would iterate over a list. asyncDbOperationGetUser(userId).flatMap(user => asyncDbOperationGetPosts(user.friends)) There are of course different ways of achieving this (async/await) but the power of learning FP concepts is that you can apply the same fundamentals to almost everything that has a defined notion of iteration (--> is a monad).
- g42gregory 5y agoWhy does functional programming need to be popular or not popular? Functional programming is one of the several programming paradigms in Python, C++ 20 and Java programming languages. It could be used when appropriate, just as other programing paradigms. I think FP is the norm, when needed, in Python and now increasingly in Java and C++.
- rossjudson 5y agoThis is possibly the best article on functional programming I've ever read.
- iammisc 5y agoFunctional programming is the most popular current paradigm. What is everyone on about? Javascript, a functional language, is one of the most popular languages ever. Rust and go, two other popular languages, also eschew object-oriented programming, the former dominant paradigm, for a truly functional one. C++ is gaining more and more functional features, and this is quickly becoming the predominant style.
- pathseeker 5y agoRust and Go pull in some stuff from functional programming (first class functions) but are not really designed around functional programming as the way to get things done. Most go programming I've seen is like python where you are slinging around maps that are getting modified all over the place. Very antithetical to functional programming.
- iammisc 5y ago> Very antithetical to functional programming. You are confusing functional programming for pure functional programming. This is like confusing Smalltalk-style OOP with OOP in general and then complaining about C++. Mutability and functionalness are orthogonal, although the immutable style lends itself well to functional programming and mutability is more kludgy in FP. But given that both Rust and Go have first class closures, they qualify as a functional programming language. The definition of FP is that functions are data. Python, Rust, Go, etc all fit this definition. Modern c++ does as well. There is no reason not to include these languages, not only they support functions as data, they also support higher order functions (functions that take callbacks accepting callbacks accepting callbacks, ad infinitum).
- mettamage 5y agoIMO with Go. Yes, it eschews object-oriented programming. Yet, funnily enough, whenever I use Go, I am noticing that I can work fine with it when thinking about it in an object-oriented way. Structs + methods were all the features I used in object-oriented programming anyway.
- 5y ago
- pansa2 5y agoFunctional programming isn’t how people think, and it isn’t how computers work. Therefore it’s a bad way for the two to communicate.
- theCodeStig 5y agoThat’s a strong assertion. Can you elaborate, to back it up?
- tbrownaw 5y agoWhich part needs to be somehow backed up? That the programming paradigm that's used primarily by a small number of people who are into mathematical purity and is generally regarded as hard to wrap your head around, isn't how people think? That the programming paradigm that takes so hard to not expose concepts like RAM or a program counter isn't how computers think? Or that the combination of these makes it unsuitable for communication between the two?
- dnautics 5y ago> That the programming paradigm that takes so hard to not expose concepts like RAM or a program counter isn't how computers think? Are you somehow under the mistaken impression that OOP does this? What happens in C++ when you have exhausted the heap and you try to new() an object? Have you ever done pointer arithmetic in Java?
- onion2k 5y agoIs there a programming model that meets the criteria of "how people think"?
- dnautics 5y agoFunctional programming. You don't have to have a long memory attention span to understand how you data are changing. It's the case that humans can only keep some small number of things in their head, no?
- rajangdavis 5y agoI like functional programming because I like algebra. When I can reason about things in a way that I understand, that makes me happier as a programmer. I don't think it needs be any more complicated than that. If it's not popular, so be it. Most of what I am interested in is not popular. I don't care.
- lambdasquirrel 5y agoThis article is from 2016, so if we're going to look back a bit, then maybe some perspective is in order? In the grand scheme of things, I look at ReactJS today, with its modern incantation of hooks, and that "language" reminds me a lot more of SML (yes, anyone remember SML?), than it does with C or Java. I started programming professionally back in 2005. Back then OCaml was the rage because we thought it would support OO, and bridge FP and OO, and ReactJS did not exist yet. It was taken for granted that OO and "imperative" were practical. So it's interesting to me that modern ReactJS is more like SML than it is like OCaml. And it's actually practical. People for whatever reason don't consider it weird. Meanwhile, "idempotency" is something desired by the masses, even in infra / devops. For example, at least amongst my coworkers, we generally agree that e.g. terraform is "better behaved" than ansible. If you're looking for a revolution in these sort of things, I don't think you're going to get it, because FP a la Haskell is indeed too "weird." As working engineers, the most important thing at the end of the day is to deliver some working tool or product. The current generation of actual-FP languages have been too much of a pain to be practical. They had to be. They were breaking new ground as far as what could be done. In my mind, Haskell proved the limits of System F. The language was pretty much a test-bed for what you could do if you eschewed any attempt at "backwards-compatibility" with previous mental methods of programming. From a research perspective, that was hard enough to do. But meanwhile, Swift is a massively better language to code in because Haskell and SML existed. Change did not come as a revolution, the way we expected it. People understand FP better than they ever have, on some instinctive level, and that's how the world was able to move further away from C++ / Java, and towards SML. Ironically this happened in UI – and in the web – which in 2005 seemed like the last place where FP could possibly succeed. It was generally understood in 2005 that FP was bad at "state," and UIs, of all things, were highly stateful. (To be clear, Haskell is still a pain as far as state goes, but not as much of a pain as it used to be.) So when you put this all together, we can say that the world works in weird ways. It wouldn't surprise me too much if the languages of tomorrow actually turned out to be weird, but that'll probably take another 15-20 years to see out.
- brabel 5y ago> People for whatever reason don't consider it weird. Speak for yourself, I find React is weird as hell! But that's not because it's functional, Elm for example makes a lot more sense in my mind.
- platz 5y agocomments are bringing out grand thesis or bike shed of FP, but wjat OP actually wrote the article about was being forced to use recursion instead of iteration andnconsidered that FP. If OP had titled his post recursion is weird I think we'd be seeing some different line of comments. Secondly, his recursion example not really support his opening comments about FP and cakes. Thirdly, you dont have to do things backwards in FP.
- he0001 5y agoMy experience is that fp is notoriously bad at dealing with errors. Errors are quite common in everyday business cases, although usually ignored, (like in c#), which makes it hard to “fit” into whatever you are working with. Any language that doesn’t treat errors as a first class citizen in it's syntax is a bad one, which I feel like that languages like Haskell isn’t doing well. Also errors are contextual so it’s not always so that an error is one in some context and may be so in others. So the language must be flexible enough to handle both in a nice way. I think Java is kind of a good example of this where it had checked exceptions to signal errors, but when introducing fp syntax they completely botched how errors work. This left you with a mess and programs keeps crashing because people didn’t know that code could throw errors.
- ChrisArchitect 5y agoAny new thoughts since this post Previous discussion: https://news.ycombinator.com/item?id=11188570 https://news.ycombinator.com/item?id=11188570
- namelosw 5y ago1. It's weird because it's different. It's different is because it's on the other branch of the skillsets most people used to for years. 2. To learn things on the other branch, people need to unlearn until they reach the common ancestor node. 3. Unlearn is a form of subtraction. Humans suck at subtraction, be it learning things, making products, or just the human civilization itself - it's even easier for it to collapse and start over. It's the same idea that Japanese is much harder to learn than German: Because it assumes the learner speaks English, while Chinese people that don't speak English would mostly find Japanese is much easier.
- goto11 5y agoLanguages do not becomes successful due to their intrinsic qualities. Languages become successful when they are coupled to a successful platform. E.g. C became popular because Unix became popular, JavaScript became popular because of the browser, Objective-C became popular because of the iPhone and so on. Therefore observing that a language or paradigm is popular or unpopular does not say anything about whether it is good or bad. JavaScript is the most popular language in the world. If Netscape had decided to use a Scheme-like language or a BASIC-like language it would still be the most popular language in the world. So paradigm has nothing to do with it. Functional programming is less popular because no major successful platform has adopted a functional language as the preferred language. I don't buy that functional languages are unpopular because they are unintuitive. Losts of stuff in JavaScript is highly unintuitive. It didn't prevent it from becoming the most popular language in the world. People will learn what they need to learn to get the job done.
- erostrate 5y agoHow does your theory explain Rust or Python?
- tgv 5y agoFor Python, the platform is education.
- jfcisco 5y agoIt also helps that Linux distros usually come with Python
- Jensson 5y agoAnd most educators decided on Python because? You don't think it has anything to do with people liking the language and therefore wanting to use it and teach in it?
- dijksterhuis 5y agoIt can also be due to tooling -- once a student has got the python binary installed you can get them writing and running code without having to make sure they have the correct version of x, y, z (don't even need conda or pip) or teaching them what a compiler is etc. Javascript is quite popular as an introductory language too -- students can open up a web browser and type stuff in the console in the middle of a lecture.
- isaacimagine 5y agoI read this title as: "Functional programming [is popular, but not] because it is weird." I was hoping how it would discuss how building software using functional programming techniques made the paradigm uniquely suitable for popular use. Anyway, I digress.
- alphanumeric0 5y agoI like the puzzle analogy but I'm not sure it holds too much weight. Didn't imperative style also kind of feel like a puzzle when you first started learning how to code? Remember those light bulbs that went off when you finally incremented an index variable at the right moment, or when you finally figured out the right condition for a while loop? Clearly all styles are puzzle-like when you are first learning them. I think functional programming has more or less the same learning curve as other styles. In my view, the reason functional programming isn't more popular is because of Comp Sci curricula. There are plenty of institutions where there may be one course on functional programming (if you're lucky). Then, many students seem to (incorrectly) internalize the idea that anything their degree doesn't cover extensively must be of lesser importance.
- deltasixeight 5y ago>Ah screw it I can’t finish this. I don’t know how to translate the steps without mutable state. I can either lose the ordering or I can say “then mix in the bananas,” thus modifying the existing state. Anyone want to try finishing this translation in the comments? I’d be interested in a version that uses monads and one that doesn’t use monads. He's wrong and he completely misunderstood functional programming. It's not weird at all. Let's get things straight. First off there's a difference between functional programming and types. Monads are more of a type centric thing and also haskell centric. Haskell is a big part of functional programming but it's only one style. You can do functional programming without monads and also without type checking. Additionally type checking and even haskell-like type checking AND monads can exist in imperative languages as well (like rust.) Does rust having monads make it functional? No. Second functional programs can be very very very very readable. It depends on how you structure it and your naming conventions. See example below: list of data primitives (aka ingredients and tools): cake grease flour small_bowl large_bowl pan whisk salt oven cream butter_milk white_sugar brown_sugar walnuts heatedOven = preHeatOven(oven, 175) panWithGreaseAndFlour = putGreaseAndFlourInPan(grease, flour, pan) bowlWithWhiskedIngredients = whiskStuffIntoBowl(small_bowl, whisk, salt, flour, baking_soda) bowlWithSugars = mixStuffInBowl(large_bowl, white_sugar, brown_sugar) bowlWithSugarsAndBananas = mixStuffInBowl(bowlWithSugars, bananas) bowlWithAllingredients = mixStuffInBowl(bowlWithSugarsAndBanas, bowlWithWhiskedIngredients, buttermilk, walnuts) panWithAllIngredients = pourContentsOfBowlIntoPan(bowlWithAllingredients, pan) heatedPan = heatPan(panWithAllIngredients, heatedOven, 30) finishedProduct = coolPan(heatedPan) I mean that's so simple I can literally translate that into english: Create a heated oven by heating an oven to 175 degrees. Create a pan with grease and Flour by putting grease and flour into a pan. Create a bowl with whisked ingredients by whisking salt, flour and baking soda into a small bowl with a whisk. .... You get the picture... It's just real practical english tends to be less pedantic that's it. Think about it this way. Let's say we live in an imperative world where we have an oven. We then heat the oven. Now in the imperative world the oven is destroyed and replaced by a heated oven. We only refer to the "heated oven" as an "oven" for convenience but in fact the original "oven" is actually destroyed as in it no longer exists. In functional programming THE only difference is that the original oven is NOT DESTROYED. That's it. You have a heated oven, but you still have a reference to the original oven. But you don't ever need to refer to original oven if you don't want to. This makes English describing imperative processes more or less IDENTICAL to functional processes. Another perspective to think about this is that in the English language we create the heated oven but the original oven is not destroyed but moved! The oven is now moved into a namespace called the past, we can only refer to the original oven by appending or prepending one of the many names and phrases of the "past" namespace to the oven! For example: The oven "before it was heated", the oven "from the past", the "original" oven,... etc. So from that perspective then the only difference between FP and english is that variables once operated on, are moved to a different namespace. So literally just extra past-tense embellishment on English grammar is the ONLY difference. It gets crazier than this. Is anything in reality really mutable? What does mutability even mean? We live in a universe where each instance of time is it's own namespace. The universe is a function of time. At t1 there is an oven, at t2 there is a heated oven. So really mutability is just syntactic sugar over immutability where just gloss over mentioning what time namespace we're in for convenience. Yes you heard that right. Everything is actually immutable and mutability doesn't exist. Our concept of "mutability" arises from language shortcuts we take and assumptions of present tense. Either way from the examples this guy writes it's pretty obvious functional programming didn't click for him. He understands the rules like immutability and he sees all the crazy tricks and nutty types people associate with functional programming but he missed the big picture. Hopefully this explanation will let the concept of functional programming click a bit more with people. There is in fact a deeper intuition for why functional programming is "better" than imperative programming. But that's another long explanation. Most people don't ever reach this point of realizing how functional programming is better. They could spend years doing functional programming and completely miss it. Instead they reach a state where they think functional programming is sort of a style of programming used to express intellectual arrogance with no practical benefits and they give it up and move back to imperative programming. Well, they are wrong and they missed a deeper understanding of a fundamental concept. If this sounds like you, I'm telling you... you missed the big picture. Literally the OP is a picture perfect example of this. Completely missed the point of FP but spent enough time with FP to understand what a monad is, even though a monad isn't really technically an FP thing.
- eterevsky 5y agoFor me functional languages lose to imperative ones because they make it harder to reason about what actually happens when the program is executed. When you see a nested loop, you immediately know that it will probably perform O(n^2) operations. This is not so in functional languages. I clearly understood it when I was reading about Haskell and learned that out of `foldl` and `foldr` one works in constant time and another in linear. I don't remember which.
- garethrowlands 5y agoHaskell execution's definitely tricky to reason about. Though, a declarative doesn't always lose. The obvious counter example is SQL, which replaced imperative approaches.
- cousin_it 5y agoBoth have to consume the whole list, so none of them can be constant. You're probably thinking of space complexity, and yeah, in Haskell it's even more tricky - it depends on how the function's caller uses the result.
- sullyj3 5y agoIt depends on the domain. In performance critical code, I agree that it usually makes sense to use an imperative language. However, not all code is performance critical. Also note none of this is to say that fp is inherently incapable of high performance code - properly tuned Haskell can be competitive with C. Libraries like Streamly[1] are designed with extremely high performance in mind. But I agree reasoning about performance is much more difficult and requires more expertise. [1] https://hackage.haskell.org/package/streamly https://hackage.haskell.org/package/streamly
- Nekorosu 5y agoI'm not convinced with a convoluted C++ example. Why would you reason about FP in a language that was never built for it? Also, there are some mixed paradigm languages (like Clojure) that avoid pitfalls of the pure FP programming. And yes, I do consider purity a pitfall for some kinds of applications. Actually, Clojure even has OOP features that are a la carte and don't create the artificial inconveniences that make you build enormous GoF pattern based solutions to overcome those.
- p0nce 5y agoFor me the problem is that "functional programming" embodies a lot of questionnable ideas: - the idea that readability is not the first thing to pursue - the idea that macros are great - the idea that leaving performance off the table is OK - the idea that objects and subtyping are useless - the idea that mutability is hard to reason about - the idea that recursion is super important - the idea that somehow closures are more readable than objects - the idea that tuple are somehow better than structs with named fields It is a style that thrive _in opposition_ to the style of useful programs out there: readables, no macros, fast, with an UI, with mutability, with objects, with names.
- hocuspocus 5y agoYou're making so many broad, inaccurate and false generalizations that I won't bother replying to every item. But let's take macros: yes, as an average application developer, you should probably avoid macros. But for some problems they're a way better tool than alternatives like runtime reflection or code generation. For instance I'm happy to use macros-based libraries that automatically derive JSON codecs. Unless you're a library developer, macros and their inherent complexity (outside of the Lisp family I guess) aren't an issue in FP languages that I know of.
- TeMPOraL 5y ago> yes, as an average application developer, you should probably avoid macros. I disagree. I think you should just learn to use them correctly. They're just another tool, and not a hard one to grok. If you're allowed to design code on your own - write modules, classes, APIs - then you should be able to handle macros responsibly as well.
- filoeleven 5y agoIn your experience with FP languages, how often do you reach for macros over functions, if you could ballpark it? Or if it makes more sense, in which scenarios are you more likely to reach for macros? The example I always hear about is creating DSLs. I haven’t done that yet with FP (Clojure), and I have not yet created a macro outside of learning exercises. So I have only a vague notion of when they are most useful. I’m not arguing to avoid them, but I have internalized the Clojure preference for “data over functions over macros.” This question is open to anyone. I’m mostly interested in the opinions of folks who have learned to use macros as “just another tool,” and who have a good set of heuristics for knowing when it’s the right tool.
- streamofdigits 5y agoFunctional programming forces you to think a bit like a theoretical physicist seeking to write equations for fundamental laws: the universe is modeled as interacting particles that start free, collide and interact and end up free again. No concept of historical dependence or sequential evolution. In physics these attributes emerge only as descriptive crutches in the context of poorly understood complex, macroscopic, systems undergoing various transitions. We have much less clue how to write universal equations for such systems. So FP might have a theoretical advantage as a building block of low-level software systems that are not throwaway labor (that is: only valuable in specific historical window / context). In any case the factors driving programming language popularity have changed dramatically ever since the developer universe got truly "connected". There is a winner-take-all network mechanic that basically inflates whatever initial advantage into a (difficult to explain ex-post) catholic dominance.
- quickthrower2 5y agoThe monadic recipe is main :: IO () main = do // … followed by imperative recipe
- goblin89 5y agoThere is an opinion that learning things more thoroughly is helped by making said things in some particular ways[0] harder to learn (so we struggle at first, make our discoveries and get that dopamine boost when we grasp a concept). If we take it as a given, then (controversial opinion) it seems possible that popularity of languages and paradigms that are easy and make intuitive sense (and are not weird, like functional languages) could by itself lead to a lowering of average knowledge level across the industry, even if the difficulty of a language has nothing to do with it being objectively somehow better. [0] Not the way Brainf*^%k does it, though.
- globular-toast 5y agoI actually don't like recipes written in an imperative style and I don't think this is how cooks think about them internally. They are the norm for written recipes, but whenever I read one I (and I assume other experienced cooks) translate it into a functional style for internal storage. Consider a recipe for macaroni cheese. In imperative style it might be written like this: Thread 1, step 1: melt butter, add flour, gradually beat in milk, simmer. Thread 1, step 2: remove sauce from heat and stir in cheese. Thread 2, step 1: bring water to boil, add salt, add 125g of pasta, simmer. Thread 2: step 2: drain pasta. Join threads: Fold pasta into sauce and serve. Nobody thinks about how to make macaroni cheese like this. My internal record for macaroni cheese is more like this: "Basically it's macaroni and cheese sauce mixed together. You cook pasta in boiling water with salt. Cheese sauce is béchamel sauce with grated cheese. Béchamel sauce is made with a roux and milk. A roux is butter and flour." In fact, if you look in any decent cookery book, the information will be stored like this. A good book teaches you techniques and builds up raw ingredients into basic building blocks and then final recipes. Only a stupid book tells you how to make béchamel sauce 20 times because 20 different dishes use it.
- cardanome 5y agoFor me OOP is weird. I never understood what people mean when they say it is close to how they think. It feels like a way to obfuscate the flow of code and requires to make decisions about what thing should have which responsibility and relation with which other thing and building weird hierarchies that will bite you back in the long term. Relations between Objects change, customers don't know what they want, change is always pain with OOP. Now people say, composition over inheritance. Right, but isn't that the point of functional programming? Functional programming maps to how I think. The most important questions is always: What data structures do I need? Get your data in order and the rest will flow naturally. I don't use functional programming because I am a math nerd or something, I am not even good at math. I use is because it is composible and easy to understand. I can refactor without any fear of side effects. Now is pure functional programming practical? For some tasks, sure but yeah not always. Imperative programming gets stuff done. Work with the strengths of both. The thing you are not used to always feels weird, that is a problem with you not the thing you try to learn.
- magicalhippo 5y ago> I can refactor without any fear of side effects. Can you? Like say you changed you sum() function to only sum every other element, because for the code you're working on right now that made sense. Well now you've screwed up the other places which relied on sum() summing all the elements. Dumb example because you'd know better, but surely you can still shoot your foot off like that with FP? And yeah I know that's not the side effects you were talking about, but when I'm changing my OOP stuff, that's the kind of side effect I'm most worried about. I've never really used a proper functional language though, so it's certainly possible I'm unenlightened.
- matt_kantor 5y ago> I know that's not the side effects you were talking about, but when I'm changing my OOP stuff, that's the kind of side effect I'm most worried about. That's not a "side effect"[1] at all. It's a logical bug in the implementation that only affects the function's return value. You absolutely still have to worry about those sorts of bugs in FP, which is why you still need tests or a fancy enough type system to prove the bug cannot happen (for your example that is unlikely to be practical). "Without any fear of side effects" doesn't mean you don't have to fear anything at all, but it's one less thing to worry about. [1]: https://en.wikipedia.org/wiki/Side_effect_(computer_science) https://en.wikipedia.org/wiki/Side_effect_(computer_science)
- philonoist 5y agoA big shout out to those institutes and universities that teach FP in intro to programming(CS 101). FP is the foundation for computer science theory.
- bluepoint 5y agoI am quite intrigued by functional programming and I spent a fair amount of time with Haskell. I believe that there are cases where functional programming should be relevant, for example numerical software, where by definition you pickup an input once, do a lot of calculations and produce an output (think of lapack, or numerical functions). There is no event loop or continuously looking for input to adjust state. Shouldn’t functional languages be ideal in implementing such algorithms in a simple way and perform better than fortran? They clearly don’t thrive there, but they should. So in the end I got the impression that functional languages about the mental challenge of finding a non trivial problem that an a functional language can solve better than a more traditional language. It might be a form of art in programming: finding the best problem for the tool.
- Tozen 5y agoI believe that functional programming is not as popular as some think it should be, because the more popular languages stole a lot of its mojo. Other languages absorbed and used many functional programming concepts. It became like, "No need to go over there, you can do most of it here, in a language you already know." As for OOP, I think many people have found ways to circumvent or minimize how much they use it, so are not going over the edge with inheritance and another kind of spaghetti. If they can use a struct, record (Delphi/Free Pascal also have advanced records), prototype (JavaScript, Lua...), OOP without classes (Go, Vlang...), or classes with only data then they do. There is more awareness to try and avoid the traps and excesses of class-based OOP.