Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-24 Thread data pulverizer via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 20:19:04 UTC, data pulverizer 
wrote:

Thinking more about it this ...


class Middle: Node
{
  Node prev;
  Node next;
}
won't work because the I've told the compiler that the static 
type is "Node", my original design was something like this:


```
struct Middle(P, N)
{
  P prev;
  N next;
}
```

which also won't work because it can't actually be instantiated 
(recursive), and the start and end nodes must be different types 
(and you can't substitute the middle node for the start and end 
node). It's the simplest case because there could be more than 
one type of middle node. More generally, correct me if I'm wrong, 
but I don't think these kinds of statically multityped tree 
structures can be formed in static languages so I've been using 
tuples - at least for the simple case I outlined.




Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread Otávio Augusto via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 18:37:45 UTC, wjoe wrote:

I have some similar functions:

void register(C: IFoo)()
{
  _insert!C();
}

void register(C)() if (behavesLikeFoo!C)
{
  _insert!C();
}

There are more overloads with parameters so I want to merge them

void register(C, ARGS...)(ARGS args) if (behavesLikeFoo!C || 
isInstanceOf!(C, IFoo))

{
  _insert!C(args);
}

I found a lot of information on how to do this at runtime but 
not at compile time.
std.traits: isInstanceOf doesn't work. Neither did anything I 
tried with typeid etc.


The behavesLikeFoo constraint works as expected but it accepts 
any class no matter whether or not it implements the interface.


see if "import std.traits: isImplicitlyConvertible" helps you.



Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 20:19:04 UTC, data pulverizer 
wrote:
This has prompted me to write a data structure that I thought 
would be impossible until now


False alarm:

```
writeln("typeof(x.next): ", typeof(x.next).stringof);
```
gives:

```
typeof(x.next): const(Node)
```

Oh well.


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 20:19:04 UTC, data pulverizer 
wrote:
This has prompted me to write a data structure that I thought 
would be impossible until now. [...SNIP...]


Here is the function with the correct template constraint:

```
auto makeChain(Args...)(Args args)
if(Args.length > 2 && is(Args[0] == Start) && is(Args[Args.length 
- 1] == End))

{
  args[0].next = args[1];
  static foreach(i; 1..(Args.length - 1))
  {
args[i].prev = args[i - 1];
args[i].next = args[i + 1];
  }
  args[$ - 1].prev = args[$ - 2];
  return args[0];
}
```



Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 19:27:13 UTC, wjoe wrote:
Appologies if you took offense. Your replies are very much 
appreciated.


No offense taken.


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 19:16:13 UTC, H. S. Teoh wrote:


Of course the compiler knows. And of course it can use this 
information for static dispatch. That's why D is so awesome at 
metaprogramming. ;-)


What the compiler *doesn't* know is whether a variable of some 
supertype of Foo (say Object) implements IFoo, because that's 
something that can only be determined at runtime (effectively, 
you need to downcast to Foo / IFoo and test if it's null).  But 
that's not what the OP is asking for in this case.



T


This has prompted me to write a data structure that I thought 
would be impossible until now. It's a data structure with a Start 
node with a link to next, then any number of Middle nodes with 
previous and next links, and an End node with a previous link all 
inheriting from a common interface Node. This is of course 
possible using runtime polymorphism, but I wanted it available 
for static dispatch rather than everything being listed as "Node" 
static type. The implementation is below and works.


Interestingly when I wrote it down with a pen and paper I thought 
that it would lead to infinitely recursive unwriteable data type 
and so didn't even bother trying to implement it. But D actually 
forms the correct static type, it prints the gobbledygook type I 
expect at compile time but the actual static type at runtime. 
Amazing! I have been using structs with tuples because I thought 
this data structure was impossible!


```
import std.stdio: writeln;

interface Node{}
class Start: Node
{
  Node next;
}
class Middle: Node
{
  Node prev;
  Node next;
}
class End: Node
{
  Node prev;
}

auto makeChain(Args...)(Args args)
if(Args.length > 3)
{
  args[0].next = args[1];
  static foreach(i; 1..(Args.length - 1))
  {
args[i].prev = args[i - 1];
args[i].next = args[i + 1];
  }
  args[$ - 1].prev = args[$ - 2];
  return args[0];
}

void main()
{
  static const x = makeChain(new Start(), new Middle(), new 
Middle(),
  new Middle(), new Middle(), new 
End());

  pragma(msg, "x.next: ", x.next, "\n");
  writeln("x.next: ", x.next);
}
```

output:

```
x.next: Middle(Start(Middle()), 
Middle(Middle(Start(Middle()), Middle()), 
Middle(Middle(Middle(Start(Middle()), 
Middle()), Middle()), 
Middle(Middle(Middle(Middle(Start(Middle()), 
Middle()), Middle()), Middle()), 
End(Middle(Middle(Middle(Middle(Start(Middle()), 
Middle()), Middle()), Middle()), 
End()))


x.next: node.Middle
```



Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 19:08:47 UTC, data pulverizer 
wrote:

On Wednesday, 23 September 2020 at 18:56:33 UTC, wjoe wrote:

[...]


Didn't think that the compiler didn't know but wasn't aware 
that you could use that information to statically dispatch. My 
mistake, I'll shut up now!


Appologies if you took offense. Your replies are very much 
appreciated.


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Sep 23, 2020 at 07:08:47PM +, data pulverizer via 
Digitalmars-d-learn wrote:
> On Wednesday, 23 September 2020 at 18:56:33 UTC, wjoe wrote:
> > 
> > It doesn't occur to me that the compiler doesn't know at compile
> > time that
> > 
> > interface IFoo{}
> > class Foo: IFoo {}
> > 
> > class Foo implements interface IFoo.
> 
> Didn't think that the compiler didn't know but wasn't aware that you
> could use that information to statically dispatch. My mistake, I'll
> shut up now!

Of course the compiler knows. And of course it can use this information
for static dispatch. That's why D is so awesome at metaprogramming. ;-)

What the compiler *doesn't* know is whether a variable of some supertype
of Foo (say Object) implements IFoo, because that's something that can
only be determined at runtime (effectively, you need to downcast to Foo
/ IFoo and test if it's null).  But that's not what the OP is asking for
in this case.


T

-- 
Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 18:56:33 UTC, wjoe wrote:


It doesn't occur to me that the compiler doesn't know at 
compile time that


interface IFoo{}
class Foo: IFoo {}

class Foo implements interface IFoo.


Didn't think that the compiler didn't know but wasn't aware that 
you could use that information to statically dispatch. My 
mistake, I'll shut up now!





Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 18:49:28 UTC, data pulverizer 
wrote:

On Wednesday, 23 September 2020 at 18:37:45 UTC, wjoe wrote:

[...]


A class at compile time is it's own static type, OOP 
polymorphism is a runtime feature not compile time. You have to 
write your own traits for specific objects to get them to 
relate to each other using static overloading.


It doesn't occur to me that the compiler doesn't know at compile 
time that


interface IFoo{}
class Foo: IFoo {}

class Foo implements interface IFoo.



Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 18:50:28 UTC, H. S. Teoh wrote:

Try this:

interface I {}
class C : I {}
class D {}
struct S {}

pragma(msg, is(C : I)); // true
pragma(msg, is(D : I)); // false
pragma(msg, is(S : I)); // false

So probably what you want is something like this:

void register(C, ARGS...)(ARGS args)
if (behavesLikeFoo!C || is(C : IFoo))
...


T


Yes, that's it. Thanks :)


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread H. S. Teoh via Digitalmars-d-learn
Try this:

interface I {}
class C : I {}
class D {}
struct S {}

pragma(msg, is(C : I)); // true
pragma(msg, is(D : I)); // false
pragma(msg, is(S : I)); // false

So probably what you want is something like this:

void register(C, ARGS...)(ARGS args)
if (behavesLikeFoo!C || is(C : IFoo))
...


T

-- 
Change is inevitable, except from a vending machine.


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread data pulverizer via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 18:37:45 UTC, wjoe wrote:

I have some similar functions:

void register(C: IFoo)()
{
  _insert!C();
}

void register(C)() if (behavesLikeFoo!C)
{
  _insert!C();
}

There are more overloads with parameters so I want to merge them

void register(C, ARGS...)(ARGS args) if (behavesLikeFoo!C || 
isInstanceOf!(C, IFoo))

{
  _insert!C(args);
}

I found a lot of information on how to do this at runtime but 
not at compile time.
std.traits: isInstanceOf doesn't work. Neither did anything I 
tried with typeid etc.


The behavesLikeFoo constraint works as expected but it accepts 
any class no matter whether or not it implements the interface.


A class at compile time is it's own static type, OOP polymorphism 
is a runtime feature not compile time. You have to write your own 
traits for specific objects to get them to relate to each other 
using static overloading.


How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn

I have some similar functions:

void register(C: IFoo)()
{
  _insert!C();
}

void register(C)() if (behavesLikeFoo!C)
{
  _insert!C();
}

There are more overloads with parameters so I want to merge them

void register(C, ARGS...)(ARGS args) if (behavesLikeFoo!C || 
isInstanceOf!(C, IFoo))

{
  _insert!C(args);
}

I found a lot of information on how to do this at runtime but not 
at compile time.
std.traits: isInstanceOf doesn't work. Neither did anything I 
tried with typeid etc.


The behavesLikeFoo constraint works as expected but it accepts 
any class no matter whether or not it implements the interface.