Hacker News new | past | comments | ask | show | jobs | submit login

Scanning through the list of features, one I dislike is selection statement initializers:

if (init; condition) {}

(Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p030...). It just seems like clutter. I generally prefer when languages discourage side effects in a branch condition.




That's sorta the point... the init isn't the branch condition. It gives terser syntax to a common patter where you want to scope something into the body of an if statement.

  {
    std::unique_ptr<T> x = foo();
    if(x->something()) {
      // use x
    }
  }
  // x out of scope, destructed
becomes

  if(auto x = foo(); x->something()) {
    // use x
  }
  // x out of scope, destructed
It's makes it easier to read the lifetime of x (an important thing you have to manually keep an eye on in C++ in many cases), and to determine what is in scope outside of the if statement. It's analogous to for-loops vs. doing loops "manually" with while. You're just used to for-loops by this point (if you don't like for loops then ok :).)

C# is also getting (has got?) this feature.


To expand on this for non-C++ programmers, scope is important in C++ because it is used for resource management via RAII [1].

In most languages, in most cases, scopes within a function are used to enhance readability rather than to specify program logic, so a feature like this would add more complexity than it removes.

[1] http://en.cppreference.com/w/cpp/language/raii


What makes this really nice is that the variable is also still in scope in the corresponding else block.


If I'm reading the paper right, the init statement could be any expression-statement or simple initialization. So, modifying unrelated, externally scoped variables in the init would be legal. I don't see this improving readability.


It's no different than the init and conditional parts of a for loop. Do people abuse for loops to do unrelated tasks? Not really.

It does improve readability. If you've ever had to have a series of conditionals in their own braces to keep the init variable in its own scope, then you have a use for this. The alternative might be having foo1, foo2, foo3… all in the same scope, and it's too easy to use the wrong one. This keeps things specifically constrained to the scope in which they are used, which improves safety and correctness, and I think also readability once you adapt to it.

Yes, it could be abused, but I don't think that's a reason not to use it for its intended purpose.


People mess up for loops a lot! That's why range-based for and the STL algorithms library are so useful. I agree having multiple fooX variables in scope is bad. In practice, I've found that either many of these return types are identical, so variables could be reused, or the logic flow could be organized in a more straightforward way.


I wouldn't want to reuse a variable for multiple purposes though; that can lead to unintentional use of the wrong value. At least this way you ensure that can't happen.

And agreed that people mess for loops up, and range based loops are better. My point was only related to the syntactic precedent for coupling an initialiser and conditional in a statement.


Generally, variable reuse is bad. But for something like an error flag that immediately causes function exit and is never referenced again, I wouldn't raise an objection in a code review.


Well, "#define if while" is also legal, and doesn't improve readability either. Like most features, when abused, they're a liability.


It's consistent with for (init; condition;) {} and solves a problem like:

if (std::vector<int> v = f(); !v.empty()) { // Use v }

without requiring an extra compound statement to limit the scope and lifetime of v.


I agree that it's consistent, I find it easier to read when the branching condition is front and center. In 99% of cases I've encountered, the scope of the branching condition variable doesn't matter. When it does, an extra set of {} defines a scope clearly.


An extra set of {} seems to be clutter to me.


That plus extra indentation. It also obscures the intent since it's not necessarily unambiguous why those braces are there? Is it just to group logically related code (without putting it in a separate method/function) or is it because you're relying on RAII -- it's only possible to tell by searching for destructors on all the classes you're instantiating.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: