Re: Covariance for []

2023-01-19 Thread davemo via Digitalmars-d-learn

On Thursday, 19 January 2023 at 12:54:39 UTC, davemo wrote:

Hello, I was wondering why the following code does not compile.

```d
import std;

[...]


It looks like the following change works fine.

```d
Range!A as()
{
return wrap(_bs.map!((b) { return cast(A) b; }));
}
```


Covariance for []

2023-01-19 Thread davemo via Digitalmars-d-learn

Hello, I was wondering why the following code does not compile.

```d
import std;

abstract class Range(T)
{
abstract T back();
abstract bool empty();
abstract T front();
abstract void popBack();
abstract void popFront();
}

class RangeWrapper(TRange) : Range!(ForeachType!(TRange))
{
alias TValue = ForeachType!(TRange);

private TRange _range;

this(TRange range)
{
_range = range;
}

override TValue back()
{
return _range.back();
}

override bool empty()
{
return _range.empty();
}

override TValue front()
{
return _range.front();
}

override void popBack()
{
return _range.popBack();
}

override void popFront()
{
return _range.popFront();
}
}

auto wrap(TRange)(TRange range)
{
return new RangeWrapper!TRange(range);
}

class A
{
}

class B : A
{
}

class C : A
{
private B[] _bs;

this()
{
_bs = [new B(), new B()];
}

Range!A as()
{
return wrap(_bs);
}
}

void main()
{
}
```

I receive the following error.

```d
onlineapp.d(73): Error: cannot implicitly convert expression 
`wrap(this._bs)` of type `onlineapp.RangeWrapper!(B[])` to 
`onlineapp.Range!(A)`

```

Anyone have any idea how I can achieve 
[covariance](https://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)#Formal_definition) for `[]`?


Re: Non-covariance and overrides

2013-09-08 Thread Jacob Carlborg

On 2013-09-07 13:42, Joseph Rushton Wakeling wrote:

On 03/09/13 08:56, Jacob Carlborg wrote:

class MyFakeSubclass
{
 MyBaseClass base
 alias base this;
}

Every method not available in MyFakeSubclass will be forwarded to base.

http://dlang.org/class.html#AliasThis


OK, but the challenge of that approach is that base has to be public,
no? Otherwise, its methods will not be accessible outside the class
(even if the alias is itself public).

And that then allows problems inasmuch as the user could then do
something like,

 auto foo = new MyFakeSubclass;
 foo.base.bar();

... and so bypass the alias.



I haven't checked if base can be private or not. But if that doesn't 
work try opDispatch:


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

You have a public opDispatch and a private base.

--
/Jacob Carlborg


Re: Non-covariance and overrides

2013-09-07 Thread Joseph Rushton Wakeling

On 02/09/13 17:00, Joseph Rushton Wakeling wrote:

Is there any way to deal with this situation and simply insist that the
subclass's function definition replaces the base class's?


I'm sure I remember reading about some way to do this -- to completely replace a 
base class' method rather than override it -- but I can't for the life of me 
think where.  And now that I think about it, I can't remember if it was for D or 
for C++. :-(




Re: Non-covariance and overrides

2013-09-03 Thread Jacob Carlborg

On 2013-09-02 17:00, Joseph Rushton Wakeling wrote:


P.S. If I don't find a handy inheritance-based way to do this, what I'll
probably do is something along the lines of,

 class MyFakeSubclass
 {
 MyBaseClass base;

 // ... extra data ...

 // ... manually-written wrappers
 }


You can use a template mixin or alias this.

Template mixin:

template MyBaseClassMixin ()
{
void foo () { } // all your methods here
}

class MyFakeSubclass
{
mixin MyBaseClassMixin;
}

http://dlang.org/template-mixin.html

Or using alias this:

class MyFakeSubclass
{
MyBaseClass base
alias base this;
}

Every method not available in MyFakeSubclass will be forwarded to base.

http://dlang.org/class.html#AliasThis

--
/Jacob Carlborg


Non-covariance and overrides

2013-09-02 Thread Joseph Rushton Wakeling

Hello all,

In my graph library, I have a couple of different graph class implementations 
which, ideally, might better be implemented as a base class and a subclass.  The 
internal data storage of the latter is a superset of the other; many of the 
functions involve simply extra lines added to the code of what would be the base 
class.  See:

http://forum.dlang.org/post/mailman.587.1377784964.1719.digitalmars-d-le...@puremagic.com

... for some details.

However, while the essentials of the API are the same, some of the functions 
have different return types -- say, an array instead of a range.  This makes 
overrides impossible, as the different return types are not covariant (that is, 
one is not a subclass of the other).


Is there any way to deal with this situation and simply insist that the 
subclass's function definition replaces the base class's?  I'm not concerned 
about the sides of inheritance such as trying to disguise the subclass as an 
instance of the base class; it's fine that the API simply gets overwritten 
rather than overridden (if you get me).


Any ideas?

Thanks  best wishes,

-- Joe


P.S. If I don't find a handy inheritance-based way to do this, what I'll 
probably do is something along the lines of,


class MyFakeSubclass
{
MyBaseClass base;

// ... extra data ...

// ... manually-written wrappers
}


Automatic return type covariance for functions that return this?

2012-09-15 Thread Ben Davis

Hi,

Is it possible in D to achieve this effect:

class Super {
  typeof(this) doStuff() { ...; return this; }
}

class Sub : Super {
  //doStuff is NOT explicitly overridden here
}

Sub x = (new Sub()).doStuff();

The last line doesn't compile because doStuff() returns Super. Is there 
a way to make it return Sub without having to explicitly override the 
function?


Thanks in advance,

Ben :)


Re: Automatic return type covariance for functions that return this?

2012-09-15 Thread Ben Davis

Never mind, I found the answer in the 'templates' page of the spec:

class Super {
   T doStuff(this T)() { ...; return cast(T)this; }
}

Sub x = (new Sub()).doStuff();

It seems a bit of a shame that I need the cast, but it's a small thing :)

On 15/09/2012 22:53, Ben Davis wrote:

Hi,

Is it possible in D to achieve this effect:

class Super {
   typeof(this) doStuff() { ...; return this; }
}

class Sub : Super {
   //doStuff is NOT explicitly overridden here
}

Sub x = (new Sub()).doStuff();

The last line doesn't compile because doStuff() returns Super. Is there
a way to make it return Sub without having to explicitly override the
function?

Thanks in advance,

Ben :)




Re: Automatic return type covariance for functions that return this?

2012-09-15 Thread Andrej Mitrovic
On 9/15/12, Ben Davis ent...@cantab.net wrote:
 The last line doesn't compile because doStuff() returns Super. Is there
 a way to make it return Sub without having to explicitly override the
 function?

You need a dynamic cast at the call site:

Sub x = cast(Sub)(new Sub()).doStuff();

x will be null if doStuff doesn't actually return a Sub object
(replace 'new Sub' with 'new Super' for demonstration).

You can't guarantee that the 'this' reference returned in the base
class doStuff method will be of dynamic type 'Sub', that's why
implicit conversions don't work. Either define this method in every
subclass or use casts at the call site.

Maybe you're looking for automatic injection of code into every
subclass, but I don't think this is possible in D. Using mixins might
work, but you'd still have to instantiate a mixin in every subclass by
hand.


Re: Automatic return type covariance for functions that return this?

2012-09-15 Thread Andrej Mitrovic
On 9/15/12, Ben Davis ent...@cantab.net wrote:
 Never mind, I found the answer in the 'templates' page of the spec:

 class Super {
 T doStuff(this T)() { ...; return cast(T)this; }
 }

 Sub x = (new Sub()).doStuff();

 It seems a bit of a shame that I need the cast, but it's a small thing :)

Ah the template this solution, I always forget about that little
trick! Nicely done. :)


Re: Automatic return type covariance for functions that return this?

2012-09-15 Thread Andrej Mitrovic
On 9/15/12, Ben Davis ent...@cantab.net wrote:
 Never mind, I found the answer in the 'templates' page of the spec:

 class Super {
 T doStuff(this T)() { ...; return cast(T)this; }
 }

Btw I think that's a dynamic cast, unless the compiler can optimize it
(I mean it should since it's a template function right?). I saw this
static cast thingy laying around somewhere:

auto static_cast(T,U)(U source)
{
return cast(T)(cast(void*)source);
}


Re: Automatic return type covariance for functions that return this?

2012-09-15 Thread bearophile

Andrej Mitrovic:


I saw this
static cast thingy laying around somewhere:

auto static_cast(T,U)(U source)
{
return cast(T)(cast(void*)source);
}


Maybe you meant:
http://d.puremagic.com/issues/show_bug.cgi?id=5559

Bye,
bearophile


Delegate covariance and contravariance

2009-10-15 Thread Haruki Shigemori
Hello.
I think that the delegate covariance and contravariance makes D better.
(ref. http://d.puremagic.com/issues/show_bug.cgi?id=3180)
What do you think?

I am not good at English.
So, I cannot explain this to Walter well...