When Java was designed they went for checked exceptions. Later when the C# language was designed they went for unchecked exceptions. I'd like to understand better why one would go with either one. Also, does GObject give a bias in any direction? Should I be using "return codes" instead of "exceptions" like most of C programs tend to do? (after all Vala exceptions just wraps GError's and they are pretty different from Java or C# exceptions) I'm curious, why does Vala have checked exceptions? What was the rationale behind that design decision? I'm also curious about what API design guidelines are useful when designing API's in languages with checked exceptions. Below I've describe a concrete question I was thinking about earlier today. What is the best way to define a .peek() method on a stack class in Vala? I've tried to outline four different ways to do it but the most readable way is not possible in Vala because the lack of unchecked exceptions (I really don't want to add throws StackError to the process_stack method because it's valid to call this function with both empty stacks and non-empty stacks and thus the caller should not need to worry). I think alternative #4 is the most readable, but Vala does not support writing code like that (no unchecked exceptions). So for now I think I will go with either #1 or #3. Even though #3 is shorter I think I like #1 the most because it makes it more clear that empty stacks are handled as a special case. In #3 it's not obvious to an outside that trypeek() fails _only_ when the stack is empty, thus while reading this code it's hard for the outsider to know when which branch is taken. This is made easier in #1 because it's clear that the assert(false) branch is not meant to be taken and if it is taken that would be obvious at runtime. Most importantly, can anyone think of an API design that would yield even more readable and simple code? Especially, can I get the code to become as simple as alternative #4 despite checked exceptions? public static void process_stack (Stack<string> stack) { // Alternative #1 --- "check, try and assert on failure" if (stack.Count == 0) { ... handle empty stack here ... } else { string element1; if (!stack.trypeek (out element1)) assert (false); stdout.printf ("element1 == %s\n", element1); } // Alternative #2 --- "checked exception" if (stack.Count == 0) { ... handle empty stack here ... } else { string element2; try { stdout.printf ("element2 == %s\n", stack.peek ()); } catch (StackError.CANT_PEEK_AT_EMPTY_STACK e) { assert (false); } } // Alternative #3 --- "dont check, just try and then handle failure" string element4; if (stack.trypeek(out element4) { stdout.printf ("element4 == %s\n", element4); } else { ... handle empty stack here ... } // Alternative #4 --- "unchecked exception" (works in C# but not in Java/Vala) if (stack.Count == 0) { ... handle empty stack here ... } else { stdout.printf ("element3 == %s\n", stack.peek ()); } } I'd be very interested to hear some opinions on this. Martin
Attachment:
main.vala
Description: Text Data