December 05, 2019
I haven't used const much in the past because I got burned on transitive const, so I managed to confuse myself.  I am not really interested in const/immutabel references here, but values. Seems like there is no reason to ever use const values, except when they contain a pointer to something non-immutable?

The only difference, as far as I can tell, is if the value type has pointers to other objects, immutable requires them to be to immutable objects. Which is a bit odd when you think of it. It basically means that you cannot put pointers to memory registers in ROM in a type safe manner... :-/ . That is a very odd restriction, because that is something you might want to do...

Seems to me that immutable should allow pointers to mutable memory and that const really shouldn't have been applicable to values, but only to pointers.

Anyway seems the rule of thumb is to:

- always use immutable on values
- except when the value might contain a pointer to non-immutable

Hm.

December 05, 2019
I haven't used const much in the past because I got burned on transitive const, so I managed to confuse myself.  I am not really interested in const/immutabel references here, only values. Seems like there is no reason to ever use const values, except when the value may contain a pointer to something non-immutable?

The only difference, as far as I can tell, is if the value type has pointers to other objects, immutable requires them to be to immutable objects. Which is a bit odd when you think of it. It basically means that you cannot put pointers to memory registers in ROM in a type safe manner... :-/ . That is a very odd restriction, because that is something you might want to do...

Seems to me that immutable should allow pointers to mutable memory and that const really shouldn't have been applicable to values, but only to pointers.

Anyway seems the rule of thumb would be:

- always use immutable on values
- except when the value might contain a pointer to non-immutable

Hm.

December 05, 2019
On Wednesday, 4 December 2019 at 23:27:49 UTC, Steven Schveighoffer wrote:
> void foo(alias f)()
> {
>    alias ConstType = const(typeof(f()));
>    pragma(msg, ConstType);
> }

I expressed myself poorly, what I am interested in is this:

struct node1 {int value; const(node1)* next;}
struct node2 {int value; immutable(node2)* next;}

alias node = node1; // may swap to node2

node f(){
    node tmp = {2019, null};
    return tmp;
}

void main() {
    // choose readonly as immutable if x can be cast as such
    // otherwise choose const
	readonly x = f();
}

December 05, 2019
I also find the following behaviour a bit unclear:

struct node0 {int value; node0* next;}
struct node1 {int value; const(node1)* next;}
struct node2 {int value; immutable(node0)* next;}

T mk(T)(){
    T tmp = {2019, null};
    return tmp;
}

node1 mk_node1(){
    node1 tmp = {2019, null};
    return tmp;
}

node2 mk_node2(){
    node2 tmp = {2019, null};
    return tmp;
}


void main() {
    immutable x0 = mk!node0();  //succeeds?
    immutable x1 = mk!node1();  //succeeds?
    immutable x2 = mk!node2();  //succeeds?
    immutable y1 = mk_node1();  //fails
    immutable y2 = mk_node2();  //succeeds, so only first child has to be immutable?
}

December 05, 2019
On Thursday, 5 December 2019 at 10:41:24 UTC, Ola Fosheim Grøstad wrote:
>     immutable x1 = mk!node1();  //succeeds?
>     immutable y1 = mk_node1();  //fails

Nevermind, seems like templated functions get stronger coercion, like:

 immutable y1 = cast(immutable)mk_node1();

(Also no need to explain that immutable(node0) rewrites all the pointer types to immutable, I get it :-)

December 05, 2019
So basically, templated functions get flow-typing. I guess that is a good reason to use templated functions more...

What is the downside? E.g.:

struct node {int value; node* next;}

node mk_node2()(){
    node tmp = {2019, null};
    return tmp;
}

node mk_node(){
    node tmp = {2019, null};
    return tmp;
}

void main() {
	immutable x = mk_node2(); //succeeds
    immutable y = mk_node(); //fails
}

December 05, 2019
On Thursday, 5 December 2019 at 12:00:23 UTC, Ola Fosheim Grøstad wrote:
> So basically, templated functions get flow-typing.

But it is not reliable :-(

struct node {int value; node* next;}

node n0 = {1,null};

node mk_node1()(node* n){
    node tmp = {2019, n};
    return tmp;
}


node mk_node2()(bool ok){
    node tmp = {2019, ok ? null : &n0};
    return tmp;
}

void main() {
    immutable y = mk_node1(null); //succeeds
	immutable x = mk_node2(true); //fails
}


1 2
Next ›   Last »