News for hackers. Stuff that matters.
Re:Programming Paradigms for Dummies: What Every Programmer ... by uryga on Monday November 05, 2018 @10:02AM (#18382788)
> Exceptions imply a temporal coupling from error occurrence to error handling.

Could you expand on this? I understood your statement as "Exceptions sort-of force you to handle an error the moment it occurs", but I'm having trouble seeing why this would be specific to exceptions and not the case with other error handling solutions.

(I don't mean to sound like a big exception-defender – I prefer ML/Rust-style Result types)

Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Monday November 05, 2018 @10:19AM (#18382913)
In some cases immediate action might have to be taken (like calling abort()) but very often that is not the case. Another strategy is to collect errors. Then decide what to do them at another point (no temporal or physical coupling!). After all errors are collected, you can group them, sort them, or aggregate them. Whatever is appropriate.

Looking at errors as just data avoids the "exceptional vs non-exceptional" hair splitting, and gives a lot of flexibility for code structure. I don't necessarily disagree with the Result type viewpoint as a return type from functions, but I also find it pretty pointless. Very often the best action is to separate out errors from successes into different tables immediately. A built-in Result type couples them, and encourages keeping them coupled.

Now you could argue that you can do that with Exceptions, too, by catching them immediately and treating them as data. In which case I want to ask "what's the point then?" and also refer to my topmost comment. Exceptions have a significant cost in infrastructure even if you don't actually use them...

Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Tuesday November 06, 2018 @01:42AM (#18388909)
What are you going to do with the errors once you have collected them?

What is the point of sorting or grouping them?

Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Tuesday November 06, 2018 @02:25AM (#18389061)
A simple example from the compiler I'm working on right now: I output type errors of expressions sorted by their location in the source file, instead of in the order they are detected. I also don't error out on the first one, but find all at once. I could also group warnings and errors together, output only the first N errors, or... whatever I fancy. Errors are just data.
Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Tuesday November 06, 2018 @06:45PM (#18395916)
Well, this example seems somewhat contrived to me because these errors are not the errors happening in the compiler, they are diagnostic messages describing the errors in the input data.

Any chance you have another example?

Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Tuesday November 06, 2018 @06:50PM (#18395955)
"An error happening in the compiler". What's that? If you mean a bug detected, then it should be handled with abort().
Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Wednesday November 07, 2018 @02:53AM (#18397668)
An error related to the file system, for example.
Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Wednesday November 07, 2018 @07:58AM (#18398789)
A file system error isn't an error happening in the compiler. The file system is an external system. So this error isn't really any different than a syntax error or type error. I would not treat it differently except making a different error message. Of course you cannot parse a file you cannot read, so there is a dependency which means that sooner or later you need to "act" on the error.
Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Thursday November 08, 2018 @05:42PM (#18410734)
Well, grouping errors in your example makes sense when all of them happened during processing a particular input which is expected to be invalid sometimes.

Could you share another example where accumulating errors makes sense?

Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Friday November 09, 2018 @09:56AM (#18414779)
You can do it with anything. Analyze all the files in a directory, for instance. Do all the IO in parallel and merge the results at a central point. Some files might be corrupt or whatever. Merge the results at a central point. Only then present them to the user in a sensible order.

A real life example: Asynchronous webservers usually have worker threads for I/O. I/O errors need to be routed to the originators of the I/O requests (which are in other threads). Exceptions cannot do that.

Here's the general point: Whether any given thing is an "Error" is highly subjective and context dependent. But clearly the error is data, so why take away the possibility to process it like any other data?

Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Saturday November 10, 2018 @09:06AM (#18421369)
This is an interesting conversation for me, but I still don't quite understand your reasoning.

IMO, using exceptions doesn't preclude treating errors as data.

In your example with parallel processing, you could throw an error as exception, let it unwind the whole stack, catch it and return as the result of the task.

This way you don't couple the code that does the useful work with the code that handles errors.

In other words, I don't understand why you dislike exceptions.

IMO they are a good tool for any task that doesn't require different actions to handle different errors.

Re:Programming Paradigms for Dummies: What Every Programmer ... by jstimpfle on Saturday November 10, 2018 @03:22PM (#18423286)
Exceptions are not just data, at least not if you do not always catch them immediately (in which case they are just pointless).

They introduce additional control paths which are hard to reason about. In many languages these are not even explicit. Exceptions require an additional syntax to handle them. And having exceptions requires significant language infrastructure and comes with a huge toll on the structure of software projects. See my topmost comment.

> In your example with parallel processing, you could throw an error as exception, let it unwind the whole stack, catch it and return as the result of the task.

Which would catch only the first encountered error per thread. And not catch all the other errors that we could encounter and report after that.

Re:Programming Paradigms for Dummies: What Every Programmer ... by gdy on Monday November 12, 2018 @03:26PM (#18435419)
Well, if you don't have exceptions, stack unwinding, RAII, you've got to manually code the same sort of logic using repetitive code. Or you would have to change your design to minimise the pain of hand-coding stack unwinding, most likely paying a price for that in form of damaging other aspects of design. In other words, NOT having exceptions, IMO, results in having to write a huge amount of code accomplishing a trivial task - aborting some unit of functionality upon unexpected error.

"And not catch all the other errors" I think, in most cases after an unexpected error happens it doesn't make sense to continue the task and report more errors, most likely induced by the first error.

Don't get me wrong, there are plenty of cases when returning errors as values is the best fit and using the exceptions would be a disaster, but my point is that, IMO, the situation when errors abort tasks and are handled in more or less the same way is much more common.

Re:Programming Paradigms for Dummies: What Every Programmer ... by gbear605 on Monday November 05, 2018 @10:16AM (#18382891)
A rather odd example with Result type systems: Say you have a function that returns the results of three other functions together in a tuple and the first one errors. The other two can still run and their result can be returned in the tuple along with an Error for the first function.
Re:Programming Paradigms for Dummies: What Every Programmer ... by uryga on Monday November 05, 2018 @11:12AM (#18383439)
Ah, so using Result types you can return

  `(Optional<A>, Optional<B>, Optional<C>)`
– each can fail or succeed independently. But you can't do that if you're using exceptions to signal errors – it's like returning

  `Optional<(A, B, C)>`
, you get either all the results or nothing. Good example, thanks!
Re:Programming Paradigms for Dummies: What Every Programmer ... by Jtsummers on Monday November 05, 2018 @12:20PM (#18384029)
You can still get something like that using exceptions, it depends on where the exceptions are caught. If you have a function which has 3 calls:

  function f (...) {
    val a = something.a();
    val b = something.b();
    val c = something.c();
    return (a,b,c);
  }
If the exceptions can occur in the calls assigning to a, b, or c and are handled locally (here, in f) then you can construct that first case. It's only if you throw the exception up one level higher that you end up in the latter case. As written, it is more like your latter example. But with a modication:

  function f(...) {
    val a = default_a;
    val b = default_b;
    val c = default_c;
    try {
      a = something.a();
    } catch {
      a = error_value_a;
    }
    ...
  }
You can get the former case.