www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - template parameter list syntax

reply Carl Sturtivant <sturtivant gmail.com> writes:
Why is it that when template arguments are supplied at the point 
of use, the nice distinguishing syntax of x!(a,b,c) is 
obligatory, yet when template parameters are supplied at the 
point of definition the syntax is not distinguished in the same 
way with a bang !
Jan 19
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 19 January 2019 at 16:36:34 UTC, Carl Sturtivant 
wrote:
 Why is it that when template arguments are supplied at the 
 point of use, the nice distinguishing syntax of x!(a,b,c) is 
 obligatory, yet when template parameters are supplied at the 
 point of definition the syntax is not distinguished in the same 
 way with a bang !
At the point of use, ! is needed to ensure there's no ambiguity between instantiating a template and calling a function. At the point of definition, there's no ambiguity, so the ! is not needed.
Jan 19
parent reply Carl Sturtivant <sturtivant gmail.com> writes:
On Saturday, 19 January 2019 at 16:40:42 UTC, Paul Backus wrote:
 On Saturday, 19 January 2019 at 16:36:34 UTC, Carl Sturtivant 
 wrote:
 Why is it that when template arguments are supplied at the 
 point of use, the nice distinguishing syntax of x!(a,b,c) is 
 obligatory, yet when template parameters are supplied at the 
 point of definition the syntax is not distinguished in the 
 same way with a bang !
At the point of use, ! is needed to ensure there's no ambiguity between instantiating a template and calling a function. At the point of definition, there's no ambiguity, so the ! is not needed.
Lots of things aren't logically needed. Syntax even: we could all program in an analog of FORTH using only trivial lexical structure. However hopefully some programming languages are designed for natural intelligibility of some sort via the design of syntax. In many languages the way parameters for functions are syntactically specified in a function definition mirrors the way arguments are supplied when the function is called, so that the syntax of the definition suggests the syntax of its use. D doesn't do this with templates. Why?
Jan 19
parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 19 January 2019 at 16:59:03 UTC, Carl Sturtivant 
wrote:
 [...]

 In many languages the way parameters for functions are 
 syntactically specified in a function definition mirrors the 
 way arguments are supplied when the function is called, so that 
 the syntax of the definition suggests the syntax of its use.

 D doesn't do this with templates. Why?
Walter Bright explains some of the reasoning behind D's implementation of templates, including the syntax, in his article "Templates Revisited": https://dlang.org/articles/templates-revisited.html
Jan 19
parent reply Carl Sturtivant <sturtivant gmail.com> writes:
On Saturday, 19 January 2019 at 17:59:48 UTC, Paul Backus wrote:
 On Saturday, 19 January 2019 at 16:59:03 UTC, Carl Sturtivant 
 wrote:
 [...]

 In many languages the way parameters for functions are 
 syntactically specified in a function definition mirrors the 
 way arguments are supplied when the function is called, so 
 that the syntax of the definition suggests the syntax of its 
 use.

 D doesn't do this with templates. Why?
Walter Bright explains some of the reasoning behind D's implementation of templates, including the syntax, in his article "Templates Revisited": https://dlang.org/articles/templates-revisited.html
I don't see anything in this document that answers my design question. Do you?
Jan 19
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Jan 19, 2019 at 08:06:36PM +0000, Carl Sturtivant via Digitalmars-d
wrote:
 On Saturday, 19 January 2019 at 17:59:48 UTC, Paul Backus wrote:
 On Saturday, 19 January 2019 at 16:59:03 UTC, Carl Sturtivant wrote:
 [...]
 In many languages the way parameters for functions are
 syntactically specified in a function definition mirrors the way
 arguments are supplied when the function is called, so that the
 syntax of the definition suggests the syntax of its use.
 
 D doesn't do this with templates. Why?
[...] The template function declaration syntax is actually a shorthand for the so-called eponymous template. When you write: auto myFunc(Args...)(Args args) { } it's actually a shorthand for: template myFunc(Args...) { auto myFunc(Args args) { } } For the shorthand to introduce ! would be incongruous because the template declaration syntax doesn't use !. T -- Fact is stranger than fiction.
Jan 19
parent reply Carl Sturtivant <sturtivant gmail.com> writes:
On Saturday, 19 January 2019 at 20:52:06 UTC, H. S. Teoh wrote:
 The template function declaration syntax is actually a 
 shorthand for the so-called eponymous template.  When you write:

 	auto myFunc(Args...)(Args args) { }

 it's actually a shorthand for:

 	template myFunc(Args...) {
 		auto myFunc(Args args) { }
 	}

 For the shorthand to introduce ! would be incongruous because 
 the template declaration syntax doesn't use !.


 T
I'm asking why template declaration syntax doesn't use ! so it's parallel to template use syntax which does use ! . I was not talking about function templates as such.
Jan 19
next sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Sat, Jan 19, 2019 at 10:52:25PM +0000, Carl Sturtivant via Digitalmars-d
wrote:
[...]
 I'm asking why template declaration syntax doesn't use ! so it's
 parallel to template use syntax which does use ! .
 
 I was not talking about function templates as such.
Ask Walter or Andrei. T -- It is widely believed that reinventing the wheel is a waste of time; but I disagree: without wheel reinventers, we would be still be stuck with wooden horse-cart wheels.
Jan 19
prev sibling parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Saturday, 19 January 2019 at 22:52:25 UTC, Carl Sturtivant 
wrote:
 On Saturday, 19 January 2019 at 20:52:06 UTC, H. S. Teoh wrote:
 The template function declaration syntax is actually a 
 shorthand for the so-called eponymous template.  When you 
 write:

 	auto myFunc(Args...)(Args args) { }

 it's actually a shorthand for:

 	template myFunc(Args...) {
 		auto myFunc(Args args) { }
 	}

 For the shorthand to introduce ! would be incongruous because 
 the template declaration syntax doesn't use !.


 T
I'm asking why template declaration syntax doesn't use ! so it's parallel to template use syntax which does use ! . I was not talking about function templates as such.
Afaik it's a parser problem. Walter wanted to avoid the catastrophic state that exist in C++ of an ambiguous grammar. He insited that the the grammar of the D language be as straightforward as can be. In the template declaration, both parenthesis pairs are required and the parser knows directly that first '(' == template parameter, second '(' rt parameter. At the instanciation site, it was preferred to have parameter inference, i.e. that the template parameter [1] can be omitted if it can be deduced from the runtime parameter. This has the consequence that the starting '(' becomes ambiguous, it can mean template parameter start or runtime parameter start. Using another operator allows to lift the ambiguity. Forcing to have parenthesis would also lift the ambiguity, but it would be at the cost of parameter inference as it would be impossible distinguish between infered parameter or no parameter. ! was chosen because it is light and its only use is in prefix context, in template instantiation it's in a infix position and thus completely unambiguous with the ! operator. [1]: https://tour.dlang.org/tour/en/basics/templates
Jan 20
parent reply Carl Sturtivant <sturtivant gmail.com> writes:
On Sunday, 20 January 2019 at 12:35:58 UTC, Patrick Schluter 
wrote:
 On Saturday, 19 January 2019 at 22:52:25 UTC, Carl Sturtivant

 Afaik it's a parser problem. Walter wanted to avoid the 
 catastrophic state that exist in C++ of an ambiguous grammar. 
 He insited that the the grammar of the D language be as 
 straightforward as can be.
 In the template declaration, both parenthesis pairs are 
 required and the parser knows directly that first '(' == 
 template parameter, second '(' rt parameter.
 At the instanciation site, it was preferred to have parameter 
 inference, i.e. that the template parameter [1] can be omitted 
 if it can be deduced from the runtime parameter. This has the 
 consequence that the starting '(' becomes ambiguous, it can 
 mean template parameter start or runtime parameter start. Using 
 another operator allows to lift the ambiguity. Forcing to have 
 parenthesis would also lift the ambiguity, but it would be at 
 the cost of parameter inference as it would be impossible 
 distinguish between infered parameter or no parameter. ! was 
 chosen because it is light and its only use is in prefix 
 context, in template instantiation it's in a infix position and 
 thus completely unambiguous with the ! operator.
 [1]: https://tour.dlang.org/tour/en/basics/templates
You've given a more detailed version of a response given earlier. https://forum.dlang.org/post/xypridqjaqxosnxaqbjm forum.dlang.org So my reply to that is also pertinent here. https://forum.dlang.org/post/anlnnizkcohoznigynpj forum.dlang.org
Jan 20
parent reply Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Sunday, 20 January 2019 at 16:22:09 UTC, Carl Sturtivant wrote:
 On Sunday, 20 January 2019 at 12:35:58 UTC, Patrick Schluter 
 wrote:
 On Saturday, 19 January 2019 at 22:52:25 UTC, Carl Sturtivant

 Afaik it's a parser problem. Walter wanted to avoid the 
 catastrophic state that exist in C++ of an ambiguous grammar. 
 He insited that the the grammar of the D language be as 
 straightforward as can be.
 In the template declaration, both parenthesis pairs are 
 required and the parser knows directly that first '(' == 
 template parameter, second '(' rt parameter.
 At the instanciation site, it was preferred to have parameter 
 inference, i.e. that the template parameter [1] can be omitted 
 if it can be deduced from the runtime parameter. This has the 
 consequence that the starting '(' becomes ambiguous, it can 
 mean template parameter start or runtime parameter start. 
 Using another operator allows to lift the ambiguity. Forcing 
 to have parenthesis would also lift the ambiguity, but it 
 would be at the cost of parameter inference as it would be 
 impossible distinguish between infered parameter or no 
 parameter. ! was chosen because it is light and its only use 
 is in prefix context, in template instantiation it's in a 
 infix position and thus completely unambiguous with the ! 
 operator.
 [1]: https://tour.dlang.org/tour/en/basics/templates
You've given a more detailed version of a response given earlier. https://forum.dlang.org/post/xypridqjaqxosnxaqbjm forum.dlang.org
The point is that Walter Bright insists on context free grammar. This is a key point that allows for fast parsing. C++ is in the mess it is because it cannot be parsed (without heroic efforts). Every syntax choice has to abide by that rule. Template parameter inference was deemed MORE important than a slight inconsistency in the syntax of definition and use of the template. If that had not been the case, you would have to explicitely give always all type parameter in the template instanciation, every single time. This would make the code much more tedious, would violate DRY principle and would not even work properly as there are types in D that cannot even be written out (Voldemort types). D would be so much less expressive because of that. So, this slight inconsistency is a small price to pay for the benefits it provides.
 So my reply to that is also pertinent here.
 https://forum.dlang.org/post/anlnnizkcohoznigynpj forum.dlang.org
Jan 20
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 20.01.19 17:34, Patrick Schluter wrote:
 On Sunday, 20 January 2019 at 16:22:09 UTC, Carl Sturtivant wrote:
 On Sunday, 20 January 2019 at 12:35:58 UTC, Patrick Schluter wrote:
 On Saturday, 19 January 2019 at 22:52:25 UTC, Carl Sturtivant

 Afaik it's a parser problem. Walter wanted to avoid the catastrophic 
 state that exist in C++ of an ambiguous grammar. He insited that the 
 the grammar of the D language be as straightforward as can be.
 In the template declaration, both parenthesis pairs are required and 
 the parser knows directly that first '(' == template parameter, 
 second '(' rt parameter.
 At the instanciation site, it was preferred to have parameter 
 inference, i.e. that the template parameter [1] can be omitted if it 
 can be deduced from the runtime parameter. This has the consequence 
 that the starting '(' becomes ambiguous, it can mean template 
 parameter start or runtime parameter start. Using another operator 
 allows to lift the ambiguity. Forcing to have parenthesis would also 
 lift the ambiguity, but it would be at the cost of parameter 
 inference as it would be impossible distinguish between infered 
 parameter or no parameter. ! was chosen because it is light and its 
 only use is in prefix context, in template instantiation it's in a 
 infix position and thus completely unambiguous with the ! operator.
 [1]: https://tour.dlang.org/tour/en/basics/templates
You've given a more detailed version of a response given earlier. https://forum.dlang.org/post/xypridqjaqxosnxaqbjm forum.dlang.org
The point is that Walter Bright insists on context free grammar. This is a key point that allows for fast parsing. C++ is in the mess it is because it cannot be parsed (without heroic efforts). Every syntax choice has to abide by that rule. Template parameter inference was deemed MORE important than a slight inconsistency in the syntax of definition and use of the template. If that had not been the case, you would have to explicitely give always all type parameter in the template instanciation, every single time. This would make the code much more tedious, would violate DRY principle and would not even work properly as there are types in D that cannot even be written out (Voldemort types). D would be so much less expressive because of that. So, this slight inconsistency is a small price to pay for the benefits it provides.
It provides zero benefits. The grammar is still as context free as before even if template declarations use consistent syntax, and the following lookahead becomes unnecessary, making parsing of function declarations simpler and more efficient: https://github.com/dlang/dmd/blob/master/src/dmd/parse.d#L4123 It's just an annoying little design mistake. It happens. I'm also not sure if you understood the OP. The suggestion is to have this consistent syntax: void foo!(T)(T arg){ ... } void bar!T(T arg){ ... } instead of this inconsistent syntax: void foo(T)(T arg) { ... } void bar(T)(T arg) { ... } The syntax at the call site is not being criticized.
Jan 20
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Saturday, 19 January 2019 at 20:06:36 UTC, Carl Sturtivant 
wrote:
 On Saturday, 19 January 2019 at 17:59:48 UTC, Paul Backus wrote:
 Walter Bright explains some of the reasoning behind D's 
 implementation of templates, including the syntax, in his 
 article "Templates Revisited":

 https://dlang.org/articles/templates-revisited.html
I don't see anything in this document that answers my design question. Do you?
Short of emailing Walter Bright and asking him directly, it's the closest thing to an answer I or anyone else can give you.
Jan 19
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 19.01.19 17:36, Carl Sturtivant wrote:
 
 Why is it that when template arguments are supplied at the point of use, 
 the nice distinguishing syntax of x!(a,b,c) is obligatory, yet when 
 template parameters are supplied at the point of definition the syntax 
 is not distinguished in the same way with a bang !
 
 
There is no good reason why. It bothers me too.
Jan 20