This is another reason I love C++ so much, I can use it in the way that makes the most sense for what I'm doing, I'm not locked into doing things a specific way for arbitrary reasons, I can choose which is the best way to write code based on the code I'm writing, getting additional performance in some places or a more user friendly interface in others (and to be clear OO isn't always the more user friendly interface and functional programming isn't always the most performant).
And that versatility goes right outa window when the project lead throws his coding standard at you. I for one like having top to bottom, left to right, readable code, without having to jump between parentheses.
@@1InVader1 I've always viewed coding standards as the guidelines for your first pass. I follow them until the code works, but then if the interface is too convoluted or the code doesn't perform as needed I ask the lead to let me improve it by breaking the standard. A good lead will listen to you and sometimes allow you to break the standard when it is beneficial to do so, but sometimes it is also worth sticking to the standard for consistency over marginal improvements to usability or performance, so I'm happy to comply with whatever the lead decides.
@@skilz8098 The problem is holding state... So a generic callable struct (pretty much a lambda) is superior. So you either have a normal function that you convert to a std::function after using std::bind or you use globals... Which are yucky. Unless you know how to do this with function pointers without std::bind.
@@stefanalecu9532 It's a good thing because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both. Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly C#, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
@@stefanalecu9532 Because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both. Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly C#, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
@@stefanalecu9532 It's a good thing because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both. Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly CSharp, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
Ivan Cukic wrote a really good book "Functional Programming in C++" in 2019 that covers how to approach true functional programming in C++ by creating copy-on-write variants of vectors and other data types so that you can work from a true functional perspective of "no side effects". It's a good read, strong recommend from me.
This is a terrible analogy. A swiss knife is composed of multiple mediocre tools that just about get the job done in exchange for convenience. Individual versions of those tools are always better. There is no logic in comparing C++ to a swiss knife. In a majority of cases, using C++ is neither convenient nor worse than using other tools for the job.
@@gumz4183it's not a "terrible" analogy, it's just not super accurate, as analogies tend to be... what david meant was that it can do "everything", similar to how the swiss army knife can do "everything"
@@szymoniak75 it's a terrible analogy. Because C++ isn't 'the' swiss army knife of programming. There are better contenders for that. It's a terrible analogy and you're reasoning is quite bad too.
This episode doesn't feel complete without mention of monadic operations for std::optional from C++23 and coming std::optional ranges support in C++26, so I hope there some episodes on that topic coming in the future. As for C++26 you can already try out optional26 from beman-project that is supported by godbolt, although no constexpr yet
@@bsdooby std::optional page on cppreference got section that called Monadic operations and there 3 of them listed. It's basically just functions that take callable as parameter and based on either result of that callable or optional itself it does something. For example and_then would call callable only if optional itself has some value. The whole idea is that you can chain these and_then, or_else in a way that's very similar to how we can now chain ranges operations with | piping. Check code example for and_then on cppreference. There also great CppCon 23 talk about monads which explains all that with good examples and even does good explanation of 'monad' is
C++ is a pretty good functional programming language. It even supports algebraic data types (product and sum types). What it lacks in order to be (even more) useful is standardised pattern matching (type matching).
IDK, for me functional means one thing: functions as data and data as functions in a LISP-y sense. C++ seems to be a far way from being functional that way.
callables are now std::functions that can either bind to certain parameters, or even be mutable to adjust captured lambda parameters. so i think there’s more here that jason will probably cover later.
Fun exercise you can do before making such bold claims about cpp, is to replace lambda in your examples to closure and pass it as template argument. Its so fun to use in implementing something like arena-allocators fun fun fun
I'd say that not allowing nulls and forcing, at compile time, that the code all paths, e.g., switches on enums, is way more relevant for a language to be functional than monads.
Never really understood why people say c++ is OOP? For me its never been either really. Its all about how you use it and implement your code back. Nothing is forced on you.
AFAIK that's because initially the motivation for C++ was to have C with classes (it was even called that), but as we all learned OOP isn't the perfect solution for any problem, various languages, C++ included, became more multi-paradigm and provided very nice functional features in later versions. But still some people write in a very old-school C++ style, which can be either like C, or like C with classes.
I vaguely remember F# could do fully transparent copy on write to make all the passing data around chains of functions more performant. I'm sure you can do that in C++ but I'm guessing you would have to implement your own data structures for it? Also, is anything truly immutable in C++?
C++ has had functional programming features for some time. A kinda of crappy functional programming language, but nonetheless, still a functional programming languange
This is another reason I love C++ so much, I can use it in the way that makes the most sense for what I'm doing, I'm not locked into doing things a specific way for arbitrary reasons, I can choose which is the best way to write code based on the code I'm writing, getting additional performance in some places or a more user friendly interface in others (and to be clear OO isn't always the more user friendly interface and functional programming isn't always the most performant).
Yup. Lambdas, std::bind, and std::function really comes in clutch when working with callbacks.
And that versatility goes right outa window when the project lead throws his coding standard at you. I for one like having top to bottom, left to right, readable code, without having to jump between parentheses.
@@1InVader1 I've always viewed coding standards as the guidelines for your first pass. I follow them until the code works, but then if the interface is too convoluted or the code doesn't perform as needed I ask the lead to let me improve it by breaking the standard. A good lead will listen to you and sometimes allow you to break the standard when it is beneficial to do so, but sometimes it is also worth sticking to the standard for consistency over marginal improvements to usability or performance, so I'm happy to comply with whatever the lead decides.
@@jasonenns5076 So does plain old function pointers.
@@skilz8098 The problem is holding state... So a generic callable struct (pretty much a lambda) is superior. So you either have a normal function that you convert to a std::function after using std::bind or you use globals... Which are yucky. Unless you know how to do this with function pointers without std::bind.
Love the thumbnail
C++ is an everything language.
Yes. That's why everyone who hates on it mentions: C++ tries to do too much. Which is the point of C++. And that is why I love it.
@@jasonenns5076 how's that a good thing? Jack of all trades, master of none
@@stefanalecu9532 It's a good thing because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both.
Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly C#, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
@@stefanalecu9532 Because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both.
Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly C#, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
@@stefanalecu9532 It's a good thing because it gives you power to use whatever makes the most sense for a given situation. Sometimes writing OO code makes sense. Sometimes writing FP code makes sense. Pick Java and you're stuck with OO; pick Haskell and you're stuck with functional. But there's no reason why you can't have both.
Recently there's even been a broad trend to add functional features to otherwise OO languages (particularly CSharp, but Java too), precisely because it's been recognized that FP together with OO data modeling is a very powerful paradigm. And Cpp has been ahead of the curve here.
Ivan Cukic wrote a really good book "Functional Programming in C++" in 2019 that covers how to approach true functional programming in C++ by creating copy-on-write variants of vectors and other data types so that you can work from a true functional perspective of "no side effects". It's a good read, strong recommend from me.
I even own this book. If I were smarter I would have referenced it in the video.
C++ is a the Swiss Army Knife of programming languages.
This is a terrible analogy. A swiss knife is composed of multiple mediocre tools that just about get the job done in exchange for convenience.
Individual versions of those tools are always better.
There is no logic in comparing C++ to a swiss knife.
In a majority of cases, using C++ is neither convenient nor worse than using other tools for the job.
@@gumz4183 seconded!
@@gumz4183 So C++ is not convenient, but it's great for doing jobs. Non-convenience would mostly mean "slightly" verbose.
@@gumz4183it's not a "terrible" analogy, it's just not super accurate, as analogies tend to be... what david meant was that it can do "everything", similar to how the swiss army knife can do "everything"
@@szymoniak75 it's a terrible analogy. Because C++ isn't 'the' swiss army knife of programming. There are better contenders for that. It's a terrible analogy and you're reasoning is quite bad too.
I did, in fact, like the meme at the start :D
I'm generally not a fan of functional programming approach, but these helpers in C++ do come in handy from time to time
This episode doesn't feel complete without mention of monadic operations for std::optional from C++23 and coming std::optional ranges support in C++26, so I hope there some episodes on that topic coming in the future. As for C++26 you can already try out optional26 from beman-project that is supported by godbolt, although no constexpr yet
which monadic operations ? Dear to give some simple example(s)?
@@bsdooby std::optional page on cppreference got section that called Monadic operations and there 3 of them listed. It's basically just functions that take callable as parameter and based on either result of that callable or optional itself it does something.
For example and_then would call callable only if optional itself has some value. The whole idea is that you can chain these and_then, or_else in a way that's very similar to how we can now chain ranges operations with | piping. Check code example for and_then on cppreference.
There also great CppCon 23 talk about monads which explains all that with good examples and even does good explanation of 'monad' is
@@qustrolabe thx for your excellent explanation!
How a language could be beautiful 🤗 thank you dude.
C++ is a pretty good functional programming language. It even supports algebraic data types (product and sum types). What it lacks in order to be (even more) useful is standardised pattern matching (type matching).
I do hope we get a good version of pattern matching in soon.
A good summary Jason!
I'm mostly functional too
IDK, for me functional means one thing: functions as data and data as functions in a LISP-y sense. C++ seems to be a far way from being functional that way.
callables are now std::functions that can either bind to certain parameters, or even be mutable to adjust captured lambda parameters. so i think there’s more here that jason will probably cover later.
I like the mene
Fun exercise you can do before making such bold claims about cpp, is to replace lambda in your examples to closure and pass it as template argument.
Its so fun to use in implementing something like arena-allocators
fun fun fun
I'd say that not allowing nulls and forcing, at compile time, that the code all paths, e.g., switches on enums, is way more relevant for a language to be functional than monads.
jack of all trades
jack++
Master of none
@@stefanalecu9532 but better than a master of one
Never really understood why people say c++ is OOP? For me its never been either really. Its all about how you use it and implement your code back. Nothing is forced on you.
Smalltalk is OOP, C++ is a poser
AFAIK that's because initially the motivation for C++ was to have C with classes (it was even called that), but as we all learned OOP isn't the perfect solution for any problem, various languages, C++ included, became more multi-paradigm and provided very nice functional features in later versions. But still some people write in a very old-school C++ style, which can be either like C, or like C with classes.
Can it do lazy evaluation?
does your CLion discount work for companies or individuals only?
Get the full suite, it gets drastically cheaper after a few years ( though personal ) I assume similar adv for corpos
c++ is everything. Remember them good old times with the "c++ is java" vibes. Nowdays maybe Rust.
I might be misremembering, but wasn't that "c# is java" instead?
god how I hated the decltype...
C++ templates are a language within a language.
Cool video. Now I wonder, what a strict functional programming language has that C++ has not?
Guaranteed no side effects, I suppose.
@@keris3920 c++ has guaranteed side effects
Not being C
Monads in Haskell, pattern matching, etc.
I vaguely remember F# could do fully transparent copy on write to make all the passing data around chains of functions more performant. I'm sure you can do that in C++ but I'm guessing you would have to implement your own data structures for it?
Also, is anything truly immutable in C++?
if passing around callables constitutes a functional language, then C had it since at least shipping qsort, but that's not the point.
functional programming is a meme
C++ has had functional programming features for some time. A kinda of crappy functional programming language, but nonetheless, still a functional programming languange
People complain about this? Really?
It's definitely happened!
c++ is a mess
first
you will always be last