3 ms·
The problem is that one person might think an exception is acceptable for OpenFile, whereas another thinks it's not. It's this ambiguity that makes for all sort
by cmroanirgo 7y ago
The problem is that one person might think an exception is acceptable for OpenFile, whereas another thinks it's not. It's this ambiguity that makes for all sorts of conflicting ideas and recommendations.
Fun Fact: the Windows API uses HRESULT to return success/failure of a particular call. The COM API uses the same. VB6 was the first platform by Microsoft to implement exceptions throughout the code (that I'm aware of)... and beneath it, it used COM. So that means that VB6 generated an exception whenever a COM status code returned E_FAIL or similar, and didn't if it was classed as SUCCESS (eg S_OK, S_FALSE, etc).
The original .NET implementors clearly used the VB6 model when developing the codebase (it was nearly a one-to-one match from VB6 to VB.NET) and very easy to port over.
That said, when I read the article, "Exceptions are the primary means of reporting errors in Frameworks" vs "Do not use exceptions for the normal flow of control, if possible" I see this never ending problem appear. Most things we do in our programs use Frameworks, which throw exceptions, which may or may not actually be exceptional for the case of the calling function. Nevertheless, it must be handled.
However, back in the C++ Win API and COM world, you could easily use: `HRESULT hr= SomeFunc(); if (FAILED(hr)) return hr;` to bubble up a failure code, or if you handled it in other ways, you can safely ignore the return code and continue on. In the .NET world exceptions must always be handled otherwise they ripple all the way up and end up as a crashed application. Of course, some think this is a good design principle to have it so: Others are not so convinced.
And so, the debate continues.
- acqq 7y agoExactly. I am certainly in the "exceptions should be really exceptional" camp and therefore I didn't "agree" with Python's open function: https://docs.python.org/3/library/functions.html#open https://docs.python.org/3/library/functions.html#open "Open file and return a corresponding file object. If the file cannot be opened, an OSError is raised." in the sense that in a program that is not only a few lines, I would prefer such kinds of library functions not to produce exceptions, thank you very much, so I had to wrap all such. But it is not optimal not being able to directly use language primitives as much as possible. On another side, writing really short programs gets to be faster: if I write only a few lines, having an "implicit" error handling shortens the code. And that's what I think is the main reason for many ills and misunderstanding in many popular languages: the practices that look good for small examples (or in the books) aren't the same as those which work well for large projects. Python's not detecting the typos in the variable names in compile time is also a typical bias towards the short programs. For large projects detecting as much at compile time and having only very exceptional exceptions and unsurprising control flow (visible reading ifs, and with a guarantee that there can't be "landings from anywhere" like in exceptions) is of huge advantage.
- xen0 7y agoPython is far more promiscuous with Exceptions than languages like C#; they're not just used for "truly exceptional" conditions (see things like StopIteration or GeneratorExit). Different languages have different attitudes to this and that's reflected in their APIs. This will naturally affect your choice of language when designing a system, depending on your tolerance for failures, your demands for robustness, or your definition of "exceptional".
- BiteCode_dev 7y agoExceptions when opening a file has been chosen because they have the nice propery of encouraging a race condition free EAFP rather than a hard to get right LBYL. It also fits nicely into the context manager pattern. Besides, remember exceptions are cheap in python. So cheap that for loops are basically syntaxic sugar for a try/catch.
- uep 7y agoFor those that don't know (I didn't): EAFP - Easier to ask for forgiveness than permission LBYL - Look before you leap They are opposite strategies, Python's preferred strategy is to do the first, just try the operation and throw an exception if it doesn't work. The second is to check a pre-condition before attempting an operation. I've always known the second as exhibiting TOCTOU, otherwise known as a time-of-check vs time-of-use race condition.
- LessDmesg 7y agoLBYL can easily be enforced by Maybe types, leaving exceptions for really exceptional things (which a nonexisting file definitely isn't). So we see how not having a real type system hurts and deforms a language in ways unrelated to types.
- Nullabillity 7y agoThat's still EAFP (you didn't check the precondition before trying), just through a different mechanism.
- 7y ago