Re: Help needed to learn templates

2022-03-20 Thread Vinod K Chandran via Digitalmars-d-learn
On Saturday, 19 March 2022 at 22:31:19 UTC, Stanislav Blinov 
wrote:


It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.



No, it was my mistake, I missed it.

The other template syntax - `template foo(alias T)` can take as 
`T` any symbol, not just a type.



I understand this.

It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I 
(the programmer) would like to refer to as U?". That's all 
there is to it (well, not quite, but it should suffice for 
starters). You're simply introducing an identifier. So, when 
`T` is an `int[][][]`, naturally, `U` becomes an alias to 
`int[][]` (look at the converse - when `U` is `int[][]`, `U[]` 
is naturally an `int[][][]`).



Okay, got it.


You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
alias U = typeof(T.init[0]);
// ...
}
```


Yes, in this case everything is simple and clear.

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


Okay. Got the point. Thanks. Now, I understand that why Ali 
suggest me to learn **`is()`** expression.





Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 13:38:42 UTC, Vinod K Chandran 
wrote:
On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
wrote:


No.

First of all Thanks for the reply. The answer "No" is a wonder 
to me. Because, from my point of view, `U` is coming from 
nowhere. My understanding is, we can use any parameter of a 
template inside the template. So in this case `U` is not in the 
parameter list. It is suddenly appearing in that `static if`.


It is appearing not in the `static if`, but in the `is` 
expression, which I described further in the rest of my first 
reply. Sorry if that wasn't clear.





The test is not `T t == U[]`. It is `is(T t == U[], U)`.


Okay, I understand.

Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


So the `T` is not the type. It's the parameter. Right ? So a 
template doesn't need a type. Only the parameter, right ? (I 
think I am too dumb to ask this. Please forgive me.)


Oh don't worry, this topic is not at all obvious with the `is` 
expression having its own syntax and semantics. `T` is a type, a 
type you instantiate `rank` with. `template rank(T)` *does* 
expect a type as a parameter. The other template syntax - 
`template foo(alias T)` can take as `T` any symbol, not just a 
type.


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` 
fails the test.


In order to understand this, I need to understand from where 
the `U` comes.


It comes from you, the programmer. Like I said before, `is(T == 
U[], U)` means "is T an array of some type, the type which I (the 
programmer) would like to refer to as U?". That's all there is to 
it (well, not quite, but it should suffice for starters). You're 
simply introducing an identifier. So, when `T` is an `int[][][]`, 
naturally, `U` becomes an alias to `int[][]` (look at the 
converse - when `U` is `int[][]`, `U[]` is naturally an 
`int[][][]`).


You can think of that test as this:

```d
import std.traits : isDynamicArray;

// ...

static if (isDynamicArray!T)
{
alias U = typeof(T.init[0]);
// ...
}
```

...which would roughly be the same thing - you test if `T` is a 
dynamic array of some type, and then make an alias for that 
array's element type. It's just that the `is` expression allows 
you to create such alias in situ.


Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 16:08:33 UTC, Ali Çehreli wrote:


Here is the clickable url:

  http://ddili.org/ders/d.en/is_expr.html

I just read it again and I still like what I wrote there. :) 
(Usually it is the other way around.)


Ali


Thanks. Let me read that chapter.




Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 15:58:25 UTC, Ali Çehreli wrote:


I wrote a chapter about the is expression but it's still 
mysterious to me. :)


  ddili.org/ders/d.en/is_expr.html



Thanks for the reply. I think I choose the wrong book. I knew 
about your book but I thought this one is specially written for 
templates. I will read the template chapters in **`Programming in 
D`**.


It means "if T matches U[] and U is a type". "a type" because 
it is just U in the is expression list.


So as per the eponymous trick, **`enum size_t rank`** will be 
executed directly. Right ? But in that case, **`rank`** template 
doesn't take a parameter. There is only the type parameter which 
is **`T`**. So I am still in confusion about **`U`**.


I believe at least some of the traits have been added since 
that doc document was written. I would write it in a much 
simpler way using template constraints today:


```d
template rank(T) {
  import std.traits : isArray;
  import std.range : ElementType;

  static if (isArray!T) {
enum size_t rank = 1 + rank!(ElementType!T);

  } else {
enum size_t rank = 0;
  }
}
```

This template is very easy to understand and I have no confusions 
about it. Because, it only takes **`T`** as type parameter and 
there is no magical **`U`**.


However, note how the template constraints had to be repeated 
as isArray!T and !isArray!T in that case.



Yeah, I noted.


Not at all! The is expression is the weirdest part of D.


Oh I see.




Re: Help needed to learn templates

2022-03-19 Thread Ali Çehreli via Digitalmars-d-learn

On 3/19/22 08:58, Ali Çehreli wrote:

> I wrote a chapter about the is expression but it's still mysterious to
> me. :)
>
>ddili.org/ders/d.en/is_expr.html

Here is the clickable url:

  http://ddili.org/ders/d.en/is_expr.html

I just read it again and I still like what I wrote there. :) (Usually it 
is the other way around.)


Ali



Re: Help needed to learn templates

2022-03-19 Thread Ali Çehreli via Digitalmars-d-learn

On 3/19/22 06:38, Vinod K Chandran wrote:
> On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov wrote:
>>
>> No.
>>
> First of all Thanks for the reply. The answer "No" is a wonder to me.

I wrote a chapter about the is expression but it's still mysterious to 
me. :)


  ddili.org/ders/d.en/is_expr.html

I may be saying some things wrong there but that's my mental model.

> Because, from my point of view, `U` is coming from nowhere.

Agreed. It is similar to U's coming from nowhere below:

void foo(U)(U[] array) {
}

So, in my mental model, that use of the is expression is the same but 
written in the reverse order from foo above:


static if (is(T t == U[], U))

It means "if T matches U[] and U is a type". "a type" because it is just 
U in the is expression list.


I believe at least some of the traits have been added since that doc 
document was written. I would write it in a much simpler way using 
template constraints today:


template rank(T) {
  import std.traits : isArray;
  import std.range : ElementType;

  static if (isArray!T) {
enum size_t rank = 1 + rank!(ElementType!T);

  } else {
enum size_t rank = 0;
  }
}

Or one can separate the logic in two template definitions:

import std.traits : isArray;

template rank(T)
if (isArray!T)
{
  import std.range : ElementType;
  enum size_t rank = 1 + rank!(ElementType!T);
}

template rank(T)
if (!isArray!T)
{
  enum size_t rank = 0;
}

However, note how the template constraints had to be repeated as 
isArray!T and !isArray!T in that case.


> My
> understanding is, we can use any parameter of a template inside the
> template. So in this case `U` is not in the parameter list. It is
> suddenly appearing in that `static if`.

In my mental model, the is expression uses at least a part of the 
template system.


>> you can simply write
>> `is(T == U[], U)`.
>>
> So the `T` is not the type.

T is the type because it is introduced as simply T in the parameter 
list. If it were 'int T', then it would be an int. So in that sense, it 
is a type-kind template parameter.


> It's the parameter. Right ? So a template
> doesn't need a type. Only the parameter, right ?

The way I read it is: "T is a type that matches U[] where U is a type as 
well."


> (I think I am too dumb
> to ask this. Please forgive me.)

Not at all! The is expression is the weirdest part of D.

Ali



Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn

On Saturday, 19 March 2022 at 08:49:02 UTC, Salih Dincer wrote:




Thanks for the reply. You explained the idea very well and it's 
easy to understand for a novice.




Re: Help needed to learn templates

2022-03-19 Thread Vinod K Chandran via Digitalmars-d-learn
On Saturday, 19 March 2022 at 11:47:53 UTC, Stanislav Blinov 
wrote:


No.

First of all Thanks for the reply. The answer "No" is a wonder to 
me. Because, from my point of view, `U` is coming from nowhere. 
My understanding is, we can use any parameter of a template 
inside the template. So in this case `U` is not in the parameter 
list. It is suddenly appearing in that `static if`.




The test is not `T t == U[]`. It is `is(T t == U[], U)`.


Okay, I understand.

Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


So the `T` is not the type. It's the parameter. Right ? So a 
template doesn't need a type. Only the parameter, right ? (I 
think I am too dumb to ask this. Please forgive me.)


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` fails 
the test.


In order to understand this, I need to understand from where the 
`U` comes.





Re: Help needed to learn templates

2022-03-19 Thread Stanislav Blinov via Digitalmars-d-learn
On Saturday, 19 March 2022 at 05:54:26 UTC, Vinod K Chandran 
wrote:


Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`


No.

Question 2 - The statif if test is - `T t == U[ ]` What does 
that mean ?


The test is not `T t == U[]`. It is `is(T t == U[], U)`.

https://dlang.org/spec/expression.html#is-identifier-equal

```
is ( Type Identifier == TypeSpecialization )

The condition is satisfied if Type is semantically correct and is 
the same as TypeSpecialization. The Identifier is declared to be 
either an alias of the TypeSpecialization or, if 
TypeSpecialization is dependent on Identifier, the deduced type.

```

You simply introduce new identifiers. Basically, the test means 
"is T an array of some type which I would like referred to as 
U?". Actually, the lower case `t` is not needed there, you can 
simply write `is(T == U[], U)`.


Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass

```d
rank!(int[ ][ ][ ])
```
The test will be `int[ ][ ][ ] == U[ ]`, Right ?


Yes, and `U` then becomes `int[][]`. Which is why the template 
recurses down and instantiates itself with `U`, until `T` fails 
the test.


Re: Help needed to learn templates

2022-03-19 Thread Salih Dincer via Digitalmars-d-learn
On Saturday, 19 March 2022 at 05:54:26 UTC, Vinod K Chandran 
wrote:
Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`
Question 2 - The statif if test is - `T t == U[ ]` What does 
that mean ?
Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass


You don't need anything extra while using it...

I think U is declare a range. Here is a recursive pattern. Just 
like the code I wrote below:


```d
import std.stdio;

alias outer O;

struct outer {
  int i;
  O * o;
}

int rank(T)(T* s) {
  int count = 1;

  if(s.o is null) return count;


  return count + rank(s.o);
}

void main() {
  auto test = O(1, new O(2, new O(3, new O)));

  rank(test.o).writeln;

  test.i.write(", ");
  test.o.i.write(", ");
  test.o.o.i.writeln;
} /* CONSOLEOUT:
3
1, 2, 3
*/
```
SDB@79


Help needed to learn templates

2022-03-18 Thread Vinod K Chandran via Digitalmars-d-learn

Hi all,
I am trying to learn D templates with Philippe Sigaud's "D 
Templates: A Tutorial". So far so good. I have completed first 19 
pages and in the 20th page, I found an obstacle. This is the code.

```d
module rank1;

template rank(T)
{
static if (is(T t == U[], U)) // is T an array of U, for some 
type U?
enum size_t rank = 1 + rank!(U); // then let’s recurse 
down.

else
enum size_t rank = 0; // Base case, ending the recursion.
}

module using_rank1;
import rank1;
static assert(rank!(int) == 0);
static assert(rank!(int[]) == 1);
static assert(rank!(int[][]) == 2);
static assert(rank!(int[][][]) == 3);
```
Question 1 - `U` is appearing in the first static if statement. 
But we had to write `U` on the template line, right? Like - 
`template rank(T, U)`
Question 2 - The statif if test is - `T t == U[ ]` What does that 
mean ?
Question 3 - if `T t == U[ ]` is the test, then I think when we 
pass

```d
rank!(int[ ][ ][ ])
```
The test will be `int[ ][ ][ ] == U[ ]`, Right ?