5 ms·
Who cares about functional programming?
- rafaelvasco 7y agoI architect my code in layers. Generally OO based then specifically functional based; I find that works best for me.
- IggleSniggle 7y agoYou should do whatever works for you! But, have you encountered the idea of "Functional core, imperative shell?" https://www.javiercasas.com/articles/functional-programming-patterns-functional-core-imperative-shell https://www.javiercasas.com/articles/functional-programming-...
- maximente 7y agoi think the original talk by Gary is basically perfect for this bc it shows the power of mixing FP and non-FP in an imperative but flexible language (ruby) it's... a little different in Haskell bc it basically makes you work in this paradigm already, so not a huge value add imo all that is to say, just watch the original talk: https://www.destroyallsoftware.com/talks/boundaries https://www.destroyallsoftware.com/talks/boundaries
- VHRanger 7y agoNot sure that everything should be "OO core". When I look at architecture, often some entire components can be viewed as a FP-style function. Adding the code to make it behave so is well worth it for the long term benefits. If you start out writing this module as a class you instantiate, it can make the whole component more stateful as it evolves -- classes naturally push towards more stateful code. Overall I think OO, FP and simple procedural programming should be at the disposal of everyone. Just that historically the last ~20 years of enterprise programming (with Java, C# and OO-heavy C++ code) have really outsized OO's influence compared to how often it's the right tool
- pbiggar 7y agoCompletely agree. There are a couple of "killer features" of functional programming that led to us adopting it both to build Dark, and for Dark itself. Immutable values makes it so much easier to reason about programs. And then removing null and exceptions. The downsides: a bit of a learning curve for programmers used to OO; some classes of problems are easier with OO, though not as many as you'd expect. The real downside I've seen is that so much valuable information is in academic papers that aren't approachable.
- DonaldPShimoda 7y ago> The real downside I've seen is that so much valuable information is in academic papers that aren't approachable. They become more approachable the longer you spend reading papers, but overall I definitely agree with you. Lots of papers just assume too much of the reader, which means you've gotta read like six other papers to find out what's really going on in this one.
- tybit 7y agoAs someone that likes functional principles but hasn’t found a simple functional language with good IDE support, I’m more worried about an approachable language than approachable papers. Hoping you’re successful in helping to solve this.
- tiborsaas 7y ago> FP would need to solve a severe problem that could not be solved with existing approaches in order to make a breakthrough So the question the author is asking is whether there is problem which can only be solved via lambda calculus and not by turning machines or at least the difference should be significant in favour of lambda calculus. Since both approaches are equivalent models of computation, I have to bet on the "no such killer app" side.
- 6gvONxR4sf7o 7y agoIt's not "can't solve" in the sense of abstract computation, but rather "can't solve" in the sense of "you couldn't build facebook in the brainfuck language."
- mosdl 7y agoLots of words without much value, just like FP! Seriously, why is this on the homepage? Doesn't contain anything interesting about FP.
- asp_net 7y agoActually you are usually writing much less code with FP approaches ;-).
- elwell 7y agoClojure is an FP language. Clojure is relatively terse.
- hans1729 7y ago>Lots of words without much value, just like FP! not sure if a) people didn't get the pun b) the pun wasn't intended or c) both :thinking:
- meowface 7y agoI don't get the pun. Could you explain?
- hans1729 7y agoImmutability is important in FP, lots of functional languages don't even have a var-keyword - they don't deal with values in the sense that oop or imperative languages do. (Instead, they just functionally transform shallow copies of input data, iirc this paradigm is called 'data driven programming') ...so, yeah, "no values" relative to the amount of words used in FP. The pun needs a bit of a stretch, but I'd take it ¯\_(ツ)_/¯
- DonaldPShimoda 7y agoIt's a bad pun, if it was meant as one. FP is all values and few words, compared to OO languages.
- 7y ago
- jahaja 7y agoIsn't FP simply too esoteric to ever become properly mainstream?
- AlexCoventry 7y agoYou can get 98% of the benefits of FP with 0% of the category theory.
- DonaldPShimoda 7y agoYou can also get many of the benefits of category theory without learning any of the category theory. :)
- DonaldPShimoda 7y agoNo, definitely not. FP concepts are catching on in mainstream languages. Lots of languages now support optionals instead of implicit nulls, maps and filters over lists, higher-order functions, etc. These all originated in FP and have just made their way over to the more mainstream imperative languages. Not only that, but FP is must more a state of mind than a set of language features. You can write functional code in practically any language, really, although some of them will make it easier than others.
- jahaja 7y agoLooking in from the outside, I just can't see how a project written in most esoteric-leaning languages can scale beyond like 5 developers without becoming an unreadable mess simply due to the expressiveness of the language.
- DonaldPShimoda 7y ago> I just can't see how a project written in most esoteric-leaning languages can scale Well what do you mean by "esoteric-leaning"? It seems like you just mean "languages I'm not used to", which is a very limiting perspective, but perhaps I've misinterpreted you here. Obviously nobody thinks you should write your production code in Brainfuck (which is an actual esoteric language). But there are plenty of places that use functional languages in production. Functional language are not esoteric by nature — they're just different. It's like calling SQL an esoteric language just because you're used to Java. Jane Street uses OCaml for everything, Facebook uses Haskell and ReasonML (which is really OCaml), Galois uses Haskell, Microsoft has F# and F* and a Haskell group, GitHub uses Haskell... There are plenty of examples of functional languages in industry. They're not esoteric, and they do scale when implemented correctly (same as anything else). > without becoming an unreadable mess simply due to the expressiveness of the language. ...? I don't mean this rudely, but are you sure you know what "expressiveness" means? More expressive languages are not inherently more or less readable than other languages. They simply enable you to do things you couldn't do in those other languages. C is more expressive than, say, x86 assembly by the inclusion of features like types. Do types make your code less readable? I don't think so. Java is more expressive than C by the inclusion of classes. Do classes inherently make your code less readable? I don't think so. Haskell is more expressive than Java by the inclusion of higher-kinded types. Do HKTs inherently make your code less readable? Not if you know what they are and how to use them — which you would if you use a language that supports them. So I don't think so.
- aequitas 7y agoI consider FP to just be one of the tools in my programming toolbox. And apply it where it will fit best. Because not every problem should be solved with FP, nor with OOP for that matter. Though it is sometimes educational to apply only a single solution to all problems. Just to see how far you can stretch the usefulness of the tool. A nice talk about where (and where not) to apply FP is this talk by Gary Bernhardt: https://www.destroyallsoftware.com/talks/boundaries https://www.destroyallsoftware.com/talks/boundaries
- seph-reed 7y agoSo true. Generally, whichever one best matches the feeling best is how I go. Some things really feel like objects, they've got little personalities, friends, parents... a whole list of talents and characteristics. OOP it is. Other things are more like physics. It doesn't really need to have a name to exist, there doesn't need to be a container, it always acts predictably. Time to get functional. I've also been using a tactic which I have no idea what it's really called, but I call it augmentation. I think of them like those crystals you add to your weapons in diablo or other RPGs. The gist is: a public readonly member which takes the object that holds it as an argument and has extra functionality. So like: ``` class Staff { public readonly flamePower = new FlameAugment(this); } (new Staff()).flamePower.doSomethingSpecialInvolvingStaff(); ```
- duncan-donuts 7y agoWouldn’t that just be a form of inversion of control? It feels a lot like dependency injection, though maybe I’m misunderstanding from the example.
- seph-reed 7y agoDefinitely like a form of inversion of control. Wouldn't think to call it that because the inversion is so shallow, and the control is always accessed from the context of the typical controller. It doesn't feel like what I use IOC for, though there is a similarity.
- 7y ago
- coldtea 7y ago>However, looking at how discontent programmers are with Objective-C, not so much anymore. Not even the immaturity of the tooling around the language like its IDE Xcode could stop the migration. Actually it has little to do with some huge "discontent" towards Objective-C, and more with Apple presenting Swift as the way forward and their main officially supported language... >So why are most of the young contenders stuck with little recognition in their niches, while Swift is taking off so quickly? Again, because no functional language has a huge company promoting it as THE language its devs should use, like Swift has with Apple. F# is not MS's favorite, for example... >For developers building applications in the Apple ecosystem, the primary hard problem seems to be Objective-C. In other words, ”the pain” is so significant that developers were almost desperately waiting for an alternative language and are now happily joining the movement of the Swift language. Yeah, no... >The first five of those factors [interlanguage working, possess extensive libraries, be highly portable, have a stable and easy to install implementation, come with debuggers and profilers], which are mainly technical, are provided by almost all of the functional languages. Not really. Compared to C#, Java, Javascript, it's not even close... >Following the theory of "The Chasm", FP would need to solve a severe problem that could not be solved with existing approaches in order to make a breakthrough (finding its "killer app") Not really. Swift doesn't solve any special problem "that could not be solved with existing approaches", C# doesn't, Java doesn't, and in general, most successful languages don't. They succeed because of platform stronghold (UNIX -> C, MS -> C++, OSX/iOS -> Swift) and other such reasons...
- AnimalMuppet 7y agoIn my opinion, Java succeeded for two reason: the (not quite fulfilled) promise of "write once, run anywhere", and the library. In the beginning, it didn't have "platform stronghold" anywhere, not even on Sun. (Although, if the platform was "everywhere", there weren't many alternatives.) And the language itself was not a spectacular advance. But the library was massive. And the promise of "run everywhere" was very tempting.
- patientplatypus 7y agoFP is fun, but there aren't many good languages for it. Haskell is too academic, Clojure is fun but hasn't taken off, Scala is too complicated (Java with FP shoehorned in, who thought this was a good idea?). I like FP but 90% of the time you'd be better off with just Python because other developers will be able to work with it and there are libraries. Or Golang or Node or whatever. Frustrating, but it is what it is.
- hszeeks 7y agoI find the characterisation of Scala very inaccurate. It is nothing like Java at all. A Scala code would look so different compared to a Java code. For an example, in Java you would create a class with static variable as a Singleton object. In Scala, you just create an Object. Type inference, Option type, pattern matching, it is nothing like Java with FP shoehorned in.
- cpursley 7y agoHave you tried Elixir?
- patientplatypus 7y agoOk fair. Elixir is nothing short of amazing.
- johnisgood 7y agoHow about OCaml? https://www.cs.cornell.edu/courses/cs3110/2019sp/textbook/ https://www.cs.cornell.edu/courses/cs3110/2019sp/textbook/ https://ocaml.org/learn/tutorials/functional_programming.html https://ocaml.org/learn/tutorials/functional_programming.htm...
- johnisgood 7y agoThis is a newer one, with advanced topics and probably other changes: https://www.cs.cornell.edu/courses/cs3110/2019fa/textbook/ https://www.cs.cornell.edu/courses/cs3110/2019fa/textbook/
- 7y ago
- hellofunk 7y agoI don’t see what the big deal is. I wrote clojure professionally for many years, full-time. It’s just as easy to write spaghetti in that language as in something more traditional.
- JohnFen 7y agoHonestly, I've never seen a language or paradigm that you can't easily write spaghetti in.
- AnimalMuppet 7y agoYeah. The trick is, can you write not-spaghetti in it?
- JohnFen 7y agoWell, I've not seen a language/paradigm that makes in impossible to write good code in, either. While there are differences, of course, I honestly don't think the choice of language makes the major difference in code quality. What makes the major difference is skill, conscientiousness, and work processes.
- timbit42 7y ago> Well, I've not seen a language/paradigm that makes in impossible to write good code in, either. 8-bit BASIC.
- jaked89 7y agoFP tends to have a disregard for practicality, and performance especially. Yes, it's elegant, by being abstract, but this abstraction comes at a cost. After falling in love in it, I wrote a large project in F#, but eventually had to ditch it and rewrite in C#. A simple analysis of any F#-generated IL will reveal this.
- asp_net 7y agoCan you tell more about what kind of project this has been, and at what point you decided to turn around?
- jaked89 7y agoIt was a WPF desktop application, with a parser component. I managed to write large portions of the UI (all in code, no XAML), but when debugging I discovered that the language and the IDE are slowing me down. Especially, it's very easy to pass the wrong values to functions (functions instead of final values, etc). Debugging this is very time-consuming. IDE-niceness is also a factor. Devs tend to disregard this, but all the intellisense, code lens, go to, find refs, etc are huge time savers. You lose many of these capabilities (or get them in a degraded manner) with F#. Yes, I used all the plugins, etc, but what you get is simply 2nd-grade. This is in part unfixable; the language is simply not designed with such aspects in mind. And, as said, performance played a factor as well.
- akra 7y agoAs someone who has done some dev in F# professionally I think a lot of the comments above could come from trying to use F# like C#. WPF (and in general older .NET Microsoft frameworks) is probably one of the worst cases for F# however; the framework is designed pretty much exclusively for C# usage (i.e. PropertyChangedEventHandlers, generated C# classes from XAML, etc). From a functional language perspective there's different ways of solving the above problems. While you could code WPF in F# it's clunky and doesn't pass the cost/benefit test IMO in its current state; you would be coding in C# style with just a different syntax since the framework enforces a given coding style. Performance wise I find it depends on what your doing. I've had nicer code run faster in F# than C# with inlining and such. You can resort to mutable coding if you have to in F# as well so I don't think its truly the case. If your using immutable data structures and writing a WPF app on top without understanding them I can see why you would get the performance hit as an example. I haven't had a problem with Intellisense, IDE niceness (e.g. Rider, VS Code), Go To Refs seem to even work in VS Code etc. All the Resharper goodies aren't there; but after awhile you find you just don't need them as much in a more leaner language.
- msla 7y agoCompilers care about functional programming in its side-effect-free form because you can only optimize code you can understand the side effects of, and side-effects generally foreclose on optimization. The most obvious example is the volatile keyword in C, and how that forces a lot of memory traffic the compiler would otherwise be able to avoid.
- ncmncm 7y agoThat is the theory. In practice, the optimizations compilers implement using the advantages of known lack of side effects and mutation generally just aim at recovering part of the performance lost through excess copying.
- platz 7y ago> Since the early 2000s, functional programming has become more and more popular This is because pre-2000's, OO was particularly well-suited to desktop software and dominated that space, which also happened to be a space which occupied a large fraction of total development. OTOH, tasks of data transformation, which after the 2000's became in more demand as software moved more and more from the desktop to the server, is particularly well-suited to FP (due to being on the other side of the expression problem). The shift from desktops to servers has real consequences on language design. Microsoft even admitted this as one of the reasons they're trying to bolt on FP features to C#.
- NotATroll 7y agoI dare say the reason many people are hesitant to adopt Functional programming is that: A) They aren't, they're probably already programming in a functional programming style. Just not in a purely FP language (Which I would never adopt to begin with) B) A lot of FP articles come off as the musings of zealots obsessed with monads, which often barely make any sense to, well, anyone. The less sense it makes at first glance, almost guarantees people will want to avoid it. Yes, maybe I can understand it. But I'm (hopefully) not the only maintainer of the codebase, and trying to communicate some FP concepts back & how to use them really, really isn't easy.
- Twisol 7y ago> A) They aren't, they're probably already programming in a functional programming style. This hasn't really been my experience. OOP in particular has a very specific design mindset, and I've seen that play out over several codebases. There isn't really anything I can call "functional" in a system fundamentally based on cyclic (often) graphs of mutable objects. I think what may be implicit (and hence miscommunicated) in discussions about FP/OOP is that it's not about programming in the small (i.e. specific algorithms, blocks of code), it's about programming in the large (modules and their relationships; management of persistent data). Many examples I see of FP/OOP are algorithmic, and hence uninteresting -- you can get some nice ideas for how to condense your code or express the core ideas better, but it isn't exactly a paradigm shift. Every Turing-complete language can encode any computable function; algorithms may have complexity distinctions but are ultimately not far removed. The FP/OOP discussion would be better served discussing the architectural implications of these styles. > B) A lot of FP articles come off as the musings of zealots obsessed with monads, which often barely make any sense to, well, anyone. Monads are an example of a dominant architectural pattern in FP that takes advantage of the core conceit of the paradigm. I think monads tend to be explained at the algorithmic level, which is unfortunate -- in many ways, they're about decoupling domain logic from control logic, which (I will posit) is desirable in any system, not just one that's FP.
- phtrivier 7y ago> > To be widely used, a language should support interlanguage working, possess extensive libraries, be highly portable, have a stable and easy to install implementation, come with debuggers and profilers, be accompanied by training courses, and have a good track record on previous projects. > The first five of those factors, which are mainly technical, are provided by almost all of the functional languages. That seems like a very generous statement. Unless the author is talking about some functional language I don't know. Is there an FP language which really has the extensive libraries of Java / Python / C++ / JS ? (You might argue with Clojure and anything with a FFI..) Is there an FP that has a debugger and profiler as Visual Studio for C++, Eclipse for Java, and your browser for JS ? (No, you REPL does not count as debugger.) Is there any language that as `interlanguage working` (ok, this one is unfair, only JVM and C really count...) Is there an FP that has an implementation that's not a nightmare to install ? (ok, this one's even more unfair - everything is a nightmare to install...)
- tigershark 7y agoF#
- thrower123 7y agoF# should be more popular. But C# is just good enough that the small amount of extra effort of using F# is a speed bump that's hard to get past.
- deleted 7y ago[deleted]
- kangnkodos 7y agoThe article doesn't mention all the programmers being (forcibly) introduced to functional programming concepts by using React and Redux. Perhaps this is another possible way to jump the chasm?
- chowells 7y agoFunctional programming alone is not very compelling. It's just a slightly different way of organizing your code and data, with different tradeoffs in terms of what code is easy and what code is hard. If all you do is present examples of using higher-order functions and algebraic data types, people will be pretty justified in saying "this doesn't really change anything important." And that's because it doesn't! Even in Haskell, once you learn the language, code is code. Sure, laziness means learning new ways to think about composing code, but that's just a small detail. In the end, the things that matter are same. Everything you know about performance optimization still applies. The only difference is the look of the code used to express it. You replace for loops with higher-order iteration combinators! Woo! It doesn't really change anything. You replace goto with recursion. Big deal! It's all the same thing. (At least in a language with proper tail-call elimination.) There is no giant breakthrough happening because there really isn't anything to break through... At least as long as all you care about is "functional programming". There are languages where more interesting things are going on than just functional programming, though. And those have actual promise for providing real benefits. Haskell has a type system that provides real benefits in terms of documentation and correctness. That is actually useful. But it's not "functional programming." So yeah. I don't care about functional programming. I care about things that are actually improvements.
- Risord 7y agoI don't either consider living without local mutable variables and loops as a clear improvement. But I do think that designing your application such way that it won't rely (or rely as little as possible) on spooky actions at a distance is.
- chowells 7y agoSure, but that's a best practice in every language. Saying "this language makes you do the thing you swear you're doing anyway" doesn't sound like a practical difference. The second-order effect of "everyone has to do what you're claiming you do" is meaningful, yes. But it's really hard to convince programmers there's value there. Look how many people still say C is a fine language, you just have to not mess up. And not rely on any library that messes up. It's really tough to market the thing everyone should be doing anyway as a feature, even when the difference between "should do" and "is required to do" is huge in practice.
- myrryr 7y agoHow the hell did Kotlin end up on the non functional list, and Scala did? Kotlin code tends to be at least as functional as Scala is. If Kotlin isn't functional, then Scala isn't, and if Scala is functional, then Kotlin most certainly is.
- jillesvangurp 7y agoYou can do functional in Java as well; and people do. It's probably something purists look down on as inferior; and they'd probably be right. However, it does bring advantages relative to non functional Java code and it's been creeping into the language and frameworks for many years now. Kotlin sort of sits in between Scala and Java. Where Scala only grudgingly allows you to do things like for loops and other imperative stuff, Kotlin is a lot less conflicted about this while providing most of what you'd want out of a functional language as well. It supports both styles pretty well. As a consequence the "my language is more functional than yours" is less relevant these days. If you look at the mainstream languages (Javascript, Java, C#, Rust, Go, Python, Ruby, Kotlin, Scala, Swift, etc.) they all borrow some things from the functional world. They all have some sort of collections supporting things like map, reduce, fold, etc. They all have some notion of lambda functions and passing function references around. Etc. In several of those languages, this has been the case for quite long as well. All of those languages have in common that they are relatively new. Bucketing languages as functional and non functional is less clear cut than it used to be. In that sense, functional programming has gone mainstream and most programmers are exposed to it now. 25 years ago when I started out, we had some functional programmer pioneers teaching at my university and I got exposed early to what at that time definitely was not very practical in terms of real world applicability. I had my compiler course on parser generator frameworks written in gopher (a haskell predecessor). I even got exposed to monads during that course. You won't see a lot of Kotlin coders talk about monads but when you start talking about side effects, they'll have plenty of solutions nevertheless. Arguably, Scala is a bit more puristic on this front but the practical value over less puristic languages is not that enormous.
- imvetri 7y agoPlease don't fancy functional programming in javascript. Its a powerful paradigm and should be used in a language with powerful compiler.
- tom_mellior 7y agoJavaScript compilers are about the most powerful ones out there.
- imvetri 7y agoSorry. I should have shared the example I was thinking of as well. Just my example. [lengthy_array].map(function).filter(function).reduce(function). JS compiler just runs them. A compiler to be powerful to handle such functional programming syntax should also have ability to inline the functions as a single function. the above example could be recompiled as [lengthy_array].array_operation(Three function composed into one)
- tom_mellior 7y agoOh, forgot to answer here. As a compiler developer I'm very surprised by the assertion that this wouldn't be optimized by something like V8 or GraalVM's JavaScript engine. But I couldn't JavaScript myself out of a paper bag, so I don't know how to verify this myself.
- kstenerud 7y agoAt the end of the day, it comes down to performance. We've been lucky for a long time where the hardware improvements seemed to almost come for free, but the golden age of Moore's law is over, and people finally are realizing that their code needs to be tighter in order to achieve performance. FP doesn't mirror how the actual machine instructions work, whereas imperative languages do. And this means that when you inevitably hit a performance wall, it's generally easier to solve it in an imperative environment because you can already visualize what's going on underneath (save for gc stalls or whatnot). FP has its places to shine, but without the ability to see how the sausage is made (and tweak it), you're always at risk of an unbreachable wall.
- zygimantasdev 7y agoFP enables better concurrent/parallel code. I would say that is more important when CPU core count is increasing
- tom_mellior 7y ago> FP doesn't mirror how the actual machine instructions work, whereas imperative languages do. Can you explain what FP concepts don't "mirror how the actual machine instructions work"? Arithmetic maps to arithmetic instructions. Calls map to calls or jumps, which are well-supported by hardware. If statements map to conditional jumps. Pattern matching maps to something like switch statements (plus extra jumps), which are not hardware features, but they aren't hardware features in imperative languages either. What else? Oh, you don't write "malloc" or "new" to allocate memory (which, again, don't map directly to individual machine instructions). That's about it, I think. What am I missing?
- kstenerud 7y agoGenerators don't mirror the hardware. They are higher order tricks with hidden costs that can bite you if you're not careful. Lazy evaluation is a convenience that is dangerous to think of as free, as is recursion. Code-as-data limits the kind of addressing that can be used in the chip itself. There are mitigations for 95% of cases, of course, and nothing's stopping you from changing the algorithm entirely or parallelizing or whatever. I'm not saying that FP is a dead end. What I'm saying is that it comes with a cost in that you end up limiting your options if you hit a roadblock, because you can't just modify the imperative path due to the higher order functionality you're relying on. FP is very powerful, but that power doesn't come for free. For real-world applictions, a mixed approach will work best for most things.