Thread overview
Feature request: Deploying a class instance in the default data segment
Dec 18, 2008
Weed
Dec 18, 2008
Bill Baxter
Dec 18, 2008
Weed
Dec 18, 2008
Bill Baxter
Dec 18, 2008
Weed
Dec 21, 2008
Weed
Dec 18, 2008
Kagamin
Dec 18, 2008
Weed
December 18, 2008
Feature request: Deploying a class instance in the default data segment and creation of a class instance at compile time.

In this post I'll try to prove the necessity of this feature.

I have found that in D it is impossible to create a polymorphic object (class or struct) which can be created at compile-time.

Good specific example of such an object is a matrix class.

For some matrices it is good to create and initialize them at compile
time, not dynamically at run time.

Also for matrices of predefined size it is wrong to duplicate their
dimensions (their width and height should be declared invariant and,
consequently occupy memory only once)

At the same time dynamically created matrices of arbitrary size which
can be changed at run time are also needed. For example to make a slice of giant matrix it's more efficient to modify it in-place than to copy it. These matrices have variable width and height.

So we have minimum two types of matrices: dynamic and constant sized with ability of compile time initialization. It is necessary to provide
interaction between them (for example overload arithmetic operators
for them). For this purpose it is necessary for them to be inherited
from common parent. So it can not be structures, only classes.

But classes can not be created at compile time.

So I propose to add possibility of deployment of class instance in the default data segment and creation of class instance at compile time.
December 18, 2008
On Thu, Dec 18, 2008 at 2:05 PM, Weed <resume755@mail.ru> wrote:
> Feature request: Deploying a class instance in the default data segment and creation of a class instance at compile time.
>
> In this post I'll try to prove the necessity of this feature.
>
> I have found that in D it is impossible to create a polymorphic object (class or struct) which can be created at compile-time.
>
> Good specific example of such an object is a matrix class.
>
> For some matrices it is good to create and initialize them at compile time, not dynamically at run time.
>
> Also for matrices of predefined size it is wrong to duplicate their dimensions (their width and height should be declared invariant and, consequently occupy memory only once)
>
> At the same time dynamically created matrices of arbitrary size which
> can be changed at run time are also needed. For example to make a slice of
> giant matrix it's more efficient to modify it in-place than to copy it.
> These matrices have variable width and height.
>
> So we have minimum two types of matrices: dynamic and constant sized with
> ability of compile time initialization. It is necessary to provide
> interaction between them (for example overload arithmetic operators
> for them). For this purpose it is necessary for them to be inherited
> from common parent.

This point I don't think is true.  DynamicMatrix can implement methods like opMult(StaticMatrix M), and vice versa.

The only thing I can think of you can't do is make an array of
pointers to Matrix, the elements of which might be a DynamicMatrix, or
might be StaticMatrix.
But even that, if you really feel you need it for some reason, could
be done using a struct/class with a union inside.  Most cases where
you might want to accept either/or can be done with templates.

> So it can not be structures, only classes.
>
> But classes can not be created at compile time.
>
> So I propose to add possibility of deployment of class instance in the default data segment and creation of class instance at compile time.

This might be a useful feature, but I'm not finding your argument for it quite convincing enough yet.

--bb
December 18, 2008
Bill Baxter пишет:
> On Thu, Dec 18, 2008 at 2:05 PM, Weed <resume755@mail.ru> wrote:
>> Feature request: Deploying a class instance in the default data segment and
>> creation of a class instance at compile time.
>>
>> In this post I'll try to prove the necessity of this feature.
>>
>> I have found that in D it is impossible to create a polymorphic object
>> (class or struct) which can be created at compile-time.
>>
>> Good specific example of such an object is a matrix class.
>>
>> For some matrices it is good to create and initialize them at compile
>> time, not dynamically at run time.
>>
>> Also for matrices of predefined size it is wrong to duplicate their
>> dimensions (their width and height should be declared invariant and,
>> consequently occupy memory only once)
>>
>> At the same time dynamically created matrices of arbitrary size which
>> can be changed at run time are also needed. For example to make a slice of
>> giant matrix it's more efficient to modify it in-place than to copy it.
>> These matrices have variable width and height.
>>
>> So we have minimum two types of matrices: dynamic and constant sized with
>> ability of compile time initialization. It is necessary to provide
>> interaction between them (for example overload arithmetic operators
>> for them). For this purpose it is necessary for them to be inherited
>> from common parent.
> 
> This point I don't think is true.  DynamicMatrix can implement methods
> like opMult(StaticMatrix M), and vice versa.

I'm not sure (see below)

> The only thing I can think of you can't do is make an array of
> pointers to Matrix, the elements of which might be a DynamicMatrix, or
> might be StaticMatrix.

Yes, or suppose I want to add a class matrix, which is part of an existing large matrix (which is a kind of frame).

> But even that, if you really feel you need it for some reason, could
> be done using a struct/class with a union inside.  Most cases where
> you might want to accept either/or can be done with templates.

I think this is impossible. If I create struct for compile-time matrix and class for all other I will not be able to create a methods for interaction between these objects through the templates because some of them will be announced before the other and it will not be able to get another type of object in a template.

(I do not know, understand this long phrase on my strange English or not. tell if the phrase is unclear)


>> So it can not be structures, only classes.
>>
>> But classes can not be created at compile time.
>>
>> So I propose to add possibility of deployment of class instance in the
>> default data segment and creation of class instance at compile time.
> 
> This might be a useful feature, but I'm not finding your argument for
> it quite convincing enough yet.

Yes, perhaps matrix is not good example
December 18, 2008
2008/12/18 Weed <resume755@mail.ru>:
> Bill Baxter пишет:
>>
>> On Thu, Dec 18, 2008 at 2:05 PM, Weed <resume755@mail.ru> wrote:
>>>
>>> Feature request: Deploying a class instance in the default data segment
>>> and
>>> creation of a class instance at compile time.
>>>
>>> In this post I'll try to prove the necessity of this feature.
>>>
>>> I have found that in D it is impossible to create a polymorphic object (class or struct) which can be created at compile-time.
>>>
>>> Good specific example of such an object is a matrix class.
>>>
>>> For some matrices it is good to create and initialize them at compile time, not dynamically at run time.
>>>
>>> Also for matrices of predefined size it is wrong to duplicate their dimensions (their width and height should be declared invariant and, consequently occupy memory only once)
>>>
>>> At the same time dynamically created matrices of arbitrary size which
>>> can be changed at run time are also needed. For example to make a slice
>>> of
>>> giant matrix it's more efficient to modify it in-place than to copy it.
>>> These matrices have variable width and height.
>>>
>>> So we have minimum two types of matrices: dynamic and constant sized with
>>> ability of compile time initialization. It is necessary to provide
>>> interaction between them (for example overload arithmetic operators
>>> for them). For this purpose it is necessary for them to be inherited
>>> from common parent.
>>
>> This point I don't think is true.  DynamicMatrix can implement methods like opMult(StaticMatrix M), and vice versa.


> I think this is impossible. If I create struct for compile-time matrix and class for all other I will not be able to create a methods for interaction between these objects through the templates because some of them will be announced before the other and it will not be able to get another type of object in a template.

You mean there will be this circular dependency?

   struct DynamicMatrix {
       DynamicMatrix opMul(StaticMatrix m) {...}
       ...
   }

   struct StaticMatrix {
        DynamicMatrix opMul(DynamicMatrix m) {...}
        ...
   }

I think this will work fine with DMD as long as you have both DynamicMatrix and StaticMatrix in the same file.

If you *do* want to put them in separate modules, then, yes, you would probably run into trouble.

It is kind of annoying that issues like this end up dictating how source code is split among files in D.  I really think it should be *my* choice to split up a file if I think it's getting too big.

--bb

December 18, 2008
Bill Baxter пишет:
> 2008/12/18 Weed <resume755@mail.ru>:
>> Bill Baxter пишет:
>>> On Thu, Dec 18, 2008 at 2:05 PM, Weed <resume755@mail.ru> wrote:
>>>> Feature request: Deploying a class instance in the default data segment
>>>> and
>>>> creation of a class instance at compile time.
>>>>
>>>> In this post I'll try to prove the necessity of this feature.
>>>>
>>>> I have found that in D it is impossible to create a polymorphic object
>>>> (class or struct) which can be created at compile-time.
>>>>
>>>> Good specific example of such an object is a matrix class.
>>>>
>>>> For some matrices it is good to create and initialize them at compile
>>>> time, not dynamically at run time.
>>>>
>>>> Also for matrices of predefined size it is wrong to duplicate their
>>>> dimensions (their width and height should be declared invariant and,
>>>> consequently occupy memory only once)
>>>>
>>>> At the same time dynamically created matrices of arbitrary size which
>>>> can be changed at run time are also needed. For example to make a slice
>>>> of
>>>> giant matrix it's more efficient to modify it in-place than to copy it.
>>>> These matrices have variable width and height.
>>>>
>>>> So we have minimum two types of matrices: dynamic and constant sized with
>>>> ability of compile time initialization. It is necessary to provide
>>>> interaction between them (for example overload arithmetic operators
>>>> for them). For this purpose it is necessary for them to be inherited
>>>> from common parent.
>>> This point I don't think is true.  DynamicMatrix can implement methods
>>> like opMult(StaticMatrix M), and vice versa.
>
>
>> I think this is impossible. If I create struct for compile-time matrix and
>> class for all other I will not be able to create a methods for interaction
>> between these objects through the templates because some of them will be
>> announced before the other and it will not be able to get another type of
>> object in a template.
>
> You mean there will be this circular dependency?
>

Yes

>    struct DynamicMatrix {
>        DynamicMatrix opMul(StaticMatrix m) {...}
>        ...
>    }
>
>    struct StaticMatrix {
>         DynamicMatrix opMul(DynamicMatrix m) {...}
>         ...
>    }
>
> I think this will work fine with DMD as long as you have both
> DynamicMatrix and StaticMatrix in the same file.
>
> If you *do* want to put them in separate modules, then, yes, you would
> probably run into trouble.
>

Yes.

In addition, in the overloaded methods will probably need to implement a different mechanism for creating all types of matrices (this need for returning values), eg, static and non-resizeable matrix template will have to pass an array pattern in a string like this (very cumbersome):

==========================================
char[] matBySize(int size) {
    char[] init;
    for (int i = 0; i < size; i++) {
        init ~= "[";
        for (int j = 0; j < size - 1; j++) {
            init ~="0, ";
        }
        init ~= "0]";
        if (i == size - 1) init ~= "]"; else init ~= ",\n";
    }
    return "mat([" ~ init ~ ")";
}


struct mat {
    int[][] value;

    static mat opCall(int[][] init) {
        mat m;
        m.value = init;
        return m;
    }

    mat opPostInc() {
        foreach (row; value) {
            foreach (ref item; row) {
                item++;
            }
        }
        return this;
    }
}

void myFunc() {
    static sm = mixin(matBySize(2));
    auto dm = mixin(matBySize(3));
}

// (thanks naryl for this code sample)
==========================================


In addition, if I want to add other types of matrices (I have already talked about the matrix, which is part of another matrix) it will be difficult to do so, because the structures do not support the interfaces and will have to manually monitor so that all methods have been implemented correctly.

Figuratively speaking, in the spirit of the matrix is class, not the structure.


> It is kind of annoying that issues like this end up dictating how
> source code is split among files in D.  I really think it should be
> *my* choice to split up a file if I think it's getting too big.
>
> --bb

December 18, 2008
Weed Wrote:

> For some matrices it is good to create and initialize them at compile time, not dynamically at run time.

Oh, yes, how could I forget about some matrices... :)
December 18, 2008
Weed пишет:
> Feature request: Deploying a class instance in the default data segment and creation of a class instance at compile time.
> 
> In this post I'll try to prove the necessity of this feature.
> 
> I have found that in D it is impossible to create a polymorphic object (class or struct) which can be created at compile-time.
> 
> Good specific example of such an object is a matrix class.
> 
> For some matrices it is good to create and initialize them at compile
> time, not dynamically at run time.
> 
> Also for matrices of predefined size it is wrong to duplicate their
> dimensions (their width and height should be declared invariant and,
> consequently occupy memory only once)
> 
> At the same time dynamically created matrices of arbitrary size which
> can be changed at run time are also needed. For example to make a slice of giant matrix it's more efficient to modify it in-place than to copy it. These matrices have variable width and height.
> 
> So we have minimum two types of matrices: dynamic and constant sized with ability of compile time initialization. It is necessary to provide
> interaction between them (for example overload arithmetic operators
> for them). For this purpose it is necessary for them to be inherited
> from common parent. So it can not be structures, only classes.
> 
> But classes can not be created at compile time.
> 
> So I propose to add possibility of deployment of class instance in the default data segment and creation of class instance at compile time.


In more general terms:
Structures and classes must be identical except that the structure can not have inheritance, and classes can not be assigned by value (to prevent slicing). Everything else, including constructors, and static initialization they must match.

(Yes, of course structures have alignment control and other pieces for the Plain Old Data)
December 21, 2008
Bill Baxter пишет:
> On Thu, Dec 18, 2008 at 2:05 PM, Weed <resume755@mail.ru> wrote:
>> Feature request: Deploying a class instance in the default data segment and
>> creation of a class instance at compile time.
>>
>> In this post I'll try to prove the necessity of this feature.
>>
>> I have found that in D it is impossible to create a polymorphic object
>> (class or struct) which can be created at compile-time.
>>
>> Good specific example of such an object is a matrix class.
>>
>> For some matrices it is good to create and initialize them at compile
>> time, not dynamically at run time.
>>
>> Also for matrices of predefined size it is wrong to duplicate their
>> dimensions (their width and height should be declared invariant and,
>> consequently occupy memory only once)
>>
>> At the same time dynamically created matrices of arbitrary size which
>> can be changed at run time are also needed. For example to make a slice of
>> giant matrix it's more efficient to modify it in-place than to copy it.
>> These matrices have variable width and height.
>>
>> So we have minimum two types of matrices: dynamic and constant sized with
>> ability of compile time initialization. It is necessary to provide
>> interaction between them (for example overload arithmetic operators
>> for them). For this purpose it is necessary for them to be inherited
>> from common parent.
> 
> This point I don't think is true.  DynamicMatrix can implement methods
> like opMult(StaticMatrix M), and vice versa.
> 
> The only thing I can think of you can't do is make an array of
> pointers to Matrix, the elements of which might be a DynamicMatrix, or
> might be StaticMatrix.
> But even that, if you really feel you need it for some reason, could
> be done using a struct/class with a union inside.  Most cases where
> you might want to accept either/or can be done with templates.
> 
>> So it can not be structures, only classes.
>>
>> But classes can not be created at compile time.
>>
>> So I propose to add possibility of deployment of class instance in the
>> default data segment and creation of class instance at compile time.
> 
> This might be a useful feature, but I'm not finding your argument for
> it quite convincing enough yet.
> 

Here other example:

Suppose a matrix structure implemented "Dynamic" and "Static" using the template mixins.

On this basis must be built other structures (for example, the structure of "image" is a dynamic matrix with additional features, the structure of "pixel" is a matrix of 3x1).

Functional of matrix structures "Static" and "Dynamic" included in the structure of "image" and "pixel". So far, so good.

But in this case becomes impossible to implement matrix multiplication operation type, return other than the size of the source matrix, just as implemented in http://www.dsource.org/projects/openmeshd/browser/trunk/LinAlg/linalg/MatrixT.d, template "template MultReturnType (ArgT)" - we will not be able to create a matrix of different dimensions but the same type as the original matrix, because we will have to list in this template "MultReturnType" all structures "image", "pixel", etc.

If the matrix would be a class that would be to return the reference to base type matrix enough