Re: Construct immutable member in derived class

2018-04-05 Thread Alex via Digitalmars-d-learn

On Thursday, 5 April 2018 at 19:31:39 UTC, Jonathan M Davis wrote:
And you can't abstract whether a member variable is marked with 
immutable or not. That's part of the variable. Declaring an 
immutable instance of an object would then treat the member 
variable in immutable for that instance, so it's possible to 
have an immutable member variable when the member variable is 
not itself marked with immutable, but class inheritance has 
nothing to do with controlling which type qualifiers were used 
on the member variable of a base class. Derived classes 
override member functions. They don't override member variables 
or anything about them. They override the behavior of the base 
class, not the structure.


That beats my argumentation. Fully agree with that.

For them to do otherwise would become quite problematic if you 
ever use a derived class through a base class reference. They 
can add onto the structure of a base class, but the derived 
class must be usuable via a base class reference, and trying to 
do something like have the derived class alter the qualifiers 
on base class member variable simply would not work with that. 
That sort of thing could only ever work if the base class were 
just a way to add functionality to a derived class rather than 
having anything to do with references, and that's simply not 
how classes work in D. If that's the sort of thing that you 
want, it would make more sense to add the functionality via 
composition rather than inheritance.


Yeah... little bit of mixing things up in my head, maybe... Did 
exactly this stuff during the last couple of months.


Thanks a lot!


Re: Construct immutable member in derived class

2018-04-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, April 05, 2018 13:36:07 Alex via Digitalmars-d-learn wrote:
> On Wednesday, 4 April 2018 at 21:49:08 UTC, Timoses wrote:
> > "[...] the construction of the base class can be independent
> > from the derived one."
> >
> > Hm, the points 7 and 8 don't clearly state what you wrote.
>
> Yes :)
>
> > But it somehow does make sense.. Still I wonder why that is so.
> >
> > Let's say you have an abstract class with immutable members.
> > Why shouldn't derived class constructors be allowed to
> > initialize these immutable members?
>
> My reason is a semantic one, so it's rather how I'm explaining
> this to me, then a formal one.
>
> Let's assume, we abstract away a member from different derived
> classes to an abstract class, which cannot be handled by this
> abstract class.
> Ok, this can happen, so it would be ok, if the base class does
> not handle the var.
>
> But then, we add a qualifier. How can this be? As the abstract
> class cannot handle the abstraction, it also can not add any
> qualifiers.
> As the qualifier is there, then, the base class at least has
> knowledge about the immutability. And due this fact, its own
> constructor has to handle this variable in some way.
>
> However, this a minor problem, isn't it? If you argue, that you
> can also abstract the immutability qualifier, then, I would say,
> that a derived class always has a better knowledge how to handle
> its members, and therefore how to call the base class
> constructor, as it knows which class it is derived from.
>
> So, for short:
> Either: the immutability belongs to the base class and therefore
> it has to manage the var
> Or: it doesn't and the derived classes have the knowledge how to
> serve their base class.

The reality of the matter is that a member variable is a member of the class
that it's in and _must_ be handled by that class. If it's not directly
initialized in its declaration or initialized in that class' constructor,
then it gets a default value. Derived classes have _zero_ control over that.
They can mutate a public or protected mutable member of a base class, but
that member variable still has to be initialized by the base class, not the
derived class.

And you can't abstract whether a member variable is marked with immutable or
not. That's part of the variable. Declaring an immutable instance of an
object would then treat the member variable in immutable for that instance,
so it's possible to have an immutable member variable when the member
variable is not itself marked with immutable, but class inheritance has
nothing to do with controlling which type qualifiers were used on the member
variable of a base class. Derived classes override member functions. They
don't override member variables or anything about them. They override the
behavior of the base class, not the structure. For them to do otherwise
would become quite problematic if you ever use a derived class through a
base class reference. They can add onto the structure of a base class, but
the derived class must be usuable via a base class reference, and trying to
do something like have the derived class alter the qualifiers on base class
member variable simply would not work with that. That sort of thing could
only ever work if the base class were just a way to add functionality to a
derived class rather than having anything to do with references, and that's
simply not how classes work in D. If that's the sort of thing that you want,
it would make more sense to add the functionality via composition rather
than inheritance.

- Jonathan M Davis



Re: Construct immutable member in derived class

2018-04-05 Thread Timoses via Digitalmars-d-learn
On Wednesday, 4 April 2018 at 22:47:07 UTC, Jonathan M Davis 
wrote:
Because doing that basically makes it impossible to guarantee 
that the type system isn't violated. Once an immutable variable 
has been initialized, its value must _never_ change. It must be 
initalized exactly once, and the compiler doesn't necessarily 
have any clue what the base class constructors did or didn't 
do. There's no guarantee that it even has access to the 
function bodies for the base class when compiling the derived 
class. So, there is no way for it to safely put off the 
initialization of any base class members for the derived class 
to do.


- Jonathan M Davis


Ah, makes sense. I was looking for a somewhat technical answer. 
Thanks for that : ).


Re: Construct immutable member in derived class

2018-04-05 Thread Alex via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 21:49:08 UTC, Timoses wrote:
"[...] the construction of the base class can be independent 
from the derived one."


Hm, the points 7 and 8 don't clearly state what you wrote.


Yes :)


But it somehow does make sense.. Still I wonder why that is so.

Let's say you have an abstract class with immutable members. 
Why shouldn't derived class constructors be allowed to 
initialize these immutable members?


My reason is a semantic one, so it's rather how I'm explaining 
this to me, then a formal one.


Let's assume, we abstract away a member from different derived 
classes to an abstract class, which cannot be handled by this 
abstract class.
Ok, this can happen, so it would be ok, if the base class does 
not handle the var.


But then, we add a qualifier. How can this be? As the abstract 
class cannot handle the abstraction, it also can not add any 
qualifiers.
As the qualifier is there, then, the base class at least has 
knowledge about the immutability. And due this fact, its own 
constructor has to handle this variable in some way.


However, this a minor problem, isn't it? If you argue, that you 
can also abstract the immutability qualifier, then, I would say, 
that a derived class always has a better knowledge how to handle 
its members, and therefore how to call the base class 
constructor, as it knows which class it is derived from.


So, for short:
Either: the immutability belongs to the base class and therefore 
it has to manage the var
Or: it doesn't and the derived classes have the knowledge how to 
serve their base class.


Re: Construct immutable member in derived class

2018-04-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, April 04, 2018 21:46:13 Timoses via Digitalmars-d-learn wrote:
> On Wednesday, 4 April 2018 at 18:11:12 UTC, Jonathan M Davis
> > That code doesn't compile - at least not with dmd master. It
> > gives these two errors:
> >
> > q.d(5): Error: constructor `q.A.this` missing initializer for
> > immutable
> > field i
> > q.d(12): Error: cannot modify immutable expression this.i
> >
> > So, it's an error that the base class doesn't initialize the
> > immutable member, and it's an error for the derived class to
> > try to assign to it.
>
> I know, should have mentioned it. The question is why, however?
> A rule like the above would force all derived classes to
> initialize the immutable variable from the base class (if they
> were allowed to).
> Why aren't they?

Because doing that basically makes it impossible to guarantee that the type
system isn't violated. Once an immutable variable has been initialized, its
value must _never_ change. It must be initalized exactly once, and the
compiler doesn't necessarily have any clue what the base class constructors
did or didn't do. There's no guarantee that it even has access to the
function bodies for the base class when compiling the derived class. So,
there is no way for it to safely put off the initialization of any base
class members for the derived class to do.

- Jonathan M Davis



Re: Construct immutable member in derived class

2018-04-04 Thread Timoses via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 16:16:24 UTC, Alex wrote:

Here is something:
https://dlang.org/spec/class.html#constructors

By the rules 7 and 8 it is suggested, what Simen already said, 
the construction of the base class can be independent from the 
derived one. And as such, the immutability has to handled in 
the constructor, next to the variable...


"[...] the construction of the base class can be independent from 
the derived one."


Hm, the points 7 and 8 don't clearly state what you wrote. But it 
somehow does make sense.. Still I wonder why that is so.


Let's say you have an abstract class with immutable members. Why 
shouldn't derived class constructors be allowed to initialize 
these immutable members?


Re: Construct immutable member in derived class

2018-04-04 Thread Timoses via Digitalmars-d-learn
On Wednesday, 4 April 2018 at 18:11:12 UTC, Jonathan M Davis 
wrote:

On Wednesday, April 04, 2018 16:05:52 Timoses via


```
class A
{
 immutable int i;

 this(){}
}

class B : A
{
 this()
 {
  this.i = 3;
 super();  // <- specifically calling
   //super constructor 
afterwards

 }
}

void main()
{
  auto b = new B;
}
```


That code doesn't compile - at least not with dmd master. It 
gives these two errors:


q.d(5): Error: constructor `q.A.this` missing initializer for 
immutable

field i
q.d(12): Error: cannot modify immutable expression this.i

So, it's an error that the base class doesn't initialize the 
immutable member, and it's an error for the derived class to 
try to assign to it.


- Jonathan M Davis


I know, should have mentioned it. The question is why, however?
A rule like the above would force all derived classes to 
initialize the immutable variable from the base class (if they 
were allowed to).

Why aren't they?


Re: Construct immutable member in derived class

2018-04-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, April 04, 2018 16:05:52 Timoses via Digitalmars-d-learn wrote:
> On Wednesday, 4 April 2018 at 10:41:52 UTC, Simen Kjærås wrote:
> > Because by the time B's constructor is called, A might already
> > have initialized it, and rely on it never changing.
>
> What about:
>
> ```
> class A
> {
>  immutable int i;
>
>  this(){}
> }
>
> class B : A
> {
>  this()
>  {
>   this.i = 3;
>  super();  // <- specifically calling
>//super constructor afterwards
>  }
> }
>
> void main()
> {
>   auto b = new B;
> }
> ```

That code doesn't compile - at least not with dmd master. It gives these two
errors:

q.d(5): Error: constructor `q.A.this` missing initializer for immutable 
field i
q.d(12): Error: cannot modify immutable expression this.i

So, it's an error that the base class doesn't initialize the immutable
member, and it's an error for the derived class to try to assign to it.

- Jonathan M Davis




Re: Construct immutable member in derived class

2018-04-04 Thread Alex via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 16:05:52 UTC, Timoses wrote:
This becomes a bit hideous, unfortunately, when there are many 
initializations involved.


Found this, but it doesn't mention anything about derived 
classes..

https://dlang.org/spec/class.html#field-init


Here is something:
https://dlang.org/spec/class.html#constructors

By the rules 7 and 8 it is suggested, what Simen already said, 
the construction of the base class can be independent from the 
derived one. And as such, the immutability has to handled in the 
constructor, next to the variable...


Re: Construct immutable member in derived class

2018-04-04 Thread Timoses via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 10:41:52 UTC, Simen Kjærås wrote:
Because by the time B's constructor is called, A might already 
have initialized it, and rely on it never changing.

What about:

```
class A
{
immutable int i;

this(){}
}

class B : A
{
this()
{
this.i = 3;
super();  // <- specifically calling
  //super constructor afterwards
}
}

void main()
{
auto b = new B;
}
```

Same result

The solution is to add a constructor overload to A, and call 
that from B:


class A
{
immutable int i;

protected this(int i) {
this.i = i;
}
}

class B : A
{
this()
{
super(3);
}
}

unittest
{
auto b = new B;
}

--
  Simen


This becomes a bit hideous, unfortunately, when there are many 
initializations involved.


Found this, but it doesn't mention anything about derived 
classes..

https://dlang.org/spec/class.html#field-init


Re: Construct immutable member in derived class

2018-04-04 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 4 April 2018 at 10:11:37 UTC, Timoses wrote:

Example:

```
class A
{
immutable int i;

this(){}
}

class B : A
{
this()
{
this.i = 3;
}
}

void main()
{
auto b = new B;
}
```

throws:
Error: constructor `onlineapp.A.this` missing initializer for 
immutable field i

Error: cannot modify immutable expression this.i


Why can't I initialize the immutable member in the derived 
class?


Because by the time B's constructor is called, A might already 
have initialized it, and rely on it never changing. The solution 
is to add a constructor overload to A, and call that from B:


class A
{
immutable int i;

protected this(int i) {
this.i = i;
}
}

class B : A
{
this()
{
super(3);
}
}

unittest
{
auto b = new B;
}

--
  Simen