Exception handling is hard
-
@masonwheeler said in Exception handling is hard:
no compiler (how do you give a Python program to a non-technical person with no Python pre-installed?)
Update: thanks to @dcon
-
@TimeBandit The Python one.
It all comes down to parser theory. When you have a "container statement" that can potentially hold more than one line, you need a way to let the parser know where it ends. So far, we've found three ways that work.
- ALGOL style. Blocks begin with
begin
and end withend
. If there is nobegin
, then only the next statement goes in the container. C uses this style, except replacing thebegin
andend
tokens with braces. (Lisp uses a bizarre variant of this style, with parens, instead ofbegin
/end
tokens, on the outside of the container statement.) - Modula style. There is no single-line rule; everything is a block. Therefore, there is no need to begin blocks with a
begin
token to disambiguate, and all blocks must end with anend
token. Ruby uses this style. - Python style: Everything is a block. A
:
is used as a variant on thebegin
token to let the parser know that the next thing to expect is a new block, and consistent indentation shows the length of the block. There is noend
token.
What makes style 3 inherently "dumb" compared to style 1?
- ALGOL style. Blocks begin with
-
@Zecc That looks pretty useful, thanks!
-
@masonwheeler said in Exception handling is hard:
What makes style 3 inherently "dumb" compared to style 1?
Clarity.
You need something that declare the beginning and end of a block, begin/end or {/} or whatever.
When you rely on indentation, you'll get screwed at some point.
Even PHP got that right !!!
File Under: I miss Pascal
-
@TimeBandit The beginning and end of the block are pretty clearly declared by the indentation level changing. It's something that you can immediately, obviously see, and people can't mess with it by putting their braces in strange places. (Inb4 )
@TimeBandit said in Exception handling is hard:
When you rely on indentation, you'll get screwed at some point.
How?
-
@Hans_Mueller said in Exception handling is hard:
but hey, this is what Linus Torvalds suggests, too.
Well, that makes a good enough argument for me to stay with braces on their own line.
Also because:
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
is easier to read than
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
-
@masonwheeler said in Exception handling is hard:
The beginning and end of the block are pretty clearly declared by the indentation level changing. It's something that you can immediately, obviously see, and people can't mess with it by putting their braces in strange places. (Inb4 )
Even if they put their braces in strange places, the code still behave like it's supposed to.
@TimeBandit said in Exception handling is hard:
When you rely on indentation, you'll get screwed at some point.
How?
By having part of code executed while it shouldn't, because it's not properly indented.
Also, I can have my IDE indent the code automagically based on braces.
-
@TimeBandit said in Exception handling is hard:
By having part of code executed while it shouldn't, because it's not properly indented.
Nope. By definition, the indentation describes where it should be executed. You might have part of the code executed where you didn't intend, but that's your problem.
Seriously, though, as I said above, it's something that looks weird at first, because it's strange and new, but you get used to it really quickly.
Also, how is "having part of my code executed where it shouldn't because it's not properly indented" any different from "having part of my code executed where it shouldn't because it's not properly braced"? (See Apple's
goto fail
security fiasco for a dramatic real-world example.)
-
I prefer
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
at minimum.
-
@masonwheeler said in Exception handling is hard:
Also, how is "having part of my code executed where it shouldn't because it's not properly indented" any different from "having part of my code executed where it shouldn't because it's not properly braced"?
if ($somenumber > 0) { doThis(); doThat(); } else { doOtherShit(); }
Yeah, it looks ugly, but it will still work as expected.
Also, in any decent IDE, if you put your cursor on a brace, it will highlight the matching one.
(See Apple's goto fail security fiasco for a dramatic real-world example.)
That's why I always use braces, even if the block is only one line. Because Clarity !
Anyway, when I played with Python, I liked a lot of things, but I hated the lack of braces.
-
@PleegWat Personally, I like the
&&
at the beginning of the line too. But that's not our corporate style.
-
@PleegWat said in Exception handling is hard:
I prefer
Not bad… but this is better in my eyes:
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
But I also prefer to not make symbols be pointlessly long.
-
@TimeBandit said in Exception handling is hard:
if ($somenumber > 0) { doThis(); doThat(); } else { doOtherShit(); }
Yeah, it looks ugly, but it will still work as expected.
Yes, in a language with Python style blocks, you can't do that.
-
@dcon I don't much care where the
&&
are, as long as the newlines and extra indent are there.
-
@masonwheeler said in Exception handling is hard:
Also, how is "having part of my code executed where it shouldn't because it's not properly indented" any different from "having part of my code executed where it shouldn't because it's not properly braced"? (See Apple's goto fail security fiasco for a dramatic real-world example.)
Braces are easier not to mess up and not notice. For instance, a missing or extra one is going to cause errors.
-
@boomzilla said in Exception handling is hard:
Braces are easier not to mess up and not notice.
*looks all confuzzled by double negatives* What do you mean by this?
For instance, a missing or extra one is going to cause errors.
Yes, a problem which is literally impossible in Python style. Are you making a point in favor of or against braces here? It's hard to tell.
-
@masonwheeler said in Exception handling is hard:
looks all confuzzled by double negatives What do you mean by this?
Eh...editing got the better of me. "More difficult to mess up and not notice."
@masonwheeler said in Exception handling is hard:
Yes, a problem which is literally impossible in Python style. Are you making a point in favor of or against braces here? It's hard to tell.
But then python style has problems literally impossible with braces. Python style is brain dead.
-
@dcon If your if statements ever get so complex you're definitely doing something wrong. :P
-
@Hans_Mueller said in Exception handling is hard:
@dcon If your if statements ever get so complex you're definitely doing something wrong. :P
Real life is complicated.
-
@masonwheeler said in Exception handling is hard:
@Zecc That looks pretty useful, thanks!
Damn, I was going to bookmark that too.
News py2exe 0.6.9 released (2008/11/15)
Yeah, that's the last release. python 3 is not supported.
(googles) AhHa! It's now at https://pypi.python.org/pypi/py2exe
-
@boomzilla said in Exception handling is hard:
But then python style has problems literally impossible with braces.
...such as?
-
@masonwheeler said in Exception handling is hard:
@boomzilla said in Exception handling is hard:
But then python style has problems literally impossible with braces.
...such as?
Seriously? You can't be serious. Can you?
OK: Like...the indentation gets messed up.
-
@boomzilla And how is that not exactly equivalent to problems involving bracing getting messed up?
-
@masonwheeler said in Exception handling is hard:
@boomzilla And how is that not exactly equivalent to problems involving bracing getting messed up?
Braces survive indentation accidents. Treating whitespace as anything but a delimiter and where you merge consecutive ones is dumber than than a git command.
-
@boomzilla said in Exception handling is hard:
Treating whitespace as anything but a delimiter and where you merge consecutive ones
My brain threw an exception upon trying to parse that...
-
@masonwheeler said in Exception handling is hard:
My brain threw an exception upon trying to parse that...
That's your brain on python.
-
@masonwheeler said in Exception handling is hard:
It's something that you can immediately, obviously see
Unless it's a difference between spaces and tabs...
-
@djls45 said in Exception handling is hard:
@masonwheeler said in Exception handling is hard:
It's something that you can immediately, obviously see
Unless it's a difference between spaces and tabs...
Visual Studio, turn on view-whitespace, solved!
(I have to do this in our c++ - we have mixed usage and like to have trailing whitespace on lines. )
-
@dcon Visual Studio supports Python?
-
@djls45 said in Exception handling is hard:
@dcon Visual Studio supports Python?
-
-
@djls45 said in Exception handling is hard:
having the opening brace on its own line doesn't mark a visually distinctive beginning of a block?
Not so much.
{
and}
are visually similar, and a brace style allowing both to occupy their own lines increases visual ambiguity.
-
@TimeBandit said in Exception handling is hard:
If there is ONE thing I hate in Python, is the fact that they threw away braces and replaced them with indentation.
In theory it's a nice thing. In practice, I find myself reading Python code as if it were this kind of thing
while (this) { while (that) { if (the other) { deal with it } } }
expressed thus:
while (this) { while (that) { if (the other) { deal with it } } }
Nothing technically wrong with it, but it gives off a distinct odor of something gone badly wrong.
-
@masonwheeler said in Exception handling is hard:
What makes style 3 inherently "dumb" compared to style 1?
The unfortunate but real history of disagreements between text editors about the interpretation of tab characters.
-
@dcon said in Exception handling is hard:
@Hans_Mueller said in Exception handling is hard:
but hey, this is what Linus Torvalds suggests, too.
Well, that makes a good enough argument for me to stay with braces on their own line.
Also because:
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
is easier to read than
if (function(x, y, z(y)) && anotherreallylongfunc(findmeinanotherworld(x), findmeinanotherworld(x)) && anotherfunc(withreallycomplexshit) && moreshit() && anotherreallylongfunc2(findmeinanotherworld(x), findmeinanotherworld(x)) { DoMe(); }
This is where I break out Obsessive Compulsive Expression Breaking Style.
if ( function(x, y, z(y)) && anotherreallylongfunc( findmeinanotherworld(x), findmeinanotherworld(x) ) && anotherfunc( withreallycomplexshit ) && moreshit() && anotherreallylongfunc2( findmeinanotherworld(x), findmeinanotherworld(x) ) ) { DoMe(); }
It's a matter of some sadness for me that OCEBS is not supported by any automatic code reformatting tool I've ever used.
-
@antiquarian said in Exception handling is hard:
You ers are all doing it wrong. The only proper style is like this:
noobs, this is the one true way to format an if else.
C FLDA IFEQ FLDB C FLDA ANDGTFLDC C FLDD OREQ FLDE C FLDD ANDGTFLDF C FLDB ADD FLDF C ELSE C FLDC SUB FLDG C ENDIF *...1....+....2....+....3....+....4....+....5....+....6....+....7... CL0N01N02N03Factor1+++OpcdeFactor2+++ResultLenDHHiLoEqComments++++++
*edit - added rpg formatting guide line
-
@darkmatter also, c'mon where's the automatic RPGII syntax highlighting???
-
@Hans_Mueller said in Exception handling is hard:
@flabdablet said in Exception handling is hard:
since all you do is scan directly upward from a closing brace to the keyword (case, do, else, for, if, while) whose block you're in.
This. When I first started out in programming I too did it like this:
if (condition) { doStuff(); } else { doDifferentStuff(); }
because I found it more readable. Also you can spot missing opening brackets really fast this way. When I tried it like this
if (condition) { doStuff(); } else { doDifferentStuff(); }
I found it too confusing. But one day I simply decided to switch to this indendation style and found it much more readable. It also saves vertical space, which I think is a huge plus. And yes, if I want to see what the closing bracket corresponds to, I simply scan upwards until I find something like "if" or "else" or "switch" or whatever. Never really looked for a corresponding opening bracket before, because opening brackets don't tell me what's going on anyway,
if (condition) { doStuff(); } else { doDifferentStuff(); }
might be pushing it a little too hard. Yes, it saves another line, which is a huge plus, but now "scanning upwards" is a bit harder to do, since I have to look for a nother closing bracket and then look to the right.
However, I like doing
if (condition) doStuff(); else doDifferentStuff();
to save even more space. Yes, I know about the possible risks, but hey, this is what Linus Torvalds suggests, too. :P
All but the best of those styles are syntax errors in Go:
-
@flabdablet said in Exception handling is hard:
The unfortunate but real history of disagreements between text editors about the interpretation of tab characters.
How is that relevant? (Hint, there are at least 3 common answers to this question that sound like they make sense, and all of them are wrong because the people who design languages are already aware of them and explicitly took measures to keep them from being a problem.)
-
@Hans_Mueller said in Exception handling is hard:
it saves another line, which is a huge plus
Why is that such a bonus? Are you coding in a terminal with only 5 rows visible?
-
-
Coding style question we all missed!
Am I the only one who doesn't like exceptions being thrown in an else branch?
if (condition) { DoStuff(); } else { throw new ConditionFailedException("error message"); }
should be replaced by
if (!condition) throw new ConditionFailedException("error message"); DoStuff();
in my opinion.
-
@Jaloopa Actually, yes I do!
-
@aliceif said in Exception handling is hard:
Am I the only one who doesn't like exceptions being thrown in an else branch?
I like trying to get all the "don't bother doing this, just crap out" early return stuff done before the meat of the method, yeah.
if (!condition) throw new ConditionFailedException("error message");
Not a fan of the all on one line if statement though. Especially if
condition
is quite long, it's hard to quickly see where the condition ends and the command starts
-
@Jaloopa said in Exception handling is hard:
I like trying to get all the "don't bother doing this, just crap out" early return stuff done before the meat of the method, yeah.
Yes, same for me. I hate code with tons of nested if() just to get to the case that works, rather than early-aborting for all failed conditions:
BAD:
if (condition1) { if (condition2) { // do stuff } // maybe some else to handle the error, throw, return... }
GOOD:
if (!condition1) { // handle the error, throw, return, whatever } if (!condition2) { // same } // do stuff
-
@masonwheeler said in Exception handling is hard:
@boomzilla And how is that not exactly equivalent to problems involving bracing getting messed up?
I think that part of his argument is that since a missing brace is an error, but not a missing tab, you know immediately that you messed up and avoid leaving a potentially subtle bug in your code.
Say you want to do 2 things in a if(). In Python, if you mess up and write:
if (something): stuff() other_stuff()
This will compile, run, and you get a bug.
In braces-languages, if you mess up and write (I've used the same indent but it doesn't actually matter, of course):
if (something) { stuff(); other_stuff();
You get a compiler error right here about a missing }, which should be enough to point you to the error.
(well, more likely you get an error at the end of the function because this is when the compiler really sees that there is a missing brace, or an error at the start of the next one because that's when it sees an invalid instruction, and you then lose some time tracking back in the code to see where the missing brace should really be, but that's a compiler/IDE issue, and at least you avoid leaving the bug in the code)
(unless you're one of those guys that commit code that doesn't even compile, but then you are worthy a front page article, not a discussion here ;-))
-
@remi More to the point, in brace-based languages you can (usually) have a program which takes your code and converts it into a version with consistent indentation. It's considerably more difficult to do this in Python (though it should be possible I guess…)
-
@dkf I'm not sure that's really "more to the point". The scenario that I'm describing (and that I'm guessing was @boomzilla's point) doesn't care about consistent indentation (which is usually something that matters when sharing code between devs, between locations, etc.), it's just about helping a single developer to write correct code. Not that your point isn't valid, but I think it's not directly related.
Now, of course, being forced to write the braces means more work for the dev, and you would put in the indent anyway (for readability), so I understand the Python argument that braces are therefore redundant and you can do without them. It's just that I think that this benefit doesn't compensate for the added problems it creates.
-
@remi Sorry. Been staring at far too much badly-merged Python code over the past few days. My brain is turning into mush…
-
@Hans_Mueller said in Exception handling is hard:
Found this today in a legacy application (where else?)
else { throw new Exception("Error in file " + filename); } } catch (Exception ex) { throw ex; }
If I had the power to do so, I would find the original developer, fire him, re-hire him and then immediately fire him again.
Back to the OP.
I am OK with this. This final catch block is a good place for a breakpoint or a quick
Console.WriteLine
hack.It's even more useful considering they seem to be using exceptions-as-goto pattern.