Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-10 Thread Steven Schveighoffer via Digitalmars-d-learn

On 1/9/21 3:20 PM, Q. Schroll wrote:
Yes. Actually, I need it for slices, but only pointer part of it really 
mattered.


A Derived[] is implicitly a const(Base)[], not a Base[].
A void delegate() @safe[] is implicitly a const(void delegate())[].
But it seems a void function() @safe[] **isn't** implicitly a const(void 
function())[].


Functions taking those are kind of useless like that.


It should work. The reason const works is under the theory that you 
cannot change it, so there is no danger of replacing the value with 
something that isn't the original type.


I would say as long as it's covariant (or contravariant? I can't 
remember), implicit casting to a const array should work.


-Steve


Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-10 Thread sighoya via Digitalmars-d-learn

On Saturday, 9 January 2021 at 18:16:04 UTC, Q. Schroll wrote:
This makes no sense in my head. Is there some reason I'm unable 
to see?


And yes, I think it should work likewise for function pointers, 
too.




Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-10 Thread sighoya via Digitalmars-d-learn

On Sunday, 10 January 2021 at 00:44:26 UTC, Q. Schroll wrote:



  Car[] cars = ...;
  Vehicle[] vehicles = cars;
  vehicles[0] = new Boat; // err...
  // cars[0] is a Boat now!?

Now what? Do what Java does and throw an Exception? Or use 
const to prevent mutation?


Yes, you are right:

```
Derived derived;
Base* bp=
*bp=base;
derived.method() //ouch
```


I'm unsure what you mean.


I mean D doesn't support co(ntra)varaince out of the box, but 
seems allowing them in certain cases increasing the degree of 
confusion just as it is the case here.
I think it would be just better to generally incorporate 
co(ntra)variance into D's semantic or completely disregard it.






Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread Q. Schroll via Digitalmars-d-learn

On Saturday, 9 January 2021 at 21:57:43 UTC, sighoya wrote:

On Saturday, 9 January 2021 at 20:20:38 UTC, Q. Schroll wrote:
That's not what I mean. You copy the reference. That's not 
what referencing meant.


  Derived d = new Derived();
  Base* bp =  // fails
  const(Base) cbp =  // compiles.


Generally, allowing covariant assignment for the Ptr, i.e. 
T*, type only in case of const T* strikes me. IMHO, both should 
be synchronously (dis)allowed.


I'm unsure what you mean.

If you have an array `cars` of type Car[], you can treat it as a 
const(Vehicle)[] because reading a Car as a Vehicle is 
unproblematic. But if it could bind to Vehicle[], its elements 
could be written arbitrary Vehicles. Say it worked, then:


  Car[] cars = ...;
  Vehicle[] vehicles = cars;
  vehicles[0] = new Boat; // err...
  // cars[0] is a Boat now!?

Now what? Do what Java does and throw an Exception? Or use const 
to prevent mutation?


Because D doesn't support co(ntra)variance, it should be both 
disallowed?


Imagine for a moment, `const` were named `read_only` and there 
were a specifier `write_only`. That looks silly, but makes sense 
in some cases:


  Vehicle[] vehicles = ...;
  write_only(Car)[] cars = vehicles; // WTF!?
  cars[i] = new Car; // wait, that's actually okay...

Because write_only isn't a thing in D, contravariance is an odd 
thing to get your a D mind around.


Otherwise, because D already support the const case, why not 
the non const case?


The non-const case makes no sense.


Are there any alignment issues supporting the non const case?


It's not alignment, probably. (Maybe it is, I know almost nothing 
about alignment, to be honest.) Among other things, in the 
non-const case, as you call it, the type system cannot guarantee 
anymore that stuff that is typed some way actually contains those 
objects.
It is one of the major issues Java has and why everyone and their 
mom tells you not to use Java's arrays and instead use List or 
similar well-behaved constructs.


BTW, my question wasn't about classes at all. I used them as an 
illustration what works and asked why (seemingly) the same thing 
doesn't with function pointers.


Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread sighoya via Digitalmars-d-learn

On Saturday, 9 January 2021 at 20:20:38 UTC, Q. Schroll wrote:
That's not what I mean. You copy the reference. That's not what 
referencing meant.


  Derived d = new Derived();
  Base* bp =  // fails
  const(Base) cbp =  // compiles.


Generally, allowing covariant assignment for the Ptr, i.e. T*, 
type only in case of const T* strikes me. IMHO, both should be 
synchronously (dis)allowed.
Because D doesn't support co(ntra)variance, it should be both 
disallowed?
Otherwise, because D already support the const case, why not the 
non const case?


Are there any alignment issues supporting the non const case?


Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread Q. Schroll via Digitalmars-d-learn

On Saturday, 9 January 2021 at 20:00:35 UTC, Jacob Carlborg wrote:

On 2021-01-09 19:16, Q. Schroll wrote:

Say I have a class hierarchy like this:
   class Base { }
   class Derived : Base { }
A Derived object cannot be referenced as a Base object, but as 
a const(Base) object. That makes sense to me.


It can:

Base b = new Derived();


That's not what I mean. You copy the reference. That's not what 
referencing meant.


  Derived d = new Derived();
  Base* bp =  // fails
  const(Base) cbp =  // compiles.


Is there a reason all you're examples are using pointers?


Yes. Actually, I need it for slices, but only pointer part of it 
really mattered.


A Derived[] is implicitly a const(Base)[], not a Base[].
A void delegate() @safe[] is implicitly a const(void 
delegate())[].
But it seems a void function() @safe[] **isn't** implicitly a 
const(void function())[].


Functions taking those are kind of useless like that.


Re: [Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread Jacob Carlborg via Digitalmars-d-learn

On 2021-01-09 19:16, Q. Schroll wrote:

Say I have a class hierarchy like this:
   class Base { }
   class Derived : Base { }
A Derived object cannot be referenced as a Base object, but as a 
const(Base) object. That makes sense to me.


It can:

Base b = new Derived();

One can replace Base by a @system delegate type (SysDG) and Derived by a 
@safe delegate type (SafeDG) and it works the same way: a SafeDG object 
cannot be referenced as a SysDG object, but as a const(SysDG) object.


However, if I try that with function pointers instead of delegates 
(SysFP, SafeFP), for some reason, a SafeFP cannot be referenced as a 
const(SysFP).

This makes no sense in my head. Is there some reason I'm unable to see?

Example code is here: https://run.dlang.io/is/zSNArx


Is there a reason all you're examples are using pointers? Classes are 
already reference types, delegates are kind of like reference types. 
They consist of a context pointer and a function pointer. Function 
pointer are, as the name suggest, already pointers.


--
/Jacob Carlborg


[Understanding] Classes and delegate inheritance vs function pointers

2021-01-09 Thread Q. Schroll via Digitalmars-d-learn

Say I have a class hierarchy like this:
  class Base { }
  class Derived : Base { }
A Derived object cannot be referenced as a Base object, but as a 
const(Base) object. That makes sense to me.


One can replace Base by a @system delegate type (SysDG) and 
Derived by a @safe delegate type (SafeDG) and it works the same 
way: a SafeDG object cannot be referenced as a SysDG object, but 
as a const(SysDG) object.


However, if I try that with function pointers instead of 
delegates (SysFP, SafeFP), for some reason, a SafeFP cannot be 
referenced as a const(SysFP).
This makes no sense in my head. Is there some reason I'm unable 
to see?


Example code is here: https://run.dlang.io/is/zSNArx