> On 17 Jan 2017, at 11:46, Jeremy Pereira <jeremy.j.pere...@googlemail.com> 
> wrote:
> 
>> 
>> On 17 Jan 2017, at 11:28, Alex Blewitt <alb...@apple.com> wrote:
>> 
>> 
>>> On 17 Jan 2017, at 11:10, Jeremy Pereira via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 
>>>> On 17 Jan 2017, at 02:38, thislooksfun via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> I really hate to bring Java up, but I really do think it got at least one 
>>>> thing right with its error system, namely that one subset of error (namely 
>>>> `RuntimeException`), wouldn't be enforced by the compiler, but could 
>>>> optionally be caught.
>>> 
>>> I don’t entirely agree for two reasons:
>>> 
>>> 1. If a runtime error is thrown and caught, there is no way to guarantee 
>>> the logical consistency of the state of the running process because who 
>>> knows which stack frames were unwound without cleaning up properly. There 
>>> is no way to safely catch a run time exception and recover.
>> 
>> From a Java perspective, clearly that's not true. 
> 
> It absolutely is true. 
> 
>     int someMethod()
>     {
>         aquireSomeLock();
>         doSomethingThatIsNotDeclaredToThrowAnException();
>         releaseSomeLock();
>     }

The general way to perform locking in Java is to use a synchronised block 
around a particular resource, and those are cleaned up by the Java VM when 
unwinding the stack, or to use a finally block to do the same. You can 
certainly write incorrect code in Java; the correct code would look like:

int someMethod() {
  try {
    acquireSomeLock();
    doSomethingThatIsNotDeclaredToThrowAnException();
  } finally {
    releaseSomeLock();
  }
}

It's more likely to be written as:

int someMethod() {
  synchronized(lockObject) {
    doSomethingThatIsNotDeclaredToThrowAnException();
  }
}

and where 'lockObject' is 'this' then the shorter

synchronized int someMethod() {
   doSomethingThatIsNotDeclaredToThrowAnException();
}

>> It may well be true for the current implementation of Swift, and there's 
>> questions about how to clean up objects with reference counts outstanding 
>> (since there's no garbage collector). It isn't necessarily the case that it 
>> isn't possible, but it does require some additional stack unwinding; and the 
>> implementation of that may be too cumbersome/impractical/undesirable to 
>> occur.
> 
> Not all resources are reference counts or memory allocations.

True; file descriptors are one such example. Again, the language has the 
ability to recover instead of blowing up when that occurs:

try(FileInputStream in = new FileInputStream("theFIle")) {
  // do stuff with input stream
} // input stream is closed

Compilers and tools can generate warnings for such cases, in the same way that 
other languages can warn about not freeing memory.

> 
>> 
>>> 2. People abuse RuntimeException to simplify their error handling code: “if 
>>> I throw a RuntimeException I don’t need a zillion catch clauses or throws 
>>> declarations”. Furthermore, if a library uses RuntimeExceptions where it 
>>> should be using Exceptions there is no way to know if its API has changed 
>>> except by reading the (hopefully up to date) documentation.
>>> 
>>> Problem 2 makes me particularly bitter because JEE programmers seem to have 
>>> learned that allowing code to throw null pointer exceptions has no real 
>>> consequences for them  so they become very cavalier about doing their null 
>>> checks. The user sees an 500 error page, the sys admin gets a 200 line 
>>> stack trace in the log, but the system carries on. If you are lucky enough 
>>> to have the source code to diagnose the problem, it usually turns out that 
>>> the exception was thrown on a line with eight chained method calls. When 
>>> you do track the problem down, it turns out you forgot a line in the 
>>> properties file or something similar but the programmer couldn’t be 
>>> bothered to help you out because it was easier just to let the null pointer 
>>> exception happen.
>> 
>> That's a pretty poor example, and in any case, the individual cause would 
>> allow the system to continue on processing subsequent requests, which is 
>> generally what's wanted. When you're working on large systems and with large 
>> data sets, there are generally always problematic items like this which have 
>> to be diagnosed sufficiently in order to be retried, or even handled 
>> manually. It has very little to do with the language and more to do with the 
>> quality of data which isn't something you always have control over.
> 
> No it’s not a poor example. I’ve seen it happen with real software in real 
> production scenarios.

And if we're talking anecdata, I've seen large production systems where a 
particular message has been unable to be processed due to some incorrect data 
formatting (in some cases, an invalid UTF-8 sequence of bytes being passed in 
and treated as UTF-8). The general way is not to crash and return that and let 
it be processed a subsequent time, but ignored, put into a manual resolve 
queued, and keep going.

> 
>> 
>>> I like Swift’s error handling because programming errors (like force 
>>> unwrapping nil) are punished mercilessly by process termination and errors 
>>> caused by external factors cannot be completely ignored. You have to at 
>>> least put an empty catch block somewhere.
>> 
>> This is one of the significant problems in Swift at the moment for 
>> server-side logic. It may make sense to do this from a single-user 
>> application, but writing a server which is designed to handle hundreds or 
>> thousands of simultaneous clients can suffer from the fact that one bad 
>> client request can take out everyone's connection. In the server working 
>> group and in existing tools like Kitura/Vapor/Perfect etc. it's a 
>> non-trivial problem to solve, other than using a CGI like model where each 
>> request is handled by a single worker process that can terminate 
>> independently of the other requests in flight.
> 
> I agree it’s a non trivial problem to resolve. I’m saying that the Java 
> “solution” of RuntimeExceptions doesn’t resolve it. 

Except you've not said /why/ the Java 'solution' of RuntimeExceptions doesn't 
resolve it. You've just used a couple of examples to prove it's possible to 
write bad Java code; but you can write bad code in any language.

Alex
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to