www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Documentation: is it intentional that template constraints are

reply Tobias Pankrath <tobias pankrath.net> writes:
e.g. here: https://dlang.org/library/object/destroy.html

I was confused at first by the trailing

  if (!is(T == struct) && !is(T == interface) && !is(T == class) 
&& !__traits(isStaticArray, T));

after I somehow managed to completely parse that page without 
recognizing all other constraints.
Oct 31 2019
next sibling parent reply Dennis <dkorpel gmail.com> writes:
Template constraints are not allowed before the signature in the 
language, so it can be expected the documentation does not swap 
that order.

On Thursday, 31 October 2019 at 13:34:35 UTC, Tobias Pankrath 
wrote:
 I was confused at first by the trailing

  if (!is(T == struct) && !is(T == interface) && !is(T == class) 
 && !__traits(isStaticArray, T));
Or are you confused by the newline between the ) and the if? I do think the indentation is a bit confusing, but I don't know a better one. I always have difficulty myself when trying to cleanly format long signatures of template functions.
Nov 01 2019
parent Tobias Pankrath <tobias+dlang pankrath.net> writes:
On Friday, 1 November 2019 at 09:17:03 UTC, Dennis wrote:
 Template constraints are not allowed before the signature in 
 the language, so it can be expected the documentation does not 
 swap that order.

 On Thursday, 31 October 2019 at 13:34:35 UTC, Tobias Pankrath 
 wrote:
 I was confused at first by the trailing

  if (!is(T == struct) && !is(T == interface) && !is(T == 
 class) && !__traits(isStaticArray, T));
Or are you confused by the newline between the ) and the if? I do think the indentation is a bit confusing, but I don't know a better one. I always have difficulty myself when trying to cleanly format long signatures of template functions.
Ah yes, now I see it.
Nov 01 2019
prev sibling parent reply berni44 <dlang d-ecke.de> writes:
On Thursday, 31 October 2019 at 13:34:35 UTC, Tobias Pankrath 
wrote:
 I was confused at first by the trailing

  if (!is(T == struct) && !is(T == interface) && !is(T == class) 
 && !__traits(isStaticArray, T));
I understood your question different from what Dennis answered. At least I was confused by similar lines, when I was a beginner and did not know much about template constraints. What I would have needed to know at that time is, that template constraints limit the situations, where the template can be used. Here for example, this destroy template can only be used, when the type T is neither struct, interface nor class (these three have separate instances, probably because they need different treatment) and it's also not a static array, for unknown reasons. What I don't understand is the 4th version with two extra parameters. Here the documentation lacks an explanation, what this is good for.
Nov 01 2019
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/01/2019 04:09 AM, berni44 wrote:

 What I don't understand is the 4th version with two extra parameters.
 Here the documentation lacks an explanation, what this is good for.
I went to the documentation by clicking "View source code" and scrolled a bit and found this: https://github.com/dlang/druntime/blob/v2.088.1/src/object.d#L590 void destroy(bool initialize = true, T : U[n], U, size_t n)(ref T obj) if (!is(T == struct)) { foreach_reverse (ref e; obj[]) destroy!initialize(e); } Apparently, it's the version for static arrays. However, I don't think the template constraint is doing anything there because if T matches a static array (of the form U[n]), then T is not a struct anyway. Ali
Nov 01 2019
parent reply Paul Backus <snarwin gmail.com> writes:
On Friday, 1 November 2019 at 15:29:24 UTC, Ali Çehreli wrote:
 On 11/01/2019 04:09 AM, berni44 wrote:

 What I don't understand is the 4th version with two extra
parameters.
 Here the documentation lacks an explanation, what this is
good for. I went to the documentation by clicking "View source code" and scrolled a bit and found this: https://github.com/dlang/druntime/blob/v2.088.1/src/object.d#L590 void destroy(bool initialize = true, T : U[n], U, size_t n)(ref T obj) if (!is(T == struct)) { foreach_reverse (ref e; obj[]) destroy!initialize(e); } Apparently, it's the version for static arrays. However, I don't think the template constraint is doing anything there because if T matches a static array (of the form U[n]), then T is not a struct anyway. Ali
`T : U[n]` could also be matched by a struct with an `alias this` to a static array member. Example: https://run.dlang.io/is/NgRU94
Nov 01 2019
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 11/01/2019 09:33 AM, Paul Backus wrote:
 On Friday, 1 November 2019 at 15:29:24 UTC, Ali =C3=87ehreli wrote:
 Apparently, it's the version for static arrays. However, I don't thin=
k
 the template constraint is doing anything there because if T matches =
a
 static array (of the form U[n]), then T is not a struct anyway.

 Ali
`T : U[n]` could also be matched by a struct with an `alias this` to a=
 static array member.

 Example: https://run.dlang.io/is/NgRU94
Thanks. Is it special to destroy() to care for that case or should all=20 our algorithms be on the watchout for such structs? I'm sure I would be=20 missing that specialization if I ever needed to write similar=20 specializations for an algorithm. Ali
Nov 01 2019
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, November 1, 2019 11:23:42 AM MDT Ali Çehreli via Digitalmars-d-
learn wrote:
 On 11/01/2019 09:33 AM, Paul Backus wrote:
  > On Friday, 1 November 2019 at 15:29:24 UTC, Ali Çehreli wrote:
  >> Apparently, it's the version for static arrays. However, I don't think
  >> the template constraint is doing anything there because if T matches a
  >> static array (of the form U[n]), then T is not a struct anyway.
  >>
  >> Ali
  >
  > `T : U[n]` could also be matched by a struct with an `alias this` to a
  > static array member.
  >
  > Example: https://run.dlang.io/is/NgRU94

 Thanks. Is it special to destroy() to care for that case or should all
 our algorithms be on the watchout for such structs? I'm sure I would be
 missing that specialization if I ever needed to write similar
 specializations for an algorithm.
Pretty much any time that a template constraint uses an implicit conversion, the code needs to be careful. Typically, the code then needs to force the conversion and then operate on the exact type in order to avoid subtle bugs. Honestly, in general, I'd argue that it's better to just not accept implicit conversions with templates. In this particular case, what it should probably be doing is just use __traits(isStaticArray, ...) in the template constraint, but whoever wrote that overload took a different tact (though depending on how old that trait is and how old that overload of destroy is, the trait may or may not have been an option when that overload of destroy was written). - Jonathan M Davis
Nov 01 2019