Re: Derived type

2021-04-01 Thread novice2 via Digitalmars-d-learn

thanks, i tried 2 variants:
```d
struct Tnew {TBase payload; alias payload this;}
```
```d
enum Tnew : Tbase {init = Tbase.init}
```

both works, but 1-st not allow "2 level" cast:
```d
struct Xptr {void* payload; alias payload this;} //Xptr based on 
void*
struct Xobj {Xptr payload; alias payload this;}  //Xobj based on  
Xptr

Xptr xptr = cast(Xptr) null; //OK
Xobj xobj = cast(Xobj) null; //ERROR
Xobj xobj = cast(Xobj) cast(Xptr) null;  //OK, needs both levels 
explitity

```
```d
enum Xptr : void* {init = (void*).init} //Xptr based on void*
enum Xobj : Xptr {init = Xptr.init} //Xobj based on  Xptr
Xptr xptr = cast(Xptr) null;//OK
Xobj xobj = cast(Xobj) null;//OK
```

so "enum" variant is better for me, thanks!


Re: Derived type

2021-04-01 Thread novice3 via Digitalmars-d-learn

On Thursday, 1 April 2021 at 12:07:17 UTC, WebFreak001 wrote:

You can add a custom init value if you want to allow one:

```d
enum Xobj : void* { init = null }
```


Thank you!


Re: Derived type

2021-04-01 Thread WebFreak001 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 19:02:09 UTC, novice2 wrote:

[...]

Strange syntax.
Behavour exactly what i want, but this code not works for me :(

  enum Xobj : void*;
  Xobj var;  //DMD Error: enum test7.Xobj forward reference of 
Xobj.init


You can add a custom init value if you want to allow one:

```d
enum Xobj : void* { init = null }
```


Re: Derived type

2021-03-31 Thread novice3 via Digitalmars-d-learn

On Wednesday, 31 March 2021 at 12:09:33 UTC, Basile B. wrote:
yeah template instances are identified using the parameters 
identifiers, then the alias is just a syntactic shortcut to 
that, not producing a new symbol with a unique mangle...


so, no way to generate struct with parametrized name by template 
or mixin template?



That being said you can still use a string mixin if the 
messages have to be correct

...


thank you!


Re: Derived type

2021-03-31 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 31 March 2021 at 04:49:50 UTC, novice3 wrote:

On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote:

struct Typedef(TBase)
{
   TBase payload;
   alias payload this;
}

alias Xobj = Typedef!(void*);


This is how std.typecons.Typedef made, IMHO.

The problem is this code generate struct with name 
"Typedef!(void*)",

then compiler show this name (not "Xobj") in messages:

https://run.dlang.io/is/eEI2yC

  void* bad;
  foo(bad);

Error: function foo(Typedef!(void*) obj) is not callable using 
argument types (void*)
   cannot pass argument bad of type void* to parameter 
Typedef!(void*) obj


yeah template instances are identified using the parameters 
identifiers, then the alias is just a syntactic shortcut to that, 
not producing a new symbol with a unique mangle... but the 
message is correct assuming you want void* to be rejected.


That being said you can still use a string mixin if the messages 
have to be correct


---
string genTypeDef(TBase)(string name)
{
return "struct " ~ name ~ "{" ~ TBase.stringof ~ " payload; 
alias payload this;}";

}

mixin(genTypeDef!(void*)("Xobj"));

void foo (Xobj obj) {}
---


Re: Derived type

2021-03-30 Thread novice3 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 21:53:34 UTC, Basile B. wrote:

struct Typedef(TBase)
{
   TBase payload;
   alias payload this;
}

alias Xobj = Typedef!(void*);


This is how std.typecons.Typedef made, IMHO.

The problem is this code generate struct with name 
"Typedef!(void*)",

then compiler show this name (not "Xobj") in messages:

https://run.dlang.io/is/eEI2yC

  void* bad;
  foo(bad);

Error: function foo(Typedef!(void*) obj) is not callable using 
argument types (void*)
   cannot pass argument bad of type void* to parameter 
Typedef!(void*) obj




Re: Derived type

2021-03-30 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 19:33:31 UTC, novice2 wrote:

On Tuesday, 30 March 2021 at 19:12:29 UTC, Ali Çehreli wrote:
"Derived type" is used in the context of object oriented 
programming at least in D


Sorry, i use wrong termin.
I just want create new type Tnew, based on exist type Tbase.
Tnew have same allowed values, same properties, same allowed 
operations as Tbase.

Compiler should distinguish New from Tbase.
Allowed implicit cast Tnew to Tbase.
Prohibited implicit cast Tbase to Tnew.
Allowed exlicit cast Tbase to Tnew.


That's precisely what the alias this feature is intended to do.

https://dlang.org/spec/class.html#alias-this


Thanks, this is what i want.
I just think that Typedef do it for me, hide this boilerplait 
code.


That's not the intended purpose of the Typedef template. Its 
documentation explicitly says it "allows the creation of a unique 
type which is based on an existing type". The keyword there is 
*unique*.


Re: Derived type

2021-03-30 Thread Basile B. via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 19:47:41 UTC, novice2 wrote:

My tries to make template for struct and alias this:

// variant 1
template Typedef(alias Tnew, Tbase)
{
  struct Tnew
  {
Tbase payload;
alias payload this;
  }
}



you must give a name to the template specialization, using alias 
[1], also the TypeDef declaration can be highly simplified:


---
struct Typedef(TBase)
{
   TBase payload;
   alias payload this;
}

alias Xobj = Typedef!(void*);

void foo (Xobj obj) {}
---


[1]: https://dlang.org/spec/declaration.html#alias



Re: Derived type

2021-03-30 Thread novice2 via Digitalmars-d-learn

My tries to make template for struct and alias this:

// variant 1
template Typedef(alias Tnew, Tbase)
{
  struct Tnew
  {
Tbase payload;
alias payload this;
  }
}

Typedef!(Xobj, void*);

void foo (Xobj obj) {}  //compiler Error: no identifier for 
declarator Typedef!(Xobj, void*)



// variant 2
mixin template Typedef(alias Tnew, Tbase)
{
  struct Tnew
  {
Tbase payload;
alias payload this;
  }
}

mixin Typedef!(Xobj, void*);  //compiler Error: undefined 
identifier Xobj





Re: Derived type

2021-03-30 Thread novice2 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 19:12:29 UTC, Ali Çehreli wrote:
"Derived type" is used in the context of object oriented 
programming at least in D


Sorry, i use wrong termin.
I just want create new type Tnew, based on exist type Tbase.
Tnew have same allowed values, same properties, same allowed 
operations as Tbase.

Compiler should distinguish New from Tbase.
Allowed implicit cast Tnew to Tbase.
Prohibited implicit cast Tbase to Tnew.
Allowed exlicit cast Tbase to Tnew.


but your examples indicate you need something else. How about 
the 'alias this' feature?


Thanks, this is what i want.
I just think that Typedef do it for me, hide this boilerplait 
code.




Re: Derived type

2021-03-30 Thread Ali Çehreli via Digitalmars-d-learn

On 3/30/21 6:28 AM, novice3 wrote:

> I want create derived type in D

"Derived type" is used in the context of object oriented programming at 
least in D but your examples indicate you need something else. How about 
the 'alias this' feature?


import std.stdio;

struct Xobj {
  void* value;
  alias value this;
}

void main() {
  int i;
  auto var = Xobj();
  writeln(var);
  int j;
  var = 
}

alias this is for implicit conversions, from Xobj to void* in this case.

Ali



Re: Derived type

2021-03-30 Thread novice2 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 14:45:12 UTC, WebFreak001 wrote:
Xobj can then be used interchangeably with void*, so all void* 
arguments accept Xobj and all Xobj arguments accept void*.


yes, i understand alias, and i dont want such behaviour


If you want a type-safe alias that makes all void* arguments 
accept Xobj but not Xobj arguments to accept void*


yes, this is that i search



you can use `Typedef` like you linked.


Problem with Typedef template - code
  alias Xobj = Typedef!(void*)
not generate type named "Xobj",
but type named "Typedef!(void*, null, null)".
This makes compiler error messages unusable.



enum Xobj : void*;
```
This allows explicit conversion in both ways using cast, but 
only allows implicit conversion from Xobj to void*, not from 
void* to Xobj:


Strange syntax.
Behavour exactly what i want, but this code not works for me :(

  enum Xobj : void*;
  Xobj var;  //DMD Error: enum test7.Xobj forward reference of 
Xobj.init




Re: Derived type

2021-03-30 Thread novice2 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 13:43:52 UTC, Mike Parker wrote:

the straightforward way is just to use an alias.


i cant use alias - compiler cannot distinguish base type and 
alias, and cannot catch programmer errors


Buf if you need a more concrete type, you can use alias this in 
a struct:

I think Typedef template should do this struct for me.

Thanks Mike, this way is what i wanted

  struct Xobj {
private void* payload;
alias payload this;
  }

  Xobj good;
  foo(good);//nice
  foo(cast(Xobj)null);  //explicit cast allowed - nice
  foo(null);//no implicit cast disallowed - compiler 
error - nice


  void* bad;
  foo(bad); //compiler distinguish type - error - nice


I think Typedef template should do this struct for me.

Problem with Typedef template - code
  alias Xobj = Typedef!(void*)
not generate struct named "Xobj",
but struct named "Typedef!(void*, null, null)".
This makes compiler error messages unusable.

I will try to make template for struct. But template is black 
magic for me :)


Re: Derived type

2021-03-30 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 14:45:12 UTC, WebFreak001 wrote:


When i adapt C code, i see new type creation:



The typedef in C in D is just an alias:

```
alias Xobj = void*;
```


I totally overlooked the part about porting from C.

Yes, this is the way to go in that case.


Re: Derived type

2021-03-30 Thread WebFreak001 via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 13:28:55 UTC, novice3 wrote:

Hello.

When i adapt C code, i see new type creation:
  typedef void* Xobj;

Or code like this:
  struct _Xobj;
  typedef struct _Xobj *Xobj;


I want create derived type in D, found std.typecons.Typedef 
template, and write:

  alias Xobj = Typedef!(void*, (void*).init);

But compiler use long type name in error messages, like this:

  Error: function test6.foo(Typedef!(void*, null, null) obj) is 
not callable using argument types (void*)


  cannot pass argument bad of type void* to parameter 
Typedef!(void*, null, null) obj


This messages dont help me understand, which type should i use.
What i should change?
Or Typedef template should be changes?
Any Typedef alternatives?


The typedef in C in D is just an alias:

```
alias Xobj = void*;
```

Xobj can then be used interchangeably with void*, so all void* 
arguments accept Xobj and all Xobj arguments accept void*.


If you want a type-safe alias that makes all void* arguments 
accept Xobj but not Xobj arguments to accept void* you can use 
`Typedef` like you linked. However using this language built-in 
feature is much simpler and cheaper in terms of resource usage 
and compile time + always results in the fastest code: (there is 
no conversions at all)


```
enum Xobj : void*;
```

This allows explicit conversion in both ways using cast, but only 
allows implicit conversion from Xobj to void*, not from void* to 
Xobj:


```
void* x = someValue;
Xobj y = cast(Xobj)x; // ok
x = y; // ok
y = x; // error (need explicit cast)
```


Re: Derived type

2021-03-30 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 30 March 2021 at 13:28:55 UTC, novice3 wrote:



This messages dont help me understand, which type should i use.
What i should change?
Or Typedef template should be changes?


From the docs:

"Unlike the alias feature, Typedef ensures the two types are not 
considered as equals.

Parameters:"

https://dlang.org/phobos/std_typecons.html#Typedef



Any Typedef alternatives?


If you want your new type to be interchangeable with another, the 
straightforward way is just to use an alias. Buf if you need a 
more concrete type, you can use alias this in a struct:


import std.stdio;

struct MyType {
void* wrapped;
alias wrapped this;
}


void doSomething(void* t) {
writeln(*(cast(int*)t));
}

void main() {
int i = 20;
MyType mt = MyType();
doSomething(mt);
}



Derived type

2021-03-30 Thread novice3 via Digitalmars-d-learn

Hello.

When i adapt C code, i see new type creation:
  typedef void* Xobj;

Or code like this:
  struct _Xobj;
  typedef struct _Xobj *Xobj;


I want create derived type in D, found std.typecons.Typedef 
template, and write:

  alias Xobj = Typedef!(void*, (void*).init);

But compiler use long type name in error messages, like this:

  Error: function test6.foo(Typedef!(void*, null, null) obj) is 
not callable using argument types (void*)


  cannot pass argument bad of type void* to parameter 
Typedef!(void*, null, null) obj


This messages dont help me understand, which type should i use.
What i should change?
Or Typedef template should be changes?
Any Typedef alternatives?


Re: Any way to override base type with dervived in derived type

2018-05-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/25/18 4:02 PM, IntegratedDimensions wrote:
So, I upgraded everything, tried to add the setter and get an compile 
time access violation:



override @property T t(T v) { _t = v; return v; }

Changing T v to TT v gives the violation

override @property T t(TT v) { _t = v; return v; }


Parameters work the opposite way as return values. That is, you can't 
override a base class's function that accepts a base type with one that 
accepts a derived type. This is because you must be able to call the 
virtual function with the base type, and this would not work.


So what is technically possible is to call an overridden function with a 
base type (i.e. override a function that accepts a TT with one that 
accepts a T), but I don't know if D allows this, and obviously it 
doesn't help with your use case.





object.Error@(0): Access Violation

0x004850C8
0x00485C96
0x0043E22A
0x0047FB50
0x0046109A
0x0052401A
0x77D0B605 in LdrQueryProcessModuleInformation
0x77D11D02 in RtlQueryProcessLockInformation
0x77D11705 in RtlQueryProcessDebugInformation
0x77CA47DF in RtlAllocateHeap


Hm... this is a runtime stack trace. And a crappy one at that (very 
little info at the top of the stack).


If you are getting this at compile time, then it's the compiler having 
an issue, which is automatically a bug (compiler should never throw an 
error).


If you have a reduced test case, I'd recommend filing an issue, and 
tagging it with ICE. But it needs to be reproducible.


-Steve


Re: Any way to override base type with dervived in derived type

2018-05-25 Thread IntegratedDimensions via Digitalmars-d-learn

On Saturday, 26 May 2018 at 01:11:39 UTC, crimaniak wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions 
wrote:
I'm pretty much guaranteed that in C, t will be type TT due to 
the design(C goes with TT like bread with butter).

...
1) Your architecture is wrong, I recommend to rethink it.


Prove it genius! I recommend you rethink your absolutes without 
having a clue. Go back to SO, they need more Nazi's.


2) You still can deal with it using template mixins 
https://dlang.org/spec/template-mixin.html


I've already said templates do not work. Time to rethink your 
answers, they are useless and you are not an authority, quick 
acting like one.





Re: Any way to override base type with dervived in derived type

2018-05-25 Thread crimaniak via Digitalmars-d-learn
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions 
wrote:
I'm pretty much guaranteed that in C, t will be type TT due to 
the design(C goes with TT like bread with butter).

...
1) Your architecture is wrong, I recommend to rethink it.
2) You still can deal with it using template mixins 
https://dlang.org/spec/template-mixin.html


Re: Any way to override base type with dervived in derived type

2018-05-25 Thread IntegratedDimensions via Digitalmars-d-learn
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer 
wrote:

On 5/24/18 4:24 PM, IntegratedDimensions wrote:


What I'd like to do is

class C : A
{
    private override @property TT t() { return cast(TT)(_t); } 
// null check if necessary

    // Stuff below uses t which is now a TT
    ...
}


It should work, you are allowed covariant overloads. However, 
private functions are not virtual, you need to make them at 
least protected.


-Steve


So, I upgraded everything, tried to add the setter and get an 
compile time access violation:



override @property T t(T v) { _t = v; return v; }

Changing T v to TT v gives the violation

override @property T t(TT v) { _t = v; return v; }


object.Error@(0): Access Violation

0x004850C8
0x00485C96
0x0043E22A
0x0047FB50
0x0046109A
0x0052401A
0x77D0B605 in LdrQueryProcessModuleInformation
0x77D11D02 in RtlQueryProcessLockInformation
0x77D11705 in RtlQueryProcessDebugInformation
0x77CA47DF in RtlAllocateHeap

While my specific use case is far more complex in design, the 
original essentially boils down to the dpaste I gave. Probably 
won't spent any time on it since I do not need the setter in this 
case(can use the field directly). But a bug is probably related 
to the code that fixed the "original bug" and possibly windows. 
What I do know is that 2.75 did not produce this access violation 
and it was the same code(I just uncommented out the setter).


The original dpaste code that did pass, I though, doesn't seem to 
pass now. I thought it was working for 2.80 and so I changed it 
to 2.69 and it failed but I might have made a mistake or the page 
lagged.


Either way, maybe you have a clue for future reference.



Re: Any way to override base type with dervived in derived type

2018-05-25 Thread IntegratedDimensions via Digitalmars-d-learn
On Friday, 25 May 2018 at 10:45:23 UTC, Steven Schveighoffer 
wrote:

On 5/24/18 4:24 PM, IntegratedDimensions wrote:


What I'd like to do is

class C : A
{
    private override @property TT t() { return cast(TT)(_t); } 
// null check if necessary

    // Stuff below uses t which is now a TT
    ...
}


It should work, you are allowed covariant overloads. However, 
private functions are not virtual, you need to make them at 
least protected.


-Steve


Wow, I didn't expect that! Thanks, exactly what I needed.

Unfortunately property setters seem to be broken.

https://dpaste.dzfl.pl/24ce8c7e0681

Seems this is a bug though that has been fix as it only happens 
on certain the older compilers. I had to downgrade because in the 
latest I get a lot of link errors ;/





Re: Any way to override base type with dervived in derived type

2018-05-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/24/18 4:24 PM, IntegratedDimensions wrote:


What I'd like to do is

class C : A
{
    private override @property TT t() { return cast(TT)(_t); } // null 
check if necessary

    // Stuff below uses t which is now a TT
    ...
}


It should work, you are allowed covariant overloads. However, private 
functions are not virtual, you need to make them at least protected.


-Steve


Re: Any way to override base type with dervived in derived type

2018-05-24 Thread IntegratedDimensions via Digitalmars-d-learn

On Friday, 25 May 2018 at 01:42:48 UTC, Basile B. wrote:
On Friday, 25 May 2018 at 01:17:45 UTC, IntegratedDimensions 
wrote:

On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote:
On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions 
wrote:

On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, 
IntegratedDimensions wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, 
treats t as T

   ...
}


The issue is that I programmed the class C with a variable 
that directly was based off TT, I later subderived T from 
TT and exposed it in I. (TT was refactored in to T and not 
T)




As as a side note:
I can hardly follow this, as you don't show, where you use 
the interface I. However, especially if TT was refactored 
in such a way, that is a set difference of T and not T, why 
you choose to derive from T instead of to contain T?




It really should be obvious that A was meant to derive from 
I. This is just standard oop.  Simply leaving off : I should 
not be a deal breaker because it would not change the whole 
problem from black to white or vice versa.


T is a member to be included. You can only derive from one 
class. C can't derive from both A and T and even if it did, 
it would mean something else.





https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



This is not a composition pattern.

This is a parallel inherentence pattern.

TT : T = T
||   |
vv   v
C  : A : I

TT is used with C and T with I.

When C changes to C', TT : T changes to TT' : T

All functions that use TT in C are forced to use it as if it 
were of type T rather than TT which requires a bunch of 
casts.


This is generally a violation of type logic. There is 
nothing in that prevents t from being something like TTT 
which has no direct relation to TT.


But the programming logic of the code enforces t to be of 
type TT in C *always*. So I don't know why I would have to 
use casting all the time. It would be nice if there where a 
simple logical way to enforce a design pattern in the type 
system knowing that it is enforced at runtime. This makes 
cleaner code, nothing else.






But all the code in C assumes t is of type TT but now due 
to the interface it looks like a T, even though internally 
it is actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return 
cast(TT)(_t); } // null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my 
uses of t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT 
due to the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type 
system that in C, t is always of type TT and so treat it 
as such rather than forcing me to explicitly cast for 
every use. Again, I could rename things to avoid the same 
name usage but in this case it is not necessary because of 
the design.


Is there any semantics that can get me around having to 
rename?


Maybe, you are looking for Curiously Recurring Template 
Pattern?


´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


No, I am trying to keep parallel derived types consistently 
connected. If A is derived from B and C from D and B uses D 
then A uses C. Consistency cannot be guaranteed by the type 
system at compile time because A is typed to use C, I want 
to restrict it further to D.


You must put a template parameter in the interface and 
specialize the class that implements the interface.


```
module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}

module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}
```

but obviously this won't work if you want to derive C1 or 
C2...



or if there 100 fields.

This isn't a proper solution.

The whole issue is not outside of C but inside

Hypothetically

class C : A
{
   @property TT : T t() { return _t; }

   // t can be used directly as TT rather than 

Re: Any way to override base type with dervived in derived type

2018-05-24 Thread Basile B. via Digitalmars-d-learn
On Friday, 25 May 2018 at 01:17:45 UTC, IntegratedDimensions 
wrote:

On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote:
On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions 
wrote:

On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, 
IntegratedDimensions wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, 
treats t as T

   ...
}


The issue is that I programmed the class C with a variable 
that directly was based off TT, I later subderived T from 
TT and exposed it in I. (TT was refactored in to T and not 
T)




As as a side note:
I can hardly follow this, as you don't show, where you use 
the interface I. However, especially if TT was refactored in 
such a way, that is a set difference of T and not T, why you 
choose to derive from T instead of to contain T?




It really should be obvious that A was meant to derive from 
I. This is just standard oop.  Simply leaving off : I should 
not be a deal breaker because it would not change the whole 
problem from black to white or vice versa.


T is a member to be included. You can only derive from one 
class. C can't derive from both A and T and even if it did, 
it would mean something else.





https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



This is not a composition pattern.

This is a parallel inherentence pattern.

TT : T = T
||   |
vv   v
C  : A : I

TT is used with C and T with I.

When C changes to C', TT : T changes to TT' : T

All functions that use TT in C are forced to use it as if it 
were of type T rather than TT which requires a bunch of casts.


This is generally a violation of type logic. There is nothing 
in that prevents t from being something like TTT which has no 
direct relation to TT.


But the programming logic of the code enforces t to be of 
type TT in C *always*. So I don't know why I would have to 
use casting all the time. It would be nice if there where a 
simple logical way to enforce a design pattern in the type 
system knowing that it is enforced at runtime. This makes 
cleaner code, nothing else.






But all the code in C assumes t is of type TT but now due 
to the interface it looks like a T, even though internally 
it is actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); 
} // null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my 
uses of t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due 
to the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type 
system that in C, t is always of type TT and so treat it as 
such rather than forcing me to explicitly cast for every 
use. Again, I could rename things to avoid the same name 
usage but in this case it is not necessary because of the 
design.


Is there any semantics that can get me around having to 
rename?


Maybe, you are looking for Curiously Recurring Template 
Pattern?


´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


No, I am trying to keep parallel derived types consistently 
connected. If A is derived from B and C from D and B uses D 
then A uses C. Consistency cannot be guaranteed by the type 
system at compile time because A is typed to use C, I want to 
restrict it further to D.


You must put a template parameter in the interface and 
specialize the class that implements the interface.


```
module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}

module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}
```

but obviously this won't work if you want to derive C1 or C2...



or if there 100 fields.

This isn't a proper solution.

The whole issue is not outside of C but inside

Hypothetically

class C : A
{
   @property TT : T t() { return _t; }

   // t can be used directly as TT rather than having to do 
(cast(TT)t) everywhere t is used.

}

would solve 

Re: Any way to override base type with dervived in derived type

2018-05-24 Thread IntegratedDimensions via Digitalmars-d-learn

On Friday, 25 May 2018 at 01:02:00 UTC, Basile B. wrote:
On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions 
wrote:

On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, 
IntegratedDimensions wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, 
treats t as T

   ...
}


The issue is that I programmed the class C with a variable 
that directly was based off TT, I later subderived T from TT 
and exposed it in I. (TT was refactored in to T and not T)




As as a side note:
I can hardly follow this, as you don't show, where you use 
the interface I. However, especially if TT was refactored in 
such a way, that is a set difference of T and not T, why you 
choose to derive from T instead of to contain T?




It really should be obvious that A was meant to derive from I. 
This is just standard oop.  Simply leaving off : I should not 
be a deal breaker because it would not change the whole 
problem from black to white or vice versa.


T is a member to be included. You can only derive from one 
class. C can't derive from both A and T and even if it did, it 
would mean something else.





https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



This is not a composition pattern.

This is a parallel inherentence pattern.

TT : T = T
||   |
vv   v
C  : A : I

TT is used with C and T with I.

When C changes to C', TT : T changes to TT' : T

All functions that use TT in C are forced to use it as if it 
were of type T rather than TT which requires a bunch of casts.


This is generally a violation of type logic. There is nothing 
in that prevents t from being something like TTT which has no 
direct relation to TT.


But the programming logic of the code enforces t to be of type 
TT in C *always*. So I don't know why I would have to use 
casting all the time. It would be nice if there where a simple 
logical way to enforce a design pattern in the type system 
knowing that it is enforced at runtime. This makes cleaner 
code, nothing else.






But all the code in C assumes t is of type TT but now due to 
the interface it looks like a T, even though internally it 
is actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); 
} // null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my uses 
of t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due 
to the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type 
system that in C, t is always of type TT and so treat it as 
such rather than forcing me to explicitly cast for every 
use. Again, I could rename things to avoid the same name 
usage but in this case it is not necessary because of the 
design.


Is there any semantics that can get me around having to 
rename?


Maybe, you are looking for Curiously Recurring Template 
Pattern?


´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


No, I am trying to keep parallel derived types consistently 
connected. If A is derived from B and C from D and B uses D 
then A uses C. Consistency cannot be guaranteed by the type 
system at compile time because A is typed to use C, I want to 
restrict it further to D.


You must put a template parameter in the interface and 
specialize the class that implements the interface.


```
module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}

module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}
```

but obviously this won't work if you want to derive C1 or C2...



or if there 100 fields.

This isn't a proper solution.

The whole issue is not outside of C but inside

Hypothetically

class C : A
{
   @property TT : T t() { return _t; }

   // t can be used directly as TT rather than having to do 
(cast(TT)t) everywhere t is used.

}

would solve the problem and it would scale.

The way it would work is that inside 

Re: Any way to override base type with dervived in derived type

2018-05-24 Thread Basile B. via Digitalmars-d-learn
On Friday, 25 May 2018 at 00:15:39 UTC, IntegratedDimensions 
wrote:

On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions 
wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, 
treats t as T

   ...
}


The issue is that I programmed the class C with a variable 
that directly was based off TT, I later subderived T from TT 
and exposed it in I. (TT was refactored in to T and not T)




As as a side note:
I can hardly follow this, as you don't show, where you use the 
interface I. However, especially if TT was refactored in such 
a way, that is a set difference of T and not T, why you choose 
to derive from T instead of to contain T?




It really should be obvious that A was meant to derive from I. 
This is just standard oop.  Simply leaving off : I should not 
be a deal breaker because it would not change the whole problem 
from black to white or vice versa.


T is a member to be included. You can only derive from one 
class. C can't derive from both A and T and even if it did, it 
would mean something else.





https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



This is not a composition pattern.

This is a parallel inherentence pattern.

TT : T = T
||   |
vv   v
C  : A : I

TT is used with C and T with I.

When C changes to C', TT : T changes to TT' : T

All functions that use TT in C are forced to use it as if it 
were of type T rather than TT which requires a bunch of casts.


This is generally a violation of type logic. There is nothing 
in that prevents t from being something like TTT which has no 
direct relation to TT.


But the programming logic of the code enforces t to be of type 
TT in C *always*. So I don't know why I would have to use 
casting all the time. It would be nice if there where a simple 
logical way to enforce a design pattern in the type system 
knowing that it is enforced at runtime. This makes cleaner 
code, nothing else.






But all the code in C assumes t is of type TT but now due to 
the interface it looks like a T, even though internally it is 
actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); } 
// null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my uses 
of t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due 
to the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type 
system that in C, t is always of type TT and so treat it as 
such rather than forcing me to explicitly cast for every use. 
Again, I could rename things to avoid the same name usage but 
in this case it is not necessary because of the design.


Is there any semantics that can get me around having to 
rename?


Maybe, you are looking for Curiously Recurring Template 
Pattern?


´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


No, I am trying to keep parallel derived types consistently 
connected. If A is derived from B and C from D and B uses D 
then A uses C. Consistency cannot be guaranteed by the type 
system at compile time because A is typed to use C, I want to 
restrict it further to D.


You must put a template parameter in the interface and specialize 
the class that implements the interface.


```
module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}

module runnable;

class T{}
class TT : T{}

interface I(N)
{
   @property N t();
}

abstract class A(N) : I!N
{
   N _t;
   @property N t() { return _t; }
}

class C1 : A!T{}
class C2 : A!TT{}

void main(string[] args)
{
import std.traits;
static assert(is(ReturnType!(C1.t) == T));
static assert(is(ReturnType!(C2.t) == TT));
}
```

but obviously this won't work if you want to derive C1 or C2...


Re: Any way to override base type with dervived in derived type

2018-05-24 Thread IntegratedDimensions via Digitalmars-d-learn

On Thursday, 24 May 2018 at 23:31:50 UTC, Alex wrote:
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions 
wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, treats 
t as T

   ...
}


The issue is that I programmed the class C with a variable 
that directly was based off TT, I later subderived T from TT 
and exposed it in I. (TT was refactored in to T and not T)




As as a side note:
I can hardly follow this, as you don't show, where you use the 
interface I. However, especially if TT was refactored in such a 
way, that is a set difference of T and not T, why you choose to 
derive from T instead of to contain T?




It really should be obvious that A was meant to derive from I. 
This is just standard oop.  Simply leaving off : I should not be 
a deal breaker because it would not change the whole problem from 
black to white or vice versa.


T is a member to be included. You can only derive from one class. 
C can't derive from both A and T and even if it did, it would 
mean something else.





https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



This is not a composition pattern.

This is a parallel inherentence pattern.

TT : T = T
||   |
vv   v
C  : A : I

TT is used with C and T with I.

When C changes to C', TT : T changes to TT' : T

All functions that use TT in C are forced to use it as if it were 
of type T rather than TT which requires a bunch of casts.


This is generally a violation of type logic. There is nothing in 
that prevents t from being something like TTT which has no direct 
relation to TT.


But the programming logic of the code enforces t to be of type TT 
in C *always*. So I don't know why I would have to use casting 
all the time. It would be nice if there where a simple logical 
way to enforce a design pattern in the type system knowing that 
it is enforced at runtime. This makes cleaner code, nothing else.






But all the code in C assumes t is of type TT but now due to 
the interface it looks like a T, even though internally it is 
actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); } 
// null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my uses 
of t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due to 
the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type system 
that in C, t is always of type TT and so treat it as such 
rather than forcing me to explicitly cast for every use. 
Again, I could rename things to avoid the same name usage but 
in this case it is not necessary because of the design.


Is there any semantics that can get me around having to rename?


Maybe, you are looking for Curiously Recurring Template Pattern?

´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


No, I am trying to keep parallel derived types consistently 
connected. If A is derived from B and C from D and B uses D then 
A uses C. Consistency cannot be guaranteed by the type system at 
compile time because A is typed to use C, I want to restrict it 
further to D.





Re: Any way to override base type with dervived in derived type

2018-05-24 Thread Alex via Digitalmars-d-learn
On Thursday, 24 May 2018 at 20:24:32 UTC, IntegratedDimensions 
wrote:

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, treats 
t as T

   ...
}


The issue is that I programmed the class C with a variable that 
directly was based off TT, I later subderived T from TT and 
exposed it in I. (TT was refactored in to T and not T)




As as a side note:
I can hardly follow this, as you don't show, where you use the 
interface I. However, especially if TT was refactored in such a 
way, that is a set difference of T and not T, why you choose to 
derive from T instead of to contain T?


https://en.wikipedia.org/wiki/Composition_over_inheritance
http://wiki.c2.com/?CompositionInsteadOfInheritance

Well, can imagine useful cases though...



But all the code in C assumes t is of type TT but now due to 
the interface it looks like a T, even though internally it is 
actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); } 
// null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my uses of 
t in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due to 
the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type system 
that in C, t is always of type TT and so treat it as such 
rather than forcing me to explicitly cast for every use. Again, 
I could rename things to avoid the same name usage but in this 
case it is not necessary because of the design.


Is there any semantics that can get me around having to rename?


Maybe, you are looking for Curiously Recurring Template Pattern?

´´´
interface I(P)
{
@property P t();
}

abstract class T(P) : I!P
{
P _p;
@property P t() { return _p; }
}

class TT : T!TT
{

}

void main()
{
auto tt = new TT();
static assert(is(typeof(tt.t) == TT));
}
´´´


Any way to override base type with dervived in derived type

2018-05-24 Thread IntegratedDimensions via Digitalmars-d-learn

class T;
class TT : T;

interface I
{
   @property T t();
}

abstract class A
{
   T _t;
   @property T t() { return _t; }

}

class C : A
{

   // Stuff below uses t as TT but compiler, of course, treats t 
as T

   ...
}


The issue is that I programmed the class C with a variable that 
directly was based off TT, I later subderived T from TT and 
exposed it in I. (TT was refactored in to T and not T)



But all the code in C assumes t is of type TT but now due to the 
interface it looks like a T, even though internally it is 
actually a TT.


What I'd like to do is

class C : A
{
   private override @property TT t() { return cast(TT)(_t); } // 
null check if necessary

   // Stuff below uses t which is now a TT
   ...
}

or whatever.

This is simply so I don't have to rename or cast all my uses of t 
in C to type TT.


I'm pretty much guaranteed that in C, t will be type TT due to 
the design(C goes with TT like bread with butter).


So, it would be nice if somehow I could inform the type system 
that in C, t is always of type TT and so treat it as such rather 
than forcing me to explicitly cast for every use. Again, I could 
rename things to avoid the same name usage but in this case it is 
not necessary because of the design.


Is there any semantics that can get me around having to rename?












Re: Access derived type in baseclass static function template

2017-08-03 Thread Timoses via Digitalmars-d-learn
On Wednesday, 2 August 2017 at 15:38:12 UTC, Steven Schveighoffer 
wrote:

On 8/2/17 11:06 AM, Timoses wrote:
On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven 
Schveighoffer wrote:
However, your original code has potential as an enhancement 
request, as the type is known at compile-time and could 
certainly be resolved to pass in as the `this` template 
parameter.


I guess the `this` is really misleading it being a static 
method.
I suppose 
https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity would be the place for an enhancement request?

Possibly related:
https://issues.dlang.org/show_bug.cgi?id=14191


Yes, that's exactly it.

Note that typeof(this) has special meaning for static methods:

class C
{
   static typeof(this) foo() { return new typeof(this); }
}

So there is precedence for the meaning of `this` in a static 
context.


-Steve


Oh, just now get it after creating the issue ^^. Makes sense. I 
kind of connected the "this" to existing instances because the 
DMD compiler often complains about something like "need this 
for..." when calling something from a static method that... 
well... needs "this" or instantiation..

E.g.:

class A
{
static void a()
{
b();
}
void b();
}

will throw
  Error: need 'this' for 'b' of type 'void()'


Re: Access derived type in baseclass static function template

2017-08-03 Thread Timoses via Digitalmars-d-learn

On Wednesday, 2 August 2017 at 12:07:46 UTC, Timoses wrote:

Hey,

wondering whether it's possible to access the derived type from 
a function template in the base class or interface.


[...]


Created an enhancement issue:

https://issues.dlang.org/show_bug.cgi?id=17714


Re: Access derived type in baseclass static function template

2017-08-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/2/17 11:06 AM, Timoses wrote:

On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer wrote:
However, your original code has potential as an enhancement request, 
as the type is known at compile-time and could certainly be resolved 
to pass in as the `this` template parameter.


I guess the `this` is really misleading it being a static method.
I suppose 
https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity 
would be the place for an enhancement request?

Possibly related:
https://issues.dlang.org/show_bug.cgi?id=14191


Yes, that's exactly it.

Note that typeof(this) has special meaning for static methods:

class C
{
   static typeof(this) foo() { return new typeof(this); }
}

So there is precedence for the meaning of `this` in a static context.

-Steve


Re: Access derived type in baseclass static function template

2017-08-02 Thread Timoses via Digitalmars-d-learn
Thanks Arafel, the alias workaround might just be a nice way to 
put it.


On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer 
wrote:
What you are looking for is virtual static methods, and D 
doesn't have those. I don't know if there's a way to make it 
work with existing features.


I'm not looking to overwrite the static method (which would refer 
to virtual, right?).


The solution I had previously was:

interface I
{
static void test(T)()
{
writeln(T.stringof);
}
}

class B : I {
alias type = int;

static void test()
{
I.test!type();
}
}

void main()
{
B.test();
}

However, this requires to add the base type as in
  I.test!type();
otherwise (only test!type();) it complains about
  Error: template instance test!type test is not a template 
declaration, it is a function


I was hoping there was a way to simply define it in the base 
class/interface without producing redundant code in each derived 
class.


Arafel's solution gets very close!

On Wednesday, 2 August 2017 at 13:51:01 UTC, Steven Schveighoffer 
wrote:
However, your original code has potential as an enhancement 
request, as the type is known at compile-time and could 
certainly be resolved to pass in as the `this` template 
parameter.


I guess the `this` is really misleading it being a static method.
I suppose 
https://issues.dlang.org/buglist.cgi?bug_severity=enhancement_status=NEW_status=ASSIGNED_status=REOPENED=D_format=report-table_axis_field=bug_severity would be the place for an enhancement request?

Possibly related:
https://issues.dlang.org/show_bug.cgi?id=14191


On Wednesday, 2 August 2017 at 14:23:26 UTC, Arafel wrote:




What you are looking for is virtual static methods, and D 
doesn't have those. I don't know if there's a way to make it 
work with existing features.




Well, there are interesting things to do:

https://dpaste.dzfl.pl/ed826ae21473

I don't know if that's what one would call "virtual static", 
but I'd say it comes close...


Nifty, but still doesn't allow knowing the derived type B in the 
foo method of A, does it?


Re: Access derived type in baseclass static function template

2017-08-02 Thread Arafel via Digitalmars-d-learn




What you are looking for is virtual static methods, and D doesn't have 
those. I don't know if there's a way to make it work with existing 
features.




Well, there are interesting things to do:

https://dpaste.dzfl.pl/ed826ae21473

I don't know if that's what one would call "virtual static", but I'd say 
it comes close...


Re: Access derived type in baseclass static function template

2017-08-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/2/17 9:11 AM, Timoses wrote:
On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer wrote: 
Thanks for the reply!


Not sure I understand correctly, though.

interface I {}
class A : I {}

void test(T)(T t) if(is(T: I))
{ writeln(T.type.stringof); }

void main()
{
 A.test;
}

throws:
   Error: no property 'test' for type 'app.A'

which it of course does... test(A) makes no sense either.
I need to call it statically and want to know the derived class type in 
the base class (or interface) function template.


Is there a trick in your answer? : P


Sorry, I didn't read your original post thoroughly, you need an instance 
to make this work properly.


A a;
a.test; // should work

What you are looking for is virtual static methods, and D doesn't have 
those. I don't know if there's a way to make it work with existing features.


However, your original code has potential as an enhancement request, as 
the type is known at compile-time and could certainly be resolved to 
pass in as the `this` template parameter.


-Steve


Re: Access derived type in baseclass static function template

2017-08-02 Thread Arafel via Digitalmars-d-learn

On 08/02/2017 02:07 PM, Timoses wrote:

Hey,

wondering whether it's possible to access the derived type from a 
function template in the base class or interface.


this T does not seem to be working, I guess because it's a static 
function and this does not exists?!





[...]



Any way I could accomplish this?


Well, it's a clumsy workaround, but the only thing missing seems to be 
the "this T" automatic deduction. I was recently hit by something 
similar: the "this" parameter deduction only works for instance methods.


It was not totally clear if it was a bug or a feature... The 
documentation [1] is however quite clear:


TemplateThisParameters are used in member function templates to pick up the type of the this reference. 


So, static functions doesn't seem to be covered.

You can, however, make it explicit:

```
B.test!B();
C.test!C();
```

And then even alias it to prevent accidental mismatches:

```
import std.stdio;

interface I
{
static void test(this T)()
{
writeln(T.type.stringof);
}
}

abstract class A
{
static void test(this T)()
{
writeln(T.type.stringof);
}
}

class B : A
{
alias type = uint;
}
class C : I {
alias type = int;
}

void main() {
test!B();
test!C();
}

alias test(T) = T.test!T;
```

[1]: http://dlang.org/spec/template.html#TemplateThisParameter


Re: Access derived type in baseclass static function template

2017-08-02 Thread Timoses via Digitalmars-d-learn
On Wednesday, 2 August 2017 at 12:49:12 UTC, Steven Schveighoffer 
wrote:

On 8/2/17 8:07 AM, Timoses wrote:

Hey,

wondering whether it's possible to access the derived type 
from a function template in the base class or interface.


this T does not seem to be working, I guess because it's a 
static function and this does not exists?!


Yep.


Any way I could accomplish this?


Move test outside the interface:

void test(C)(C c) if(is(C : I))
{
   writeln(C.type.stringof);
}

Though, at that point, you don't need I. I'm assuming you have 
a more complex real-world example.


-Steve


Thanks for the reply!

Not sure I understand correctly, though.

interface I {}
class A : I {}

void test(T)(T t) if(is(T: I))
{ writeln(T.type.stringof); }

void main()
{
A.test;
}

throws:
  Error: no property 'test' for type 'app.A'

which it of course does... test(A) makes no sense either.
I need to call it statically and want to know the derived class 
type in the base class (or interface) function template.


Is there a trick in your answer? : P


Re: Access derived type in baseclass static function template

2017-08-02 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/2/17 8:07 AM, Timoses wrote:

Hey,

wondering whether it's possible to access the derived type from a 
function template in the base class or interface.


this T does not seem to be working, I guess because it's a static 
function and this does not exists?!


Yep.


Any way I could accomplish this?


Move test outside the interface:

void test(C)(C c) if(is(C : I))
{
   writeln(C.type.stringof);
}

Though, at that point, you don't need I. I'm assuming you have a more 
complex real-world example.


-Steve


Access derived type in baseclass static function template

2017-08-02 Thread Timoses via Digitalmars-d-learn

Hey,

wondering whether it's possible to access the derived type from a 
function template in the base class or interface.


this T does not seem to be working, I guess because it's a static 
function and this does not exists?!



interface I
{
static void test(this T)()
{
writeln(T.type.stringof);
}
}

abstract class A
{
static void test(this T)()
{
writeln(T.type.stringof);
}
}

class B : A
{
alias type = uint;
}
class C : I {
alias type = int;
}

void main() {
B.test();
C.test();
}

Throws:
Error: template app.A.test cannot deduce function from argument 
types !()(), candidates are:

app.A.test(this T)()
Error: template app.I.test cannot deduce function from argument 
types !()(), candidates are:

app.I.test(this T)()


Any way I could accomplish this?


Re: Getting most derived type of object that implements interface

2016-07-25 Thread cc via Digitalmars-d-learn

Ahh I see, thanks guys.


Re: Getting most derived type of object that implements interface

2016-07-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 7/25/16 5:54 AM, Kagamin wrote:

Cast it to Object:
FooInterface a = new BarImplementsInterface();
FooBaseClass b = new BarDerivedClass();
Object o = cast(Object)a;
writefln("a class: %s", a.classinfo.name);
writefln("b class: %s", b.classinfo.name);
writefln("o class: %s", o.classinfo.name);


Yes, for the unrelated reason that COM objects may not be D objects, 
interfaces that can only possibly be D Objects don't implicitly cast to 
Object.


-Steve


Re: Getting most derived type of object that implements interface

2016-07-25 Thread ketmar via Digitalmars-d-learn
yep, cast it. without the cast, compiler assuming that it knows 
the type in runtime, and is using well-known classinfo address 
instead of really looking into instance for that.


Re: Getting most derived type of object that implements interface

2016-07-25 Thread Kagamin via Digitalmars-d-learn

Cast it to Object:
FooInterface a = new BarImplementsInterface();
FooBaseClass b = new BarDerivedClass();
Object o = cast(Object)a;
writefln("a class: %s", a.classinfo.name);
writefln("b class: %s", b.classinfo.name);
writefln("o class: %s", o.classinfo.name);


Getting most derived type of object that implements interface

2016-07-25 Thread cc via Digitalmars-d-learn
I'm having trouble getting the full name of an object of a class 
that implements an interface, using typeid() or .classinfo, the 
behavior seems to be different from that of a class that simply 
derives other classes.


interface FooInterface {}
class BarImplementsInterface : FooInterface {}

class FooBaseClass {}
class BarDerivedClass : FooBaseClass {}

void main() {
FooInterface a = new BarImplementsInterface();
FooBaseClass b = new BarDerivedClass();
writefln("a class: %s", a.classinfo.name);
writefln("b class: %s", b.classinfo.name);
}

Output:
a class: test.FooInterface
b class: test.BarDerivedClass


I expected "a class: test.BarImplementsInterface" as the result 
output.. Am I expecting the wrong behavior?  Is there a preferred 
way to do this?


Re: Cannot implicitly convert derived type

2014-02-23 Thread Frustrated

On Sunday, 23 February 2014 at 01:37:08 UTC, Steven Schveighoffer
wrote:
On Sat, 22 Feb 2014 15:17:37 -0500, Frustrated 
c1514...@drdrb.com wrote:



It is legal exactly because I will always guarantee that the
proper button will be used.


Static typing says it's not legal. D does not do dynamic type 
checking upon calling virtual functions.



It is not logically legal as mentioned several times... no one
needs to mention that. But it is legal within the context of 
the

code. I'll never use a RogueButton so why force me to code for
the chance I might?


You may not be the only one using WindowsGui. You can't 
guarantee other code won't do it. In any case, the compiler 
cannot possibly know your intentions.


Basically, the point is, the compiler could enforce the above 
but

make the code more readable.

e.g.,

I do this:

@property WindowsButton button(WindowsButton b)
{

}

The compiler turns this into

@property WindowsButton button(iButton _b)
{
if (is(_b : WindowsButton)) assert(0, Rogue button used);
auto b = cast(WindowsButton)_b;

}


This solution is not as efficient as the one I outlined. If you 
have a WindowsGui object, no need to accept iButton when you 
require WindowsButton.



One allows me to program in a natural way while the other makes
me jump through hoops which litters the code with a bunch of
casts and checks which are only there in the odd event that I
assign the wrong type(which, I'm not going to do on purpose).


Sorry, if you want a dynamically typed language, use one. D is 
not that.


Again, the whole point of why it is illegal because you can 
pass

a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could
absolutely guarantee that I won't pass them then there should 
be

no problem(no asserts). Since I can't guarantee it I have to
litter my code with checks? The compiler could do this for me.


You can't guarantee it. That is the point. The compiler could 
do the checks for you, but D is not dynamically typed. The best 
you can do is encapsulate the type checking code as a mixin.


-Steve



It has nothing to do with being dynamically typed. We can't solve
this problem until you get your head out of the gutter(the gutter
being how D does things already. Can't make progress on something
if you ever look beyond what it can do).

This has to do with simply adding checks to enforce the type. I
can guarantee it, but like you said, I can't guarantee what
others do. Hence the check.

The fact is, I presented two versions of the code. One represents
the other. It is a representational problem, nothing more,
nothing less. Please understand that from now on.

e.g., a switch statement is just a representational form of if
statements to simplify. I'll I'm talking about is adding a switch
statement. (if you take that literal and can't see how it relates
to the original problem then you are completely missing the point
of the whole discussion)

I did think it might be possible to use CT reflection to generate 
all the type checking automatically but this might be difficult 
and would have to generate a new class. It seems like the only 
way to get at this problem in D.


Re: Cannot implicitly convert derived type

2014-02-23 Thread Jesse Phillips

On Saturday, 22 February 2014 at 20:17:37 UTC, Frustrated wrote:

I do this:

@property WindowsButton button(WindowsButton b)
{

}

The compiler turns this into

@property WindowsButton button(iButton _b)
{
if (is(_b : WindowsButton)) assert(0, Rogue button used);
auto b = cast(WindowsButton)_b;

}


Why does your WindowsGui violate the iGui contract?


Re: Cannot implicitly convert derived type

2014-02-23 Thread Frustrated

On Sunday, 23 February 2014 at 20:41:30 UTC, Jesse Phillips wrote:

On Saturday, 22 February 2014 at 20:17:37 UTC, Frustrated wrote:

I do this:

@property WindowsButton button(WindowsButton b)
{

}

The compiler turns this into

@property WindowsButton button(iButton _b)
{
   if (is(_b : WindowsButton)) assert(0, Rogue button used);
   auto b = cast(WindowsButton)_b;

}


Why does your WindowsGui violate the iGui contract?


It doesn't. It simply that one can't specify dependencies in D

if (iGui is WindowsGui) then iButton is WindowsButton;

It's not very hard logic but people are not even trying.

I am attempting to make a mixin to solve the problem. The mixin
will simply overload all methods in the derived class(WindowsGui)
and when WindowsButton is used it will create an overload using
iButton(to satisfy the interface) with the check to make sure the
iButton is a WindowsButton.

It will give me what I want except I have to create the mixin and
then insert it in all the classes. (In theory though it should
not add any overhead is used where it is not suppose to)

But unfortunately when I try to find all members that use
WindowsButton(or whatever) to be able to create the new overload,
I get error due to the inner foreach.

foreach (am; __traits(derivedMembers, B))
foreach (m; [__traits(getOverloads, B, am)])
{
 // check if method contains an
parameter of type WindowsButton, then create identical method
definition that uses iButton instead. Put a check in the method
and call this method using a cast. This essentially overrides the
virtual method satisfying the interface but passes the work to
the user defined method.
}

What the above code will do, when working, is create the verbose
code you quoted from the first case:

@property WindowsButton button(WindowsButton b)
{
}

The ***mixin*** turns **ADDS** this

@property WindowsButton button(iButton _b)
{
if (is(_b : WindowsButton)) assert(0, Rogue button used);
auto b = cast(WindowsButton)_b;
button(b); // Call the user defined function here(hopefully)
}


Re: Cannot implicitly convert derived type

2014-02-23 Thread Jesse Phillips

On Sunday, 23 February 2014 at 21:06:03 UTC, Frustrated wrote:

Why does your WindowsGui violate the iGui contract?


It doesn't. It simply that one can't specify dependencies in D

if (iGui is WindowsGui) then iButton is WindowsButton;

It's not very hard logic but people are not even trying.


I understand what you intend your code to do, but that is still 
breaking the contract which you setup. iGui takes an iButton 
because you defined it that way, to only handle specific types of 
iButton is a breach of contract. The language lets you break 
contracts, but it should not help you do so.




Re: Cannot implicitly convert derived type

2014-02-23 Thread Frustrated

On Sunday, 23 February 2014 at 23:14:24 UTC, Jesse Phillips wrote:

On Sunday, 23 February 2014 at 21:06:03 UTC, Frustrated wrote:

Why does your WindowsGui violate the iGui contract?


It doesn't. It simply that one can't specify dependencies in D

if (iGui is WindowsGui) then iButton is WindowsButton;

It's not very hard logic but people are not even trying.


I understand what you intend your code to do, but that is still 
breaking the contract which you setup. iGui takes an iButton 
because you defined it that way, to only handle specific types 
of iButton is a breach of contract. The language lets you break 
contracts, but it should not help you do so.


Nope. It has nothing to do with the contract. You are totally
missing the point.

It is all about reducing typing a bunch of extra shit. Don't know
why you can't see that.

In any case once I get the mixin in finish it will do what I want
and be good enough.

IF the damn language had the ability to specify dependencies then
it wouldn't be a problem. Just because you insist on using D's
current model as the only model you will always be right... I
hope that makes you happy. In the mean time I'll be moving on to
writing cleaner code...


Re: Cannot implicitly convert derived type

2014-02-23 Thread Jesse Phillips

On Sunday, 23 February 2014 at 23:23:07 UTC, Frustrated wrote:

Nope. It has nothing to do with the contract. You are totally
missing the point.


iGui has a function which takes any iButton. That is a defined 
contract of iGui, your denial does not change that.


Re: Cannot implicitly convert derived type

2014-02-23 Thread Jesse Phillips

On Monday, 24 February 2014 at 00:09:55 UTC, Jesse Phillips wrote:

On Sunday, 23 February 2014 at 23:23:07 UTC, Frustrated wrote:

Nope. It has nothing to do with the contract. You are totally
missing the point.


iGui has a function which takes any iButton. That is a defined 
contract of iGui, your denial does not change that.


Let me put this another way. I started with the question of why 
you need to break the contract you define. In other words, What 
is the problem you are trying to solve. But instead you insisted 
the it must be solved this way instead of giving details on 
what the problem actually is.


D already provides a way to say that WindowsGui only takes 
WindowsButtons, you did so in your original code, just don't 
extend iGui since that isn't the contract you fulfill.


Re: Cannot implicitly convert derived type

2014-02-23 Thread Steven Schveighoffer

On Sun, 23 Feb 2014 08:26:10 -0500, Frustrated c1514...@drdrb.com wrote:


It has nothing to do with being dynamically typed. We can't solve
this problem until you get your head out of the gutter(the gutter
being how D does things already. Can't make progress on something
if you ever look beyond what it can do).


You have a nasty habit of assuming people do not know as much as you.

Bottom line, I get what you are asking, always have. It could be done, but  
D won't do it for you, nor will it be modified to do that. The costs of  
additional runtime type checks are far too great to implicitly add them.  
Use mixin generation, and be done with it.


-Steve


Re: Cannot implicitly convert derived type

2014-02-22 Thread Frustrated

On Saturday, 22 February 2014 at 01:03:22 UTC, Steven
Schveighoffer wrote:
On Fri, 21 Feb 2014 17:54:06 -0500, Frustrated 
c1514...@drdrb.com wrote:



interface iGui
{
@property iButton button(ref iButton button);
}

class WindowsGui : iGui
{
WindowsButton _button;

@property WindowsButton button(ref WindowsButton button)
//@property iButton button(ref iButton button)
{
_button = button;
return button;
}
}

interface iButton { }
class WindowsButton : iButton { }


Should this not work?


What you are trying to do is not legal.

e.g.:

class RogueButton : iButton { }

iGui gui = new WindowsGui;
gui.button = new RogueButton;

Note that setting gui.button to any iButton is legal, but the 
derived type REQUIRES a WindowsButton. This would have to be 
rejected at runtime, because the compile-time type is 
implicitly convertible.


There are two types of variance that are logical, 
contravariance and covariance. covariance allows you to 
*return* a more derived type than the base. In other words, 
this would be legal (assume same iButton/WindowsButton 
structure):


interface iGui
{
@property iButton button();
}

class WindowsGui : iGui
{
@property WindowsButton button() {...};
}

This works, because whenever you return a WindowsButton, you 
ALSO are returning an iButton. In fact, D supports this.


The opposite is contravariance, and that's used on *input* 
parameters. In this case, the derived method can accept a base 
of the parameter that the base class defines:


interface iGui
{
   void button(WindowsButton); // please humor me, I know you 
don't want to do this :)

}

class WindowsGui : iGui
{
   void button(iButton);
}

This is logically sound, because the actual implementation only 
requires an iButton. Therefore, passing a WindowsButton into 
the iGui interface still satisfies that requirement.


However, D does NOT support contravariance.


2. In the second case, I can cast to make everything work. This
seems wrong. Hence goto 1. WindowsGui is designed to only work
with WindowsButton, say, and I should never have to use iButton
in the WindowsGui class unless, maybe, I want to support
non-windows buttons in the WindowsGui for some reason.


This is actually the correct mechanism if you want to use 
polymorphism. However, in some cases, a templated system may be 
more advantageous than an interface system.


One other possibility is to use overloading -- i.e.:

class WindowsGui
{
   @property WindowsButton button(WindowsButton b) { return 
_button = b;}


   @property WindowsButton button(iButton b)
   {
   if(auto wb = cast(WindowsButton)b)
   button = wb;
   else
   throw new ButtonException;
   }
}

This is not really an attractive solution, but it could be 
easily generated as a mixed-in solution.


-Steve



It is legal exactly because I will always guarantee that the
proper button will be used.

It is not logically legal as mentioned several times... no one
needs to mention that. But it is legal within the context of the
code. I'll never use a RogueButton so why force me to code for
the chance I might?

Again,

WindowsGui only uses WindowsButton which is a iButton type. So
why force me to always use iButton and cast it to WindowsButton?
Why can't I relax the condition to use the base type?

The only reason it is illegal is because I could use a
RogueButton, BUT I WON'T! If I do, then it is an error.

Basically, the point is, the compiler could enforce the above but
make the code more readable.

e.g.,

I do this:

@property WindowsButton button(WindowsButton b)
{

}

The compiler turns this into

@property WindowsButton button(iButton _b)
{
if (is(_b : WindowsButton)) assert(0, Rogue button used);
auto b = cast(WindowsButton)_b;

}


One is very clean, the other is not. If by chance I use the wrong
button(a Rogue button) then it results in an error(hopefully user
controlled).

One allows me to program in a natural way while the other makes
me jump through hoops which litters the code with a bunch of
casts and checks which are only there in the odd event that I
assign the wrong type(which, I'm not going to do on purpose).

Again, the whole point of why it is illegal because you can pass
a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could
absolutely guarantee that I won't pass them then there should be
no problem(no asserts). Since I can't guarantee it I have to
litter my code with checks? The compiler could do this for me.




Re: Cannot implicitly convert derived type

2014-02-22 Thread Frustrated

On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote:

Generic?



I don't see how this would help. I'd have to specify every
concrete type in the creation of the object which might be
significant. I can't use a generic virtual method so that doesn't
help either.

It would be nice to have something like

T foo(T : iButton)(T button);

Which then I override with

WindowsButton foo(WindowsButton button) { }

Since WindowsButton is derived from iButton. The compiler would
have to insert a type check to make sure when I called the first
one(from the interface) that it was a windows button that was
passed(since any iButton could be passed) when using the
WindowsGui.

The main point of all this is simply efficiency. I have to liter
the code with checks and casts when it is entirely possible to
get the compiler to automate it all. By doing so one can program
the concrete class in a much more natural way.




Re: Cannot implicitly convert derived type

2014-02-22 Thread Steven Schveighoffer

On Sat, 22 Feb 2014 15:17:37 -0500, Frustrated c1514...@drdrb.com wrote:


It is legal exactly because I will always guarantee that the
proper button will be used.


Static typing says it's not legal. D does not do dynamic type checking  
upon calling virtual functions.



It is not logically legal as mentioned several times... no one
needs to mention that. But it is legal within the context of the
code. I'll never use a RogueButton so why force me to code for
the chance I might?


You may not be the only one using WindowsGui. You can't guarantee other  
code won't do it. In any case, the compiler cannot possibly know your  
intentions.



Basically, the point is, the compiler could enforce the above but
make the code more readable.

e.g.,

I do this:

@property WindowsButton button(WindowsButton b)
{

}

The compiler turns this into

@property WindowsButton button(iButton _b)
{
 if (is(_b : WindowsButton)) assert(0, Rogue button used);
 auto b = cast(WindowsButton)_b;

}


This solution is not as efficient as the one I outlined. If you have a  
WindowsGui object, no need to accept iButton when you require  
WindowsButton.



One allows me to program in a natural way while the other makes
me jump through hoops which litters the code with a bunch of
casts and checks which are only there in the odd event that I
assign the wrong type(which, I'm not going to do on purpose).


Sorry, if you want a dynamically typed language, use one. D is not that.


Again, the whole point of why it is illegal because you can pass
a RogueButton... BUT I DON'T INTEND TO PASS THEM! If I could
absolutely guarantee that I won't pass them then there should be
no problem(no asserts). Since I can't guarantee it I have to
litter my code with checks? The compiler could do this for me.


You can't guarantee it. That is the point. The compiler could do the  
checks for you, but D is not dynamically typed. The best you can do is  
encapsulate the type checking code as a mixin.


-Steve


Re: Cannot implicitly convert derived type

2014-02-22 Thread Ali Çehreli

On 02/22/2014 12:17 PM, Frustrated wrote:

 Again, the whole point of why it is illegal because you can pass
 a RogueButton... BUT I DON'T INTEND TO PASS THEM!

Thinking that way, many rules of a statically type-checked language like 
D would be unnecessary. ;)


 WindowsGui only uses WindowsButton which is a iButton type.

WindowsGui is totally free to use any type it wants. However, it cannot 
both claim to implement an interface without actually obeying its 
requirements.


 Why can't I relax the condition to use the base type?

The users of iGui don't even know what a WindowsButton is:

interface iGui
{
@property iButton button(ref iButton button);
}

Imagine the following that I write:

void foo(WindowsGui gui, iButton b)
{
gui.button(b);
}

Is the call legal or not? How would I know and why should I care? I have 
a WindowsGui, which happens to be an iGui and I have an iButton. 
According to the contract of the interface I should be able to call it 
without fear of type problems.


Even, I can create my own iButton and pass it to that WindowsGui:

gui.button(new MyButton());

I should be able to do all of that just because WindowsGui promises to 
be an iGui.


Getting back to what I said above: WindowsGui is totally free to use any 
type it wants. That's why both Steven and I made it take its button as a 
constructor parameter. Then, you also mentioned a setter. That's fine 
too. As long as WindowsGui allows me to give it an iButton when I call 
button(), it is all fine.


Ali



Re: Cannot implicitly convert derived type

2014-02-22 Thread Eric Suen
interface iButton { }

class WindowsButton : iButton { }

interface iGui(T)
{
@property T button(ref T button);
}

class WindowsGui : iGui!(WindowsButton)
{
 @property WindowsButton button(ref WindowsButton button) {
  return button;
 }
}

Frustrated c1514...@drdrb.com
 On Saturday, 22 February 2014 at 05:20:25 UTC, Eric Suen wrote:
 Generic?


 I don't see how this would help. I'd have to specify every
 concrete type in the creation of the object which might be
 significant. I can't use a generic virtual method so that doesn't
 help either.

 It would be nice to have something like

 T foo(T : iButton)(T button);

 Which then I override with

 WindowsButton foo(WindowsButton button) { }

 Since WindowsButton is derived from iButton. The compiler would
 have to insert a type check to make sure when I called the first
 one(from the interface) that it was a windows button that was
 passed(since any iButton could be passed) when using the
 WindowsGui.

 The main point of all this is simply efficiency. I have to liter
 the code with checks and casts when it is entirely possible to
 get the compiler to automate it all. By doing so one can program
 the concrete class in a much more natural way.

 




Cannot implicitly convert derived type

2014-02-21 Thread Frustrated

interface iGui
{
@property iButton button(ref iButton button);
}

class WindowsGui : iGui
{
WindowsButton _button;

@property WindowsButton button(ref WindowsButton button)
//@property iButton button(ref iButton button)
{
_button = button;
return button;
}
}

interface iButton { }
class WindowsButton : iButton { }


Should this not work?

Error: class main.WindowsGui interface function 'iButton
button(ref iButton
button) @property' is not implemented   

Or by using the commented line:

Error: cannot implicitly convert expression (button) of type
main.iButton to main.WindowsButton  


1. In the first case I override a property using a more derived
type. This should work but doesn't. Seems D doens't support
covariance properly?

2. In the second case, I can cast to make everything work. This
seems wrong. Hence goto 1. WindowsGui is designed to only work
with WindowsButton, say, and I should never have to use iButton
in the WindowsGui class unless, maybe, I want to support
non-windows buttons in the WindowsGui for some reason.

Basically, because of the covariance issue I end up having to use
a lot of casts. Hopefully theres some simple trick that won't
pollute the code to make this work. I guess I could use a
templated property with a generic type that is derivable from
iButton to make it work?

In some sense I can understand the error. If I'm using iGui then
I have the option to use any button(since it is generic) but if
iGui is a WindowsGui I'm not allowing this. The issue is, that I
will have some type of dependency restrictions on the types.

e.g.,

iGui g = new WindowsGui;

g.button = new LinuxButton; // ok but not ok!! (should result in
an error in some way)

Obviously I can cast and check the type and do all that. Just
feels like the wrong way to go about it because it requires a lot
of casting and polluting the code with checks that in general,
should be unnecessary. Again: In the WindowsGui I want to use
WindowsButton, not iButton because WindowsGui will never need any
other type of button. iButton is too general to use in WindowsGui.

(it would be cool if one could do something like

class WindowsGui : iGui
iButton = WindowsButton // constrains iButton to always be a
WindowsButton. Checks/casts are automatically added by compiler
when necessary
{
// use WindowsButton here with proper covariance relations and
checks/casts
}

Anyways, hopefully there is some single trick to get what I'm
asking?


Re: Cannot implicitly convert derived type

2014-02-21 Thread Ali Çehreli

On 02/21/2014 02:54 PM, Frustrated wrote:

interface iGui
{
 @property iButton button(ref iButton button);
}

class WindowsGui : iGui
{
 WindowsButton _button;

 @property WindowsButton button(ref WindowsButton button)
 //@property iButton button(ref iButton button)
 {
 _button = button;
 return button;
 }
}

interface iButton { }
class WindowsButton : iButton { }


Should this not work?

Error: class main.WindowsGui interface function 'iButton
button(ref iButton
button) @property' is not implemented

Or by using the commented line:

Error: cannot implicitly convert expression (button) of type
main.iButton to main.WindowsButton


1. In the first case I override a property using a more derived
type. This should work but doesn't. Seems D doens't support
covariance properly?

2. In the second case, I can cast to make everything work. This
seems wrong. Hence goto 1. WindowsGui is designed to only work
with WindowsButton, say, and I should never have to use iButton
in the WindowsGui class unless, maybe, I want to support
non-windows buttons in the WindowsGui for some reason.

Basically, because of the covariance issue I end up having to use
a lot of casts. Hopefully theres some simple trick that won't
pollute the code to make this work. I guess I could use a
templated property with a generic type that is derivable from
iButton to make it work?

In some sense I can understand the error. If I'm using iGui then
I have the option to use any button(since it is generic) but if
iGui is a WindowsGui I'm not allowing this. The issue is, that I
will have some type of dependency restrictions on the types.

e.g.,

iGui g = new WindowsGui;

g.button = new LinuxButton; // ok but not ok!! (should result in
an error in some way)

Obviously I can cast and check the type and do all that. Just
feels like the wrong way to go about it because it requires a lot
of casting and polluting the code with checks that in general,
should be unnecessary. Again: In the WindowsGui I want to use
WindowsButton, not iButton because WindowsGui will never need any
other type of button. iButton is too general to use in WindowsGui.

(it would be cool if one could do something like

class WindowsGui : iGui
 iButton = WindowsButton // constrains iButton to always be a
WindowsButton. Checks/casts are automatically added by compiler
when necessary
{
 // use WindowsButton here with proper covariance relations and
checks/casts
}

Anyways, hopefully there is some single trick to get what I'm
asking?


It should not work because the derived type is requiring more than the 
interface. iGui requires that the parameter to button() is iButton:


@property iButton button(ref iButton button);

However, WindowsGui is bringing an extra requirement by asking a more 
specific iButton:


@property WindowsButton button(ref WindowsButton button)

Note that there is no problem with the return type because this time the 
derived type is still returning an iButton because WindowsButton is an 
iButton.


I don't know whether this works for you but I made the actual button a 
constructor parameter:


interface iGui
{
@property iButton button();
}

class WindowsGui : iGui
{
WindowsButton _button;

// The constructor gets the button
this(WindowsButton button)
{
this._button = button;
}

@property WindowsButton button()
{
return _button;
}
}

interface iButton { }
class WindowsButton : iButton { }

void main()
{
auto w = new WindowsGui(new WindowsButton());
w.button;
}

Ali



Re: Cannot implicitly convert derived type

2014-02-21 Thread Frustrated

On Friday, 21 February 2014 at 23:19:19 UTC, Ali Çehreli wrote:

On 02/21/2014 02:54 PM, Frustrated wrote:

interface iGui
{
@property iButton button(ref iButton button);
}

class WindowsGui : iGui
{
WindowsButton _button;

@property WindowsButton button(ref WindowsButton button)
//@property iButton button(ref iButton button)
{
_button = button;
return button;
}
}

interface iButton { }
class WindowsButton : iButton { }


Should this not work?

Error: class main.WindowsGui interface function 'iButton
button(ref iButton
button) @property' is not implemented

Or by using the commented line:

Error: cannot implicitly convert expression (button) of type
main.iButton to main.WindowsButton


1. In the first case I override a property using a more derived
type. This should work but doesn't. Seems D doens't support
covariance properly?

2. In the second case, I can cast to make everything work. This
seems wrong. Hence goto 1. WindowsGui is designed to only work
with WindowsButton, say, and I should never have to use iButton
in the WindowsGui class unless, maybe, I want to support
non-windows buttons in the WindowsGui for some reason.

Basically, because of the covariance issue I end up having to 
use

a lot of casts. Hopefully theres some simple trick that won't
pollute the code to make this work. I guess I could use a
templated property with a generic type that is derivable from
iButton to make it work?

In some sense I can understand the error. If I'm using iGui 
then

I have the option to use any button(since it is generic) but if
iGui is a WindowsGui I'm not allowing this. The issue is, that 
I

will have some type of dependency restrictions on the types.

e.g.,

iGui g = new WindowsGui;

g.button = new LinuxButton; // ok but not ok!! (should result 
in

an error in some way)

Obviously I can cast and check the type and do all that. Just
feels like the wrong way to go about it because it requires a 
lot

of casting and polluting the code with checks that in general,
should be unnecessary. Again: In the WindowsGui I want to use
WindowsButton, not iButton because WindowsGui will never need 
any
other type of button. iButton is too general to use in 
WindowsGui.


(it would be cool if one could do something like

class WindowsGui : iGui
iButton = WindowsButton // constrains iButton to always 
be a

WindowsButton. Checks/casts are automatically added by compiler
when necessary
{
// use WindowsButton here with proper covariance relations 
and

checks/casts
}

Anyways, hopefully there is some single trick to get what I'm
asking?


It should not work because the derived type is requiring more 
than the interface. iGui requires that the parameter to 
button() is iButton:


@property iButton button(ref iButton button);

However, WindowsGui is bringing an extra requirement by asking 
a more specific iButton:


@property WindowsButton button(ref WindowsButton button)

Note that there is no problem with the return type because this 
time the derived type is still returning an iButton because 
WindowsButton is an iButton.


I don't know whether this works for you but I made the actual 
button a constructor parameter:


interface iGui
{
@property iButton button();
}

class WindowsGui : iGui
{
WindowsButton _button;

// The constructor gets the button
this(WindowsButton button)
{
this._button = button;
}

@property WindowsButton button()
{
return _button;
}
}

interface iButton { }
class WindowsButton : iButton { }

void main()
{
auto w = new WindowsGui(new WindowsButton());
w.button;
}

Ali


But what about a setter? Using DI isn't the way to go here.

The point that in the windows class, it will only ever use a
windows button. This is fine, but because I'm using
iGui(programming to interfaces), it causes a problem inside the
windows class, which it shouldn't.

e.g., if I only had one gui and used one class, then there would
never be a problem.

Also, it is not a problem of construct, I already have a solution
by casting. But casting hides the fact that windowsgui is meant
to use only a windows button... which is obvious in the design.


Again

iGui uses an iButton
WindowsGui uses a WindowsButton

But when iGui is an actual WindowsGui, it forces WindowsGui to be
more generic than it is meant to be.

The key piece of information here is that I will only ever use
WindowsButtons with WindowsGui... this fact is not general and
the reason the compiler throws the error BUT it is always the
case in my code(except in errors).

I need to inform the compiler that it is always the case and then
I can do what I want.




Re: Cannot implicitly convert derived type

2014-02-21 Thread Steven Schveighoffer

On Fri, 21 Feb 2014 17:54:06 -0500, Frustrated c1514...@drdrb.com wrote:


interface iGui
{
@property iButton button(ref iButton button);
}

class WindowsGui : iGui
{
WindowsButton _button;

@property WindowsButton button(ref WindowsButton button)
//@property iButton button(ref iButton button)
{
_button = button;
return button;
}
}

interface iButton { }
class WindowsButton : iButton { }


Should this not work?


What you are trying to do is not legal.

e.g.:

class RogueButton : iButton { }

iGui gui = new WindowsGui;
gui.button = new RogueButton;

Note that setting gui.button to any iButton is legal, but the derived type  
REQUIRES a WindowsButton. This would have to be rejected at runtime,  
because the compile-time type is implicitly convertible.


There are two types of variance that are logical, contravariance and  
covariance. covariance allows you to *return* a more derived type than the  
base. In other words, this would be legal (assume same  
iButton/WindowsButton structure):


interface iGui
{
@property iButton button();
}

class WindowsGui : iGui
{
@property WindowsButton button() {...};
}

This works, because whenever you return a WindowsButton, you ALSO are  
returning an iButton. In fact, D supports this.


The opposite is contravariance, and that's used on *input* parameters. In  
this case, the derived method can accept a base of the parameter that the  
base class defines:


interface iGui
{
   void button(WindowsButton); // please humor me, I know you don't want  
to do this :)

}

class WindowsGui : iGui
{
   void button(iButton);
}

This is logically sound, because the actual implementation only requires  
an iButton. Therefore, passing a WindowsButton into the iGui interface  
still satisfies that requirement.


However, D does NOT support contravariance.


2. In the second case, I can cast to make everything work. This
seems wrong. Hence goto 1. WindowsGui is designed to only work
with WindowsButton, say, and I should never have to use iButton
in the WindowsGui class unless, maybe, I want to support
non-windows buttons in the WindowsGui for some reason.


This is actually the correct mechanism if you want to use polymorphism.  
However, in some cases, a templated system may be more advantageous than  
an interface system.


One other possibility is to use overloading -- i.e.:

class WindowsGui
{
   @property WindowsButton button(WindowsButton b) { return _button = b;}

   @property WindowsButton button(iButton b)
   {
   if(auto wb = cast(WindowsButton)b)
   button = wb;
   else
   throw new ButtonException;
   }
}

This is not really an attractive solution, but it could be easily  
generated as a mixed-in solution.


-Steve


Re: Cannot implicitly convert derived type

2014-02-21 Thread Eric Suen
Generic?

Frustrated c1514...@drdrb.com ...
 interface iGui
 {
 @property iButton button(ref iButton button);
 }

 class WindowsGui : iGui
 {
 WindowsButton _button;

 @property WindowsButton button(ref WindowsButton button)
 //@property iButton button(ref iButton button)
 {
 _button = button;
 return button;
 }
 }

 interface iButton { }
 class WindowsButton : iButton { }


 Should this not work?

 Error: class main.WindowsGui interface function 'iButton
 button(ref iButton
 button) @property' is not implemented
 Or by using the commented line:

 Error: cannot implicitly convert expression (button) of type
 main.iButton to main.WindowsButton

 1. In the first case I override a property using a more derived
 type. This should work but doesn't. Seems D doens't support
 covariance properly?

 2. In the second case, I can cast to make everything work. This
 seems wrong. Hence goto 1. WindowsGui is designed to only work
 with WindowsButton, say, and I should never have to use iButton
 in the WindowsGui class unless, maybe, I want to support
 non-windows buttons in the WindowsGui for some reason.

 Basically, because of the covariance issue I end up having to use
 a lot of casts. Hopefully theres some simple trick that won't
 pollute the code to make this work. I guess I could use a
 templated property with a generic type that is derivable from
 iButton to make it work?

 In some sense I can understand the error. If I'm using iGui then
 I have the option to use any button(since it is generic) but if
 iGui is a WindowsGui I'm not allowing this. The issue is, that I
 will have some type of dependency restrictions on the types.

 e.g.,

 iGui g = new WindowsGui;

 g.button = new LinuxButton; // ok but not ok!! (should result in
 an error in some way)

 Obviously I can cast and check the type and do all that. Just
 feels like the wrong way to go about it because it requires a lot
 of casting and polluting the code with checks that in general,
 should be unnecessary. Again: In the WindowsGui I want to use
 WindowsButton, not iButton because WindowsGui will never need any
 other type of button. iButton is too general to use in WindowsGui.

 (it would be cool if one could do something like

 class WindowsGui : iGui
 iButton = WindowsButton // constrains iButton to always be a
 WindowsButton. Checks/casts are automatically added by compiler
 when necessary
 {
 // use WindowsButton here with proper covariance relations and
 checks/casts
 }

 Anyways, hopefully there is some single trick to get what I'm
 asking? 




Re: Tools for building a dynamic derived type? I need a push in the right direction.

2013-09-07 Thread Gary Willoughby

On Wednesday, 21 August 2013 at 03:37:46 UTC, Kapps wrote:
On Tuesday, 20 August 2013 at 18:55:44 UTC, Gary Willoughby 
wrote:
I've been researching ways to accomplish creating a template 
that creates a special kind of derived type and i think i need 
a push in the right direction. Take this simple class:


class Person
{
private string _name;
private int _age;

this(string name, int age)
{
this._name = name;
this._age  = age;
}

public string getName()
{
return this._name;
}

public int getAge()
{
return this._age;
}
}

I want to create a mock of this class which would mean 
achieving the following:


1). Extend the class
2). Override all public methods to do nothing (or look for 
enabled methods)
3). Provide a way of dynamically enabling methods with new 
return values


Extending the class is pretty easy and adding methods 
dynamically looks to be solved (TDPL 12.11.1) but it's the 
override all public methods to do something different which is 
beating me. I know it will probably involve mixins and dealing 
with tuples somewhere along the line but documentation is 
lacking everywhere i look.


std.traits gives me information about a type but using that 
information is where i need the documentation. e.g. i know the 
traits methods return tuples but how do you work with these 
tuples? how to Iterate through them? I seem to always get 
stuck when trying to iterate through tuples and generate 
compiler errors.


I've taken a look at the std.typecons source especially 
BlackHole and WhiteHole templates but i get lost. They are 
almost doing what i want but for abstract methods.


The general usage is probably going to be something like this:

class Mock(T) : T
{
   // Implementation
}

auto cat = Mock!Cat(Ginger); // constructors supported.

auto person = Mock!Person();

person.addMethod(getName, delegate(){
   return Foo;
});

person.addMethod(getAge, delegate(){
   return 10;
});

Any help will be greatly appreciated.


AutoImplement 
(http://dlang.org/phobos/std_typecons.html#.AutoImplement) from 
std.typecons should do what you want. Instead of implementing 
only abstract methods, you could make it implement all 
non-final methods by changing the 'what' template parameter to 
simply return true (final methods are skipped regardless). Then 
you could change the 'how' template parameter to return 
ReturnType!parent.init unless an argument is set in an AA. I 
can't say I've ever tried this though, so I'm not sure how well 
it would work in reality.


https://github.com/QAston/DMocks-revived may interest you as 
well.


Thanks that gave me a lot to work with! :)


Re: Tools for building a dynamic derived type? I need a push in the right direction.

2013-08-21 Thread Jacob Carlborg

On 2013-08-20 20:55, Gary Willoughby wrote:


The general usage is probably going to be something like this:

class Mock(T) : T
{
 // Implementation
}

auto cat = Mock!Cat(Ginger); // constructors supported.

auto person = Mock!Person();

person.addMethod(getName, delegate(){
 return Foo;
});

person.addMethod(getAge, delegate(){
 return 10;
});

Any help will be greatly appreciated.


I'm not exactly sure how you want it to work, but this is an idea:

Create and store an instance of T in Mock. Implement opDispatch in Mock 
and forward an methods added by addMethod to the delegate. If no 
delegate exists for that method forward to the instance of T instead.


http://dlang.org/operatoroverloading.html#Dispatch

--
/Jacob Carlborg


Tools for building a dynamic derived type? I need a push in the right direction.

2013-08-20 Thread Gary Willoughby
I've been researching ways to accomplish creating a template that 
creates a special kind of derived type and i think i need a push 
in the right direction. Take this simple class:


class Person
{
private string _name;
private int _age;

this(string name, int age)
{
this._name = name;
this._age  = age;
}

public string getName()
{
return this._name;
}

public int getAge()
{
return this._age;
}
}

I want to create a mock of this class which would mean achieving 
the following:


1). Extend the class
2). Override all public methods to do nothing (or look for 
enabled methods)
3). Provide a way of dynamically enabling methods with new return 
values


Extending the class is pretty easy and adding methods dynamically 
looks to be solved (TDPL 12.11.1) but it's the override all 
public methods to do something different which is beating me. I 
know it will probably involve mixins and dealing with tuples 
somewhere along the line but documentation is lacking everywhere 
i look.


std.traits gives me information about a type but using that 
information is where i need the documentation. e.g. i know the 
traits methods return tuples but how do you work with these 
tuples? how to Iterate through them? I seem to always get stuck 
when trying to iterate through tuples and generate compiler 
errors.


I've taken a look at the std.typecons source especially BlackHole 
and WhiteHole templates but i get lost. They are almost doing 
what i want but for abstract methods.


The general usage is probably going to be something like this:

class Mock(T) : T
{
// Implementation
}

auto cat = Mock!Cat(Ginger); // constructors supported.

auto person = Mock!Person();

person.addMethod(getName, delegate(){
return Foo;
});

person.addMethod(getAge, delegate(){
return 10;
});

Any help will be greatly appreciated.


Re: Tools for building a dynamic derived type? I need a push in the right direction.

2013-08-20 Thread Kapps

On Tuesday, 20 August 2013 at 18:55:44 UTC, Gary Willoughby wrote:
I've been researching ways to accomplish creating a template 
that creates a special kind of derived type and i think i need 
a push in the right direction. Take this simple class:


class Person
{
private string _name;
private int _age;

this(string name, int age)
{
this._name = name;
this._age  = age;
}

public string getName()
{
return this._name;
}

public int getAge()
{
return this._age;
}
}

I want to create a mock of this class which would mean 
achieving the following:


1). Extend the class
2). Override all public methods to do nothing (or look for 
enabled methods)
3). Provide a way of dynamically enabling methods with new 
return values


Extending the class is pretty easy and adding methods 
dynamically looks to be solved (TDPL 12.11.1) but it's the 
override all public methods to do something different which is 
beating me. I know it will probably involve mixins and dealing 
with tuples somewhere along the line but documentation is 
lacking everywhere i look.


std.traits gives me information about a type but using that 
information is where i need the documentation. e.g. i know the 
traits methods return tuples but how do you work with these 
tuples? how to Iterate through them? I seem to always get stuck 
when trying to iterate through tuples and generate compiler 
errors.


I've taken a look at the std.typecons source especially 
BlackHole and WhiteHole templates but i get lost. They are 
almost doing what i want but for abstract methods.


The general usage is probably going to be something like this:

class Mock(T) : T
{
// Implementation
}

auto cat = Mock!Cat(Ginger); // constructors supported.

auto person = Mock!Person();

person.addMethod(getName, delegate(){
return Foo;
});

person.addMethod(getAge, delegate(){
return 10;
});

Any help will be greatly appreciated.


AutoImplement 
(http://dlang.org/phobos/std_typecons.html#.AutoImplement) from 
std.typecons should do what you want. Instead of implementing 
only abstract methods, you could make it implement all non-final 
methods by changing the 'what' template parameter to simply 
return true (final methods are skipped regardless). Then you 
could change the 'how' template parameter to return 
ReturnType!parent.init unless an argument is set in an AA. I 
can't say I've ever tried this though, so I'm not sure how well 
it would work in reality.


https://github.com/QAston/DMocks-revived may interest you as well.