Re: Why a template with Nullable does not compile?

2019-03-12 Thread Victor Porton via Digitalmars-d-learn

On Tuesday, 12 March 2019 at 15:26:05 UTC, Victor Porton wrote:

template FieldInfo(T, Nullable!T default_) {
}

On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson 
wrote:
It seems to be getting confused between the two types of 
Nullable, namely:

Nullable(T), and
Nullable(T, T defaultVal)


I don't understand why exactly it is getting confused. How can 
it decide that "Nullable!T default_" is a two-arguments 
template when it is so not "Nullable!(T, default_)"? Please 
explain the EXACT cause of the error.


My question why it is getting confused was not answered.


Re: Why a template with Nullable does not compile?

2019-03-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Mar 12, 2019 at 04:23:29PM +, Victor Porton via Digitalmars-d-learn 
wrote:
[...]
> I know what is eponymous template. But how it behaves when the
> eponymous member inside itself is also a template? How to instantiate
> it? (provide please an example how to instantiate)

You need to provide two sets of template arguments. Usually, the only
time we nest eponymous templates this way is when we're writing a
function that needs to take two variadic sets of template parameters. In
that case, we only need to write one set of template parameters and let
IFTI fill in the second set of parameters for us.

For example:

template map(funcs...) {
template map(Ranges...) {
auto map(Ranges rr) {
...
}
}
}

auto r = map!(func1, func2)(r1, r2);

The first part `map!(func1, func2)` resolves to an instantiation of the
outer template, which is an inner template, then the compiler uses IFTI
to deduce the second set of arguments as !(typeof(r1), typeof(r2)) in
order to instantiate the inner template.

If you want to instantiate it by hand, you could do something like this:

alias Outer = map!(func1, func2);   // instantiate outer template
alias inner = Outer!(int[], int[]); // instantiate inner template
inner([ 1, 2, 3], [ 4, 5, 6 ]);


T

-- 
People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG


Re: Why a template with Nullable does not compile?

2019-03-12 Thread Victor Porton via Digitalmars-d-learn

On Tuesday, 12 March 2019 at 16:20:11 UTC, H. S. Teoh wrote:
On Tue, Mar 12, 2019 at 03:26:05PM +, Victor Porton via 
Digitalmars-d-learn wrote: [...]
On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson 
wrote:

[...]

> template FieldInfo(T) {
> template FieldInfo(Nullable!(T) default_)
> {
> enum FieldInfo = 0;
> }
> }
> 
> seems to work, but I can't seem to instantiate one of it.


Why you use the same name "FieldInfo" for both the template 
and its subtemplate? Does it make some sense?


This is a D idiom called the "eponymous template".  Whenever 
the template contains a member of the same name as the 
template, it's an eponymous template, and you can refer 
directly to the member by the template name, rather than using 
templateName.memberName.


For example, a template function is usually written like this:

ReturnType myFunc(TemplateArgs...)(RuntimeArgs args...)
{
... // implementation here
}

This is actually shorthand for the eponymous template:

template myFunc(TemplateArgs...)
{
ReturnType myFunc(RuntimeArgs args...)
{
... // implementation here
}
}

Similarly, when you write:

enum isInputRange(T) = hasMember!(T, empty) && ...

that's actually shorthand for:

template isInputRange(T)
{
enum isInputRange = hasMember!(T, empty) && ...
}

The eponymonus template idiom allows you to use a single name 
to refer to both the template and the member. Without this 
idiom, you'd have to use the very verbose notation:


static if (isInputRange!T.isInputRange) ...

or

auto retval = myFunc!(A, B, C).myFunc(1, 2, 3);


I know what is eponymous template. But how it behaves when the 
eponymous member inside itself is also a template? How to 
instantiate it? (provide please an example how to instantiate)


Re: Why a template with Nullable does not compile?

2019-03-12 Thread H. S. Teoh via Digitalmars-d-learn
On Tue, Mar 12, 2019 at 03:26:05PM +, Victor Porton via Digitalmars-d-learn 
wrote:
[...]
> On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson wrote:
[...]
> > template FieldInfo(T) {
> > template FieldInfo(Nullable!(T) default_)
> > {
> > enum FieldInfo = 0;
> > }
> > }
> > 
> > seems to work, but I can't seem to instantiate one of it.
> 
> Why you use the same name "FieldInfo" for both the template and its
> subtemplate? Does it make some sense?

This is a D idiom called the "eponymous template".  Whenever the
template contains a member of the same name as the template, it's an
eponymous template, and you can refer directly to the member by the
template name, rather than using templateName.memberName.

For example, a template function is usually written like this:

ReturnType myFunc(TemplateArgs...)(RuntimeArgs args...)
{
... // implementation here
}

This is actually shorthand for the eponymous template:

template myFunc(TemplateArgs...)
{
ReturnType myFunc(RuntimeArgs args...)
{
... // implementation here
}
}

Similarly, when you write:

enum isInputRange(T) = hasMember!(T, empty) && ...

that's actually shorthand for:

template isInputRange(T)
{
enum isInputRange = hasMember!(T, empty) && ...
}

The eponymonus template idiom allows you to use a single name to refer
to both the template and the member. Without this idiom, you'd have to
use the very verbose notation:

static if (isInputRange!T.isInputRange) ...

or

auto retval = myFunc!(A, B, C).myFunc(1, 2, 3);


T

-- 
It won't be covered in the book. The source code has to be useful for 
something, after all. -- Larry Wall


Re: Why a template with Nullable does not compile?

2019-03-12 Thread Victor Porton via Digitalmars-d-learn

template FieldInfo(T, Nullable!T default_) {
}

On Tuesday, 12 March 2019 at 09:05:36 UTC, Nicholas Wilson wrote:
It seems to be getting confused between the two types of 
Nullable, namely:

Nullable(T), and
Nullable(T, T defaultVal)


I don't understand why exactly it is getting confused. How can it 
decide that "Nullable!T default_" is a two-arguments template 
when it is so not "Nullable!(T, default_)"? Please explain the 
EXACT cause of the error.



template FieldInfo(T) {
template FieldInfo(Nullable!(T) default_)
{
enum FieldInfo = 0;
}
}

seems to work, but I can't seem to instantiate one of it.


Why you use the same name "FieldInfo" for both the template and 
its subtemplate? Does it make some sense?


Re: Why a template with Nullable does not compile?

2019-03-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote:

Why does this not compile?

import std.typecons;

template FieldInfo(T, Nullable!T default_) {
}

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set


It seems to be getting confused between the two types of 
Nullable, namely:

Nullable(T), and
Nullable(T, T defaultVal)

template FieldInfo(T) {
template FieldInfo(Nullable!(T) default_)
{
enum FieldInfo = 0;
}
}

seems to work, but I can't seem to instantiate one of it.



Re: Why a template with Nullable does not compile?

2019-03-11 Thread Victor Porton via Digitalmars-d-learn

On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote:

Why does this not compile?

import std.typecons;

template FieldInfo(T, Nullable!T default_) {
}

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias 
T = T;` cannot alias itself, use a qualified name to create an overload set


LDC - the LLVM D compiler (1.11.0):
  based on DMD v2.081.2 and LLVM 6.0.1



Why a template with Nullable does not compile?

2019-03-11 Thread Victor Porton via Digitalmars-d-learn

Why does this not compile?

import std.typecons;

template FieldInfo(T, Nullable!T default_) {
}

/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): 
Error: `alias T = T;` cannot alias itself, use a qualified name 
to create an overload set
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): 
Error: `alias T = T;` cannot alias itself, use a qualified name 
to create an overload set