May 21, 2016
On Friday, 20 May 2016 at 20:30:22 UTC, chmike wrote:

>
> I'm a bit surprized that the language doesn't support this. We have immutable strings that can be assigned to different variables. Why couldn't we do the same with objects ?

Consider this:

immutable(char)[] str;

Here, the array elements of str are immutable, i.e. you cannot do this:

str[0] = 's'

However, the array reference itself is mutable, so you can freely assign array references around. This is what string is aliased to.

To prevent the array reference from being assigned:

immutable(char[]) str;

Now trying to assign another string to str will produce a compiler error.

With arrays and pointers, we distinguish between the data and the reference. With classes, we do not; there is only the reference.

May 21, 2016
On Friday, 20 May 2016 at 16:09:54 UTC, chmike wrote:

>
> But I now met another error in my main(). I can't assign the immutable object to a mutable reference.
>
> Info x1 = MyInfos.one;
>
> Is it possible to define a mutable reference to an immutable instance ? 
>
> This is confusing and frustrating. In C++ we can write
> MyInfos {
>    . . .
>    // one is a constant pointer to a constant object of type Obj
>    Obj const * const one;
>    . . .
> }
>

I strongly advise you put C++ out of your head when programming D and try to come at it as if you have never seen C++. Otherwise, you will just keep getting frustrated. D is a different language and, while some C++ idioms may work just fine, others do not and cannot.

Consider this:

immutable(int*) ifoo;

Because the * is inside the parens in the declaration of ifoo, we are saying that we never want the pointer to be reassigned. The compiler is free to behave as if that is true and that ifoo will always point to the same address. It might make certain optimizations based on that guarantee that might not otherwise be possible. The same is true if you replace immutable with const in this particular declaration. If you somehow manage to circumvent that guarantee, then you are breaking the compiler's expectations and entering the realm of undefined behavior. You can think of an immutable class reference as being an immutable pointer like ifoo.

C++ has no such guarantees. The compiler is not free to make the same assumptions D can make. If D allowed you to do what C++ does, then D compilers would be in the same boat. This is one of the reasons why you can't expect D code to behave like C++ code in every case, no matter how similar things look on the surface.


May 21, 2016
On Friday, 20 May 2016 at 16:09:54 UTC, chmike wrote:

> This is confusing and frustrating. In C++ we can write
> MyInfos {
>    . . .
>    // one is a constant pointer to a constant object of type Obj
>    Obj const * const one;
>    . . .
> }
>
> And in main()
>
> Info const * x1 = MyInfos.one;
>
> x1 i a modifiable pointer to a constant object of type Info.
>
> Is this possible in D ? I couldn't find how to do that.

I should have addressed this above. This is another of the those things that will bite you if you are thinking in C++ when writing D. Classes in D are references types, so right out of the gate they can not be treated as C++ classes. You absolutely can have modifiable pointers to const and immutable data with built in types and structs, but not with classes. Always think of const(classref) as const(class*). There is no such thing as const(class)* in D.
May 21, 2016
Unfortunately it is not possible to write this

import std.typecons;
class Info{...}
rebindable!Info x;

I get the following error message

source/app.d(11,3): Error: template std.typecons.rebindable matches more than one template declaration:
/usr/include/dmd/phobos/std/typecons.d(1675,14):     rebindable(T)(T obj) if (is(T == class) || is(T == interface) || isDynamicArray!T || isAssociativeArray!T)
and
/usr/include/dmd/phobos/std/typecons.d(1694,14):     rebindable(T)(Rebindable!T obj)


This would have been equivalent to define a mutable reference to an object of type Info and allow me to write this

alias rebindable!Info InfoR;
InfoR x;

Unfortunately I didn't manage to get something compiling with rebindable. I don't understand how I'm supposed to use it.


Note that I'm designing a library that I would like intuitive to use. Hacking around the problem won't cut it.

I need a type defining a mutable reference to an immutable object. Rebindable doesn't give me that apparently.

I need something allowing me to write this

interface Info {...}
class MyInfos {
    static class Obj : Info {...}
    static immutable Obj one = new immutable Obj(...);
}

mutableObjectRef!Info x1, x2;
assert(x1 is null);
assert(x1 == null);
x1 = MyInfos.one;
assert(x1 is MyInfos.one);
assert(x1 == MyInfos.one);
x2 = x1;

switch(x1){
case MyInfos.one: ... ;
default:...;
}

x1 must have the semantic of an object reference, support polymorphism, allowing to down or up cast and of course access immutable members and methods.
MyInfos.one is an object reference that I shouldn't be allowed to modify. I can't use a function because it needs the value semantic so I can use it as a case argument in a switch.

It doesn't seam that this is what rebind provides. It looks like mutableObjectRef should be a templated struct. But I'm not experienced enough in D to implement it. I don't know if its only possible.






May 21, 2016
Since I'm trying to implement a flyweight pattern, the opEqual need only comparision of reference in my case.

By the way, what operation is the switch performing ? OpEqual or is ?
May 21, 2016
On 05/21/2016 01:07 AM, chmike wrote:
> Unfortunately it is not possible to write this
>
> import std.typecons;
> class Info{...}
> rebindable!Info x;

You have a capitalization typo. Rebindable is a type template, rebindable is a function template.

import std.typecons;
class Info{}

void main() {
    auto x = rebindable(new immutable(Info)());
    pragma(msg, typeof(x));

    auto y = Rebindable!(immutable(Info))(new Info());
    pragma(msg, typeof(y));
}

Ali

May 21, 2016
On Saturday, 21 May 2016 at 08:24:19 UTC, Ali Çehreli wrote:
> On 05/21/2016 01:07 AM, chmike wrote:
> > Unfortunately it is not possible to write this
> >
> > import std.typecons;
> > class Info{...}
> > rebindable!Info x;
>
> You have a capitalization typo. Rebindable is a type template, rebindable is a function template.
>
> import std.typecons;
> class Info{}
>
> void main() {
>     auto x = rebindable(new immutable(Info)());
>     pragma(msg, typeof(x));
>
>     auto y = Rebindable!(immutable(Info))(new Info());
>     pragma(msg, typeof(y));
> }
>
> Ali

Thank you. I'll start a new thread with the subject "problems with Rebindable".
See https://forum.dlang.org/post/bprfdptcvzzkfzxlhflb@forum.dlang.org
1 2
Next ›   Last »