Are YOU a Great Programmer? or a Regular Programmer with GREAT Habits. Download my FREE guide on how to adopt 30 of my favourite Programming Habits. Get yours HERE ➡ www.subscribepage.com/great-programmer
Automatic parallelization and performance really isn't the main reason to choose a functional programming language. Algebraic data types for domain driven design, immutability by default and concepts like referential transparency produce code that is much easier to reason about the program state by merely reading the code rather than assessing all mutable fields and properties across multiple objects that talk to each other, usually by having to step through the operations in a debugger.
@@J-Kimble But no one argues that an oversized objectivity is good. And many argue that a purely functional approach is better. No, it isn't. The code is often bloated and hard to debug. Much more readable is imperative with funcitonal elements. Not pure fuctional.
Not just has had. There are two ways of language development: towards Lambda Calculus, Category Theory and other math, or towards ad hoc stillborn internally controversial ideas (COBOL, OOP, etc). And this concerns not just languages, but the application architecture as well.
Yeah. I learned functional through Java libraries, not a functional language. Did a bit more in .Net. I’ve got 1 year in production Clojure but that’s it for me. I still think in functional terms daily in Java, Kotlin, Typescript. In Clojure we still used protocols quite a bit and the impure bits of the codebase looked fairly OO.
Perhaps thinking in something closer to a natural language (conditionals, repetition and commands) is more accessible to most than mathematical thinking...and not many people have been exposed to algebraic structures, functors and monads. @@InconspicuousChap
Functional programming doesn’t just potentially make your code run faster, it also allows forces you to structure your code in terms of inputs and outputs, making it easier to test and reuse. This can of course be done in OOP languages as well, but then it’s much easier to make a mess out of globals and side effects.
@ If you write pure functions it is much easier and safer to run those over a data collection using many threads or even using different machines. Think “map-reduce” where each worker gets a small piece of the total work where those results are later collected in a reduce step. This CAN of course be done in any language, but then you have to worry about thread safety in a way that you don’t need to to if all your data is immutable.
@@krumbergify So the main benefit of functional programming is immutability which can really be achived in any language, it is just the pure functional languages that enforce it at the compiler level.
@ Yes. Guarantees matter. You can certainly write concurrency safe code in C++, but Rust makes it much easier since the compiler enforces that there are no data races in your Rust code (as long as you don’t write unsafe blocks).
Hi Dave, thank you for the interesting video. It is difficult to come up with hard data on performance, but maybe my experience is still worth mentioning: In 2012, we one wrote a data processing program in Java, using self-implemented purely functional streams (not the java stream lib!) and data structures. There were only two single-threaded streams, one in the middle for sorting and then the final stream for collecting the data. All other stream transformations inbetween could be parallelized horizontally and vertically. While our program run 3x faster on a quadcore compared to a single core, I agree that if tight loops were written in a heavily tuned imperative/destructive style, the program might have been about 20x faster, only limited by I/O. The funtional style allowed us, however, to be lazy with optimization and focus more on testability and expressivness. So my other observations might be of interest: 1. Conversions from iterators to immutable, lazy streams and vice versa enabled us to travel between both worlds, with the former being a bit tricky to implement. 2. Immutability made it easy to transparently compress the data outside the working window, which actually increased(!) the overall speed. 3. Writing tests worked like a charm and even a small testing dsl could be written in only 2 days. 4. Lazy streams and structural sharing lead to memory leaks at tail calls that were difficult to track due to the fact that eclipse and the jdk produced different bytecode. 5. In an imperative language you can implement purely functional data structures which are impossible to write in most (all?) purely functional language, namely those involving identity checking via deduplication for fast diffing. 6. One must be very careful that non-funtional side effects don't leak, for instance, identity hashs destroy referential transparency and therefore repeatability of tests. In the end, it was a fun experience, and the new program was still 20x faster than the old, db-centric C++ solution. LOC was reduced from approx. 300.000 to 25.000. The old program did not have any tests while the 25.000 for the new program even included ca. 8000 lines for the new data structures and 10.000 lines for tests. As far as I know, the program still runs flawlessly, processsing several 100.000 fairly complex data records per day within a few minutes. Of course, the numbers are from memory and not exact, but I'm pretty sure that they faitfully describe the overall picture.
It's like Cartesian vs Polar coordinates. Some problems are better solved or expressed in one vs the other. Religious fanaticism is baked into some people's DNA.
By my measure, functional programming had a resurgence about a decade ago. Mainstream languages subsumed some of those features, and static typing took charge then with things like Typescript, Rust, and typing for Python. I think automatic parallelization isn't a big deal in major programs. But one place I really like it is with scripting. I experimented with writing my utility scripts in a variety of languages, and one thing I really liked about Elixir was how trivial it was to turn most of my serial scripts into parallel ones. All it usually involved was changing a couple lines of code. Experimentation and measuring was trivial. Lots of functional languages can also do OOP. Like Clojure with their multimethods, which mimics a less powerful version of Common Lisp's OOP. If you've never tried out OOP in Common Lisp, I recommend it. It made it a real joy for me.
FP is not a class of programming languages. As it suggests, it is a programming paradigm. So, your analysis of FP's popularity based on the popularity of individual languages is fundamentally flawed. Yes, purely FP languages like haskell and erllang are not much higher on the list than before, however almost all the major languages on that list have moved towards FP. Since, Java8 onwards, the vast majority of new Java language features were adding support for FP. Also Javascript has completely been moving towardsFP. Especially in its libraries. Ever heard of a little library called React? The reactive design at its core comes completely from FP. FP is indeed eating the world, but it is mostly doing so by changing the existing programming language giants, not by breaking through with soleley FP based languages.
I'll be hitting that button. You'll not get continuous feedback from me, I'll just let you know that it's not necessarily because I disagree with you. Just that this hasn't been worth my 20 minutes, and I'm not a fan of clickbait titles in general.
Keep a large and varied toolbox. "Functional programming is the ultimate tool" is dumb. "OOP is the ultimate tool" is dumb. Etc. Learn everything, use the tool that best solves the problem.
FP has a hard time catching on because it is a major paradigm shift that can be difficult for some programmers to understand. With FP, it is easier to write async code and to automatically parallelize in terms of concurrent scalability. Some code I've written in imperative/FP is fully thread-safe without the use of locks so team members don't realize all the async and tasks going on with the support for an unknown number of network connections. That non-understanding does have some drawbacks. The advantage is that I don't have to consider its thread-safety later on. I haven't done performance benchmarks though nobody has found any performance issues. The concept of a microservice is that it is a large external function in FP. I'm not a paradigm purist and will reach for the tool that I think would work the best.
Smalltalk is really fun to use. It's a living system full of objects that you can modify (mutate) for fun and see what breaks. Educational systems, such as Etoys and Scratch, were built on top of it. If you're daring enough, you can even modify its compiler while using it. And if you make a mistake, you have save points (images) to save the day. Functional languages, on the other hand, aim at writing repeatable and testable algorithms by limiting side effects. Their focus on immutable data help avoid mistakes that stem from complex graphs of mutable objects and unconstrained concurrency. They both have their uses. One is explorative and playful the other is rigorous and predictable.
*Way* too much emphasis on parallelization. It's like dunking on the OO 'reuse' argument that just doesn't work beyond the most basic stuff. That doesn't mean OO is useless, just that aspect as oversold.
2:47 Fortran is a modern programming language that now sees its renessaince with an active community and new set of tools developed. :) It actually was in the top 10 TIOBE index for the past couple months!
I have used Scala a about a decade ago and got it in production systems. Not pure FP however it does nudge you to think about state, idempotency, etc. Now even if I code in Python and JavaScript I definitely like there are FP influenced constructs and think about the lessons I learned back then.
As long as the BEAM is still used, functional will never die. The people who actually write code that needs to scale (and vercel doesn't count, sorry) use it for a reason.
I feel the need to nitpick about the clockspeed claim of 3 GHz, true enough that the previous trend has broken, but a lot of CPUs these days are capable of ~5 GHz sustained if adequately cooled. Even if we ignore "gaming PCs" and look at the pinnacle of reliability, IBM mainframes, their newest CPU is the Telum II which runs at a fixed 5.5 GHz. So I think 5 GHz would be a better choice as the current practical limit of clock speed.
In my limited experience, writing parallel programs, off the main thread, meant that I could write really unoptimised code in the parallel processes and it didn't have any impact on the program as a whole. I'm sure you wouldn't be able to measure any performance boost on a benchmark but the perceived performance was great. And writing unoptimised code takes a lot less time to write. I want to make clear that agree with everything you said in the video. Your millage may vary.
Always a thumbs up for any emphasis on Amdahls law, the most important in high performance compute. Most often for large problems that require massive parallelism one is more concerned about memory cache, memory paging and data distribution. Some problems it is cheaper to repeat calculations than to distribute those calculations, in others the very largest memory space possible is the way to go for the exact opposite reason. OO or functional is pretty far down the list, and likely immaterial, especially once the compiler has done its thing. If the kernel matters that much then assembly may be required, but that still has to do better than the compiler on its own.
Nailed it. True, there's a lot more to be said both for and against, but I'm glad we're actually talking about this. FP is great, but it's not a silver bullet and there are valuable things you give up when you use it.
Thanks, good commentary! Absolutely agree: apply the approaches and paradigms that best express the problem and the solution in the most understandable, readable - and, yes, elegant! - way. Then think about performance & optimize, including parallelization. Weaned on structured programming, thence to OO and finally FP, I've found they all bring concepts that can help enable beautiful code that solves the problems. I do find myself using FP more and more for more concise code, but wherever there is persistence and mutable state, those are objects. (These days the team I'm on slings Python, but I have a crush on Julia...)
I worked for a company that used ruby and elixir, and spend some time learning both (previously I used JS and Java). I loved both languages (oop and fp respectively), but could not find another elixir job after that contract ended. I stick with ruby for personal projects. IMHO, I think the culprit is the dynamic of the job market. A competent java programmer can learn elixir in a reasonable amount of time, but the recruiters will pass on those candidates, then complain that it is impossible to staff, and suggest moving to another technology. Is a vicious circle.
Every paradigm has its place. I use OO where encapsulated state is of importance (in-memory caching comes to mind for example) and FF for modeling my data types and implementing something with inputs and outputs (often algorithms). Interesting for me was my realisation that, in the end, web requests and their responses are nothing else than input->output functions. So, for me, the functional approach fits extremely well for that kind of application.
Modern languages have just taken the best parts of several paradigms, including FP. When every class with behaviour is really a singleton that's just a module, and when every method is pure then that's really a function, the syntax is just closer to natural language so it's easier for most people to read, and less strict about mutable state in local variables, as long as that mutable state is confined to the function.
I think one argument for FP style, if we talk a language like Rust, is that it gives you a way to make higher level abstraction, and also we can get rid of the null by using the option Monad. And if the compiler can manage to make the code into a imperative style, one compilation then it should be with out cost.
@@sarabwt The way Koitlin handles null is a functional programming element. All major languages have integrated elements from functional languages, that is the real success of functional programming.
@ The way how you call a function on a type that may be null and it returns null in case the underlying object was null instead of raising an exception, that’s a functional programming pattern.
We have some interesting situation when Java stream().map(...) was MATCH MORE faster then parallelStream().map(...) on big amount of simple map operations
The value of FP is not only the pararel of performance compared to the single core. But how to compose the software and the cognitive impact of it. In my opinion, oop shines in dependency management and encapsulation, but it failed to sell inheritance as a core feature when it isn't. FP basics help maintain explicit state, avoid globals, and decouple software from time. I like both styles.
The readability, understand-ability, and maintainability by developers has to trump functional (or functional style) code most of the time, for businesses at least. I've been a dev for 34 years and hate picking up someone else's code that is unfathomable, taking far too long to figure out what it is doing.
Guy Steele (of Scheme and Common Lisp fame) tried (and he tried _really hard)_ to make a language that would actually live up to the promise of effortless parallelism. It was called "Fortress", and in many ways it was heavily influenced by functional ideas, but built from the ground up with this vision of "abstracting away" the computational substrate as a core design idea. Long story short, it didn't work. They came across some very difficult problems along the way and the project, while promising, was abandoned. This idea that FP will just automatically and effortlessly let you threadpool everything is a pipe dream.
@@a_rugau From what I have seen Rust is Functional inspired but isn't functional in the traditional sense. Due to its borrow checker you can write low level code and know it will work with certain guarantees, like functional, however, the mechanism it does it to give these safety guarantees don't use immutability but the borrow checker. Its syntax is inspired from the ML functional family, esp. OCAML
Well, certainly the default stance of variables to being immutable goes some way to justifying that claim, but I think I'd think of it as a hybrid, rather than a pure functional language, like most modern languages.
Horses for courses is right. Or perhaps horses for environments? I once worked on Java applets in the browser, and I can say that OOP is not a good fit for that environment. It cured me of my Java snobbery when I saw how easy it was to handle events and async code using first-class functions that even early Javascript supported, compared to the laborious boilerplate that Java 5/6 required.* I recall an earlier video on this channel about event-driven programming, and my feeling is that this is a paradigm that may well suit FP more. At least, if GUI coding is any indication. I have no data to support that claim, though. :( * It has been a while since I have worked in the Java space. I would expect that the lambdas have improved things now.
One of the reasons I thought object orientated programming took over was because back in the day (my day was the mid-90s), moving data around was extremely expensive and it was better to organise functions around data than shuttle data by copying it around through functions. Moving the data was more expensive cause you'd have to deal with whether you're in the first 640kb, or 1mb, or higher memory and then you'd have to maybe deal with DMA transfers etc. I know it's not the ONLY reason. But pointers basically solve this by passing references to data that never moves in ram which can be passed into functions which is a lot faster. Especially if you also consider that you need to maybe copy the data, another very expensive behaviour especially when you only have 33Mhz of cpu time and no DMA controller to help you. These days functional styles I guess are not so much of a problem anymore. Data can be moved around and there is gigabytes of if to make copies in and never run out. But yeah...in the 90's, these things were real problems you needed to deal with. Lets ignore completely the issue of shuttling polygon data across the ISA/PCI/AGP buses which was basically one of the biggest performance hogs of games in the 90s where large amounts of data was being processed on a regular basis by normal users (not scientific programmers). Then the idea of vertex buffers which let you shuttle huge amounts of data over the AGP bus in one go sort of solved the problem but was the first step in a larger story.
Functional programming, like OOP, became a commodity in nearly all modern languages. I often apply FP and functional concepts in C++ or Go, especially in multi-threaded applications. If it cannot be done purely functional, I step back to single threaded solutions, because it's often an indicator that the algorithm is not suitable for parallel processing (think twice before using mutexes or semaphores). But the most simple solution is usually just an imperative procedure. OOP shines when used like Alan Kay suggested - by radical decoupling and only using messages for communication. Use the paradigms where you gain the biggest benefit from them, always take the middle path and never trust in silver bullets!
I see a lot of FP videos, but every time I've encountered it in the wild, there's a dearth of unit tests (or any tests at all) and no one wants to touch it for fear of breaking it because somehow inevitably the person who wrote it no longer works at the client. The assumption seems to be that it runs in a magical black box (though I myself have a very mixed style in Python).
I'm currently learning Haskell to work on my FP muscles and am enjoying the exercise, but gotta say, not sure I'd want to use it in production. The language itself is fine, with its own fair share of quirks, but the developer experience with documentation, the LSP, and package management is a bit of pain. I'd love to work on a full production project in Haskell just to see what the heck I'm missing.
@@jonathanjacobson7012 [...] May or may not be a good method of abstractly representing the problem at hand. But sure, it is individuals' problems if recursion doesn't represent the problems they want to solve.
I went through a phase of loving fp and in the process took it too far. I lot of code was satisfying to write but sometimes difficult to read after written. I also began to fear the runtime overhead that it creates. Nowadays I’m much more pragmatic I still fp but not exclusively, rather, I like the declarative approach when it can improve maintainability. For example, I discovered that reduce can be used in more situations than at first may seem to be the case. When I see a reduce in code I know exactly what it’s trying to achieve. However solving the same problem without a reduce often means it can be harder to deduce the intentions of the code because of the lack of an instantly recognisable pattern and thus increased cognitive load. But to me practically is king, so use fp when appropriate not because you want to go all in on an ideology
Look again, at the title, I didn't claim it was dead, I posed the question. Betteridge’s Law of Headlines. It states: “Any headline that ends in a question mark can be answered by the word ‘no.’” 😉
I think it kinda correlates to the death of enthusiasm on rust backend. Something something clean code + messy internet + messy business requirement = disaster.
I also think presenting FP as a huge performance boost is wrong. Fp can only outshine OO performance wise in machine learning which rely heavely on paralellism. It's also impossible to build everything with a purely FP style At the beginning I thought I hated OO but I just had a problem with inheritance and classes. When I get rid of those and use OO ideology designed by Allan Key, everything become great So I prioritize a FP first then procedural and OO when needed
Functional programmers claim that there are no side effects, but it's not true. Without effects programs producing nothing but heat. So you need effects anyway, and you have the same problems you encounter in a non FP language, except now you additionaly need to deal with monads or a similar mechanism. For sure, in some cases it's a good safety mechanism, but in many cases it's just adds nothing more than friction. And it's not like you cannot write additional safety checks in non FP languages anyway. It's the same with static typing, it's a redundancy measure (mostly; in high performance applications they are also hints for the compiler to what exact machine data type use in a paticular moment), it's very reliable, but there is no magic in it, you can use other redundancy measures like tests to achieve same results (I still think that static/gradual typing is better but my point is it's not unavoidable). And absolutely it won't save you from logical errors, the claim that Haskell code is somehow bug free is far fetched.
Language choice isn’t based on technical merits. 90% of it is sociopolitical. If everyone going through a boot camp learns JavaScript or Python, they’re not going into jobs using functional programming.
The main advantage of using "purely" functional, or OO programming languages or a language that enforces paradigm X, is that you are "forced" to develop an new type of thinking. This is purely impossible in an environment that allows multiple paradigms. This is why C++ programmers back in the day, used C++ as C, with a sprinkle of OO ideas or we use functional ideas here and there. I think the great value of strictly X-type languages is that they force you to think that way and develop some skills that you will or will not use, depending on your problem. You do not learn Haskell to make your next big project in Haskell, but to train your brain to think AND in that way
I think comparing code snippets of toy algorithms feels a little like comparing big-O results for small values of N... Better than nothing, but not at all illustrative of how it scales to even slightly larger codebases and teams. Also, although I also found the Scala code to be more verbose, I don't think it's safe to conclude it's more complex just by LOC. The imperative style in the Java example is easier to parse, but you're also forced to parse through it every time. Of course it's possible to factor the code into properly abstracted functions, but I'd argue FP/declarative pushes you more naturally toward doing it from the start whereas imperative (and to a similar extent OO) doesn't. Would also be interested to hear from a Scala dev how well crafted that code is or whether the same result could be obtained without so much hoop jumping.
Yeah, see, I'm probably wrong but I've always said there's a (not pure) functional language right at the top of "the list"... JavaScript. I always think that a nice, neat description of JavaScript is "Lisp dressed up in C's clothing". Oooh... Dave throwing shade at Zig! ☹😉
For a long time now I’ve maintained that developers fail to appreciate just how fast computers are. Most efforts at multi-threading add complexity, increase errors, introduce overheads orthogonal to the problem; and ultimately slow things down. The biggest mistake is failing to be fully aware of what the performance bottle-neck actually is. When it’s not the CPU, the only thing multi-threading “achieves” is making multiple cores fight for access to the bottle-necked resource.
...and it is very rarely "the CPU"! Everything else is SO MUCH SLOWER than any CPU these days, that a huge amount of the work in a high performance system is keeping the CPU fed with data.
8:34 we really have good mainstream language support for parallelisable programming though. Plenty of things in theory could be parallelised… like the mapping and filter functions performed on collections. But there isn’t any pipe function in any language that I’ve used. Eg. Each method call in `myArr.filter(filterFn).map(someTransformation).groupBy(someGrouping)` returns a collection before the next method call. That can’t be parallelised. If we had pipes, then each method would get called one after the other for each individual element. That process can be parallelised. Effectively, the group y would be different from the rest, as it would likely need to operate on a collection of Tasks or Promises, and await the results before dumping into the final data structure.
In C#, calling Linq-methods like Group etc. is a pipe operation. It doesn't return a list, it returns an iterator (IEnumerable). The iteration flows right to left and starts, when For...each is called on the rightmost reference. It is also a great solution to write memory friendly code. There is support for awaiting iterations, which is handy when you need to aggregate a host of files.
Ive been experimenting with functional programming, it is good but i have been using a hybrid approach, sometimes using a direct function call in an object is more performant and sometimes having a decoupled task or service is more appropriate. I probably dont fully grasp what is an isnt functional programming, but i have enjoyed using messages to keep everything nice and tidy and synchrononized.
I am in the camp that functional programming is just a set of tools that can be applied to any other paradigms. I don’t see why mixed paradigm programming languages are not put into a category of its own, these languages have a greater impact for most developers and that’s why they end up being much more popular. But, it’s strange that functional programming languages don’t have object oriented concepts integrated into them as object oriented languages have these days. I haven’t tried using pure functional languages as I find the syntax more difficult to understand as they enjoy hiding everything in symbols, plus it looks like many people are creating their own libraries in these pure functional languages.
I mean who are those "we" who are going to move one way or another? Hundred millions of coders only knowing how to plug a framework into their CRUD app? They would be happy to use COBOL, BASIC, Python or any other ad hoc stuff with the lowest entry threshold possible, only it's not them who decide it. E.g. Apache Spark dealing with big data is written in Scala and is most efficiently used from applications written in Scala. Whether coders want that or not they have to learn Scala in order to use it. That would be the case with any area where FP is a fit: once problems become big enough, they require more math to be solved, and FP is some of that math. That's the way the world is moved, not via mediocracy voting.
You can split FP into two camps: the pragmatic and the more pure version based on category theory, with functors, monads, and actual mathematical laws. You won't see the latter adopted because it requires a lot more skill and not a lot of people have even heard of it.
Multiparadigm languages like Python, JavaScript or Swift are procedural, functional (to an extent) and object-oriented (to an extent) all in one (kinda). We should inspect, at what extent functional ideas like pure functions are actually used in these languages. And at least in my domain (data processing) while OOP is used of course, but it is not a leading paradigm in good code bases, at least not in “Java style”. Most new mainstream languages (like Go, Rust, Swift, Kotlin) are more or less as functional as object-oriented. And although CS education has a strong bias towards OOP style programming (this is my feeling), developers learn how to write different style of programs at the job, e.g. not wrapping functions into classes unnecessarily if they don’t need to.
FP has (slowly) been siping in imperative/oop languages, and with time its become the norm. We will never see "real" FP (like in ocaml) as popular as something like javascript. Its does not matter, as the impact has been there, and devs are more aware. There might still be room for a killer lang that "takEs oVer thE worlD", but that remains to be seen.
Is a purely FP language a good choice for front end applications (web, mobile or desktop)? And if so, are there examples of that? The most simple definition of FP I use for myself is that I make use of a function pointer rather than a data pointer.
I don't think we can call LISP a functional language. It's a very different programming model to what existed at the time, and it had a different idea about how functions could be manipulated and applied, but still a procedural language which happily works with non-immutable values and shared state. McCarthy used the word "lambda" to label a function declaration, but he has written that he had no interest in (or knowledge of) lambda calculus - it just seemed like a sensible sort of thing to call a function declaration.
Idea in functional paradigm is not the performance. It is avoiding side effects. In fact, when solving problem, functional paradigm should be the first to try. If that is too hard to understand or seems to be complex, then object oriented paradigm can be used. While functional paradigm avoids side-effects, to be useful program it needs side-effects. Next best option after functional paradigm is to split problem to functional tasks and put them to pipeline. Then there is only one way to mess it up: using wrong order of tasks. But why should anyone use OOP is that code is written to other people and to be easy to understand. When some local states and messaging is involved, or need to design high level structures OOP is then right tool make those inside process that is running.
The approach of thinking about a single way of solving a problem has the benefit that many things can be assumed to be true and the programmer can step on these assumptions allowing them to focus their attention on the actual problem solving and not on the coding style. The problem is that this approach comes with the cost of worse performance (both in terms of writing the code that doesn't fit the paradigm well and in terms of actual runtime performance). Nevertheless, this approach is widely used in the industry. For example, when using a specific library or framework the programmer is bound to write their code in a style that fits that particular library. And often using two libraries that do the same thing but differently results in a lot of code mess and complicates stuff even though one library could be better suited in one part of the application and the other library could be better suited in another part of the application.
The idea that Functional Programming was always going to take of in an Imperative-based system is just like saying the Chinese language will be the next standard for communication in an English-based country; it was never going to happen because what's the point in learning some other foreign and abstract idea, when you've already learnt your own abstract language that is tailor-made for the exact environment you use.
Hey mate, Functional Programming is top-notch. Honestly, those familiar with the bridge between DOP Data Oriented Programming, and Functional Programming should get acquainted. The challenges of design decisions to mitigate and deliver great software need further exploration for people to understand the implications, which are indeed very positive. Sincerely, this is not a subjective opinion, but an objective fact, as I have read about Functional OOP Book and seen the power of this design pattern.
Stackoverflow pools from a statistics viewpoint are completely useless to infer anything. If you volunteer yourself to answer a pool, you don't have a proper sample and therefore any inference based on it is invalid.
Maybe the hype has died down, though the patterns feel much more prevalent throughout code bases. Best case as any hype passes is to have the elements that organically make sense be absorbed by the relevant parties/sectors. Personally am still reading books on functional cpp, and patterns learned from an old ocaml course still heavily define my style in all languages. So it hasn't gone anywhere for me.
Modern programming languages like Go and Rust don't have classes or inheritance. Instead they have come up with new concepts that make the code much simpler to write and maintain.
I've started learning clojure. I see that the pick of the popularity for this language was in 2014. It was more popular than Scala or kotlin, nowadays in JVM world it flipped, the most functional languages are less popular.
I think this video, as many others, confuses parallelism with concurrency. Concurrency is not about running things faster. Also, FP is not (only) about using pure functions. FP is about using higher-order things. Mutation is only one type of side effect. So FP has more to do with correctness - building larger systems without bugs. Languages have not really embraced FP. Having iterators in language is not FP.
For sure pure functional programming languages are not widespread in use, and I don't remember them really ever being widespread in use. But you could say the same about pure Object Oriented Programming languages. Hmnn, does such a thing even exists? I guess a Pure Object Oriented language would do things like make private members mandatory. Functional ideas have been spreading to languages and frankly, it's possible to write programs with a Functional Mindset in just about every of the languages at the top of the list. Quite frankly, as a Java Dev there are OOP concepts I avoid as a plague and discourage in code reviews whenever possible. While at the same time there we are encouraging Java code that aggressively uses pseudo-nomads just so that we can avoid null pointer exceptions (Optional). You'll see a thousand lambdas in my Java code before you see the "extends" keyword.
My advice: program at least 3 years in a FP language and then make a 2nd video. Hearsay is not good enough. The main problem is mainstream, critical mass or what is a safe choice career-wise for both developers and their managers. Started a new FP project 5 years ago - ask me how many times I was (jokingly) asked if it was a good choice, if hiring is OK etc...
I like functional programming elements in not pure FP languages, I try to program in a functional way as much as possible and my language allows. I think in many ways it's more expressive and concise than OOP. But many of the most bizzare and even nonsensical takes on programming I ever heard were from FP purists.
Name a new programming language in the last decade, hell two decades, that are purely OOP. I can’t. Everything popular that’s come out in the last decade (Elixir,Clojure,Swift,Julia,Kotlin,TypeScript,Go,Dart,Rust,Zig, Odin, etc) have all been either functional, functional/procedural, or entirely procedural. OOP has disappeared from new languages entirely.
It's false that anything you can do in one language, you can do in another. Speed. Performance. You cannot run software fast in a language that runs sluggishly. Response times are important, not just for games.
Being able to parallelise is for sure an argument used in favour of FP, but I feel this talk focusses (too) heavily on that aspect to make general claims about FP. For example, for me a key benefit of FP is being able to look at the signature of a function and know all there is to know about its inputs and outputs. This allows for composition of smaller functions into larger ones. I have no intent to start a discussion here but piecing together behaviour from (larger) object hierarchies is not exactly easy. FP, as I believe is stated as well, is in fact very popular seeing most major languages have added FP to their feature set. Finally, if being able to easily move between both paradigms is of value, I wonder why languages like Scala, Kotlin and Rust are not more popular. Learn any of these and you can adopt either style ( maybe to a lesser extend Rust).
Functional programming is just an approach prioritizing separation of data and business logic, leaving data alone instead of mutating it endlessly, and using composition of pure (and not so pure) functions as an alternative to inheritance. In terms of where it is: it's literally everywhere. Nowadays even Java gave up and introduced lambdas; map/filter/reduce are staples for quite a while in a lot of languages, notably except Go for some reason, but otherwise more modern languages take elements of every programming style (as they should be) if using them makes sense, but note that nobody's in a rush to bring inheritance back, or even introduce it into the language to begin with. FP ain't a silver bullet - nothing is, but it's definitely a neat methodology that offers some interesting concepts. No need to be salty about OOP not being the coolest kid on the block, Jesus 😹 In terms of concrete examples of FP being used: - Rust is heavily inspired by FP; - OCaML is functional (and it also has OO elements, hence O in OCaML, but nobody uses them 😸), and it's the language of choice at Jane Street for one; - need I mention all the FP features in JavaScript and Python at the very least? - Lua, which is gaining popularity due to being easily embeddable and thus being used all over the place, from scripting in games on Roblox platform to web server, reverse proxy and load balancers in Nginx, and let's not forget Neovim, which endorses Lua as hard as possible And those are just the ones that immediately spring to mind. People also abandon OOP in favor of other paradigms, like procedural for instance. All in all, it wasn't even so much "hype" about switching to FP as much as it was hype to jump ship from OOP train, because people have been going overboard with OOP nonsense whether using it made sense or not. And yes, in some contexts it still makes perfect sense to use OOP.
Before watching the video: No. It is definitely not dead. I learned a ton from functional programming that I selectively apply depending upon the situation.
Functional programming is nice to have, for problems that are best expressed in that way. But in Java at least, from what my accidental research into how it came to be and what are its pros and cons, I have found out, that it is neither good at shortening code, nor does it make it more readable, it breaks hotpath, and some early examples I have found were nothing short of extreme clever misuse of generics to avoid use of instanceof operator (write 70+ lines of code to make the ugly if else if instanceof go away with cute switch statement and go from offending ugly nine lines down to cute four, at least in the mind of clever author of that programming boondoggle). The problem with functional programming that I have is that it requires a far more specific mindset than imperative or object oriented when compared to, shall we say, everyday mindset a person has. Personally I would prefer to use functional language to solve functional problem and cleanly connect it to my java program than to see the mess, that was bolted on.
I prefer the functional way of thinking. That is a me thing, I guess. But most people prefer the imperative style of programming. Anyway, all your functional code gets compiled down to imperative ASM at some point.
Are YOU a Great Programmer? or a Regular Programmer with GREAT Habits. Download my FREE guide on how to adopt 30 of my favourite Programming Habits. Get yours HERE ➡ www.subscribepage.com/great-programmer
Automatic parallelization and performance really isn't the main reason to choose a functional programming language. Algebraic data types for domain driven design, immutability by default and concepts like referential transparency produce code that is much easier to reason about the program state by merely reading the code rather than assessing all mutable fields and properties across multiple objects that talk to each other, usually by having to step through the operations in a debugger.
@@robertlenders8755 DDD mentioned
Not always. A gazillion function calls are often difficult to read and debug.
@@piotrc966 A gazillion of everything is hard to read. Think of the 234 layers of interfaces in any oop lang.
@@J-Kimble But no one argues that an oversized objectivity is good. And many argue that a purely functional approach is better. No, it isn't. The code is often bloated and hard to debug. Much more readable is imperative with funcitonal elements. Not pure fuctional.
FP has had huge influence on other languages, with features like lambdas and immutability and declarative coding.
Not just has had. There are two ways of language development: towards Lambda Calculus, Category Theory and other math, or towards ad hoc stillborn internally controversial ideas (COBOL, OOP, etc). And this concerns not just languages, but the application architecture as well.
Yeah. I learned functional through Java libraries, not a functional language. Did a bit more in .Net. I’ve got 1 year in production Clojure but that’s it for me.
I still think in functional terms daily in Java, Kotlin, Typescript.
In Clojure we still used protocols quite a bit and the impure bits of the codebase looked fairly OO.
Perhaps thinking in something closer to a natural language (conditionals, repetition and commands) is more accessible to most than mathematical thinking...and not many people have been exposed to algebraic structures, functors and monads. @@InconspicuousChap
Functional programming doesn’t just potentially make your code run faster, it also allows forces you to structure your code in terms of inputs and outputs, making it easier to test and reuse. This can of course be done in OOP languages as well, but then it’s much easier to make a mess out of globals and side effects.
How exactly does functional programming make your code faster ?
Functional programming is math. OOP is anti-math, promoting poor code structure and awful data models.
@ If you write pure functions it is much easier and safer to run those over a data collection using many threads or even using different machines. Think “map-reduce” where each worker gets a small piece of the total work where those results are later collected in a reduce step.
This CAN of course be done in any language, but then you have to worry about thread safety in a way that you don’t need to to if all your data is immutable.
@@krumbergify So the main benefit of functional programming is immutability which can really be achived in any language, it is just the pure functional languages that enforce it at the compiler level.
@ Yes. Guarantees matter. You can certainly write concurrency safe code in C++, but Rust makes it much easier since the compiler enforces that there are no data races in your Rust code (as long as you don’t write unsafe blocks).
I've abandoned the idea of FP after I benchmarked it years go. Having said that, OOP has its overheads so I use it only when it makes sense.
Hi Dave, thank you for the interesting video. It is difficult to come up with hard data on performance, but maybe my experience is still worth mentioning:
In 2012, we one wrote a data processing program in Java, using self-implemented purely functional streams (not the java stream lib!) and data structures. There were only two single-threaded streams, one in the middle for sorting and then the final stream for collecting the data. All other stream transformations inbetween could be parallelized horizontally and vertically. While our program run 3x faster on a quadcore compared to a single core, I agree that if tight loops were written in a heavily tuned imperative/destructive style, the program might have been about 20x faster, only limited by I/O. The funtional style allowed us, however, to be lazy with optimization and focus more on testability and expressivness. So my other observations might be of interest: 1. Conversions from iterators to immutable, lazy streams and vice versa enabled us to travel between both worlds, with the former being a bit tricky to implement. 2. Immutability made it easy to transparently compress the data outside the working window, which actually increased(!) the overall speed. 3. Writing tests worked like a charm and even a small testing dsl could be written in only 2 days. 4. Lazy streams and structural sharing lead to memory leaks at tail calls that were difficult to track due to the fact that eclipse and the jdk produced different bytecode. 5. In an imperative language you can implement purely functional data structures which are impossible to write in most (all?) purely functional language, namely those involving identity checking via deduplication for fast diffing. 6. One must be very careful that non-funtional side effects don't leak, for instance, identity hashs destroy referential transparency and therefore repeatability of tests.
In the end, it was a fun experience, and the new program was still 20x faster than the old, db-centric C++ solution. LOC was reduced from approx. 300.000 to 25.000. The old program did not have any tests while the 25.000 for the new program even included ca. 8000 lines for the new data structures and 10.000 lines for tests. As far as I know, the program still runs flawlessly, processsing several 100.000 fairly complex data records per day within a few minutes. Of course, the numbers are from memory and not exact, but I'm pretty sure that they faitfully describe the overall picture.
It's like Cartesian vs Polar coordinates. Some problems are better solved or expressed in one vs the other. Religious fanaticism is baked into some people's DNA.
@@Laggie74 I don't like what you're saying! I'm gonna go become a mips programmer!!!
By my measure, functional programming had a resurgence about a decade ago. Mainstream languages subsumed some of those features, and static typing took charge then with things like Typescript, Rust, and typing for Python.
I think automatic parallelization isn't a big deal in major programs. But one place I really like it is with scripting. I experimented with writing my utility scripts in a variety of languages, and one thing I really liked about Elixir was how trivial it was to turn most of my serial scripts into parallel ones. All it usually involved was changing a couple lines of code. Experimentation and measuring was trivial.
Lots of functional languages can also do OOP. Like Clojure with their multimethods, which mimics a less powerful version of Common Lisp's OOP.
If you've never tried out OOP in Common Lisp, I recommend it. It made it a real joy for me.
FP is not a class of programming languages. As it suggests, it is a programming paradigm. So, your analysis of FP's popularity based on the popularity of individual languages is fundamentally flawed. Yes, purely FP languages like haskell and erllang are not much higher on the list than before, however almost all the major languages on that list have moved towards FP. Since, Java8 onwards, the vast majority of new Java language features were adding support for FP. Also Javascript has completely been moving towardsFP. Especially in its libraries. Ever heard of a little library called React? The reactive design at its core comes completely from FP. FP is indeed eating the world, but it is mostly doing so by changing the existing programming language giants, not by breaking through with soleley FP based languages.
I guess you didn't watch to the end 😉
I hope watching too the end will discourage me from hitting that "Don't recommend channel" button.
I'll be hitting that button. You'll not get continuous feedback from me, I'll just let you know that it's not necessarily because I disagree with you. Just that this hasn't been worth my 20 minutes, and I'm not a fan of clickbait titles in general.
Kotlin made much easier to mix functional and OO programming into the Java virtual machine
Keep a large and varied toolbox. "Functional programming is the ultimate tool" is dumb. "OOP is the ultimate tool" is dumb. Etc. Learn everything, use the tool that best solves the problem.
FP has a hard time catching on because it is a major paradigm shift that can be difficult for some programmers to understand.
With FP, it is easier to write async code and to automatically parallelize in terms of concurrent scalability. Some code I've written in imperative/FP is fully thread-safe without the use of locks so team members don't realize all the async and tasks going on with the support for an unknown number of network connections. That non-understanding does have some drawbacks. The advantage is that I don't have to consider its thread-safety later on. I haven't done performance benchmarks though nobody has found any performance issues.
The concept of a microservice is that it is a large external function in FP.
I'm not a paradigm purist and will reach for the tool that I think would work the best.
Smalltalk is really fun to use. It's a living system full of objects that you can modify (mutate) for fun and see what breaks. Educational systems, such as Etoys and Scratch, were built on top of it. If you're daring enough, you can even modify its compiler while using it. And if you make a mistake, you have save points (images) to save the day.
Functional languages, on the other hand, aim at writing repeatable and testable algorithms by limiting side effects. Their focus on immutable data help avoid mistakes that stem from complex graphs of mutable objects and unconstrained concurrency.
They both have their uses. One is explorative and playful the other is rigorous and predictable.
*Way* too much emphasis on parallelization. It's like dunking on the OO 'reuse' argument that just doesn't work beyond the most basic stuff. That doesn't mean OO is useless, just that aspect as oversold.
2:47 Fortran is a modern programming language that now sees its renessaince with an active community and new set of tools developed. :) It actually was in the top 10 TIOBE index for the past couple months!
I have used Scala a about a decade ago and got it in production systems. Not pure FP however it does nudge you to think about state, idempotency, etc. Now even if I code in Python and JavaScript I definitely like there are FP influenced constructs and think about the lessons I learned back then.
As long as the BEAM is still used, functional will never die. The people who actually write code that needs to scale (and vercel doesn't count, sorry) use it for a reason.
@@C4CH3S I guess I am a Next.js soy dev then 🤣
I can't wait to test out Gleam on the BEAM I hear it is OP.
Vercel typescript soydev andys would never understand being an elixir gigachad
Let it crash!
I feel the need to nitpick about the clockspeed claim of 3 GHz, true enough that the previous trend has broken, but a lot of CPUs these days are capable of ~5 GHz sustained if adequately cooled. Even if we ignore "gaming PCs" and look at the pinnacle of reliability, IBM mainframes, their newest CPU is the Telum II which runs at a fixed 5.5 GHz. So I think 5 GHz would be a better choice as the current practical limit of clock speed.
In my limited experience, writing parallel programs, off the main thread, meant that I could write really unoptimised code in the parallel processes and it didn't have any impact on the program as a whole. I'm sure you wouldn't be able to measure any performance boost on a benchmark but the perceived performance was great. And writing unoptimised code takes a lot less time to write. I want to make clear that agree with everything you said in the video. Your millage may vary.
Always a thumbs up for any emphasis on Amdahls law, the most important in high performance compute. Most often for large problems that require massive parallelism one is more concerned about memory cache, memory paging and data distribution. Some problems it is cheaper to repeat calculations than to distribute those calculations, in others the very largest memory space possible is the way to go for the exact opposite reason. OO or functional is pretty far down the list, and likely immaterial, especially once the compiler has done its thing. If the kernel matters that much then assembly may be required, but that still has to do better than the compiler on its own.
Oh, they're out there, but since things like I/O bring ugliness to their FP purity, they do not communicate.
@@arbitrarysequence we have monads for this!
Lisp (and all its dialects) is not FP, but Parenthesis Oriented Programming
I like PoPs, but it's not limited to Lisp. Prolog is fun too!
They’re all watching the primeagen
Nailed it. True, there's a lot more to be said both for and against, but I'm glad we're actually talking about this. FP is great, but it's not a silver bullet and there are valuable things you give up when you use it.
Thanks, good commentary! Absolutely agree: apply the approaches and paradigms that best express the problem and the solution in the most understandable, readable - and, yes, elegant! - way. Then think about performance & optimize, including parallelization. Weaned on structured programming, thence to OO and finally FP, I've found they all bring concepts that can help enable beautiful code that solves the problems. I do find myself using FP more and more for more concise code, but wherever there is persistence and mutable state, those are objects. (These days the team I'm on slings Python, but I have a crush on Julia...)
I worked for a company that used ruby and elixir, and spend some time learning both (previously I used JS and Java). I loved both languages (oop and fp respectively), but could not find another elixir job after that contract ended. I stick with ruby for personal projects. IMHO, I think the culprit is the dynamic of the job market. A competent java programmer can learn elixir in a reasonable amount of time, but the recruiters will pass on those candidates, then complain that it is impossible to staff, and suggest moving to another technology. Is a vicious circle.
Every paradigm has its place. I use OO where encapsulated state is of importance (in-memory caching comes to mind for example) and FF for modeling my data types and implementing something with inputs and outputs (often algorithms).
Interesting for me was my realisation that, in the end, web requests and their responses are nothing else than input->output functions. So, for me, the functional approach fits extremely well for that kind of application.
Modern languages have just taken the best parts of several paradigms, including FP.
When every class with behaviour is really a singleton that's just a module, and when every method is pure then that's really a function, the syntax is just closer to natural language so it's easier for most people to read, and less strict about mutable state in local variables, as long as that mutable state is confined to the function.
I think one argument for FP style, if we talk a language like Rust, is that it gives you a way to make higher level abstraction, and also we can get rid of the null by using the option Monad. And if the compiler can manage to make the code into a imperative style, one compilation then it should be with out cost.
Null safety has nothing to do with FP. Kotlin had null safety way before rust was even a thing.
@@sarabwt i was more thinking about using an optional monad to force you to handle "null" checks at compile time
@@sarabwt The way Koitlin handles null is a functional programming element. All major languages have integrated elements from functional languages, that is the real success of functional programming.
@@janlanik2660 No it isn't. Again, null safety has nothing to do with FP.
@ The way how you call a function on a type that may be null and it returns null in case the underlying object was null instead of raising an exception, that’s a functional programming pattern.
We have some interesting situation when Java stream().map(...) was MATCH MORE faster then parallelStream().map(...) on big amount of simple map operations
The value of FP is not only the pararel of performance compared to the single core. But how to compose the software and the cognitive impact of it. In my opinion, oop shines in dependency management and encapsulation, but it failed to sell inheritance as a core feature when it isn't. FP basics help maintain explicit state, avoid globals, and decouple software from time. I like both styles.
The readability, understand-ability, and maintainability by developers has to trump functional (or functional style) code most of the time, for businesses at least. I've been a dev for 34 years and hate picking up someone else's code that is unfathomable, taking far too long to figure out what it is doing.
Guy Steele (of Scheme and Common Lisp fame) tried (and he tried _really hard)_ to make a language that would actually live up to the promise of effortless parallelism. It was called "Fortress", and in many ways it was heavily influenced by functional ideas, but built from the ground up with this vision of "abstracting away" the computational substrate as a core design idea.
Long story short, it didn't work. They came across some very difficult problems along the way and the project, while promising, was abandoned.
This idea that FP will just automatically and effortlessly let you threadpool everything is a pipe dream.
Great content sir! Thank you.
May I ask, would Rust be considered functional? I've dip the toe in it, and seems like it wants to be seen that way.
@@a_rugau From what I have seen Rust is Functional inspired but isn't functional in the traditional sense. Due to its borrow checker you can write low level code and know it will work with certain guarantees, like functional, however, the mechanism it does it to give these safety guarantees don't use immutability but the borrow checker.
Its syntax is inspired from the ML functional family, esp. OCAML
Well, certainly the default stance of variables to being immutable goes some way to justifying that claim, but I think I'd think of it as a hybrid, rather than a pure functional language, like most modern languages.
Horses for courses is right. Or perhaps horses for environments?
I once worked on Java applets in the browser, and I can say that OOP is not a good fit for that environment. It cured me of my Java snobbery when I saw how easy it was to handle events and async code using first-class functions that even early Javascript supported, compared to the laborious boilerplate that Java 5/6 required.*
I recall an earlier video on this channel about event-driven programming, and my feeling is that this is a paradigm that may well suit FP more. At least, if GUI coding is any indication. I have no data to support that claim, though. :(
* It has been a while since I have worked in the Java space. I would expect that the lambdas have improved things now.
One of the reasons I thought object orientated programming took over was because back in the day (my day was the mid-90s), moving data around was extremely expensive and it was better to organise functions around data than shuttle data by copying it around through functions. Moving the data was more expensive cause you'd have to deal with whether you're in the first 640kb, or 1mb, or higher memory and then you'd have to maybe deal with DMA transfers etc.
I know it's not the ONLY reason. But pointers basically solve this by passing references to data that never moves in ram which can be passed into functions which is a lot faster. Especially if you also consider that you need to maybe copy the data, another very expensive behaviour especially when you only have 33Mhz of cpu time and no DMA controller to help you.
These days functional styles I guess are not so much of a problem anymore. Data can be moved around and there is gigabytes of if to make copies in and never run out. But yeah...in the 90's, these things were real problems you needed to deal with.
Lets ignore completely the issue of shuttling polygon data across the ISA/PCI/AGP buses which was basically one of the biggest performance hogs of games in the 90s where large amounts of data was being processed on a regular basis by normal users (not scientific programmers). Then the idea of vertex buffers which let you shuttle huge amounts of data over the AGP bus in one go sort of solved the problem but was the first step in a larger story.
"object orientated programming" will never cease to trigger me. but it is personal preference I guess!
@@gronki1 yeah, who hasn't thrown up a little bit after reading java code and finding an AbstractFactoryGeneratorRepositoryController.java 🤣
Functional programming, like OOP, became a commodity in nearly all modern languages.
I often apply FP and functional concepts in C++ or Go, especially in multi-threaded applications. If it cannot be done purely functional, I step back to single threaded solutions, because it's often an indicator that the algorithm is not suitable for parallel processing (think twice before using mutexes or semaphores).
But the most simple solution is usually just an imperative procedure.
OOP shines when used like Alan Kay suggested - by radical decoupling and only using messages for communication.
Use the paradigms where you gain the biggest benefit from them, always take the middle path and never trust in silver bullets!
I am an F# developer and I use it for domain modelling and readability
Yeah, FP languagea are great for domain modeling! I like using Scala for that
I see a lot of FP videos, but every time I've encountered it in the wild, there's a dearth of unit tests (or any tests at all) and no one wants to touch it for fear of breaking it because somehow inevitably the person who wrote it no longer works at the client. The assumption seems to be that it runs in a magical black box (though I myself have a very mixed style in Python).
I'm currently learning Haskell to work on my FP muscles and am enjoying the exercise, but gotta say, not sure I'd want to use it in production. The language itself is fine, with its own fair share of quirks, but the developer experience with documentation, the LSP, and package management is a bit of pain. I'd love to work on a full production project in Haskell just to see what the heck I'm missing.
@@ripwolfe elixir is much more suited for production than haskell
FP is also about recursion, which may (or may not) improve your understanding of how to solve a probelm.
@@jonathanjacobson7012
[...] May or may not be a good method of abstractly representing the problem at hand.
But sure, it is individuals' problems if recursion doesn't represent the problems they want to solve.
I went through a phase of loving fp and in the process took it too far. I lot of code was satisfying to write but sometimes difficult to read after written. I also began to fear the runtime overhead that it creates. Nowadays I’m much more pragmatic I still fp but not exclusively, rather, I like the declarative approach when it can improve maintainability. For example, I discovered that reduce can be used in more situations than at first may seem to be the case. When I see a reduce in code I know exactly what it’s trying to achieve. However solving the same problem without a reduce often means it can be harder to deduce the intentions of the code because of the lack of an instantly recognisable pattern and thus increased cognitive load. But to me practically is king, so use fp when appropriate not because you want to go all in on an ideology
Given the 250 pages before an assignment statement was used in the SICP book, it's not really as "dead" as you claim it is LOL
Look again, at the title, I didn't claim it was dead, I posed the question. Betteridge’s Law of Headlines. It states: “Any headline that ends in a question mark can be answered by the word ‘no.’” 😉
I think it kinda correlates to the death of enthusiasm on rust backend. Something something clean code + messy internet + messy business requirement = disaster.
I also think presenting FP as a huge performance boost is wrong. Fp can only outshine OO performance wise in machine learning which rely heavely on paralellism. It's also impossible to build everything with a purely FP style
At the beginning I thought I hated OO but I just had a problem with inheritance and classes. When I get rid of those and use OO ideology designed by Allan Key, everything become great
So I prioritize a FP first then procedural and OO when needed
Functional programmers claim that there are no side effects, but it's not true. Without effects programs producing nothing but heat. So you need effects anyway, and you have the same problems you encounter in a non FP language, except now you additionaly need to deal with monads or a similar mechanism. For sure, in some cases it's a good safety mechanism, but in many cases it's just adds nothing more than friction. And it's not like you cannot write additional safety checks in non FP languages anyway. It's the same with static typing, it's a redundancy measure (mostly; in high performance applications they are also hints for the compiler to what exact machine data type use in a paticular moment), it's very reliable, but there is no magic in it, you can use other redundancy measures like tests to achieve same results (I still think that static/gradual typing is better but my point is it's not unavoidable). And absolutely it won't save you from logical errors, the claim that Haskell code is somehow bug free is far fetched.
Language choice isn’t based on technical merits. 90% of it is sociopolitical. If everyone going through a boot camp learns JavaScript or Python, they’re not going into jobs using functional programming.
The main advantage of using "purely" functional, or OO programming languages or a language that enforces paradigm X, is that you are "forced" to develop an new type of thinking.
This is purely impossible in an environment that allows multiple paradigms. This is why C++ programmers back in the day, used C++ as C, with a sprinkle of OO ideas or we use functional ideas here and there.
I think the great value of strictly X-type languages is that they force you to think that way and develop some skills that you will or will not use, depending on your problem. You do not learn Haskell to make your next big project in Haskell, but to train your brain to think AND in that way
I think comparing code snippets of toy algorithms feels a little like comparing big-O results for small values of N... Better than nothing, but not at all illustrative of how it scales to even slightly larger codebases and teams. Also, although I also found the Scala code to be more verbose, I don't think it's safe to conclude it's more complex just by LOC. The imperative style in the Java example is easier to parse, but you're also forced to parse through it every time. Of course it's possible to factor the code into properly abstracted functions, but I'd argue FP/declarative pushes you more naturally toward doing it from the start whereas imperative (and to a similar extent OO) doesn't. Would also be interested to hear from a Scala dev how well crafted that code is or whether the same result could be obtained without so much hoop jumping.
Yeah, see, I'm probably wrong but I've always said there's a (not pure) functional language right at the top of "the list"... JavaScript. I always think that a nice, neat description of JavaScript is "Lisp dressed up in C's clothing".
Oooh... Dave throwing shade at Zig! ☹😉
For a long time now I’ve maintained that developers fail to appreciate just how fast computers are.
Most efforts at multi-threading add complexity, increase errors, introduce overheads orthogonal to the problem; and ultimately slow things down.
The biggest mistake is failing to be fully aware of what the performance bottle-neck actually is.
When it’s not the CPU, the only thing multi-threading “achieves” is making multiple cores fight for access to the bottle-necked resource.
...and it is very rarely "the CPU"! Everything else is SO MUCH SLOWER than any CPU these days, that a huge amount of the work in a high performance system is keeping the CPU fed with data.
8:34 we really have good mainstream language support for parallelisable programming though. Plenty of things in theory could be parallelised… like the mapping and filter functions performed on collections. But there isn’t any pipe function in any language that I’ve used.
Eg. Each method call in `myArr.filter(filterFn).map(someTransformation).groupBy(someGrouping)` returns a collection before the next method call. That can’t be parallelised. If we had pipes, then each method would get called one after the other for each individual element. That process can be parallelised. Effectively, the group y would be different from the rest, as it would likely need to operate on a collection of Tasks or Promises, and await the results before dumping into the final data structure.
In C#, calling Linq-methods like Group etc. is a pipe operation.
It doesn't return a list, it returns an iterator (IEnumerable). The iteration flows right to left and starts, when For...each is called on the rightmost reference. It is also a great solution to write memory friendly code.
There is support for awaiting iterations, which is handy when you need to aggregate a host of files.
There is a nice conference by Richard Feldman about why FP has not become the norm.
Ive been experimenting with functional programming, it is good but i have been using a hybrid approach, sometimes using a direct function call in an object is more performant and sometimes having a decoupled task or service is more appropriate. I probably dont fully grasp what is an isnt functional programming, but i have enjoyed using messages to keep everything nice and tidy and synchrononized.
I am in the camp that functional programming is just a set of tools that can be applied to any other paradigms. I don’t see why mixed paradigm programming languages are not put into a category of its own, these languages have a greater impact for most developers and that’s why they end up being much more popular. But, it’s strange that functional programming languages don’t have object oriented concepts integrated into them as object oriented languages have these days. I haven’t tried using pure functional languages as I find the syntax more difficult to understand as they enjoy hiding everything in symbols, plus it looks like many people are creating their own libraries in these pure functional languages.
We're alive and well in HFT and finance in general.
I mean who are those "we" who are going to move one way or another? Hundred millions of coders only knowing how to plug a framework into their CRUD app? They would be happy to use COBOL, BASIC, Python or any other ad hoc stuff with the lowest entry threshold possible, only it's not them who decide it. E.g. Apache Spark dealing with big data is written in Scala and is most efficiently used from applications written in Scala. Whether coders want that or not they have to learn Scala in order to use it. That would be the case with any area where FP is a fit: once problems become big enough, they require more math to be solved, and FP is some of that math. That's the way the world is moved, not via mediocracy voting.
You can split FP into two camps: the pragmatic and the more pure version based on category theory, with functors, monads, and actual mathematical laws. You won't see the latter adopted because it requires a lot more skill and not a lot of people have even heard of it.
Multiparadigm languages like Python, JavaScript or Swift are procedural, functional (to an extent) and object-oriented (to an extent) all in one (kinda). We should inspect, at what extent functional ideas like pure functions are actually used in these languages. And at least in my domain (data processing) while OOP is used of course, but it is not a leading paradigm in good code bases, at least not in “Java style”. Most new mainstream languages (like Go, Rust, Swift, Kotlin) are more or less as functional as object-oriented. And although CS education has a strong bias towards OOP style programming (this is my feeling), developers learn how to write different style of programs at the job, e.g. not wrapping functions into classes unnecessarily if they don’t need to.
18:40 An excellent demonstration of the danger of premature optimisation!
FP has (slowly) been siping in imperative/oop languages, and with time its become the norm. We will never see "real" FP (like in ocaml) as popular as something like javascript. Its does not matter, as the impact has been there, and devs are more aware. There might still be room for a killer lang that "takEs oVer thE worlD", but that remains to be seen.
Is a purely FP language a good choice for front end applications (web, mobile or desktop)? And if so, are there examples of that? The most simple definition of FP I use for myself is that I make use of a function pointer rather than a data pointer.
I don't think we can call LISP a functional language. It's a very different programming model to what existed at the time, and it had a different idea about how functions could be manipulated and applied, but still a procedural language which happily works with non-immutable values and shared state. McCarthy used the word "lambda" to label a function declaration, but he has written that he had no interest in (or knowledge of) lambda calculus - it just seemed like a sensible sort of thing to call a function declaration.
Idea in functional paradigm is not the performance. It is avoiding side effects.
In fact, when solving problem, functional paradigm should be the first to try. If that is too hard to understand or seems to be complex, then object oriented paradigm can be used.
While functional paradigm avoids side-effects, to be useful program it needs side-effects. Next best option after functional paradigm is to split problem to functional tasks and put them to pipeline. Then there is only one way to mess it up: using wrong order of tasks.
But why should anyone use OOP is that code is written to other people and to be easy to understand. When some local states and messaging is involved, or need to design high level structures OOP is then right tool make those inside process that is running.
The approach of thinking about a single way of solving a problem has the benefit that many things can be assumed to be true and the programmer can step on these assumptions allowing them to focus their attention on the actual problem solving and not on the coding style.
The problem is that this approach comes with the cost of worse performance (both in terms of writing the code that doesn't fit the paradigm well and in terms of actual runtime performance).
Nevertheless, this approach is widely used in the industry. For example, when using a specific library or framework the programmer is bound to write their code in a style that fits that particular library. And often using two libraries that do the same thing but differently results in a lot of code mess and complicates stuff even though one library could be better suited in one part of the application and the other library could be better suited in another part of the application.
The idea that Functional Programming was always going to take of in an Imperative-based system is just like saying the Chinese language will be the next standard for communication in an English-based country; it was never going to happen because what's the point in learning some other foreign and abstract idea, when you've already learnt your own abstract language that is tailor-made for the exact environment you use.
Hey mate, Functional Programming is top-notch. Honestly, those familiar with the bridge between DOP Data Oriented Programming, and Functional Programming should get acquainted. The challenges of design decisions to mitigate and deliver great software need further exploration for people to understand the implications, which are indeed very positive.
Sincerely, this is not a subjective opinion, but an objective fact, as I have read about Functional OOP Book and seen the power of this design pattern.
They figured out how to write code in a way only math majors could understand
Stackoverflow pools from a statistics viewpoint are completely useless to infer anything. If you volunteer yourself to answer a pool, you don't have a proper sample and therefore any inference based on it is invalid.
the lean4 community is alive and well my friends
Maybe the hype has died down, though the patterns feel much more prevalent throughout code bases. Best case as any hype passes is to have the elements that organically make sense be absorbed by the relevant parties/sectors.
Personally am still reading books on functional cpp, and patterns learned from an old ocaml course still heavily define my style in all languages. So it hasn't gone anywhere for me.
Modern programming languages like Go and Rust don't have classes or inheritance. Instead they have come up with new concepts that make the code much simpler to write and maintain.
I've started learning clojure. I see that the pick of the popularity for this language was in 2014. It was more popular than Scala or kotlin, nowadays in JVM world it flipped, the most functional languages are less popular.
JVM world was in full force in 2014 too, it started in 1995! So I think that the cause must be something else.
Embrace no paradigm: all hail the mighty Nim!
I think this video, as many others, confuses parallelism with concurrency. Concurrency is not about running things faster. Also, FP is not (only) about using pure functions. FP is about using higher-order things. Mutation is only one type of side effect. So FP has more to do with correctness - building larger systems without bugs. Languages have not really embraced FP. Having iterators in language is not FP.
For sure pure functional programming languages are not widespread in use, and I don't remember them really ever being widespread in use. But you could say the same about pure Object Oriented Programming languages. Hmnn, does such a thing even exists? I guess a Pure Object Oriented language would do things like make private members mandatory.
Functional ideas have been spreading to languages and frankly, it's possible to write programs with a Functional Mindset in just about every of the languages at the top of the list. Quite frankly, as a Java Dev there are OOP concepts I avoid as a plague and discourage in code reviews whenever possible. While at the same time there we are encouraging Java code that aggressively uses pseudo-nomads just so that we can avoid null pointer exceptions (Optional). You'll see a thousand lambdas in my Java code before you see the "extends" keyword.
My advice: program at least 3 years in a FP language and then make a 2nd video. Hearsay is not good enough.
The main problem is mainstream, critical mass or what is a safe choice career-wise for both developers and their managers.
Started a new FP project 5 years ago - ask me how many times I was (jokingly) asked if it was a good choice, if hiring is OK etc...
Since down under everything turns out to be imperative, imperative programming is the best programming.
Functional programming have been around since lisp was created in the 60’s
I like functional programming elements in not pure FP languages, I try to program in a functional way as much as possible and my language allows. I think in many ways it's more expressive and concise than OOP. But many of the most bizzare and even nonsensical takes on programming I ever heard were from FP purists.
Name a new programming language in the last decade, hell two decades, that are purely OOP. I can’t. Everything popular that’s come out in the last decade (Elixir,Clojure,Swift,Julia,Kotlin,TypeScript,Go,Dart,Rust,Zig, Odin, etc) have all been either functional, functional/procedural, or entirely procedural. OOP has disappeared from new languages entirely.
It's false that anything you can do in one language, you can do in another. Speed. Performance. You cannot run software fast in a language that runs sluggishly. Response times are important, not just for games.
Hi Prime :)
Being able to parallelise is for sure an argument used in favour of FP, but I feel this talk focusses (too) heavily on that aspect to make general claims about FP.
For example, for me a key benefit of FP is being able to look at the signature of a function and know all there is to know about its inputs and outputs. This allows for composition of smaller functions into larger ones. I have no intent to start a discussion here but piecing together behaviour from (larger) object hierarchies is not exactly easy.
FP, as I believe is stated as well, is in fact very popular seeing most major languages have added FP to their feature set.
Finally, if being able to easily move between both paradigms is of value, I wonder why languages like Scala, Kotlin and Rust are not more popular. Learn any of these and you can adopt either style ( maybe to a lesser extend Rust).
I guess that you didn't watch to the end, since that is pretty much exactly the conclusion that I reached in the video. 😉
Functional programming is just an approach prioritizing separation of data and business logic, leaving data alone instead of mutating it endlessly, and using composition of pure (and not so pure) functions as an alternative to inheritance.
In terms of where it is: it's literally everywhere. Nowadays even Java gave up and introduced lambdas; map/filter/reduce are staples for quite a while in a lot of languages, notably except Go for some reason, but otherwise more modern languages take elements of every programming style (as they should be) if using them makes sense, but note that nobody's in a rush to bring inheritance back, or even introduce it into the language to begin with.
FP ain't a silver bullet - nothing is, but it's definitely a neat methodology that offers some interesting concepts. No need to be salty about OOP not being the coolest kid on the block, Jesus 😹
In terms of concrete examples of FP being used:
- Rust is heavily inspired by FP;
- OCaML is functional (and it also has OO elements, hence O in OCaML, but nobody uses them 😸), and it's the language of choice at Jane Street for one;
- need I mention all the FP features in JavaScript and Python at the very least?
- Lua, which is gaining popularity due to being easily embeddable and thus being used all over the place, from scripting in games on Roblox platform to web server, reverse proxy and load balancers in Nginx, and let's not forget Neovim, which endorses Lua as hard as possible
And those are just the ones that immediately spring to mind.
People also abandon OOP in favor of other paradigms, like procedural for instance.
All in all, it wasn't even so much "hype" about switching to FP as much as it was hype to jump ship from OOP train, because people have been going overboard with OOP nonsense whether using it made sense or not. And yes, in some contexts it still makes perfect sense to use OOP.
Before watching the video: No. It is definitely not dead. I learned a ton from functional programming that I selectively apply depending upon the situation.
Functional Programming is a good idea on paper but a bad one on practice.
"Certainly" sounds like the script for this video has been written by ChatGPT
I was excited to learn haskell 10-12 years ago. Then python ate the world.
All programming is functional after you transform the AST to single assignment vars.
We're ok we're in /r/clojure
No Ring to rule them All :)
Functional programming is nice to have, for problems that are best expressed in that way. But in Java at least, from what my accidental research into how it came to be and what are its pros and cons, I have found out, that it is neither good at shortening code, nor does it make it more readable, it breaks hotpath, and some early examples I have found were nothing short of extreme clever misuse of generics to avoid use of instanceof operator (write 70+ lines of code to make the ugly if else if instanceof go away with cute switch statement and go from offending ugly nine lines down to cute four, at least in the mind of clever author of that programming boondoggle).
The problem with functional programming that I have is that it requires a far more specific mindset than imperative or object oriented when compared to, shall we say, everyday mindset a person has.
Personally I would prefer to use functional language to solve functional problem and cleanly connect it to my java program than to see the mess, that was bolted on.
I prefer the functional way of thinking. That is a me thing, I guess. But most people prefer the imperative style of programming. Anyway, all your functional code gets compiled down to imperative ASM at some point.
It never took in my circle.
Haskell is like communism: Too high a learning curve to win without conspiracy.
Gleam will take over my world
I love linq. It's no way dead.
it's just part of the toolset. Use it where it helps you.