www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Tidy template instantiation syntax

reply bearophile <bearophileHUGS lycos.com> writes:
D has removed some cases of bug-prone C syntax, like:

int main() {
    int* ptr1, ptr2;
    return 0;
}


But D needs to avoid introducing new ones. In D2 there is a shortcut to
instantiate templates, but it must not cause ambiguity for the eyes of the
programmer that reads the code (the point is not about syntax well defined for
a compiler, but about syntax that causes no troubles for mammals. The same is
true for the bug-prone C syntax).

So to avoid troubles this code raises a syntax error:

struct Foo(T) {}
Foo!Foo!int y;
void main() {}

test.d(2): multiple ! arguments are not allowed


But this code may look ambiguous for human programmers that read unfamiliar
code:

struct Foo(T) {}
Foo!int* x;
static assert(!is(typeof(x) == Foo!(int*)));
static assert(is(typeof(x) == Foo!(int)*));
void main() {}


So in such cases I'd like D to require parentheses, so this becomes a syntax
error:
Foo!int* x;

And you need to write:
Foo!(int*)

or:
Foo!(int)*

This avoids a possible source of confusion.

The relative enhancement request:
http://d.puremagic.com/issues/show_bug.cgi?id=5286

Bye,
bearophile
Nov 29 2010
next sibling parent reply KennyTM~ <kennytm gmail.com> writes:
On Nov 30, 10 05:20, bearophile wrote:
 D has removed some cases of bug-prone C syntax, like:

 int main() {
      int* ptr1, ptr2;
      return 0;
 }


 But D needs to avoid introducing new ones. In D2 there is a shortcut to
instantiate templates, but it must not cause ambiguity for the eyes of the
programmer that reads the code (the point is not about syntax well defined for
a compiler, but about syntax that causes no troubles for mammals. The same is
true for the bug-prone C syntax).

 So to avoid troubles this code raises a syntax error:

 struct Foo(T) {}
 Foo!Foo!int y;
 void main() {}

 test.d(2): multiple ! arguments are not allowed


 But this code may look ambiguous for human programmers that read unfamiliar
code:

 struct Foo(T) {}
 Foo!int* x;
 static assert(!is(typeof(x) == Foo!(int*)));
 static assert(is(typeof(x) == Foo!(int)*));
 void main() {}


 So in such cases I'd like D to require parentheses, so this becomes a syntax
error:
 Foo!int* x;

 And you need to write:
 Foo!(int*)

 or:
 Foo!(int)*

 This avoids a possible source of confusion.

 The relative enhancement request:
 http://d.puremagic.com/issues/show_bug.cgi?id=5286

 Bye,
 bearophile

-1. The programmer should be able to look up the operator precedence when they encounter code like this. This proposal is like requiring *p+1 to become a syntax error because it could be one of (*p)+1 *(p+1) I don't believe this is a common and hard-to-catch source of bugs, so the compiler doesn't need to be a style-checker here.
Nov 29 2010
parent so <so so.do> writes:
 I do not agree with this position. I actually find *p+1 undecidable.  
 Would like the compiler enforcing proper parenthesizing in all such  
 ambiguous cases.

 By the way, there has been a study about operator precedence in C-like  
 languages. It shows very common errors by _experienced_ programmers even  
 in plain expressions (no incolving special cases like pointer  
 ref/deref). This study also shows the proportion of lines of codes  
 involving more that one operator is tiny. An implicit conclusion, for  
 me, is to remove operator precedence. I do not ask for this, indeed, in  
 D, just comment.

By saying that you find "*p + 1" is undecidable, you already said "remove operator precedence". It is quite the opposite and quite clear by the definition. There are corner cases on operator precedence, this one is not one of them. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 01 2010
prev sibling next sibling parent reply critic <very critical.net> writes:
bearophile Wrote:

 D has removed some cases of bug-prone C syntax, like:
 
 int main() {
     int* ptr1, ptr2;
     return 0;
 }
 
 
 But D needs to avoid introducing new ones. In D2 there is a shortcut to
instantiate templates, but it must not cause ambiguity for the eyes of the
programmer that reads the code (the point is not about syntax well defined for
a compiler, but about syntax that causes no troubles for mammals. The same is
true for the bug-prone C syntax).
 
 So to avoid troubles this code raises a syntax error:
 
 struct Foo(T) {}
 Foo!Foo!int y;
 void main() {}
 
 test.d(2): multiple ! arguments are not allowed
 
 
 But this code may look ambiguous for human programmers that read unfamiliar
code:
 
 struct Foo(T) {}
 Foo!int* x;
 static assert(!is(typeof(x) == Foo!(int*)));
 static assert(is(typeof(x) == Foo!(int)*));
 void main() {}
 
 
 So in such cases I'd like D to require parentheses, so this becomes a syntax
error:
 Foo!int* x;
 
 And you need to write:
 Foo!(int*)
 
 or:
 Foo!(int)*
 
 This avoids a possible source of confusion.
 
 The relative enhancement request:
 http://d.puremagic.com/issues/show_bug.cgi?id=5286
 
 Bye,
 bearophile

It has been many times said that the template T!X syntax optimization is a very lousy hack with problems. In their arrogance, the authors completely ignore all criticism.
Nov 29 2010
parent Max Samukha <spambox d-coding.com> writes:
On 11/30/2010 01:54 AM, critic wrote:
 It has been many times said that the template T!X syntax optimization is a
very lousy hack with problems. In their arrogance, the authors completely
ignore all criticism.

Every optimization comes with problems. What problems does the T!X optimization have, apart from the minor one being discussed?
Nov 30 2010
prev sibling next sibling parent spir <denis.spir gmail.com> writes:
On Tue, 30 Nov 2010 06:03:47 +0800
KennyTM~ <kennytm gmail.com> wrote:

 -1. The programmer should be able to look up the operator precedence=20
 when they encounter code like this. This proposal is like requiring
=20
     *p+1
=20
 to become a syntax error because it could be one of
=20
     (*p)+1
     *(p+1)
=20
 I don't believe this is a common and hard-to-catch source of bugs, so=20
 the compiler doesn't need to be a style-checker here.

I do not agree with this position. I actually find *p+1 undecidable. Would = like the compiler enforcing proper parenthesizing in all such ambiguous cas= es. By the way, there has been a study about operator precedence in C-like lang= uages. It shows very common errors by _experienced_ programmers even in pla= in expressions (no incolving special cases like pointer ref/deref). This st= udy also shows the proportion of lines of codes involving more that one ope= rator is tiny. An implicit conclusion, for me, is to remove operator preced= ence. I do not ask for this, indeed, in D, just comment. Denis -- -- -- -- -- -- -- vit esse estrany =E2=98=A3 spir.wikidot.com
Nov 30 2010
prev sibling parent reply so <so so.do> writes:
 So in such cases I'd like D to require parentheses, so this becomes a  
 syntax error:
 Foo!int* x;

 And you need to write:
 Foo!(int*)

 or:
 Foo!(int)*

 This avoids a possible source of confusion.

 The relative enhancement request:
 http://d.puremagic.com/issues/show_bug.cgi?id=5286

 Bye,
 bearophile

Like many else, i also have encountered the C case in the report. It was always my own fault forgetting operator precedence and still using it without parentheses. Would that make the well defined operator precedence a bad thing? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Dec 01 2010
parent bearophile <bearophileHUGS lycos.com> writes:
so:

 Like many else, i also have encountered the C case in the report.
 It was always my own fault forgetting operator precedence and still using  
 it without parentheses.
 Would that make the well defined operator precedence a bad thing?

Exactly. Compilers and languages may be improved, while the fallible human nature can't. So it's the duty of the language+compiler to avoid being bug-prone for humans. Bye, bearophile
Dec 01 2010