5 ms·
I haven't announced my keynote yet, but it's about various ways of handling errors and their tradeoffs. This has inspired some spirited debate in the D forums!
by WalterBright 3mo ago
I haven't announced my keynote yet, but it's about various ways of handling errors and their tradeoffs. This has inspired some spirited debate in the D forums! I'm looking forward to engaging with everyone.
- gregdaniels421 3mo agoAges ago in C++ there was the hope of having the standard library give more error codes and use error values instead of full exceptions. Zig has some excellent innovations in that direction, any hope of that in D? Edit: I think it was called "Herbception"s after Herb Sutter, and it really sounded like a good idea to me
- WalterBright 3mo agoIt's been a while since I looked at Zig. I couldn't say anything intelligent about it without some study. I used to be a big fan of C++ exceptions, but eventually soured on it for various reasons. Here's an article partially addressing it from a while back: https://dlang.org/articles/exception-safe.html https://dlang.org/articles/exception-safe.html
- germandiago 3mo agoI think there is nothing better than exceptions + RAII for error handling since exceptions cannot be ignored by accident. I would classify D's scope exit/failure/success as RAII actually, even if D uses a GC. Sometimes you might not need exceptions and something like std::expected or optional is better. In my case I use expected for some network APIs since I expect failures to happen out of my control aspart of the flow of my program, but I do not see why I would not use exceptions in many other situations, such as for non-ignorsble errors. I could think of a lack of disk space or some other fatal error thst is not under the control of the program. If you forget to handle this, the error will cascade. Also, exceptions do not make the signature of a function change (at least not in C++, Java checked exceptions is different). This means that the plasticity for adding errors at any depth of the call stack augments without bypassing any error silently. All in all, I would say exceptions should be the main mechanism in normal circumstances and for expected errors you csn use error/result types.
- gregdaniels421 3mo ago> I would classify D's scope exit/failure/success as RAII actually, even if D uses a GC. It has better than that, but it is a bit clunky compared with C++(just use struct instead of class). You can have proper destructors, but if you have a container you need to be more careful than in C++. In D exceptions are the default like in C++ and you have to opt out with nothrow or extern(C) or betterC. Really try some D code in a bigger situation it is 90% good and almost worth using over C++, but if you can't have GC it is a huge pain, but better than C.
- WalterBright 3mo agoI've never understood why GC would be a huge pain. It makes some things a lot easier, like Compile Time Function Execution. Also, recently the GC implementation received a big modernization upgrade.
- WalterBright 3mo ago> I would classify D's scope exit/failure/success as RAII actually, even if D uses a GC. D's scope exit/failure/success is built on top of RAII and has nothing to do with the GC. > I would say exceptions should be the main mechanism in normal circumstances and for expected errors you csn use error/result types. Come to DConf (or watch the live stream) and I hope I can change your mind, or at least challenge your conclusions!
- germandiago 3mo ago> D's scope exit/failure/success is built on top of RAII and has nothing to do with the GC. What I meant here (I do not know the mechanism) is that I am aware that D has a GC. This means, correct me if I am wrong, that D does not use destructors (like C++) for scope exit/failure/success, though they are scoped mechanisms (RAII-like). > Come to DConf (or watch the live stream) I always follow D (even if I did not use it intensively). I have extremely high respect for you as a language designer and as a technician. Your knowledge is very refined, so I never take your opinions lightly. Probably one of the most knowledgeable persons in the industry for native language design. However, I am far and cannot attend, so I will definitely watch it. > or at least challenge your conclusions! No problem in challenging them. I am always open to do things better. This is just my practical experience as I implement stuff so far. I currently think exceptions seems like a good default mechanism (apparently at least) compared to alternatives. But I also think other mechanisms have their place and can/should be used even in the same program, just for different things. All mechanisms have trade-offs. I just talked about defaults from my POV for the kind of software I develop (mostly server-side, some client-side, and not embedded in the extremely constrained sense). ----------------------------- One question: I tried to use D several times in my career (20 years of C++ experience here, roughly). I found it a lot of fun. I like it better than more "modern languages". I like the plasticity D provides. But I am not sure how it would work if I want to do: 1. backend (server-side mainly, Linux is main platform, x86-64) 2. desktop + android and iOS (being mobile more important than desktop) 3. web assembly (even more important than mobile at this moment, could change). 4. backwards compatibility (heard complaints of versions breaking stuff frequently around). 5. interaction with C++. I do like D a lot, but the problems I had before were more related to tooling (autocomplete, I use mainly Emacs but did not try for a few years) and toolchain maturity. It would be ready for all of the above? Also, very very handy would be to wrap C++ code and C code. I saw that D had an ongoing effort for C++ compatibility better than other languages, but I am afraid it could be half-broken. Even if it is, it is documented what works and what does not work? That would help a lot. Thanks.
- wannabe44 3mo agoIt was the throwing values proposal. Bjarne was not satisfied with the proposal because it didn't interact well with existing exceptions code.
- jeffreygoesto 3mo agoI loved the comparison of HerbCeptions with expected in https://m.youtube.com/watch?v=GC4cp4U2f2E https://m.youtube.com/watch?v=GC4cp4U2f2E, a very insightful easy of looking at that topic and really entertaining, too.
- pjmlp 3mo agoValue type exceptions went nowhere, because that was yet another paper that was never turned into a proper proposal. Additionally, Khalil Estell has made an excellent work proving that the way exceptions are currently implemented is not optimal and there is plenty of room for improvement, when someone cares about their implementation. "Cutting C++ Exception Time by +90%? - Khalil Estell - CppCon 2025" https://www.youtube.com/watch?v=wNPfs8aQ4oo https://www.youtube.com/watch?v=wNPfs8aQ4oo
- alphaglosined 3mo agoI created the D version of the value type exceptions proposal. In the end, it was DOA due to compiler architecture, so that was the end of that beautiful design. I've had to accept result types is about as good as its going to get, all that is missing to make them nice is unwrapping support in if statements. Which I too have a proposal for and implemented it. But alas politics.
- vips7L 3mo agoYou might not see this since I'm rather late. What is a value type exception? Is it one that doesn't collect a stack trace? Or doesn't unwind in the usual way or something?
- macoovacany 3mo agoGoing to include the common lisp condition system in the comparison?
- WalterBright 3mo agoI tried Lithp a couple times, but it never caught on with me. I wouldn't know what the best techniques for Lithp error handling would be. I can never get past the ugly syntax.
- mananaysiempre 3mo agoError handling in Dylan[1] worked mostly the same way, if syntax is truly the issue. I posted a toy implementation in Lua a few years ago as well[2]. In general there’s nothing Lisp-specific about the idea, you just need dynamic scoping, closures that don’t outlive their parents, and a way to unwind the stack. Standard exception handling is: - Whenever an error happens, the program puts a description of it into an “exception” object. You go from the innermost dynamic scope to the outermost looking for handlers. Once you find a handler willing to accept that type of exception, you unwind to the point where it was installed then invoke it, passing the exception object. Condition handling[3] is: - Whenever an error happens, the program puts a description of it into a “condition” object. You go from the innermost dynamic scope to the outermost looking for handlers. Once you find a condition handler willing to accept that type of condition, you invoke it as a regular callback, without unwinding, passing the condition object. - The handler then packs up some data into a “restart” object. You go through all the dynamic scopes again (remember that the erroring function is still active). Once you find a restart handling willing to accept this type of restart, you unwind to the point where it was installed then invoke it, passing the restart object. (I am omitting things outside the happy path: a way for the exception/condition handler to punt, what happens if the condition handler does not invoke a restart, etc.) As far as the benefits of this two-phase approach, Practical Common Lisp gives an example[4] of a single-record parser that raises an “invalid record” condition, a loop around it that installs a “skip to next record” restart, and finally the caller can make the policy decision on what to do for invalid records. As another example, Common Lisp signals an “unbound-variable”[5] condition leaving the “use-value” and “store-value” restarts in scope, then the REPL installs a handler that offers them interactively. (My own half-serious example of a DOS abort/retry/fail prompt is in this vein too, chosen mostly because it feels strange that you can’t do it in a conventional exception system.) [1] https://package.opendylan.org/dylan-programming-book/exceptions.html https://package.opendylan.org/dylan-programming-book/excepti... [2] https://news.ycombinator.com/item?id=31196046 https://news.ycombinator.com/item?id=31196046 [3] https://www.nhplace.com/kent/Papers/Condition-Handling-2001.html https://www.nhplace.com/kent/Papers/Condition-Handling-2001.... [4] https://gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts https://gigamonkeys.com/book/beyond-exception-handling-condi... [5] https://www.lispworks.com/documentation/HyperSpec/Body/e_unbo_1.htm https://www.lispworks.com/documentation/HyperSpec/Body/e_unb...
- swyx 3mo agowould you ever do an SF edition? would be happy to host for you. i do a lot of conferences.
- WalterBright 3mo agoWhat's an SF edition?
- LorenDB 3mo agoI would assume OP is asking if you would attend a DConf in San Francisco. By the way, big fan of D even though I don't get to use it much. Appreciate your work!
- WalterBright 3mo agoA San Francisco DConf would indeed be nice. We've done them in Silicon Valley before.
- swyx 3mo agoif you are interested, hello @ ai.engineer with your avaiability/expectations would be great, happy to dedicate some stuff to run it for u for free/cost (depending on the size)