last day (15 days later) » 

23:55
9
A: Quick Sort Implementation C++11

coderoddeAdvice 1 You can save some indentation space: if (size > 1) { ... // Lots of code. } to if (size < 2) { return; } ... // Lots of code here. Advice 2 You can do the partitioning in-place; there is no need for asking for more memory. The pseudocode in Wikipedia is rather detailed, u...

Advice 1: I think it looks more structed and readable without return. I understand that there are some too long lines but let it be my code-style. Advice 2: Will improove, thanks
Many prefer no early return. It's a goto end;.
@PaulDraper Fair enough. But some people prefer to abuse the code vertically rather than horizontally.
@PaulDraper Which is the true attraction behind it: This case is handled, now let's work on the rest. Simplified mental picture is far more important than some space.
@Paul These people are misguided. And no, it’s nothing like a goto end.
23:55
@KonradRudolph: Sorry, but whether it's Python or C# or C++, almost every time I try to put an early return, I end up finding myself getting massively confused when debugging that procedure a few weeks later, because I've added something to the procedure that is not always getting hit when I expect it, because I had an early return. So I've learned the hard way that it's good advice. Maybe you're smart enough to not hit this pitfall, in which case more power to you, but not everyone is in your boat, and it's not because they're misguided.
@Mehrdad What you’ve described (code isn’t always getting hit) isn’t a problem with early exits but a problem with conditional statements in general. If that is a source of problems for you then … there’s something fundamentally wrong with your code. Early exits are really the least of your worry here (and the fact that you’re apparently conflating these issues is itself concerning).
@KonradRudolph: ...what? I'm literally describing to you a problem that only comes up when I have early exits, and you tell me it's a problem with conditional statements? I don't have the worry when I don't have early exits. I obviously still have conditional statements. Trivial example is like when you add a tentative logging statement at the end of the procedure before returning, to indicate that the procedure finished, except that you never see it because you had an earlier return statement. You put a breakpoint and indeed it never gets it, and you get confused. etc.
@KonradRudolph: The crux of the issue is that indentation of a piece of code informs you that the control flow through it is conditional, so you can always see that when you're looking at the part of the procedure you're interested in (looking at the indentation & the condition takes maybe ~constant or ~log time per line). But if you have an early return instead, you lose that information, and now you have to remember to scan through all the prior code (~linear time?) to figure out under what conditions the current statement might get hit (and it's harder to add new code to the end).
@Mehrdad I’m telling you that you’re wrong, yes: the exact same problem you’re describing exists due to conditionals generally, not due to early exits specifically; you’re misattributing the source of the problem. This should be hard to deny. And while it’s true that this is an actual problem (and hence it’s often a good idea to rewrite code to be conditional-free), conditionals are simply a fundamental facet of logic flow. Avoiding them entirely isn’t practical.
@KonradRudolph: I don't encounter this problem when I have conditionals but no early returns. Do you not understand this?
Incidentally, regarding the logging statement at the end of the function: inform yourself about RAII. It’s precisely there to solve this particular problem, and is the reason why the early-exit concern that’s true for C doesn’t hold for the other languages you cited.
@Mehrdad Do you not understand “you are misdiagnosing the problem”? Are you familiar with confirmation bias? Your reasoning is an example of that.
23:55
@KonradRudolph: Logging in RAII wouldn't work because (a) I/O can throw, and you shouldn't have throwing logic in a destructor, and (b) I was talking about tentative logging, i.e. when you're debugging something (I'm not gonna write a whole class with a destructor just to log something to debug something else), and (c) not all variables are necessarily available when you need them if you use RAII, since you have to put the object early.
@KonradRudolph: You can tell me the source of the problem is my astrological symbol and it really couldn't matter less what you call it. What matters is what actually happens, and what happens is that this problem doesn't come up when you have conditionals but no early return statements. You can attribute it to Donald Trump if you want.
@KonradRudolph: And by variables not being available I guess I meant objects, sorry.
Then catch the IO errors. Look, this is an extremely well-researched problem. I like your instinct of questioning established facts, it’s intellectually healthy. But you need to do your research as well. You’re reinventing a problem that is well and truly solved. Fine, but it’s dangerous to derive general guidelines from that because you fail to consider the trade-offs of ignoring the established guideline: Avoiding early exit leads to higher complexity code. Doing it for the wrong reasons is therefore simply a bad idea. Don’t do it.
@KonradRudolph: Who says I've failed to consider the trade-offs? You think I haven't tried this both ways and I'm just making it up out of the blue for you?
@KonradRudolph: I have to say it's weird having this conversation with you because you're actually one of the few people on SO/SE that I really look up to. (As in, if someone asked me to name the 1 person I look up to most on SE, there's like a 33-50% chance I'd think of you first.) There's a lot I admire in you. But your C++ expertise wasn't anything that ever stuck out to me. I know you know it well enough, and I'm not saying your way is wrong, but there's more than one way to skin a cat. For some of us who aren't you, the method that minimizes complexity also makes us cut ourselves.
@Mehrdad: Why would you need to create a new class to use RAII for executing some code on scope-exit? Don't you have one handy for calling an arbitrary lambda on destruction?
@Deduplicator: I was wondering when someone was going to ask that. No I don't, for lots of reasons. (a) I literally never need such a thing (this would be the only case where I would need to). (b) It's dangerous practice because, again, it's not exception-safe—arbitrary lambdas can easily throw, and obviously I don't necessarily want that exception to be suppressed; I'd want it to propagate up where any exception handlers in the call chain can handle it appropriately. (cont'd...)
@Deduplicator: (...cont'd) (c) It's very confusing to put the business logic of your code in a different place than it runs. It's not like releasing a resource. Releasing a resource is not the point of acquiring it, it's just merely clean-up, and it makes sense to structurally push that out of the code implicitly. But you want the significant code to be where it runs, not triggered by a }. Nonlinear control-flow like that is very hard to read and debug. (d) Again, if your returns are like return make_foo(...) you won't even have those available for the lambda earlier.
@Deduplicator: I would be very curious what your counterarguments are to all of these.

last day (15 days later) »