August 17, 2012
On Friday, 17 August 2012 at 00:32:03 UTC, Mehrdad wrote:
> On Friday, 17 August 2012 at 00:10:52 UTC, Jonathan M Davis wrote:
>> In contrast, in D,
>>
>> const ref Array!(T*) getStuff() const;
>>
>> you would _know_ that not only is the container not altered,
>> but you know that the elements aren't altered either -
>> or anything which the elements point to.
>
>
> I'm not so sure about that.
> ...snip...

Your example is not equivalent to what he was saying.

Also, D's const is _not_ a guarantee that there are no mutable references to something. That'd be immutable. It just says that it's illegal to modify something which is const (... i.e. _directly_ ... obviously, you can modify something which is const via a mutable reference dangling around, but that's _not_ something that const is supposed to protect you from)

>
> Right, it's the equivalent of static fields, see my example above.

ditto to above
August 17, 2012
2012/8/17 Jonathan M Davis <jmdavisProg@gmx.com>
>
> On Friday, August 17, 2012 02:32:01 Mehrdad wrote:
> > > C++ makes no such guarantees, because you're free to cast away const and modifiy objects
> >
> > Not correct, as far as I understand.
> > C++ only lets you cast away _const references_ to _mutable_
> > objects.
> > If the object happens to have been const _itself_, then that's
> > undefined behavior.
>
> Well, then our understandings on the matter conflict, and I don't know for certain which of us is correct.
>
> - Jonathan M Davis


The C++ standard, section 7.1.6.1:

Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const
 object during its lifetime (3.8) results in undefined behavior.

Torarin
August 17, 2012
On Friday, 17 August 2012 at 00:44:20 UTC, Chris Cain wrote:
> Also, D's const is _not_ a guarantee that there are no mutable references to something. That'd be immutable.

And, by the way, I'd call this a bug (not sure if reported yet):



int yourGlobalCounter;

struct S
{
    int*[] items;

    this(int i)
    {
        items = new int*[1];
        items[0] = &yourGlobalCounter;
        yourGlobalCounter = i;
    }

    ref const(int*[]) getItems() const
    {
        ++yourGlobalCounter;
        return items;
    }
}

import std.stdio;

void main() {
    immutable(S) s = immutable(S)(0);
    auto it = s.getItems();
    writeln(*it[0]);
    s.getItems();
    writeln(*it[0]);
}


August 17, 2012
On Friday, 17 August 2012 at 00:44:20 UTC, Chris Cain wrote:
> On Friday, 17 August 2012 at 00:32:03 UTC, Mehrdad wrote:
>> On Friday, 17 August 2012 at 00:10:52 UTC, Jonathan M Davis wrote:
>>> In contrast, in D,
>>>
>>> const ref Array!(T*) getStuff() const;
>>>
>>> you would _know_ that not only is the container not altered,
>>> but you know that the elements aren't altered either -
>>> or anything which the elements point to.
>>
>>
>> I'm not so sure about that.
>> ...snip...
>
> Your example is not equivalent to what he was saying.


How?


Jon said "you know that the elements aren't altered either - or anything which the elements point to".


I just showed that the const-ness of getStuff() tells you _nothing_ about that fact.

Did I miss something?
August 17, 2012
On Friday, 17 August 2012 at 00:51:55 UTC, Torarin wrote:
>
> The C++ standard, section 7.1.6.1:
>
> Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.
>
> Torarin


+1 thanks for taking the time to look it up. :)
August 17, 2012
On Friday, 17 August 2012 at 01:17:19 UTC, Mehrdad wrote:
>
> How?
>
>
> Jon said "you know that the elements aren't altered either - or anything which the elements point to".
>
>
> I just showed that the const-ness of getStuff() tells you _nothing_ about that fact.
>
> Did I miss something?

Yeah. Again, you can't modify __the const view__. It's legal for const things to be mutable underneath. And it's legal to modify mutable things via mutable views. Ergo, const things can change that way. But that's not what he's trying to tell you.

If you want something to be guaranteed to never change through any means, you use immutable. And if you find a way to mutate immutable things (without casts), it's a bug, not a feature (and thus should be reported).

I'm pretty sure everyone's aware of the inconsistency with immutable and the constructors at this time (like the bug I pointed out above), so that's kind of a weak point where the programmer actually has to know what they're doing, but I'm sure that'll be fixed at some point.
August 17, 2012
Just to be abundantly clear about his point.

// v is a const vector, but holds pointers ...

*v[0] = 5; // legal in C++, illegal in D (except in constructors which will allow this, ATM)

Transitivity gives you more information and guarantees about what you can and can't do with your view. Also, if the only view of the data you have is that const view, it's effectively the same as immutable (it couldn't be changed by any valid code).
August 17, 2012
On Friday, 17 August 2012 at 01:25:18 UTC, Chris Cain wrote:
> Yeah. Again, you can't modify __the const view__.

Isn't that kinda useless, if it tells you nothing about the object itself?
August 17, 2012
Also note that Jon __clearly__ said:

"you know that the elements aren't altered either anything which the elements point to".



He was clearly _not_ talking about modifying the pointer.
He said you cannot alter the "elements pointed TO".


Given that, I have no idea how that is supposed to be saying "you can't modify the const _view_". He's clearly talking about the target of the pointer, not the pointer itself.
August 17, 2012
On Friday, 17 August 2012 at 01:43:03 UTC, Mehrdad wrote:
> Isn't that kinda useless, if it tells you nothing about the object itself?

Not sure what your point is. It tells you enough about how you work with that "object itself" and sets (real) boundaries which is unlike C++'s const which tells you truly nothing. Seems pretty useful in my eyes. C++'s const is the thing that's really useless.

It's an abstraction, and like all abstractions, you don't necessarily get a perfect understanding of the bits and bytes and where they are and how they're going to function. But it does give you more reasoning ability about your code if used properly. Plus don't forget that it allows you to use the same code for immutable and mutable objects, which is extremely valuable.