Re: Comparing Exceptions and Errors
On Sunday, 5 June 2022 at 00:40:26 UTC, Ali Çehreli wrote: Errors are thrown when the program is discovered to be in an invalid state. We don't know what happened and when. For example, we don't know whether the memory has been overwritten by some rogue code. That is not very probable in 100% @safe code. You are basically saying that D cannot compete with Go and other «safe» languages. Dereferencing a null pointer usually means that some code failed to create an instance and check for it. My code can detect that the failure is local under the assumption thay the runtime isnt a piece of trash. What happened? What can we assume. We don't know and we cannot assume any state. So D will never be able to provide actors and provide fault tolerance. Is the service in a usable state? Yes, the actor code failed. The actor code change frequently, not the runtime kernel. Possibly. Not shutting down might produce incorrect results. Do we prefer up but incorrect or dead? I prefer that service keeps running: chat service, game service, data delivered with hashed «checksum». Not all software are database engines where you have to pessimize about bugs in the runtime kernel. If the data delivered is good enough for the client and better than nothing then the service should keep running!!! I hope there is a way of aborting the program when there are invariant Invariants are USUALLY local. I dont write global spaghetti code. As a programmer you should be able to distinguish between local and global failure. You are assuming that the programmer is incapable of making judgements. That is assuming way too much.
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 22:03:08 UTC, kdevel wrote: On Saturday, 4 June 2022 at 14:05:14 UTC, Paul Backus wrote: This is entirely a question of API design. If it should be the caller's responsibility to check for some condition before calling the function, then you can throw an `Error` when that condition does not hold (or more likely, use an `assert` or an `in` contract to check for it). Provided one does not catch `Error`s this means one has to isolate such an API design by using a subprocess. This is what one usually tries to avoid. See here: http://joeduffyblog.com/2016/02/07/the-error-model/#bugs-arent-recoverable-errors And also the following section: http://joeduffyblog.com/2016/02/07/the-error-model/#reliability-fault-tolerance-and-isolation If it should be the callee's responsibility to check, you should throw an `Exception` (or use `enforce`). If the library always throws exceptions it can be used in both API "designs". In the case that the implementor of the caller expects `Error`s instead of `Exceptions` she could use a small wrapper which catches the Exceptions and rethrows them as `Error`s. Likewise for error codes. Using contracts and invariants impedes this approach. See here: https://bloomberg.github.io/bde-resources/pdfs/Contracts_Undefined_Behavior_and_Defensive_Programming.pdf
Re: Comparing Exceptions and Errors
On 6/4/22 9:43 PM, Steven Schveighoffer wrote: But I think you are still not supposed to continue execution. I'm not sure what a compiler might assume at this point, and I unfortunately can't find in the language specification where it states this. It might not be in there at all, the spec is sometimes lacking compared to the implementation. BTW, I think this is the main reason why it keeps coming up for D learners, and why I wrote the article in the first place. It would be good (if it's not already in the spec) to have something mentioned about the pitfalls of catching Errors. -Steve
Re: Comparing Exceptions and Errors
On 6/4/22 6:56 PM, kdevel wrote: On Saturday, 4 June 2022 at 16:55:31 UTC, Steven Schveighoffer wrote: [...] The point of an `Error` is that your code can assume it cannot happen. If it does happen, the code is invalid. According to my favorite dictionary "assume" means "take for granted" [1]. If `Error`s may happen how can code (or its author) "assume" that `Error`s cannot happen? You don't assume it, you guarantee it. You are expected to provide a guarantee to the compiler that your code won't throw these errors. But you aren't perfect, and so maybe you make a mistake, and trigger an Error. The compiler handles this unexpected condition by unwinding the stack back to the main function, printing the error and exiting, so you can go fix whatever mistake you made. It's kind of like a segfault. There's no valid reason to read memory you don't own (yes, I know you can use segfaults to trigger loading of memory, I'm not talking about that kind of segfault). So what do you do when an unexpected segfault happens? You crash the program, and exit. In this case, the language is giving you by default a hint about where it occurred, and if you desire, you can get more information by catching the error where you want and doing more checks, etc. This is reflected in the fact that the compiler will omit cleanup code if an `Error` is thrown (it can assume that it will never happen). But instead the compiler should *emit* the cleanup code and we would not have to discuss here carefully avoiding to name the root cause of all this entanglements. A compiler *could* do this, and in fact, the compiler used to do this. But I think you are still not supposed to continue execution. I'm not sure what a compiler might assume at this point, and I unfortunately can't find in the language specification where it states this. It might not be in there at all, the spec is sometimes lacking compared to the implementation. However, I did ask Walter about this last beerconf, and he said to treat a throw/catch of an error like a goto, anything can happen. The point of using `Error` is for a last resort check for program correctness (because you failed to validate the input before getting to that point). If the code threw an `Exception` instead of an `Error` everything would be fine. I think the point of Errors is that you can remove them for efficiency. In other words, just like asserts or bounds checks, they are not expected to be part of the normal working program. Exceptions are part of the program, and provide a different mechanism of handling error conditions. [...] A great example are range functions. Often times you see at the beginning of any `popFront` method the statement `assert(!empty);`. This is universally accepted, as you shouldn't be calling `popFront` if you haven't checked for `empty`. Yep. ``` core.exception.AssertError@[...]linux/bin64/../../src/phobos/std/range/primitives.d(2280): Attempting to popFront() past the end of an array of int ``` I see no difference to the potentially invalid array index case. It would ease the use of the range if it threw an `Exception`. But it's possible to turn off asserts and make the code run faster. I personally never turn them off on certain programs (web server) because the penalty is not noticeable enough. But if these were Exceptions, they *could not be turned off*. Consider the normal flow of a range in a foreach loop, it's: ```d // foreach(elem; range) for(auto r = range; !r.empty; r.popFront) { auto elem = r.front; } ``` If both `popFront` and `front` also always call `empty` you are calling `empty` 3 times per loop, with an identical value for the 2nd and 3rd calls. Having the assert allows diagnosing invalid programs without crashing your program, but also allowing full performance when you want it. Phobos' `RedBlackTree` has an `invariant` which walks the entire RBT and validates the red-black property holds *before and after every method call*. This is not what you would want for performant code as it completely destroys the complexity guarantees. Yet it's there to help diagnose problems with RBT if you are working on modifying it. These kinds of checks are to help the developer prove their code is correct without having to continually prove it's correct for normal use. -Steve
Re: D for data science and statistics
On 6/4/22 13:26, Nicolas wrote: > 2. What about its integration with data analysis tools? Do you think it > could be an alternative to, let's say, Python? I suspect Python is much more mature in that space. I would browse the following page, which lists many organizations using D for data processing: https://dlang.org/orgs-using-d.html Wow! Time passes fast... It's been 8 years since the following article came up: https://tech.nextroll.com/blog/data/2014/11/17/d-is-for-data-science.html And the following is by Netflix: https://netflixtechblog.medium.com/introducing-vectorflow-fe10d7f126b8 There is also open source code which may have useful modules. Here are results for searching "statistics": https://code.dlang.org/search?q=statistics And Mir appears under "science": https://code.dlang.org/search?q=science Ali
Re: Comparing Exceptions and Errors
On 6/4/22 10:17, Ola Fosheim Grøstad wrote: > Why can't Error unwind the stack properly? Errors are thrown when the program is discovered to be in an invalid state. We don't know what happened and when. For example, we don't know whether the memory has been overwritten by some rogue code. Or perhaps a bit got flipped in memory. When the state of the program is discovered to be outside of what we think is normal, we cannot execute further code. It would be madness to wish that some cleanup code would do the right thing when e.g. we were sure that an array would never be empty but we found it to be empty. What happened? What can we assume. We don't know and we cannot assume any state. (As has been stated many times in this thread and elsewhere, Exceptions are different. They don't have anything to do with invariants.) > In a not-miniscule service you can be pretty certain that some ±1 bugs > will be there, especially in a service that is receiving new features on > a regular basis. So, if you get an index/key error/null-dereferencing > that wasn't checked for, unwinding that actor/task/handler makes sense, > shutting down the service doesn't make sense. Is the service in a usable state? > If you allow the whole service to go down then you have opened a > Denial-of-Service vector Possibly. Not shutting down might produce incorrect results. Do we prefer up but incorrect or dead? > I am not a fan of Go, but it is difficult to find a more balanced > solution, and Go 1.18 has generics, so it is becoming more competitive! I hope there is a way of aborting the program when there are invariant violations discovered. Ali
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 22:31:38 UTC, Ola Fosheim Grøstad wrote: So what do you have to do to avoid having Errors thrown? How do you make your task/handler fault tolerant in 100% @safe code? Run it in a separate process with minimum shared memory.
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 16:55:31 UTC, Steven Schveighoffer wrote: [...] The point of an `Error` is that your code can assume it cannot happen. If it does happen, the code is invalid. According to my favorite dictionary "assume" means "take for granted" [1]. If `Error`s may happen how can code (or its author) "assume" that `Error`s cannot happen? That makes absolutely no sense to me. This is reflected in the fact that the compiler will omit cleanup code if an `Error` is thrown (it can assume that it will never happen). But instead the compiler should *emit* the cleanup code and we would not have to discuss here carefully avoiding to name the root cause of all this entanglements. The point of using `Error` is for a last resort check for program correctness (because you failed to validate the input before getting to that point). If the code threw an `Exception` instead of an `Error` everything would be fine. [...] I actually replaced some arrays with an `Exception` throwing wrapper because I didn't want to crash the whole server for certain cases, and I didn't want to continuously validate array indexes. +1 [...] A great example are range functions. Often times you see at the beginning of any `popFront` method the statement `assert(!empty);`. This is universally accepted, as you shouldn't be calling `popFront` if you haven't checked for `empty`. Yep. ``` core.exception.AssertError@[...]linux/bin64/../../src/phobos/std/range/primitives.d(2280): Attempting to popFront() past the end of an array of int ``` I see no difference to the potentially invalid array index case. It would ease the use of the range if it threw an `Exception`. [1] https://www.thefreedictionary.com/assume
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 22:01:57 UTC, Steven Schveighoffer wrote: You shouldn't retry on Error, and you shouldn't actually have any Errors thrown. So what do you have to do to avoid having Errors thrown? How do you make your task/handler fault tolerant in 100% @safe code?
Re: D for data science and statistics
On Saturday, 4 June 2022 at 20:26:54 UTC, Nicolas wrote: Hi all! Pleased to meet you. I am currently deep-diving into data analysis and statistics with R and SQL. I got mid-level programming experience, focusing on algorithms and innovation instead of sticking to one programming language. I only got three questions: 1. Is there any extensive, up-to-date documentation on D? I really like its syntax and potential, so I am going to try and study anything regarding this programming language. 2. What about its integration with data analysis tools? Do you think it could be an alternative to, let's say, Python? 3. What IDE do you recommend when it comes to D? Thank you all. You're awesome ^-^ Hi there! 1) Phobos documentation is available online. Great book also http://ddili.org/ders/d.en/index.html 2) R integration: https://dlang.org/blog/2020/01/27/d-for-data-science-calling-r-from-d/ Python integration: https://pyd.readthedocs.io/en/latest/ D usage in Data Science example: https://tech.nextroll.com/blog/data/2014/11/17/d-is-for-data-science.html Stats package: https://github.com/DlangScience/dstats 3) one of the best is “Code-d” LSP server, which could be used from VS Code or Vim/NeoVim PS there are several Machine Learning libraries: vectorflow from Netflix, grain and rnnlib But all of them are far away from modern libs like TF or PyTorch or OpenAI
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 14:05:14 UTC, Paul Backus wrote: [...] What does that mean? Am I `Error` blind? Generally you do not need to subclass `Error` yourself. The most common way of throwing an `Error` in user code is to use `assert`, which (with default compiler flags) throws an `AssertError` on failure. Function contracts and struct/class invariants work the same way. `git grep -Enw 'assert|unittest'` reveals that my code contains assert statements only in unittests. Someone (was it Walter?) once pointed out that asserts are ignored in relase mode (like C assert) and that for my purposes `enforce` (i.e. throw an Exception) is best suited. 3. Can you provide some piece of code which *must* throw `Error` and cannot throw an appropriate Exception? This is entirely a question of API design. If it should be the caller's responsibility to check for some condition before calling the function, then you can throw an `Error` when that condition does not hold (or more likely, use an `assert` or an `in` contract to check for it). Provided one does not catch `Error`s this means one has to isolate such an API design by using a subprocess. This is what one usually tries to avoid. If it should be the callee's responsibility to check, you should throw an `Exception` (or use `enforce`). If the library always throws exceptions it can be used in both API "designs". In the case that the implementor of the caller expects `Error`s instead of `Exceptions` she could use a small wrapper which catches the Exceptions and rethrows them as `Error`s. Likewise for error codes. Using contracts and invariants impedes this approach.
Re: Comparing Exceptions and Errors
On 6/4/22 2:46 PM, Ola Fosheim Grøstad wrote: On Saturday, 4 June 2022 at 18:32:48 UTC, Sebastiaan Koppe wrote: Most wont throw a Error though. And typical services have canary releases and rollback. So you just fix it, which you have to do anyway. I take it you mean manual rollback, but the key issue is that you want to retry on failure. Not infrequently the source for the failure will be in the environment, the code just didn't handle the failure correctly. You shouldn't retry on Error, and you shouldn't actually have any Errors thrown. I'll draw a line in the sand here -- OutOfMemoryError shouldn't be an Error, but an Exception. Because there's no way you can check if an allocation will succeed before doing it, and arguably, there are ways to deal with out of memory problems without shutting down the process. On a service with SLA of 99.999% the probable "failure time" would be 6 seconds per week, so if you can retry you may still run fine even if you failed to check correctly for an error on that specific subsystem. That makes the system more resilient/robust. Exceptions are perfectly fine to catch and retry. Anticipating the failing condition, and throwing an exception instead is a viable solution. -Steve
Re: D for data science and statistics
As i personally did not used Windows the last 5 years, i use as editor for any language: neovim-qt. Someone else might answer about good Windows editors. As for the other questions google "awesome dlang" will return interesting results. I consider Dlang general purpose as opposed to specialized languages like R or Julia.
D for data science and statistics
Hi all! Pleased to meet you. I am currently deep-diving into data analysis and statistics with R and SQL. I got mid-level programming experience, focusing on algorithms and innovation instead of sticking to one programming language. I only got three questions: 1. Is there any extensive, up-to-date documentation on D? I really like its syntax and potential, so I am going to try and study anything regarding this programming language. 2. What about its integration with data analysis tools? Do you think it could be an alternative to, let's say, Python? 3. What IDE do you recommend when it comes to D? Thank you all. You're awesome ^-^
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 18:32:48 UTC, Sebastiaan Koppe wrote: Most wont throw a Error though. And typical services have canary releases and rollback. So you just fix it, which you have to do anyway. I take it you mean manual rollback, but the key issue is that you want to retry on failure. Not infrequently the source for the failure will be in the environment, the code just didn't handle the failure correctly. On a service with SLA of 99.999% the probable "failure time" would be 6 seconds per week, so if you can retry you may still run fine even if you failed to check correctly for an error on that specific subsystem. That makes the system more resilient/robust.
Re: dlang compilers & licenses.
Nice , a lot of freedom with dmd & ldc.
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 17:17:13 UTC, Ola Fosheim Grøstad wrote: Why can't Error unwind the stack properly? It does normally, but it doesn't destruct objects when those are in `nothrow` functions. Nothrow functions don't throw, so have no cleanup. You could argue it is strange that assert throws... In a not-miniscule service you can be pretty certain that some ±1 bugs will be there, especially in a service that is receiving new features on a regular basis. Most wont throw a Error though. And typical services have canary releases and rollback. So you just fix it, which you have to do anyway. Not saying its perfect, but if you only use asserts when you have to, and handle other things using the type system, it doesn't actually happen all that often.
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 16:55:50 UTC, Sebastiaan Koppe wrote: The reasoning is simple: Error + nothrow will sidestep any RAII you may have. Since you cannot know what potentially wasn't destructed, the only safe course of action is to abandon ship. Why can't Error unwind the stack properly? Yes, in plenty of cases that is completely overkill. Then again, programs should be written to not assert in the first place. In a not-miniscule service you can be pretty certain that some ±1 bugs will be there, especially in a service that is receiving new features on a regular basis. So, if you get an index/key error/null-dereferencing that wasn't checked for, unwinding that actor/task/handler makes sense, shutting down the service doesn't make sense. If you allow the whole service to go down then you have opened a Denial-of-Service vector, which is a problem if the service is attracting attention from teens/immature adults. (E.g. games, social apps, political sites, educational sites etc). Considering most asserts I have seen are either due to a bad api or just laziness - and shouldn't have to exist in the first place - maybe it's not that bad. Well, problem is if a usually reliable subsystem is intermittently flaky, and you get this behaviour, then that isn't something you can assume will be caught in tests (you cannot test for all scenarios, only the likely ones). I am not a fan of Go, but it is difficult to find a more balanced solution, and Go 1.18 has generics, so it is becoming more competitive! At the end of the day you don't have to love a language to choose it… and for a service, runtime behaviour is more important than other issues.
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 01:17:28 UTC, Steven Schveighoffer wrote: If a thread does not catch an error and end the program, that's a defect in druntime I think. If it tries to rethrow the exception in the main thread (oh, man I have to check... Yeah, this is what it does), then it's entirely possible that the main thread will never even get to the `Error`! Yes, for that reason, and others, people should not use that api. If we are paranoid and want to do as little as possible, at least we should attempt to copy a string literal to stderr. Something like "Thread exiting with Error." And exit(1) right after that. Yes, that is what it should do. Probably yes.
Re: Comparing Exceptions and Errors
On 6/4/22 7:57 AM, kdevel wrote: On Friday, 3 June 2022 at 23:40:50 UTC, Steven Schveighoffer wrote: During the last beerconf, I wrote a short blog post about how `Error` and `Exception` are different, and why you should never continue after catching `Error`s. Feedback welcome, I didn't announce here when I wrote it because it's kind of small/insignificant, but maybe it can help newcomers to the language: https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/ Here my feedback: 1. What if div is called with x = -2147483648 and y = -1? Isn't code which allows a divisor == 0 to propagate to the CPU an error? Must the code thus not throw an object instantiated from a subclass of `Error`? Well, that is just a toy example to show code that might use an Error. It's not intended to be a fully-fleshed-out function. I recommend simply using the divide operator in real code. The point of an `Error` is that your code can assume it cannot happen. If it does happen, the code is invalid. This is reflected in the fact that the compiler will omit cleanup code if an `Error` is thrown (it can assume that it will never happen). The point of using `Error` is for a last resort check for program correctness (because you failed to validate the input before getting to that point). What if I have that function div used in code which is called from say controller code of a CGI binary. Or likewise from a vibe.d-thread servicing a web request? How do I isolate that fault? Do I have to spawn a subprocess as Walter suggested in the case of memory corruption [1]? [This is of course all rhetorical!] vibe should exit the process if an `Error` is thrown. There is a version you can specify to have it catch `Error`, but it would only be for debugging. https://vibed.org/docs#compile-time-configuration (see `VibeDebugCatchAll`) One thing that always bugs me in my vibe code is out of bounds errors for arrays. I actually replaced some arrays with an `Exception` throwing wrapper because I didn't want to crash the whole server for certain cases, and I didn't want to continuously validate array indexes. 2. Since 2017 or so I have written some 10 KLOC of D, maybe about two dozen classes deriving from Exception. But I did not annotate any of my methods or function with "nothrow" nor did I author any class deriving from `Error`. What does that mean? Am I `Error` blind? As long as you aren't catching `Throwable` or `Error`, you should be fine. Simply not marking things `nothrow` doesn't mean that they won't be inferred `nothrow`. `auto` and template functions are inferred. In practice, there are probably very very few places where this can bite you. Which also means, if it does bite, it's going to be really really hard to track down. 3. Can you provide some piece of code which *must* throw `Error` and cannot throw an appropriate Exception? As Paul said, this is up to your API. If you specify that you assume the inputs to the function are cleansed, then you can correctly throw an Error if they are out of spec. A great example are range functions. Often times you see at the beginning of any `popFront` method the statement `assert(!empty);`. This is universally accepted, as you shouldn't be calling `popFront` if you haven't checked for `empty`. -Steve
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 14:19:22 UTC, Ola Fosheim Grøstad wrote: Also, what it is the purpose of @safe if you have to kill all threads? Such rigidity will just make Go look all the more attractive for service providers! I agree with this, but given the current semantics there is nothing else to do but teardown everything upon first sight of Error. The reasoning is simple: Error + nothrow will sidestep any RAII you may have. Since you cannot know what potentially wasn't destructed, the only safe course of action is to abandon ship. Yes, in plenty of cases that is completely overkill. Then again, programs should be written to not assert in the first place. Considering most asserts I have seen are either due to a bad api or just laziness - and shouldn't have to exist in the first place - maybe it's not that bad.
Re: What happened to Deimos and why ?
How come i don't see commit activity on github ?. The code is perfect or not maintained ?
Re: dlang compilers & licenses.
On Saturday, 4 June 2022 at 14:13:08 UTC, Alain De Vos wrote: Do DMD , GDC , LDC have the same or different licenses in use ? DMD https://github.com/dlang/dmd/blob/master/LICENSE.txt LDC https://github.com/ldc-developers/ldc/blob/master/LICENSE GDC https://github.com/D-Programming-GDC/gcc/blob/ci/mainline/COPYING3 https://github.com/D-Programming-GDC/gcc/blob/ci/mainline/COPYING.RUNTIME
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 01:17:28 UTC, Steven Schveighoffer wrote: I've thought in the past that throwing an error really should not throw, but log the error (including the call stack), and then exit without even attempting to unwind the stack. But code at least expects an attempt to throw the Error up the stack, so code that is expecting to catch it would break. This is too harsh for a service that is read-only, meaning a service that only read from a database and never writes to it. All running threads have to be given a chance to exit gracefully, at the very minimum. What is the source for these errors anyway? A filesystem not responding? A crashed device driver? A race condition? A deadlock? Starvation? Many sources for errors can be recovered from by rescheduling in a different order at a different time. What I'd like to see is a fault tolerant 100% @safe actor pattern with local per-actor GC. By fault tolerant I mean that the actor is killed and then a new actor is rescheduled (could be an alternative "reference" implementation or the same after a time delay). Also, what it is the purpose of @safe if you have to kill all threads? Such rigidity will just make Go look all the more attractive for service providers!
Re: What happened to Deimos and why ?
On Saturday, 4 June 2022 at 13:44:06 UTC, Alain De Vos wrote: What happened to Deimos and why ? Nothing, it does its job same as it always has.
dlang compilers & licenses.
Do DMD , GDC , LDC have the same or different licenses in use ?
Re: Comparing Exceptions and Errors
On Saturday, 4 June 2022 at 11:57:32 UTC, kdevel wrote: 2. Since 2017 or so I have written some 10 KLOC of D, maybe about two dozen classes deriving from Exception. But I did not annotate any of my methods or function with "nothrow" nor did I author any class deriving from `Error`. What does that mean? Am I `Error` blind? Generally you do not need to subclass `Error` yourself. The most common way of throwing an `Error` in user code is to use `assert`, which (with default compiler flags) throws an `AssertError` on failure. Function contracts and struct/class invariants work the same way. 3. Can you provide some piece of code which *must* throw `Error` and cannot throw an appropriate Exception? This is entirely a question of API design. If it should be the caller's responsibility to check for some condition before calling the function, then you can throw an `Error` when that condition does not hold (or more likely, use an `assert` or an `in` contract to check for it). If it should be the callee's responsibility to check, you should throw an `Exception` (or use `enforce`).
What happened to Deimos and why ?
What happened to Deimos and why ?
Re: Comparing Exceptions and Errors
On Friday, 3 June 2022 at 23:40:50 UTC, Steven Schveighoffer wrote: During the last beerconf, I wrote a short blog post about how `Error` and `Exception` are different, and why you should never continue after catching `Error`s. Feedback welcome, I didn't announce here when I wrote it because it's kind of small/insignificant, but maybe it can help newcomers to the language: https://www.schveiguy.com/blog/2022/05/comparing-exceptions-and-errors-in-d/ -Steve Here my feedback: 1. What if div is called with x = -2147483648 and y = -1? Isn't code which allows a divisor == 0 to propagate to the CPU an error? Must the code thus not throw an object instantiated from a subclass of `Error`? What if I have that function div used in code which is called from say controller code of a CGI binary. Or likewise from a vibe.d-thread servicing a web request? How do I isolate that fault? Do I have to spawn a subprocess as Walter suggested in the case of memory corruption [1]? [This is of course all rhetorical!] 2. Since 2017 or so I have written some 10 KLOC of D, maybe about two dozen classes deriving from Exception. But I did not annotate any of my methods or function with "nothrow" nor did I author any class deriving from `Error`. What does that mean? Am I `Error` blind? 3. Can you provide some piece of code which *must* throw `Error` and cannot throw an appropriate Exception? [1] http://forum.dlang.org/post/t6ef8c$1cu5$1...@digitalmars.com Re: Why is D unpopular?