Thread overview
Immutable member functions on mutable objects
Nov 29, 2009
Tomek Sowiñski
Nov 29, 2009
Tomek Sowiñski
Nov 29, 2009
Tomek Sowiñski
Nov 29, 2009
Simen kjaeraas
Nov 29, 2009
Tomek Sowiñski
Nov 29, 2009
Simen kjaeraas
Nov 30, 2009
BCS
November 29, 2009
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
November 29, 2009
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
November 29, 2009
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.
November 29, 2009
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).
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
November 29, 2009
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

November 29, 2009
On Sun, 29 Nov 2009 19:15:19 +0100, Tomek Sowiñski <just@ask.me> wrote:

>> 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.

Not quite. If you try

immutable(A) a;
a = 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
November 30, 2009
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.
}


December 01, 2009
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