This also works well with a C++ `defer` helper. #define CONCAT_LITERAL(x, y) x ## y #define CONCAT(x, y) CONCAT_LITERAL(x, y) template struct DeferWrapper { F f; DeferWrapper(F f) : f(f) {} ~DeferWrapper() { f(); } }; template DeferWrapper deferWrapper(F f) { return DeferWrapper (f); } #define defer(code) auto CONCAT(_defer_, __COUNTER__) = deferWrapper([&]() code) Example of usage: { Foo *foo; if (initializeFoo()) {…
Avoid Else, Return Early (2013)
321–330 of 601 posts
Re: Avoid Else, Return Early (2013)
#322Programmers with lots of hours of maintaining code eventually evolve to return early, sorting exit conditions at top and meat of the methods at the bottom. Same way you evolve out of one liners. Same way comments are extra weight that should only be in public or algorithm/need to know areas. Same way braces go on the end of the method/class name to reduce LOC. Same way you move on from heavy OO to dicts/lists. Same w…
> Programmers with lots of hours of maintaining code eventually evolve to return early, [..] I agree with all your other points and I‘d even agree if you wrote return early makes code more readable but not that it‘s something experienced programmers do. Programming is still - to some degree - resource management. Inexperienced devs often miss that fact, because they are focused on memory management and believe they c…
Re: Avoid Else, Return Early (2013)
#323Earlier quoted context omitted.
No, I do a git blame, and see all the relevant commit messages. If there's not 1 line of code from that commit remaining why is it relevant? If something looks weird still - I go back to the commit that created this part of code and git blame that. I don't remember a case where I had to do 2 steps like that. BTW we have a rule of putting JIRA ticket numbers in commits, that makes it even easier to find out. You can s…
>No, I do a git blame, and see all the relevant commit messages. sounds great until there's a refactor (including moving code around), then all the "comments" get buried.
So something entirely outside the codebase, which may or may not be available to the person who needs the information, and which may or may not need to be extensively searched through years of history to find the relevant commit message, which may or may not be sufficient to explain the code... is better than having a comment in the code.
Re: Avoid Else, Return Early (2013)
#324Earlier quoted context omitted.
When you read through a part of your system that you've either never seen before or have forgotten how it works, do you also read all commit messages for all of that code? I'm asking because that's the only way I can imagine one can learn about the edge cases and surprising consequences in non-trivial systems if you have a rule about not using comments to explain them.
No, I do a git blame, and see all the relevant commit messages. If there's not 1 line of code from that commit remaining why is it relevant? If something looks weird still - I go back to the commit that created this part of code and git blame that. I don't remember a case where I had to do 2 steps like that. BTW we have a rule of putting JIRA ticket numbers in commits, that makes it even easier to find out. You can s…
Re: Avoid Else, Return Early (2013)
#325Re: Avoid Else, Return Early (2013)
#326Programmers with lots of hours of maintaining code eventually evolve to return early, sorting exit conditions at top and meat of the methods at the bottom. Same way you evolve out of one liners. Same way comments are extra weight that should only be in public or algorithm/need to know areas. Same way braces go on the end of the method/class name to reduce LOC. Same way you move on from heavy OO to dicts/lists. Same w…
> Same way braces go on the end of the method/class name to reduce LOC. Screw that. I've been writing code for 15 years, and Allman style braces make it so much easier to mentally parse code into blocks that they're worth every single LOC. I can't speak for anyone else but I'm not working on an 80x24 terminal anymore.
Re: Avoid Else, Return Early (2013)
#327Earlier quoted context omitted.
This is a reasonable suggestion since the code isn't too bad. std::unique_ptr > p(new Foo, [](Foo* p) { if (p) destroyFoo(p); }); // initialize Foo and set to NULL if failed It increases complexity a bit because you no longer have a simple pointer, and you can't allocate on the stack anymore (my example should have declared `Foo foo;` with `destroyFoo(&foo)`, sorry for typo.)
If you didn't want a pointer you could have just used something like: template struct FooWrapper { TFoo foo; const TDestr destroyFoo; template FooWrapper(Tinit initializeFoo, TDestr destroyFoo) : destroyFoo(destroyFoo) { foo = initializeFoo(); if (!foo) throw FooException(...); } ~FooWrapper() { destroyFoo(&foo); } } Although really that should have been part of the "Foo" class itself, but if you need to deal with ex…
An issue with your wrapper is that it is not generic enough and thus must be written for each Foo-like object. That could likely be fixed with more template arguments, but of course there are multiple ways to initialize C objects like
- `fooInitialize(Foo foo); // expects that foo is pre-allocated`
- `fooInitialize(Foo foo); // allocates and sets the Foo pointer. Annoying, but some libraries do this.`
- `Foo fooInitialize(...); // taking certain arguments`
A single `defer` wrapper allows you implement custom destruction behavior for each instance, which is useful if you want to set flags or log errors in the destruction process.
Re: Avoid Else, Return Early (2013)
#328Earlier quoted context omitted.
I've also been coding 30 years. I have to use same line at work, and I use next line in my (very large) side projects. Honestly, I don't know what the difference is.
> (very large) side projects How big once you remove all the extra newlines?
Thank god OC didn't mention "Just like you move from tabs to spaces."
Re: Avoid Else, Return Early (2013)
#329Premature return considered harmful.
Re: Avoid Else, Return Early (2013)
#330Earlier quoted context omitted.
> Programmers with lots of hours of maintaining code eventually evolve to return early, [..] I agree with all your other points and I‘d even agree if you wrote return early makes code more readable but not that it‘s something experienced programmers do. Programming is still - to some degree - resource management. Inexperienced devs often miss that fact, because they are focused on memory management and believe they c…
Oh common. This might be true for a very specific type of codebase, but it isn't true for programming in general. If I'm coding a library of standard statistical functions I'm exiting early. If I'm coding a Rails webapp I'm exiting early. If I'm coding a shell script, even one used on tens of thousands of servers, I'm exiting early. The resource almost all programmers are managing is the resource of human time. Human…
Also, some of your examples (like altering or reviewing code) can become easier and faster if resource management is a first-class citizen in your code base or language (i.e. is either more explicit in the code, and you know to look for it and manage it, or it is somehow taken care of automatically by your language, so you would have a hard time forgetting it, even if it is handled implicitly).