CppCon 2018: Andrei Alexandrescu “Expect the expected”

  Рет қаралды 59,719

CppCon

CppCon

5 жыл бұрын

CppCon.org
-
Presentation Slides, PDFs, Source Code and other presenter materials are available at: github.com/CppCon/CppCon2018
-
Writing code that is resilient upon errors has always been a pain point in all languages. Exceptions are the politically correct means to signal errors in C++, but many applications still resort to error codes for reasons related to ease of understanding, ease of handling errors locally, and efficiency of generated code.
This talk shows how a variety of theoretical and practical artifacts can be combined together to address error codes and exceptions in one wholesome, simple package. The generic type expected<T> can be used for both local (error-code-style) and centralized (exception-style) manners, drawing from the strengths of each.
-
Andrei Alexandrescu, The D Language Foundation
Vice President
Andrei Alexandrescu is a researcher, software engineer, and author. He wrote three best-selling books on programming (Modern C++ Design, C++ Coding Standards, and The D Programming Language) and numerous articles and papers on wide-ranging topics from programming to language design to Machine Learning to Natural Language Processing. Andrei holds a PhD in Computer Science from the University of Washington and a BSc in Electrical Engineering from University "Politehnica" Bucharest. He is the Vice President of the D Language Foundation.
-
Videos Filmed & Edited by Bash Films: www.BashFilms.com
*-----*
Register Now For CppCon 2022: cppcon.org/registration/
*-----*

Пікірлер: 53
@mrlithium69
@mrlithium69 5 жыл бұрын
I love the way he presents! Very conversational, and natural, while still hitting all the salient details and not just outright repeating whats on the slides. And funny, throwing in jokes - not nervous at all. He also anticipates our possible thinking stumbling blocks and even addresses the natural tangential side-thoughts. Totally comprehensive. And from a non-native speaker of English, it's all the more impressive. What a legend! (much better than Titus - total opposite in fact) - almost on Bjarne's level. Big fan of his contributions too. He really sees the big picture and doesn't get distracted.
@andralex
@andralex 5 жыл бұрын
Thank you very much!
@user-ov5nd1fb7s
@user-ov5nd1fb7s 5 жыл бұрын
"I heard you not saying", LOL. I am going to use this quote from now on.
@acf2802
@acf2802 3 жыл бұрын
3 years later and this still is in proposal.
@Norhther
@Norhther 3 жыл бұрын
Love the idea, hate the semantics
@Elite7555
@Elite7555 4 жыл бұрын
Andrei is a phenomenal speaker!
@Omnifarious0
@Omnifarious0 5 жыл бұрын
He's absolutely right about how expected should behave, down to the last detail. I really hope the standards committee makes it and does it the way he recommends, right down to not having operator *. I've been thinking through how to do error handling for a hypothetical C++ wrapper to the POSIX/Linux api. I came to the exact same conclusion for how it should be done. Compilers are good enough at flow analysis to emit diagnostics if you never check things like `expected`, or even if you ignore any exected.
@WiktorWandachowicz
@WiktorWandachowicz 5 жыл бұрын
Big possible change at 33:55 wrt. exceptions - and at 34:00 I even did the clapping myself :) To create exceptions and use them for handling errors, *without* throwing the exceptions immediately is IMHO a really great idea! Such a simple solution: a function should return a real value or exception object. Simple, powerful, beautiful. Go, JF!
@belst_
@belst_ Жыл бұрын
I think a solution to expected would be to annotate functions returning that as nodiscard, that way you would at least get a compiler warning if you just ignore the return type edit: ok exactly that question was asked right at the end
@eLBehmo
@eLBehmo 4 жыл бұрын
At 50:00: For those who want the returned and unchecked error to throw (in the destructor of expected): yes I implemented such a solution and 'it works'. But you generally don't need it if you mark your functions nodiscard and check your warnings!
@RaaynML
@RaaynML 4 жыл бұрын
22:50 does anyone have a link to the function by Herb Sutter mentioned?
@aliancemd
@aliancemd 5 жыл бұрын
Around ~ minute 4 it was clear that this will sound like C++'s version of Rust's "Result".
@seidenada526
@seidenada526 5 жыл бұрын
I've just read about Rust error handling and the ? operator is pretty neat (nothing like the ternary in C++ for those wondering). With std::expected it would be like calling .value() just after receiving one std::expected from a function, i.e. auto a = openFile("..").value(); What I liked in Rust is that, if opening the file failed, the calling function would just propagate the error in it's own returned Result, when in C++ you enter the alternative path of exception propagation.. It would be more verbose to have the Rust-like behavior in C++, i.e. auto a = openFile(".."); if (!a) return unexpected(a.error()); Too much typing =p
@aliancemd
@aliancemd 5 жыл бұрын
​@@seidenada526 If you are curious, I recommend also checking "failure" on "crates.io", it's error chaining made easy :) Dropbox did say that they observed that their Rust code is not only free of memory management issues but also has a lot less bugs in general - my guess is that because you have to handle the error case in Rust and you just slap "?" everywhere you want to propagate the error and handle it where you want to recover for example, this way it's very simple to handle all error cases(failed to open file? failed to parse the JSON from it? failed to read an int value from that JSON? No problem, just slap "?" and handle all of it :) ).
@wintermute701
@wintermute701 4 жыл бұрын
34:45 Is there any difference between calling the copy constructor with placement new vs. using a member initialization list, i.e. : yay(rhs) ?
@timseguine2
@timseguine2 5 жыл бұрын
I finally decided that Andrei's voice reminds me of Triumph the insult comic dog. "This code is really great... for me to poop on!"
@masondeross
@masondeross 10 ай бұрын
Update: We finally have expected in C++23!
@blenderpanzi
@blenderpanzi 5 жыл бұрын
If you write your application using expected with exception handling deactivated, then .value() is surly also undefined behavior?
@OperationDarkside
@OperationDarkside 5 жыл бұрын
1. Great and entertaining talk. 2. There's a ')' missing in slide 30, I think.
@serengeor5148
@serengeor5148 5 жыл бұрын
Yeap, I noticed it almost instantly and then I thought it was put after assert by mistake (not the case though).
@zhaoli2984
@zhaoli2984 5 жыл бұрын
it is mimicking the NAN convention in floating point computation.
@MaceUA
@MaceUA 5 жыл бұрын
I don't understand why they discarded the approach with storing an std::exception_ptr instead of some template argument E inside the Expected. If I remember correctly, that's what Andrei initially proposed a few years ago when presenting the idea of Expected. That approach looked much cleaner (no need to specify two template arguments) and more flexible (you could store any kinds of exceptions in the Expected, even if the function "throws" multiple unrelated exception types). Is there an explanation why this decision was made now?
@xfreeman86
@xfreeman86 5 жыл бұрын
boost::result defaults the second type parameter to std::error_code. If you want, you can declare a type alias that does that for std::expected
@kuhluhOG
@kuhluhOG 4 жыл бұрын
MaceUA I think because of error codes (aka ints).
@erikvanvelzen
@erikvanvelzen 5 жыл бұрын
37:55 I'm not 100% sold on the constructor-based thing. Personally I would have a private constructor with named constructors std::expected::ofValue and std::expected::ofError. Though I see that's a bit more verbose. edit: I see at 47:50 something like that exists, so you can use either expected() or unexpected()
@xfreeman86
@xfreeman86 5 жыл бұрын
@Ziggi Mon the copy and unexpected constructors are more specific, and the default constructor cannot be instantiated anyway if T is not default constructible (it is instantiated only when someone tries to use it, not when the class is instantiated). You only need enable_if to control the overload set of valid instantiations
@andrybak
@andrybak 4 жыл бұрын
At 45:59 - is desctructor of temporary `E t` called on scope exit?
@LoSte26
@LoSte26 2 жыл бұрын
yes, it is.
@oof-software
@oof-software 2 жыл бұрын
Wouldn't returning `expected` show less intention than returning `optional`? Since in the end both return types say 'this function might return an error or nothing'. My guess is, that `expected` would be preferred only for homogeneity among other return types.
@jonaskoelker
@jonaskoelker 8 ай бұрын
> Wouldn't returning `expected` show less intention than returning `optional`? I'd say that depends on whether the actual name of `error_type` indicates clearly that it represents an error. If the error type is `int`, that is not the case. Although that depends a lot on what customs and conventions will get adopted in the wild. You probably can and want to define a "expected::flatMap(f: function from A to expected) returning expected", which will let you sequentially combine computations which return `expected` (not calling `f` if the step that tried to produce an `A` failed). Treating `void` specially would make `flatMap` less powerful. I guess I'm making the homogeneity-is-good argument-though more for programming capability reasons that easy readability reasons.
@MaceUA
@MaceUA 5 жыл бұрын
Slide 28: it might be better to use std::conjunction to short-circuit the expression inside enable_if. Also, another part of homework for implementers: make this swap() function conditionally noexcept, where it can be. That could help some other generic code to be more efficient.
@maximetournier8716
@maximetournier8716 5 жыл бұрын
where is monadic bind operator?
@vvviiimmm
@vvviiimmm 5 жыл бұрын
So if anyone familiar with IO[A, E] or even Either[A, B] types in FP -- this is essentially the same with a lot of C++ noise. Furthermore, the proposed implementation doesn't compose well (52:12)
@vorpal22
@vorpal22 5 жыл бұрын
Coming back to C++ after not using it in over a decade and working predominantly in Java / Scala, I am amazed at how utterly crappy std::optional is.
@vorpal22
@vorpal22 5 жыл бұрын
@D X ​ I started catching up with all the changes made in C++11, 14, and 17 just maybe six months ago, and I'm really loving it, which surprised me, because C++98 is what originally put me off of programming for a long time (until I learned Python). I love template metaprogramming in particular (even though I have a huge ton to learn on that subject) and playing around with constexpr to see what I can do with it. I agree that STL types compose / inherit very well in most cases. std::optional seems like the exception rather than the rule, but that may be because the STL is completely iterator based, and giving optional iterators would work (and I'm surprised they haven't done it - it would make it fit much better into the STL) but admittedly would look weird. I think that many C++ programmers fail to understand how much optional types have changed programming with pointers / references because optional in C++ is so limited. It really seems to offer little benefit over using nullptr, unlike, say, Java or Scala, where you can just easily chain together transformations and filters over the optional types so nicely and really see the benefit of having a monad of optional. Wasn't boost::optional more advanced than stl::optional? I should look into that as a point of curiosity. Hmmm... it would be a fun challenge to make an optional type that works with iterators. Another project for me to think about.
@YourCRTube
@YourCRTube 5 жыл бұрын
@@vorpal22 Don't forget optional, as an std thing, is _less then an year old!_ Monadic interface is proposed (there is a paper) and probably optional of reference will come as well. People like optional a lot, so it will improve for sure.
@vorpal22
@vorpal22 5 жыл бұрын
@@YourCRTube How long has it been in boost? From the boost optional page, it looks like at least four years, and possibly more than 10. I really hope that there are some improvements in mind for C++20. (I'm intrigued and terrified by C++20... it seems like there will be many new things there and I'm just catching up to 14 and 17.) I'm glad to hear that optional is well liked. I honestly have no idea... I'm just starting to get into the C++ community. I felt very intimated by the fact that I hadn't programmed in C++ for so long, but I'm starting to feel more comfortable and all the C++ programmers I've chatted with online have been very patient and helpful. I'd really like to go to some C++ conferences in the next year... CppCon and C++ by Sea both are calling to me. Do you have any recommendations?
@vorpal22
@vorpal22 5 жыл бұрын
@@YourCRTube BTW... thanks for pointing me towards the monadic interface paper! I'm going to sit down and read it over. I'm definitely intrigued.
@Mirality
@Mirality 5 жыл бұрын
47:56 I wonder if the missing parenthesis was unexpected...
@andralex
@andralex 5 жыл бұрын
Oi... thanks!
@zhaoli2984
@zhaoli2984 5 жыл бұрын
yet another way to handle errors in cpp?
@inferioaltio
@inferioaltio 5 жыл бұрын
Can someone explain, why did they use placement new instead of simple initializing in constructors?
@YourCRTube
@YourCRTube 5 жыл бұрын
Because this is the way to construct an object without allocating memory - union is C-thing and it does not know about constructors, but it has the memory already allocated.
@inferioaltio
@inferioaltio 5 жыл бұрын
​@@YourCRTube Still don't really understand why expected(const T& rhs) : yay(rhs) {} is worse than placement new, in both cases yay will be constructed once (and I suppose memory for yay will be allocated only once as well)
@ARTijOMS
@ARTijOMS 5 жыл бұрын
I believe the primary reason it is written this way is so that union is not mistaken for class - placement new is the "union style" of starting the lifetime of an object. From the standard: [Note: In general, one must use explicit destructor calls and placement new-expression to change the active member of a union. -end note]
@damianjarek1974
@damianjarek1974 5 жыл бұрын
Non-trivial data members of unions have to be constructed that way (and you have to call the destructor on your own as well!). Construction initialization for unions is only allowed for trivial types.
@inferioaltio
@inferioaltio 5 жыл бұрын
@@damianjarek1974 I did some research and found this reply on stackoverflow stackoverflow.com/questions/33058717/do-unrestricted-unions-require-placement-new-and-a-constructor-definition basically it says that in this particular case both ways are correct.
@fnc12
@fnc12 10 ай бұрын
I really expected an expected to be inside the other expected but Andrei failed my expectations!
@user-ov5nd1fb7s
@user-ov5nd1fb7s 5 жыл бұрын
The guy is funny
@myverynow
@myverynow 5 жыл бұрын
found local choreography normal (cause they do java instead of c++) LOL
CppCon 2015: Andrei Alexandrescu “Declarative Control Flow"
1:07:35
Зомби Апокалипсис  часть 1 🤯#shorts
00:29
INNA SERG
Рет қаралды 7 МЛН
НЕОБЫЧНЫЙ ЛЕДЕНЕЦ
00:49
Sveta Sollar
Рет қаралды 8 МЛН
CppCon 2018: Jason Turner “Surprises in Object Lifetime”
1:01:28
CppCon 2019: Jason Turner “The Best Parts of C++"
58:36
CppCon
Рет қаралды 89 М.
Back to Basics: Exceptions - Klaus Iglberger - CppCon 2020
1:01:45
Зомби Апокалипсис  часть 1 🤯#shorts
00:29
INNA SERG
Рет қаралды 7 МЛН