www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Optional braces

reply Jacob Carlborg <doob me.com> writes:
This might sound like a crazy idea. I don't expect everyone to drop what 
they're doing and start to implement this, it's just an idea.

In Java (C, C++ and others) braces are optional for statements like if, 
while, for and so on, containing only one expression. In D this is true 
as well, but compared with Java, D also allow try, catch and finally 
statements to have optional braces.

What about extending this to allow optional braces everywhere, where the 
braces contain a single expression? I'm thinking this will be most 
useful for functions/methods, templates and delegates. Specially for 
methods acting as properties that just forwards a value.

Examples:

class Foo
{
     private int a_;
     int a () return a_;
     int a (int a) return a_ = a;
}

template Bar (T) alias T FooBar;

auto foo = delegate () return 3;
auto bar = return 3; // don't if this would be possible

-- 
/Jacob Carlborg
Aug 18 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/19/2011 08:50 AM, Jacob Carlborg wrote:
 This might sound like a crazy idea. I don't expect everyone to drop what
 they're doing and start to implement this, it's just an idea.

 In Java (C, C++ and others) braces are optional for statements like if,
 while, for and so on, containing only one expression. In D this is true
 as well, but compared with Java, D also allow try, catch and finally
 statements to have optional braces.

 What about extending this to allow optional braces everywhere, where the
 braces contain a single expression? I'm thinking this will be most
 useful for functions/methods, templates and delegates. Specially for
 methods acting as properties that just forwards a value.

 Examples:

 class Foo
 {
 private int a_;
 int a () return a_;
 int a (int a) return a_ = a;
 }

I think this makes code harder to read for no obvious benefit. I don't think this is any better than class Foo{ private int a_; int a(){return a_;} int a(int a){return a_ = a;} }
 template Bar (T) alias T FooBar;

This one I'd probably use.
 auto foo = delegate () return 3;
 auto bar = return 3; // don't if this would be possible


Aug 19 2011
next sibling parent reply Trass3r <un known.com> writes:
Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr <timon.gehr gmx.ch>:
 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than

 class Foo{
      private int a_;
      int a(){return a_;}
      int a(int a){return a_ = a;}
 }

+1 Optional braces should be limited to statements.
Aug 19 2011
parent reply kennytm <kennytm gmail.com> writes:
Trass3r <un known.com> wrote:
 Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr <timon.gehr gmx.ch>:
 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than
 
 class Foo{
      private int a_;
      int a(){return a_;}
      int a(int a){return a_ = a;}
 }

+1 Optional braces should be limited to statements.

I agree. Besides, a minor problem is that 'if' statements may be mistaken as template conditions: void f1(T)(T x) if (isFoo!T) { x ++; } void f2(T)(T x) { if (isFoo!T) { x ++; } }
Aug 19 2011
parent Jacob Carlborg <doob me.com> writes:
On 2011-08-19 16:33, kennytm wrote:
 Trass3r<un known.com>  wrote:
 Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr<timon.gehr gmx.ch>:
 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than

 class Foo{
       private int a_;
       int a(){return a_;}
       int a(int a){return a_ = a;}
 }

+1 Optional braces should be limited to statements.

I agree. Besides, a minor problem is that 'if' statements may be mistaken as template conditions: void f1(T)(T x) if (isFoo!T) { x ++; } void f2(T)(T x) { if (isFoo!T) { x ++; } }

Oh, never thought of that. -- /Jacob Carlborg
Aug 19 2011
prev sibling parent Ulrik Mikaelsson <ulrik.mikaelsson gmail.com> writes:
There is one case where it might make sense. I've brought up a
variation of this before, but basically;

Object getMeSome() try {
  // Really try
} catch (SpecificFailure e) {
  return null;
}

vs.

Object getMeSome() {
  try {
    // Really try
  } catch (SpecificFailure e) {
    return null;
  }
}

Of course, every optional feature needs good judgement for appropriate
usage, for example the ternary statement vs. if/else.

2011/8/19 Trass3r <un known.com>:
 Am 19.08.2011, 14:16 Uhr, schrieb Timon Gehr <timon.gehr gmx.ch>:
 I think this makes code harder to read for no obvious benefit.
 I don't think this is any better than

 class Foo{
 =C2=A0 =C2=A0 private int a_;
 =C2=A0 =C2=A0 int a(){return a_;}
 =C2=A0 =C2=A0 int a(int a){return a_ =3D a;}
 }

+1 Optional braces should be limited to statements.

Aug 19 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/19/11 1:50 AM, Jacob Carlborg wrote:
 This might sound like a crazy idea. I don't expect everyone to drop what
 they're doing and start to implement this, it's just an idea.

 In Java (C, C++ and others) braces are optional for statements like if,
 while, for and so on, containing only one expression. In D this is true
 as well, but compared with Java, D also allow try, catch and finally
 statements to have optional braces.

 What about extending this to allow optional braces everywhere, where the
 braces contain a single expression? I'm thinking this will be most
 useful for functions/methods, templates and delegates. Specially for
 methods acting as properties that just forwards a value.

 Examples:

 class Foo
 {
 private int a_;
 int a () return a_;
 int a (int a) return a_ = a;
 }

 template Bar (T) alias T FooBar;

 auto foo = delegate () return 3;
 auto bar = return 3; // don't if this would be possible

One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei
Aug 19 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/19/2011 05:12 PM, Andrei Alexandrescu wrote:
 On 8/19/11 1:50 AM, Jacob Carlborg wrote:
 This might sound like a crazy idea. I don't expect everyone to drop what
 they're doing and start to implement this, it's just an idea.

 In Java (C, C++ and others) braces are optional for statements like if,
 while, for and so on, containing only one expression. In D this is true
 as well, but compared with Java, D also allow try, catch and finally
 statements to have optional braces.

 What about extending this to allow optional braces everywhere, where the
 braces contain a single expression? I'm thinking this will be most
 useful for functions/methods, templates and delegates. Specially for
 methods acting as properties that just forwards a value.

 Examples:

 class Foo
 {
 private int a_;
 int a () return a_;
 int a (int a) return a_ = a;
 }

 template Bar (T) alias T FooBar;

 auto foo = delegate () return 3;
 auto bar = return 3; // don't if this would be possible

One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei

if(condition){ ...; }();else ...; if(condition) ...; else{ ... }(); :o)
Aug 19 2011
parent Mehrdad <wfunction hotmail.com> writes:
On 8/19/2011 8:29 AM, Timon Gehr wrote:
 On 08/19/2011 05:12 PM, Andrei Alexandrescu wrote:
 On 8/19/11 1:50 AM, Jacob Carlborg wrote:
 This might sound like a crazy idea. I don't expect everyone to drop 
 what
 they're doing and start to implement this, it's just an idea.

 In Java (C, C++ and others) braces are optional for statements like if,
 while, for and so on, containing only one expression. In D this is true
 as well, but compared with Java, D also allow try, catch and finally
 statements to have optional braces.

 What about extending this to allow optional braces everywhere, where 
 the
 braces contain a single expression? I'm thinking this will be most
 useful for functions/methods, templates and delegates. Specially for
 methods acting as properties that just forwards a value.

 Examples:

 class Foo
 {
 private int a_;
 int a () return a_;
 int a (int a) return a_ = a;
 }

 template Bar (T) alias T FooBar;

 auto foo = delegate () return 3;
 auto bar = return 3; // don't if this would be possible

One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei

if(condition){ ...; }();else ...; if(condition) ...; else{ ... }(); :o)

Aug 19 2011
prev sibling next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-19 17:12, Andrei Alexandrescu wrote:
 On 8/19/11 1:50 AM, Jacob Carlborg wrote:
 This might sound like a crazy idea. I don't expect everyone to drop what
 they're doing and start to implement this, it's just an idea.

 In Java (C, C++ and others) braces are optional for statements like if,
 while, for and so on, containing only one expression. In D this is true
 as well, but compared with Java, D also allow try, catch and finally
 statements to have optional braces.

 What about extending this to allow optional braces everywhere, where the
 braces contain a single expression? I'm thinking this will be most
 useful for functions/methods, templates and delegates. Specially for
 methods acting as properties that just forwards a value.

 Examples:

 class Foo
 {
 private int a_;
 int a () return a_;
 int a (int a) return a_ = a;
 }

 template Bar (T) alias T FooBar;

 auto foo = delegate () return 3;
 auto bar = return 3; // don't if this would be possible

One thing I'd subjectively like is to require braces on both branches of if/else if at least one has braces. Andrei

Why is that? -- /Jacob Carlborg
Aug 19 2011
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message 
news:j2luh6$23bb$1 digitalmars.com...
 One thing I'd subjectively like is to require braces on both branches of 
 if/else if at least one has braces.

Yuck! I'd really hate that.
Aug 21 2011
parent reply bearophile <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 Yuck! I'd really hate that.

Recently I have converted this Python code: def foo(sol): global best if is_solution(sol[-1]): if best or len(sol) < len(best): best = list(sol) else: for next in alternatives(sol[-1]): if next not in sol: foo(sol + [next]) To this innocent-looking D code, do you see the problem? void foo(Pair[] sol) { if (isSolution(sol[$-1])) if (!best.length || sol.length < best.length) best = sol.dup; else foreach (next; alternatives(sol[$-1])) if (!canFind(sol, next)) foo(sol ~ [next]); } There is a situation where I'd like D to require braces: http://d.puremagic.com/issues/show_bug.cgi?id=4375 Bye, bearophile
Aug 21 2011
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2011-08-21 20:02, bearophile wrote:
 Nick Sabalausky:

 Yuck! I'd really hate that.

Recently I have converted this Python code: def foo(sol): global best if is_solution(sol[-1]): if best or len(sol)< len(best): best = list(sol) else: for next in alternatives(sol[-1]): if next not in sol: foo(sol + [next]) To this innocent-looking D code, do you see the problem? void foo(Pair[] sol) { if (isSolution(sol[$-1])) if (!best.length || sol.length< best.length) best = sol.dup; else foreach (next; alternatives(sol[$-1])) if (!canFind(sol, next)) foo(sol ~ [next]); } There is a situation where I'd like D to require braces: http://d.puremagic.com/issues/show_bug.cgi?id=4375 Bye, bearophile

Yes, the else is for the second if-statement, not the first one. That's why I always use braces when I have nested if-statements, at least for the outer if-statement. -- /Jacob Carlborg
Aug 21 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"bearophile" <bearophileHUGS lycos.com> wrote in message 
news:j2rh7g$2tfq$1 digitalmars.com...
 To this innocent-looking D code, do you see the problem?

 void foo(Pair[] sol) {
    if (isSolution(sol[$-1]))
        if (!best.length || sol.length < best.length)
            best = sol.dup;
    else
        foreach (next; alternatives(sol[$-1]))
            if (!canFind(sol, next))
                foo(sol ~ [next]);
 }

That's why I always use braces to avoid the construct "if(cond) stmt; if(cond) stmt; else..."
 There is a situation where I'd like D to require braces:
 http://d.puremagic.com/issues/show_bug.cgi?id=4375

That's a fantastic idea. It basically checks exactly what I've been relying on convention for. *Only* potential problem I see with it is if someone wants to do this: if(blah blah blah) if(useFoo) foo(); else bar(); else ... That's fairly sensible code. Although I admit I've never come across a situation where I actually wanted to do that. So personally I wouldn't mind giving up the ability to do that.
Aug 21 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/21/11 4:02 PM, Nick Sabalausky wrote:
 "bearophile"<bearophileHUGS lycos.com>  wrote in message
 news:j2rh7g$2tfq$1 digitalmars.com...
 To this innocent-looking D code, do you see the problem?

 void foo(Pair[] sol) {
     if (isSolution(sol[$-1]))
         if (!best.length || sol.length<  best.length)
             best = sol.dup;
     else
         foreach (next; alternatives(sol[$-1]))
             if (!canFind(sol, next))
                 foo(sol ~ [next]);
 }

That's why I always use braces to avoid the construct "if(cond) stmt; if(cond) stmt; else..."
 There is a situation where I'd like D to require braces:
 http://d.puremagic.com/issues/show_bug.cgi?id=4375

That's a fantastic idea.

Yah, it's pretty neat, and very much in the spirit of D. I'd missed it. Andrei
Aug 21 2011
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Andrei Alexandrescu:

 Yah, it's pretty neat, and very much in the spirit of D. I'd missed it.

Thank you Andrei. This problem is know as "Dangling else problem". When a bug receives a name, you know it's common enough. This is one of the about one dozen of tiny/small breaking changes I'd like for D2. I'd like to speed up a little this very slow "presentation" I am doing of them, because it's taking a very long time (on the other hand this specific enhancement request did receive an answer). Bye, bearophile
Aug 21 2011
prev sibling parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, August 21, 2011 20:36:55 bearophile wrote:
 Andrei Alexandrescu:
 Yah, it's pretty neat, and very much in the spirit of D. I'd missed it.

Thank you Andrei. This problem is know as "Dangling else problem". When a bug receives a name, you know it's common enough. This is one of the about one dozen of tiny/small breaking changes I'd like for D2. I'd like to speed up a little this very slow "presentation" I am doing of them, because it's taking a very long time (on the other hand this specific enhancement request did receive an answer).

Except that it's not a bug. It's an issue that crops up in grammars for programming languages. There is classic solution to the problem which D follows. So, there is no ambiguity, and there is no bug. It's very much by design. Bugs caused by mis-handling if statements related to dangling elses are _very_ rare in C-based languages. I really think that the only reason that you're running into this at all is because you've been translating python code to D without adding braces. - Jonathan M Davis
Aug 21 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Jonathan M Davis:

 Except that it's not a bug. It's an issue that crops up in grammars for 
 programming languages.

Right, I have just seen I was wrong :-)
 There is classic solution to the problem which D 
 follows. So, there is no ambiguity, and there is no bug. It's very much by 
 design.

There is no ambiguity for the compiler, because in C/C++/D the else is associated to the nearest if. But programmers are mammals, they aren't compilers. So they sometimes err, despite there is no formal ambiguity.
  Bugs caused by mis-handling if statements related to dangling elses are 
 _very_ rare in C-based languages. I really think that the only reason that 
 you're running into this at all is because you've been translating python code 
 to D without adding braces.

It's not a very common bug, but in past it has happened to me not just in translating Python code. Ada, Python, Pascal and other languages have specific means to avoid this bug. It's a bug easy to avoid, and style guides often suggest to add braces in this situation anyway. See also for more practical considerations: http://code.google.com/p/copute/issues/detail?id=21 Bye, bearophile
Aug 21 2011
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/21/2011 11:02 PM, Nick Sabalausky wrote:
 "bearophile"<bearophileHUGS lycos.com>  wrote in message
 news:j2rh7g$2tfq$1 digitalmars.com...
 To this innocent-looking D code, do you see the problem?

 void foo(Pair[] sol) {
     if (isSolution(sol[$-1]))
         if (!best.length || sol.length<  best.length)
             best = sol.dup;
     else
         foreach (next; alternatives(sol[$-1]))
             if (!canFind(sol, next))
                 foo(sol ~ [next]);
 }

That's why I always use braces to avoid the construct "if(cond) stmt; if(cond) stmt; else..."
 There is a situation where I'd like D to require braces:
 http://d.puremagic.com/issues/show_bug.cgi?id=4375

That's a fantastic idea. It basically checks exactly what I've been relying on convention for. *Only* potential problem I see with it is if someone wants to do this: if(blah blah blah) if(useFoo) foo(); else bar(); else ... That's fairly sensible code. Although I admit I've never come across a situation where I actually wanted to do that. So personally I wouldn't mind giving up the ability to do that.

Well, it would not have to be disallowed. The rule could be like this: Parse with the normal dangling else rule. If an if statement without an else clause is found, examine the then clause. If the then clause is an if statement with an else clause, error. So if(c1)if(c2) x; else y; would be disallowed, but if(c1)if(c2) x; else y; else z; would be allowed.
Aug 21 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Sunday, August 21, 2011 12:47:22 Nick Sabalausky wrote:
 "Andrei Alexandrescu" <SeeWebsiteForEmail erdani.org> wrote in message
 news:j2luh6$23bb$1 digitalmars.com...
 
 One thing I'd subjectively like is to require braces on both branches of
 if/else if at least one has braces.

Yuck! I'd really hate that.

As would I. I pretty much only use braces with a single-statement if statement if either the condition or the statement doesn't fit on one line. I consider the braces to be wasteful and unnecessary otherwise. But everyone has different ideas about what they prefer in formatting. - Jonathan M Davis
Aug 21 2011
prev sibling next sibling parent Ali =?iso-8859-1?q?=C7ehreli?= <acehreli yahoo.com> writes:
On Sun, 21 Aug 2011 20:32:05 +0200, Jacob Carlborg wrote:

 Yes, the else is for the second if-statement, not the first one. That's
 why I always use braces when I have nested if-statements, at least for
 the outer if-statement.

That rule is too complicated for me. :) My version is "I always use braces." Ali
Aug 22 2011
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
 One thing I'd subjectively like is to require braces on both branches of
if/else
 if at least one has braces.

It's rather simple to just disallow the form: if (a) if (b) statement ^ error: use if(a&&b) or if(a){if(b)statement} and not even pay attention if there's a dangling else or not. I've always viewed things like: if (a) if (b) ... ... with suspicion, anyway, dangling else or not.
Aug 23 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 08/23/2011 10:46 PM, Walter Bright wrote:
 On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
 One thing I'd subjectively like is to require braces on both branches
 of if/else
 if at least one has braces.

It's rather simple to just disallow the form: if (a) if (b) statement ^ error: use if(a&&b) or if(a){if(b)statement} and not even pay attention if there's a dangling else or not. I've always viewed things like: if (a) if (b) ... ... with suspicion, anyway, dangling else or not.

I agree, but imho if (a) if (b) ... else ... else ... would not /have/ to be disallowed, because it is unambiguous for a context-free grammar parser, and therefore for humans. (but I'd not cry if it was)
Aug 23 2011
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/23/11 2:31 PM, Timon Gehr wrote:
 On 08/23/2011 10:46 PM, Walter Bright wrote:
 On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
 One thing I'd subjectively like is to require braces on both branches
 of if/else
 if at least one has braces.

It's rather simple to just disallow the form: if (a) if (b) statement ^ error: use if(a&&b) or if(a){if(b)statement} and not even pay attention if there's a dangling else or not. I've always viewed things like: if (a) if (b) ... ... with suspicion, anyway, dangling else or not.

I agree, but imho if (a) if (b) ... else ... else ... would not /have/ to be disallowed, because it is unambiguous for a context-free grammar parser, and therefore for humans. (but I'd not cry if it was)

Yah, disallowing complete and nested if/else pairs would be an annoyance (I'm not sure how big). Otherwise, Walter's idea sounds good to me. Walter, would you be okay with accepting if-if-else-else (at any depth) as a correct case and otherwise disable nested incomplete ifs? Andrei
Aug 23 2011
parent Walter Bright <newshound2 digitalmars.com> writes:
On 8/23/2011 3:32 PM, Andrei Alexandrescu wrote:
 Yah, disallowing complete and nested if/else pairs would be an annoyance (I'm
 not sure how big). Otherwise, Walter's idea sounds good to me. Walter, would
you
 be okay with accepting if-if-else-else (at any depth) as a correct case and
 otherwise disable nested incomplete ifs?

I don't see much value in that.
Aug 24 2011
prev sibling next sibling parent reply kennytm <kennytm gmail.com> writes:
Walter Bright <newshound2 digitalmars.com> wrote:
 On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
 One thing I'd subjectively like is to require braces on both branches of
if/else
 if at least one has braces.

It's rather simple to just disallow the form: if (a) if (b) statement ^ error: use if(a&&b) or if(a){if(b)statement} and not even pay attention if there's a dangling else or not. I've always viewed things like: if (a) if (b) ... ... with suspicion, anyway, dangling else or not.

Not sure if it's a big enough problem, but what about dangling else of this form? if (a.length > 0) foreach (i, ref e; a) if (i > 0) e += a[i-1]; else // oops throw new Exception("empty array");
Aug 24 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/24/2011 1:09 AM, kennytm wrote:
 Not sure if it's a big enough problem, but what about dangling else of this
 form?

      if (a.length>  0)
          foreach (i, ref e; a)
              if (i>  0)
                   e += a[i-1];
      else      // oops
          throw new Exception("empty array");

That wouldn't be complained about with what I suggested. This isn't the dangling else problem, though, it's just bad indenting.
Aug 24 2011
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 08/24/2011 06:22 PM, Walter Bright wrote:
 On 8/24/2011 1:09 AM, kennytm wrote:
 Not sure if it's a big enough problem, but what about dangling else of
 this
 form?

 if (a.length> 0)
 foreach (i, ref e; a)
 if (i> 0)
 e += a[i-1];
 else // oops
 throw new Exception("empty array");

That wouldn't be complained about with what I suggested. This isn't the dangling else problem, though, it's just bad indenting.

I'd say this is actually the dangling else problem. (When it occurs, it is always just bad indenting) Without the tie-breaker, the code snippet would be ambiguous. That is a case that should be catched.
Aug 24 2011
prev sibling parent reply "Nick Sabalausky" <a a.a> writes:
"Walter Bright" <newshound2 digitalmars.com> wrote in message 
news:j313kp$1fc1$1 digitalmars.com...
 On 8/19/2011 8:12 AM, Andrei Alexandrescu wrote:
 One thing I'd subjectively like is to require braces on both branches of 
 if/else
 if at least one has braces.

It's rather simple to just disallow the form: if (a) if (b) statement ^ error: use if(a&&b) or if(a){if(b)statement} and not even pay attention if there's a dangling else or not. I've always viewed things like: if (a) if (b) ... ... with suspicion, anyway, dangling else or not.

Oh god no, don't ban that. I *like* to do that sort of thing: if(useThisFeature) foreach(x; 0..100) foreach(y; 0..100) if(blah blah long thing) if(simple unrelated condition) if(hell, maybe even another) statement(); Absolutely beats the hell out of: if(useThisFeature) { foreach(x; 0..100) { foreach(y; 0..100) { if(blah blah long thing with the simple unrelated condition requiring ugly line breaks and screwy formattng/alignment in a big pita to read uber-expression. fuck this shit. It looks ok in english, but in code the damn thing reads like a fucking regex) { statement(); } } } }
Aug 25 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/25/2011 6:04 PM, Nick Sabalausky wrote:
 Oh god no, don't ban that. I *like* to do that sort of thing:

Unusual, but legitimate. I think I'll shelve the idea.
Aug 25 2011
next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/25/11 6:10 PM, Walter Bright wrote:
 On 8/25/2011 6:04 PM, Nick Sabalausky wrote:
 Oh god no, don't ban that. I *like* to do that sort of thing:

Unusual, but legitimate. I think I'll shelve the idea.

It would be great to reconsider. The counter-argument is very weak. Andrei
Aug 25 2011
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 8/25/2011 6:30 PM, Andrei Alexandrescu wrote:
 On 8/25/11 6:10 PM, Walter Bright wrote:
 On 8/25/2011 6:04 PM, Nick Sabalausky wrote:
 Oh god no, don't ban that. I *like* to do that sort of thing:

Unusual, but legitimate. I think I'll shelve the idea.

It would be great to reconsider. The counter-argument is very weak.

We've already put a number of special cases in the grammar to ward off "bugs". But I worry that we might wind up tarting up the language with too many a boatload of them, to the point where it becomes a confusing mass. At what point should Meg Ryan stop with the plastic surgery? :-)
Aug 25 2011
next sibling parent kennytm <kennytm gmail.com> writes:
Walter Bright <newshound2 digitalmars.com> wrote:

 We've already put a number of special cases in the grammar to ward off "bugs".
 
 But I worry that we might wind up tarting up the language with too many a
 boatload of them, to the point where it becomes a confusing mass. At what
 point should Meg Ryan stop with the plastic surgery? :-)

The surgery is just that you need to add an error or warning when you see an IfStatementWithElse (and TryStatement too?) used directly in a ScopeStatement, and change ElseStatement's rule to IfStatementWithElse | ScopeStatement.
Aug 25 2011
prev sibling next sibling parent reply bearophile <bearophileHUGS lycos.com> writes:
Walter:

Here you are essentially asking for a more global view of the D design, to see
if we are using too much "plastic surgery". To have such global view we need to
look at many unrelated things. So sorry if this looks like a lot of meat on the
fire, there is no other way.


 We've already put a number of special cases in the grammar to ward off "bugs".

There is one more special case that we plan to disallow, that's not in DMD yet: 5409 Disallow (!x & y) http://d.puremagic.com/issues/show_bug.cgi?id=5409 And there are few more special cases where I'd like to see changes/improvements on (there are other improvements that I'd like to see, but they aren't special cases): 3878 Arguments and attributes with the same name 4407 Catch wrong argument<->attribute assignments in methods 5187 Attribute hiding error or warning 5788 Return [] array 5807 Disallow mixed C/D style array declarations 6005 Type alias - variable name don't clash 6277 Disallow short floating point literals (The enhancement request 6277 was discussed a lot, and generally accepted by people here.)
But I worry that we might wind up tarting up the language with too many a
boatload of them, to the point where it becomes a confusing mass. At what point
should Meg Ryan stop with the plastic surgery? :-)<

This a valid concern. The purpose of the discussions here is right to weight advantages against disadvantages, and to see what one weights more. But to perform this weighting you have to consider all factors at the same time. A well chosen "plastic surgery" in a language is often one that doesn't change the look of real world programs much. This is possible because a good rule is something that often wise programmers already follow when they write good code, or is something that is usually a bug anyway, like (!x & y). Where possible it's good to base similar decisions on data and real usage. So: - How many changes requires Phobos if the "else mismatch" syntax gets disallowed in D? - Is this syntax change able to catch bugs in the already existing Phobos code? (and other good D2 code)? - How much bad does it look D2 code if you introduce this grammar change? Is the result of this plastic surgery actually bad looking? Such data helps answer the final question: are those disadvantages less important than the estimated amount of bugs caused by mismatch else? My suggestion is to implement this small grammar change, compile Phobos with it, and then to take a look how much changes it requires, how much worse looking (if any) Phobos code becomes, and if this change finds any bugs in the code. This will help take the decision. In my experience in my D code there are causes of bugs more important than "else mismatch", like: 3878 Arguments and attributes with the same name 4407 Catch wrong argument<->attribute assignments in methods 3999 Enum equality to an int 5212 Safer typesafe variadics So I care more for those enhancement requests than for "else mismatch". Bye, bearophile
Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
 And there are few more special cases where I'd like to see
changes/improvements on (there are other improvements that I'd like to see, but
they aren't special cases):
 
 3878 Arguments and attributes with the same name
 4407 Catch wrong argument<->attribute assignments in methods
 5187 Attribute hiding error or warning
 5788 Return [] array
 5807 Disallow mixed C/D style array declarations
 6005 Type alias - variable name don't clash
 6277 Disallow short floating point literals

Please remove 6277 from this short list, because it doesn't introduce one more special case, it removes two of them. Bye, bearophile
Aug 26 2011
prev sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/25/11 9:13 PM, Walter Bright wrote:
 On 8/25/2011 6:30 PM, Andrei Alexandrescu wrote:
 On 8/25/11 6:10 PM, Walter Bright wrote:
 On 8/25/2011 6:04 PM, Nick Sabalausky wrote:
 Oh god no, don't ban that. I *like* to do that sort of thing:

Unusual, but legitimate. I think I'll shelve the idea.

It would be great to reconsider. The counter-argument is very weak.

We've already put a number of special cases in the grammar to ward off "bugs". But I worry that we might wind up tarting up the language with too many a boatload of them, to the point where it becomes a confusing mass. At what point should Meg Ryan stop with the plastic surgery? :-)

It's a legitimate concern, and there's no right response to it. My point is that the argument is weak and caving to it would be a mistake. In essence Nick claims he can't be bothered to change: if (long_expression_one) if (long_expression_two) if (long_expression_three) statement with if ((long_expression_one) && (long_expression_two) && (long_expression_three)) statement which adds a grand total of two parens. The claim "blah blah long thing with the simple unrelated condition requiring ugly line breaks and screwy formattng/alignment in a big pita to read uber-expression. fuck this shit. It looks ok in english, but in code the damn thing reads like a fucking regex" does not stand scrutiny, and mixing in the matter of indentation is a red herring as indentation is unaffected by the introduction of the rule. I'll also note that the argument smacks of the misleading vividness fallacy (http://en.wikipedia.org/wiki/Misleading_vividness). We shouldn't shelve an idea because a poor argument against it was eloquently phrased. Finally, we've derived significant benefits from ideas in the same spirit. I don't see signs that we've started overdoing it, or that the returns are diminishing. To me all signs point to a fertile approach to explore. Andrei
Aug 26 2011
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 8/26/11 8:48 AM, Steven Schveighoffer wrote:
 On Fri, 26 Aug 2011 11:03:21 -0400, Andrei Alexandrescu
 <SeeWebsiteForEmail erdani.org> wrote:

 It's a legitimate concern, and there's no right response to it. My
 point is that the argument is weak and caving to it would be a
 mistake. In essence Nick claims he can't be bothered to change:

 if (long_expression_one)
 if (long_expression_two)
 if (long_expression_three)
 statement

 with

 if ((long_expression_one)
 && (long_expression_two)
 && (long_expression_three))
 statement

 which adds a grand total of two parens. The claim "blah blah long
 thing with the simple unrelated condition requiring ugly line breaks
 and screwy formattng/alignment in a big pita to read uber-expression.
 fuck this shit. It looks ok in english, but in code the damn thing
 reads like a fucking regex" does not stand scrutiny, and mixing in the
 matter of indentation is a red herring as indentation is unaffected by
 the introduction of the rule.

 I'll also note that the argument smacks of the misleading vividness
 fallacy (http://en.wikipedia.org/wiki/Misleading_vividness). We
 shouldn't shelve an idea because a poor argument against it was
 eloquently phrased.

 Finally, we've derived significant benefits from ideas in the same
 spirit. I don't see signs that we've started overdoing it, or that the
 returns are diminishing. To me all signs point to a fertile approach
 to explore.

Hm... the only problem I see with simply disallowing if(a) if(b) is this: if(a) while(condition) if(b) statement; else // oops! this goes with if(b) statement; Or would this be disallowed as well? This could not be combined into a single if statement obviously, so the only the option to fix this is adding braces.

I don't think that bug is bound to occur with any significant frequency. Over the years I've seen ample evidence that the mismatched else in conjunction with repeated ifs causes bugs, both in other people's code and (alas) my own. But I have never seen or heard of a case in which an inserted additional control flow statement still caused problems.
 I'd hate to see this disallowed, which seems perfectly legitimate:

 if(a)
 while(condition)
 if(b)
 statement;

Me too. Andrei
Aug 26 2011
prev sibling next sibling parent reply Adam Ruppe <destructionator gmail.com> writes:
 we might as well get rid of the semicolon as well.

You can have my semicolons when you pry them from my cold, dead hands.
Aug 26 2011
parent Jakob Ovrum <jakobovrum+ng gmail.com> writes:
On 2011/08/27 1:52, Andrej Mitrovic wrote:
Of course they're still needed in other places, but to be
 honest I'm tired of "found foo, expected bla" errors due to missing
 semicolons.

You can have both semi-colons and nice error messages if you put some effort into the parser. Clang manages this even for C++. Some sample SDC output: test.d(5:16): error: missing ';' after initialisation. int foo = 2 ^ ; test.d(5:18): error: missing ';' after expression. assert(false) ^ ; test.d(5:27): error: missing ';' after declaration. void function(int) foo ^ ;
Aug 26 2011
prev sibling parent Rainer Schuetze <r.sagitario gmx.de> writes:
On 26.08.2011 17:03, Andrei Alexandrescu wrote:
 On 8/25/11 9:13 PM, Walter Bright wrote:
 But I worry that we might wind up tarting up the language with too many
 a boatload of them, to the point where it becomes a confusing mass. At
 what point should Meg Ryan stop with the plastic surgery? :-)

It's a legitimate concern, and there's no right response to it. My point is that the argument is weak and caving to it would be a mistake. In essence Nick claims he can't be bothered to change: if (long_expression_one) if (long_expression_two) if (long_expression_three) statement with if ((long_expression_one) && (long_expression_two) && (long_expression_three)) statement which adds a grand total of two parens.

I often write code like this: if(auto p = getSome()) if(auto parent = p.getParent()) if(auto uncle = parent.getBrother()) uncle.doSome(); This cannot be translated into a conjunction of conditions without having to specify declarators before. I would not like to lose that possiblity. I'm not so sure about the dangling else issue. I don't want to be pampered all the time, but I have to admit to have run into that issue, too.
Aug 26 2011
prev sibling parent bearophile <bearophileHUGS lycos.com> writes:
Walter:

 Nick Sabalausky wrote:
 Oh god no, don't ban that. I *like* to do that sort of thing:

Unusual, but legitimate. I think I'll shelve the idea.

This is the code by Nick Sabalausky:
 if(useThisFeature)
 foreach(x; 0..100)
 foreach(y; 0..100)
 if(blah blah long thing)
 if(simple unrelated condition)
 if(hell, maybe even another)
     statement();

It contains no "else", so it is not influenced by what I was asking for in my enhancement request. ----------------- By the way, hiding the nesting of the code removing most indents is not a good coding style practice. So it's better to write it this way, with indents: if (useThisFeature) foreach (x; 0 .. 100) foreach (y; 0 .. 100) if (blah blah long thing) if (simple unrelated condition) if (hell, maybe even another) statement(); If you think those are too many indents, then you are right. But this is the nature of that piece of code. Hiding it doesn't help its understandability. And you are often able to rewrite it like this: if (!useThisFeature) return; foreach (x; 0 .. 100) foreach (y; 0 .. 100) if ((blah blah long thing) && (simple unrelated condition) && (hell, maybe even another)) statement(); Bye, bearophile
Aug 25 2011
prev sibling next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 26.08.2011, 11:32 Uhr, schrieb bearophile <bearophileHUGS lycos.com>:

 There is one more special case that we plan to disallow, that's not in  
 DMD yet:

 5409 Disallow (!x & y)
 http://d.puremagic.com/issues/show_bug.cgi?id=5409

Is (!x & y) an issue or is it rather people omitting spaces in their code !x&y ? I can't imagine anyone will assume that !x & y negates the whole expression. At least a kernel developer should know the operator precedence. Are there actually lots of kernel bugs related to the version with spaces? I think the warning you get in many languages/IDEs when you write "if (x = y)" is ok. It tells you to wrap that expression in parenthesis if you really meant to do an assignment. It is a very special case that is not common among all imperative languages and is easily overlooked, especially if you worked with a language that uses = for comparisons. If in the above case we are forced to write ((!x) & y) that's ... LISP. At least I'm not convinced by what is in the bug report.
Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Marco Leise:

 Is (!x & y) an issue or is it rather people omitting spaces in their code  
 !x&y ?

This topic was already discussed in past, in two threads, this one of them: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=135741 The Coccinelle tool has found a large number of !x & y bug patterns in already debugged high-quality C/C++ code. Search for "Correct occurrences of !x&y" in this page: http://coccinelle.lip6.fr/impact_linux.php See also, a good lint catches this bug: http://d.puremagic.com/issues/show_bug.cgi?id=5814 It's a common mistake, it causes significant troubles, it's easy to catch, avoiding it is cheap syntax-wise, and there is a precedent similar case already implemented in D.
 If in the above case we are forced to write ((!x) & y) that's ... LISP.

Nope, it asks for just one pair of parentheses, like: !(x & y) Or: (!x) & y
 least I'm not convinced by what is in the bug report.

You will have to bring on the table stronger evidence that this an useless change, if you want to refuse the enhancement request 5409. Walter and Don have accepted it, I think. I don't know what Andrei thinks of it. Bye, bearophile
Aug 26 2011
prev sibling next sibling parent reply "Marco Leise" <Marco.Leise gmx.de> writes:
Am 26.08.2011, 13:10 Uhr, schrieb bearophile <bearophileHUGS lycos.com>:

 Marco Leise:

 Is (!x & y) an issue or is it rather people omitting spaces in their  
 code
 !x&y ?

This topic was already discussed in past, in two threads, this one of them: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=135741 The Coccinelle tool has found a large number of !x & y bug patterns in already debugged high-quality C/C++ code. Search for "Correct occurrences of !x&y" in this page: http://coccinelle.lip6.fr/impact_linux.php See also, a good lint catches this bug: http://d.puremagic.com/issues/show_bug.cgi?id=5814

And once these lints complain about 1 + 2 * 3 being ambiguous I lose all hope in mankind. But point taken, there is a provably large number of such bugs. In fact they can be narrowed down to 'check if a flag is disabled' as in this example: "if (!(flags & SOME_FLAG))".
 It's a common mistake, it causes significant troubles, it's easy to  
 catch, avoiding it is cheap syntax-wise, and there is a precedent  
 similar case already implemented in D.

Ok, I get it.
 If in the above case we are forced to write ((!x) & y) that's ... LISP.

Nope, it asks for just one pair of parentheses, like: !(x & y) Or: (!x) & y

I guess "(!x) & y" is a rare case anyway. I though of "if ((!x) && y)". Does your enhancement include other operators like '&&' or is it practically just for the 'check if flag is disabled' case?
 At least I'm not convinced by what is in the bug report.

You will have to bring on the table stronger evidence that this an useless change, if you want to refuse the enhancement request 5409. Walter and Don have accepted it, I think. I don't know what Andrei thinks of it. Bye, bearophile

Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Marco Leise:

 Does your enhancement include other operators like '&&' or is it  
 practically just for the 'check if flag is disabled' case?

My enhancement request regards just a narrow case. (But the actual implementation of it may add some other related cases, I don't know). Bye, bearophile
Aug 26 2011
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Fri, 26 Aug 2011 11:03:21 -0400, Andrei Alexandrescu  
<SeeWebsiteForEmail erdani.org> wrote:

 It's a legitimate concern, and there's no right response to it. My point  
 is that the argument is weak and caving to it would be a mistake. In  
 essence Nick claims he can't be bothered to change:

 if (long_expression_one)
 if (long_expression_two)
 if (long_expression_three)
    statement

 with

 if ((long_expression_one)
 && (long_expression_two)
 && (long_expression_three))
    statement

 which adds a grand total of two parens. The claim "blah blah long thing  
 with the simple unrelated condition requiring ugly line breaks and  
 screwy formattng/alignment in a big pita to read uber-expression. fuck  
 this shit. It looks ok in english, but in code the damn thing reads like  
 a fucking regex" does not stand scrutiny, and mixing in the matter of  
 indentation is a red herring as indentation is unaffected by the  
 introduction of the rule.

 I'll also note that the argument smacks of the misleading vividness  
 fallacy (http://en.wikipedia.org/wiki/Misleading_vividness). We  
 shouldn't shelve an idea because a poor argument against it was  
 eloquently phrased.

 Finally, we've derived significant benefits from ideas in the same  
 spirit. I don't see signs that we've started overdoing it, or that the  
 returns are diminishing. To me all signs point to a fertile approach to  
 explore.

Hm... the only problem I see with simply disallowing if(a) if(b) is this: if(a) while(condition) if(b) statement; else // oops! this goes with if(b) statement; Or would this be disallowed as well? This could not be combined into a single if statement obviously, so the only the option to fix this is adding braces. I'd hate to see this disallowed, which seems perfectly legitimate: if(a) while(condition) if(b) statement; -Steve
Aug 26 2011
parent reply kennytm <kennytm gmail.com> writes:
"Steven Schveighoffer" <schveiguy yahoo.com> wrote:

 Hm... the only problem I see with simply disallowing if(a) if(b) is this:
 
 if(a)
   while(condition)
     if(b)
       statement;
 else // oops! this goes with if(b)
   statement;
 
 Or would this be disallowed as well?  This could not be combined into a 
 single if statement obviously, so the only the option to fix this is  adding
braces.
 
 I'd hate to see this disallowed, which seems perfectly legitimate:
 
 if(a)
    while(condition)
       if(b)
         statement;
 
 -Steve

I've created a patch* for dangling else checking. Your first example will be banned and the second is allowed. Check the test cases there for more examples. *: https://github.com/D-Programming-Language/dmd/pull/336
Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
kennytm:

 I've created a patch* for dangling else checking.

I have not yet compiled and tried your code, but from what I see all the design decisions you have taken are good, including the error message (I think it doesn't need to contain "dangling else" because that's a different thing), the cases you accept and you refuse, the use of the -d switch, etc).
 You can disable the check with the -d flag.

If this is true, then I suggest to give a hint about this in the error message too. So I suggest to add to the error message the word "deprecated". Thank you, bearophile ~~ D: Getting better one micro step each week - Continental drift for the win ~~
Aug 26 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
I've used this a few times:

foreach (dir; dirs)
foreach (string file; dirEntries(dir, SpanMode.shallow))
{
    if (file.isFile)
        // do something..
}

And I only use this in short loops like this. It's more compact, I
dislike having to create too much indentation.

I don't see what banning this buys us. If we're going to force some
kind of predefined coding style on everyone then we might as well get
rid of the semicolon as well.
Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 I don't see what banning this buys us.

That's not banned. Bye, bearophile
Aug 26 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/26/11, bearophile <bearophileHUGS lycos.com> wrote:
 Andrej Mitrovic:

 I don't see what banning this buys us.

That's not banned. Bye, bearophile

Ok, I thought this was included.
Aug 26 2011
parent bearophile <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 Ok, I thought this was included.

It wasn't included in my original enhancement request. But now I don't exactly know what situations Andrei wants to disallow. Bye, bearophile
Aug 26 2011
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/26/11, Adam Ruppe <destructionator gmail.com> wrote:
 we might as well get rid of the semicolon as well.

You can have my semicolons when you pry them from my cold, dead hands.

I'd kill them (the semicolons, not your hands :p) in places they're not needed anymore. And we already have that in struct, class, enum definitions. Of course they're still needed in other places, but to be honest I'm tired of "found foo, expected bla" errors due to missing semicolons.
Aug 26 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Cool stuff! DMD is almost there but it reports the line number of
whatever comes next, even if there was only whitespace, e.g.:

void main()
{
    int foo = 2


} <- error line here instead of above
Aug 26 2011