at 42:37, when you say "it's not particularly readable" - if you made "with" a template member function of optional, then it would look a lot nicer, and you wouldn't even need crazy operator overloading for that either. Something like: auto k = oi.with([](x) { return x + 1; }).with([](x) { return x * 2; });
You're right - thanks for the comment. But that requires being able to extend a std library (or boost) library. Maybe you can do that with boost. but I was trying to work with what we have. In fact this is a point I make when talking about Swift, which allows you to extend classes - and even get existing classes to confirm to new interfaces - that this is a way of achieving "functional composition" in a more OO way. Maybe if/ when we get unified call syntax or similar we'll be better able to extend existing libraries.
Oh, sorry, I implied it was your own optional type, given than most (all?) previous topics covered your custom implementations of types. Well, you are right then, a new overloaded infix operator is the best solution in that case.
Thank you very much for your video. It opened my mind in regards to functional programming. I've found, what I believe to be, a small issue with the "optional", "with", etc... The part of the code: "if (opt) return withFun(*opt); else..." Would have racing problems. If you have a parallel thread running, the "if (opt)" could return true and the *opt could potentially be invalid during the time of the call. One way of solving this problem would be to use weak_ptr together with shared_ptr. But that could potentially replace optional entirely. Consider the following: (remember that reference counting in shared_ptr is thread-safe) #include #include using namespace std; template using const_weak_ptr = weak_ptr; template using const_shared_ptr = shared_ptr; template auto const_make_shared(Types&&... Args) { return make_shared(std::forward(Args)...); } template auto with(const_weak_ptr opt, T2&& default) { auto st = opt.lock(); if (st) { return st; } else { return const_make_shared(std::forward(default)); } } int main() { { auto shared = const_make_shared(1); const_weak_ptr oi = shared; auto test = with(oi, 2); cout
Thanks for the comment. If I'm reading you correctly I don't think this is a fundamental problem with the with function, but rather a more general "threading with mutable state is hard" problem. If your optional is immutable then I don't believe there is an issue (unless I'm missing your point - this is only a problem if the other thread resets or changes what the optional holds, right?). While you can model an optional value using pointer semantics (weak/shared in this case) that gives up some of the expressiveness of using optional (not conflating the indirection with the possibility of an absent value).
At 9:20-9:30 when talking about the performance overhead incurred by using lambda function to initialize a const function based on many conditions: How can compiler optimize that to something similar to the previous code while preserving the fact that the variable is const?
It can inline it but also constness typically has no effect on compiler optimizations. I'm frequently looking at the disassembly of profiler hotspots and never found a case where const makes a difference as far as instruction selection and register allocation. There might be one but I've never come across it. That's actually a very straightforward case for the compiler to optimize.
This guy needs to write a book on this. I would buy it in an instant
I think your talk made me a better C++ programmer. Thanks for that!
(sorry only just saw this comment) - you're very welcome - and that you, too!
at 42:37, when you say "it's not particularly readable" - if you made "with" a template member function of optional, then it would look a lot nicer, and you wouldn't even need crazy operator overloading for that either. Something like: auto k = oi.with([](x) { return x + 1; }).with([](x) { return x * 2; });
You're right - thanks for the comment. But that requires being able to extend a std library (or boost) library. Maybe you can do that with boost. but I was trying to work with what we have.
In fact this is a point I make when talking about Swift, which allows you to extend classes - and even get existing classes to confirm to new interfaces - that this is a way of achieving "functional composition" in a more OO way. Maybe if/ when we get unified call syntax or similar we'll be better able to extend existing libraries.
Oh, sorry, I implied it was your own optional type, given than most (all?) previous topics covered your custom implementations of types. Well, you are right then, a new overloaded infix operator is the best solution in that case.
Cool - I love it when we get on the same page :-)
Thanks for this video. A really good talk!!
Nice talk. Thank you!
Thank you very much for your video. It opened my mind in regards to functional programming.
I've found, what I believe to be, a small issue with the "optional", "with", etc...
The part of the code:
"if (opt)
return withFun(*opt);
else..."
Would have racing problems. If you have a parallel thread running, the "if (opt)" could return true and the *opt could potentially be invalid during the time of the call.
One way of solving this problem would be to use weak_ptr together with shared_ptr. But that could potentially replace optional entirely.
Consider the following: (remember that reference counting in shared_ptr is thread-safe)
#include
#include
using namespace std;
template
using const_weak_ptr = weak_ptr;
template
using const_shared_ptr = shared_ptr;
template
auto const_make_shared(Types&&... Args) {
return make_shared(std::forward(Args)...);
}
template
auto with(const_weak_ptr opt, T2&& default) {
auto st = opt.lock();
if (st) {
return st;
}
else {
return const_make_shared(std::forward(default));
}
}
int main()
{
{
auto shared = const_make_shared(1);
const_weak_ptr oi = shared;
auto test = with(oi, 2);
cout
Thanks for the comment.
If I'm reading you correctly I don't think this is a fundamental problem with the with function, but rather a more general "threading with mutable state is hard" problem. If your optional is immutable then I don't believe there is an issue (unless I'm missing your point - this is only a problem if the other thread resets or changes what the optional holds, right?).
While you can model an optional value using pointer semantics (weak/shared in this case) that gives up some of the expressiveness of using optional (not conflating the indirection with the possibility of an absent value).
At 9:20-9:30 when talking about the performance overhead incurred by using lambda function to initialize a const function based on many conditions:
How can compiler optimize that to something similar to the previous code while preserving the fact that the variable is const?
Maybe it turns it into an inline function. Just speculating.
It can inline it but also constness typically has no effect on compiler optimizations. I'm frequently looking at the disassembly of profiler hotspots and never found a case where const makes a difference as far as instruction selection and register allocation. There might be one but I've never come across it. That's actually a very straightforward case for the compiler to optimize.
Great talk
💚💙🤎💜❤️
levelofindirection.com/storage/FCPPrefs.html
reference in video