www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Immutable member functions on mutable objects

reply =?ISO-8859-1?Q?Tomek_Sowi=f1ski?= <just ask.me> writes:
I've got a problem calling an immutable getter on an "ordinary" object.

struct A {
    float _pole;
    float pole() immutable {
        return _pole;
    }
}

void main() {
    A a;
    auto x = a.pole;   // Ouch!
}

Error: function hello.A.pole () immutable is not callable using argument types
()

There's no problem when pole is const. I assume the problem is the hidden
"this" parameter (is it? the message is a bit confusing). Then again, A is
implicitly convertible to immutable(A) so there shouldn't be a problem, no?
Maybe a compiler bug?

BTW, can someone explain what's exactly the difference between a const and
immutable member function? The D page says only about the latter.

Tomek
Nov 29 2009
next sibling parent reply =?ISO-8859-1?Q?Tomek_Sowi=f1ski?= <just ask.me> writes:
Tomek Sowiński Wrote:

 I've got a problem calling an immutable getter on an "ordinary" object.
 [snip]
Weird: if I reverse the situation -- the object is immutable and function is ordinary -- I also get an error. struct A { float _pole; float pole() { return _pole; } } void main() { immutable A a; auto x = a.pole; // Ouch! } Error: function hello.A.pole () is not callable using argument types () Tomek
Nov 29 2009
parent =?ISO-8859-1?Q?Tomek_Sowi=f1ski?= <just ask.me> writes:
Tomek Sowiński Wrote:

 Weird: if I reverse the situation -- the object is immutable and function is
ordinary -- I also get an error.
 
 struct A {
     float _pole;
     float pole() {
         return _pole;
     }
 }
 
 void main() {
     immutable A a;
     auto x = a.pole;   // Ouch!
 }
 
 Error: function hello.A.pole () is not callable using argument types ()
Sorry, scratch that. The compiler tripped correctly; pole() could've altered its object through "this" (the error message could be clearer, though). So only my root post needs explaining.
Nov 29 2009
prev sibling next sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 29 Nov 2009 13:23:07 +0100, Tomek Sowi=C3=B1ski <just ask.me> wr=
ote:

 I've got a problem calling an immutable getter on an "ordinary" object=
.
 struct A {
     float _pole;
     float pole() immutable {
         return _pole;
     }
 }

 void main() {
     A a;
     auto x =3D a.pole;   // Ouch!
 }

 Error: function hello.A.pole () immutable is not callable using argume=
nt =
 types ()

 There's no problem when pole is const. I assume the problem is the  =
 hidden "this" parameter (is it? the message is a bit confusing). Then =
=
 again, A is implicitly convertible to immutable(A) so there shouldn't =
be =
 a problem, no? Maybe a compiler bug?

 BTW, can someone explain what's exactly the difference between a const=
=
 and immutable member function? The D page says only about the latter.

 Tomek
A is not implicitly castable to immutable(A), only to const(A). const member functions can be called on any A, unmarked ones only on A, and immutable ones only on immutable(A). Basically, immutable is there to give future optimization options, and immutable objects are not interchangable with mutable objects. const is the "missing link", allowing one to pass both mutable and immutable to a function taking const parameters. An explanation often given on these newsgroups is that const is a read-only view of the data, whereas immutable is a promise that the data will never change. -- = Simen
Nov 29 2009
parent reply =?ISO-8859-1?Q?Tomek_Sowi=f1ski?= <just ask.me> writes:
Simen kjaeraas Wrote:

 On Sun, 29 Nov 2009 13:23:07 +0100, Tomek SowiƱski <just ask.me> wrote:
 
 I've got a problem calling an immutable getter on an "ordinary" object.

 struct A {
     float _pole;
     float pole() immutable {
         return _pole;
     }
 }

 void main() {
     A a;
     auto x = a.pole;   // Ouch!
 }

 Error: function hello.A.pole () immutable is not callable using argument  
 types ()

 There's no problem when pole is const. I assume the problem is the  
 hidden "this" parameter (is it? the message is a bit confusing). Then  
 again, A is implicitly convertible to immutable(A) so there shouldn't be  
 a problem, no? Maybe a compiler bug?

 BTW, can someone explain what's exactly the difference between a const  
 and immutable member function? The D page says only about the latter.

 Tomek
A is not implicitly castable to immutable(A), only to const(A).
I think it is. This compiles: immutable a = A(3.4); But only because it's copied.
 const member functions can be called on any A, unmarked ones only
 on A, and immutable ones only on immutable(A).
Concise and enlightening. Thanks.
 Basically, immutable is there to give future optimization options,
 and immutable objects are not interchangable with mutable objects.
 const is the "missing link", allowing one to pass both mutable and
 immutable to a function taking const parameters.
 
 An explanation often given on these newsgroups is that const is a
 read-only view of the data, whereas immutable is a promise that
 the data will never change.
I more or less understand the const system on variables. It was the function annotations that got me. Before your answer my thinking was: a const function promises to leave "this" (and anything accessible through it?) alone. What more promise could marking a function immutable give? BTW, the future optimization options are about removing locks or something more? Tomek
Nov 29 2009
parent "Simen kjaeraas" <simen.kjaras gmail.com> writes:
On Sun, 29 Nov 2009 19:15:19 +0100, Tomek Sowi=C3=B1ski <just ask.me> wr=
ote:

 A is not implicitly castable to immutable(A), only to const(A).
I think it is. This compiles: immutable a =3D A(3.4); But only because it's copied.
Not quite. If you try immutable(A) a; a =3D A(3.4); you should find that it does not compile. Only because there must be a way to initialize immutable objects does your example compile.
 BTW, the future optimization options are about removing locks or  =
 something more?
Removing locks, yes. Also, pure functions take only immutable (or copied) parameters and may be optimized out if the same function is called several times with the same parameters. There may be other optimizations I am not aware of or do not remember OTOH. -- = Simen
Nov 29 2009
prev sibling next sibling parent BCS <none anon.com> writes:
Hello Tomek,

 I've got a problem calling an immutable getter on an "ordinary"
 object.
 
 struct A {
 float _pole;
 float pole() immutable {
 return _pole;
 }
 }
 void main() {
 A a;
 auto x = a.pole;   // Ouch!
 }
 Error: function hello.A.pole () immutable is not callable using
 argument types ()
 
immutable requiers that the value not be able to change void main() { A a; auto x = a.pole; a._pole++; auto y = a.pole; // pole returns something different than it did last time. }
Nov 30 2009
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Sun, 29 Nov 2009 07:23:07 -0500, Tomek SowiƱski <just ask.me> wrote:

 I've got a problem calling an immutable getter on an "ordinary" object.

 struct A {
     float _pole;
     float pole() immutable {
         return _pole;
     }
 }

 void main() {
     A a;
     auto x = a.pole;   // Ouch!
 }

 Error: function hello.A.pole () immutable is not callable using argument  
 types ()

 There's no problem when pole is const. I assume the problem is the  
 hidden "this" parameter (is it? the message is a bit confusing). Then  
 again, A is implicitly convertible to immutable(A) so there shouldn't be  
 a problem, no? Maybe a compiler bug?

 BTW, can someone explain what's exactly the difference between a const  
 and immutable member function? The D page says only about the latter.
Don't forget that: struct A { float pole() immutable {...} } is essentially syntax sugar for: struct A {} float pole(immutable ref A this) {...} It is a common misconception that const and immutable are *function* decorators. They are actually decorators for the hidden 'this' reference. When you look at it that way, it becomes hopefully much clearer how to deal with const and immutable. -Steve
Dec 01 2009