On 06/26/2016 11:18 AM, Jochen Theodorou wrote:
On 26.06.2016 09:11, Mr Andersson wrote:


On 06/24/2016 10:55 PM, Jochen Theodorou wrote:
On 24.06.2016 18:12, Mr Andersson wrote:
[...]
static Groovy is on par most of the time, dynamic Groovy depends, but
I think it is more in the range of being 2.5 times java (100ms runtime
becomes 250ms). I think that is close enough.... and there is still
some potential

But a Java fork would be almost 1:1, if all it generated was Java like
code.

Java like code means to do what Java does. Basically you want a
language that includes Java and does things different only in parts,
which are not in Java... That means loosing ==, that means loosing our
array access logic, that means loosing double dispatch of course..
doing builders will become difficult... unless you want to do them
like Kotlin. Runtime meta programming basically impossible

I think the performance issues is the invokeDynamic calls that
groovy does internally, and they might not necessarily be needed.

there not that many of those, really.

[...]
However, any editor could in principle, and in theory tell you on any
call, what exceptions can be thrown and what kind of exceptions you
could choose to handle. Ofcourse that would result in many exceptions
often but the need to declare them on each method is largely syntatical
and ugly.

think of a public method and an unknown subclass overriding that
method. How can your editor know, that your library method can only
throw the exceptions you use in your code and no other? It cannot,
unless you make the method final, or say you don´t do libraries ;)

Yes, I also mentioned that case. But since that abstract method either
has an throws exception declaration on it for specifically stating what
kind of exception can be thrown, to notify the editor. One should still
however expect other types of exceptions. The thing is that currently,
even if an abstract method does not directly state it throws an
exception type, it can still throw a new RuntimeException(new
IOException()) so why force the wrapping in the first place?

wrapping is irritating me. The JVM does not really know a difference between a checked and a unchecked exception. Thus on the JVM level you really do not need to wrap anything.... and in Groovy we do not do that, if we can avoid it. In fact I removed lots of wrapped exceptions over the years, that have been only required to transport them through the runtime for the satisfaction of the java compiler.

Why force an implementor to either handle an exception type when most of
the time it doesn't even make sense to do so. If an implementor to a no
throw exception abstract method, say has to open a file and read it, and
then return a String, what should that implementor really do to handle
the IOException? First it happens so rarely that it doesn't make sense
to handle it, then even if you do handle it, you can only log it. The
abstract method caller still excepts a response, and you can not abort
the caller, unless you throw a RuntimeException and hope that he manages
it, or return null. Why trycatch(Runtime) when you could just as well
trycatch(Throwable) in this case. You would not need a getCause call to
figure out if it's wrapped or how many times it has been wrapped.  You
could also without wrapping trycatch(IOException) directly.

and then your project is also checked with sonar and it wants to force you to not just ignore the exception as well.. yeah, I know that pain

But to be honest, the entire notion of exceptions is kind of broken. An
IOException is not unique other than by at best it's message, and if one
decides to bubble an IOException, at some point you will no longer know
what actually was the root reason if in the call hierarchy as multiple
places can throw an IOException for various reasons.

but the question is how to make it better. Just making all checked exception unchecked won´t solve this.

Yes, that's the million dollar question :)


I know of 3 ways of error handling...

(a) exceptions, like in Java, Python and many other languages
(b) error object or status code as return value, like C for example
(c) using multiple return to transport status code (or error object) as well as normal return value.. like Go

I don´t like option b much, but in all cases you need to adapt the control flow of your code to the error handling in some way or other.

Hmm, what about d) If all objects by default have access to three methods, hasException(), setException() and getException() .. including *nul**l*** which can be returned as a new Error('...'), the caller would by default check if the value is not null, and then he could proceed to get the error();

for instance:

public String getText(URL file) {
// we try to get the content but fail because there is no internet connection return new Exception( theIOException ); // basically (new null).setException( exception );
}

Just an idea. The problem here though is that the editor in my first argument would be able to see that an exception/error could occur so we would be back at the first problem. Since we are talking about Java, real exceptions are a real thing and we can't get away from the existing code and API's, so this would just introduce complexity and offer two different way of managing exceptions.

I would still like to argue for treating checked and unchecked the same. There really isn't any difference in theory. It is just forced upon by the API desginers that something can throw a checked exception just because they were unable to communicate a different return type any different way. The only difference is that the API designer has determined that YOU MUST handle it or bubble it. Bubbling it is not always easy. Since Runtime exceptions can be thrown by any API, including for instance *ConurrentHashMap.compute* the problem with knowing what a method can throw has already moved from the throws declaration to be added as *pure documentation instead*. The compiler if it did not ignore runtime exceptions would despite lack of documentaion many times be able to tell you at least some of teh exceptions that can be thrown, the remaining would have to be declared or experienced.

https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html#compute-K-java.util.function.BiFunction-

With Java 8 and lambdas this problem is just getting bigger and bigger. Most the Java API's that accepts lambdas are not allowed to throw Exceptions which i a major mistake if you ask me. At least one exception should've been allowed by default on all those major lambdas. Instead, we are now literally *forced* to wrap them as RuntimeException simple to avoid having to handle a getText(file) call. How ugly isn't that? not only design but also try catch blocks all over the place too doing nothing other than hide the real exception.

The difference between checked and unchecked really isn't that big. Checked exception should really only be thrown when there is a critical error, where the caller MUST manage it. Checked exceptions are abused and thrown instead, probably mostly to get that easy documentation with your code, since most of the time no one knows what kind of RuntimeExceptions that can be thrown if there is no documentation of them.

And yes, you are right, the compiler does allow for a checked exception to be thrown without a warning. I have code for that, but I have yet to use it.

For instance this works:

public static <E extends Exception> E bubble(Throwable ex) throws E { throw (E)ex; // Silences checked exceptions. Casting won't actually work but fools the compiler. }

However, I would still like info in my editor what exceptions the call hierarchy as good as it can analyze it.

Most of the time, if an abstract class has 10 implementions which can fire, the editor would be able to tell you that 5 of them can occur by direct invocation, and then you have 3 other "possible" ones depending on the implementation path that's taken. The code most of the time exist for what you need to get done.










 bye Jochen



Reply via email to