July 11, 2012
On Wednesday, 11 July 2012 at 15:59:21 UTC, deadalnix wrote:
> If it cannot and should not be const, it isn't a comparison or an equality test, it is another operation altogether that is performed.

That's bullshit. You've seen the example I raised. How can you tell me it's not an equality test?
July 11, 2012
On Wednesday, 11 July 2012 at 15:27:55 UTC, Andrei Alexandrescu wrote:

> I think I'll find it rather difficult to get behind modeling arbitrary escapes from immutability. If you want classes, you buy into a certain contract with inherent rights and constraints (starting with using references). It's a given, and again I find it unreasonable to ask that classes allow for arbitrary customization.

Some classes don't lend themselves to immutability. Let's take something obvious like a class object representing a dataset in a database. How is an immutable instance of such a class useful?

The solution to this problem is obvious and right there for us to use, the only thing arbitrary here is the limitation we put on classes by not using it.

> Your LuaD example goes like this:
>
>     /**
>      * Compare this object to another with Lua's equality semantics.
>      * Also returns false if the two objects are in different Lua states.
>      */
>     bool opEquals(T : LuaObject)(ref T o) @trusted
>     {
>         if(o.state != this.state)
>             return false;
>
>         push();
>         o.push();
>         scope(success) lua_pop(state, 2);
>
>         return lua_equal(state, -1, -2);
>     }
>
> You may be able to make this work by putting the state associated with push() and pop() in the Cache subsystem.

Sounds like the kind of workaround people would accompany with a nasty comment.

> If all else breaks, have opEquals assert(false, "Call bool lua_equals()").

This is exactly what I was talking about earlier. opEquals failed me for no good reason, so I'm begrudgingly going to leave an assert behind and give up, writing my own method. As mentioned, this has far-reaching consequences for anything that relies on opEquals.

> We can't really model every possible design.

No, but apparently we can model this one quite readily.

July 11, 2012
On 7/11/12 1:04 PM, Timon Gehr wrote:
> On 07/11/2012 06:45 PM, Andrei Alexandrescu wrote:
>> On 7/11/12 12:30 PM, H. S. Teoh wrote:
>>> It *is* a problem when you're talking about abstractions. If I have
>>> million node binary trees and I'm testing for equality, I'd like to be
>>> able to cache the results. But being forced to use const means I can't
>>> cache anything. And this isn't just about caching; if my tree is
>>> partially stored in the database, and I have a DB connection object in
>>> my tree class, then I can't use opEquals because I can't modify the DB
>>> state (which is impractical if I have to actually use it to make DB
>>> queries -- the DB engine may have to cache DB pages, etc.). Any
>>> abstraction of opEquals beyond the bitwise level cannot be implemented.
>>
>> How about the static hash/cache?
>>
>> Andrei
>
> Will break horribly as soon as it is discovered that the methods should
> be pure as well.

I don't think they should be pure. Do you have reasons to think otherwise?

Andrei
July 11, 2012
On 11/07/2012 19:32, Jakob Ovrum wrote:
> On Wednesday, 11 July 2012 at 15:59:21 UTC, deadalnix wrote:
>> If it cannot and should not be const, it isn't a comparison or an
>> equality test, it is another operation altogether that is performed.
>
> That's bullshit. You've seen the example I raised. How can you tell me
> it's not an equality test?

To be fair, I know nothing about LUA.

But you are talking here about discussing with another language, so, by definition, don't have the same semantic than D. You'll have to do unsafe things at jointures point in such case, I seems obvious to me.
July 11, 2012
On 7/11/12 1:40 PM, Jakob Ovrum wrote:
> Some classes don't lend themselves to immutability. Let's take something
> obvious like a class object representing a dataset in a database. How is
> an immutable instance of such a class useful?

This is a good point. It seems we're subjecting all classes to certain limitations for the benefit of a subset of those classes.

Andrei
July 11, 2012
On 11/07/2012 19:46, Andrei Alexandrescu wrote:
> On 7/11/12 1:04 PM, Timon Gehr wrote:
>> On 07/11/2012 06:45 PM, Andrei Alexandrescu wrote:
>>> On 7/11/12 12:30 PM, H. S. Teoh wrote:
>>>> It *is* a problem when you're talking about abstractions. If I have
>>>> million node binary trees and I'm testing for equality, I'd like to be
>>>> able to cache the results. But being forced to use const means I can't
>>>> cache anything. And this isn't just about caching; if my tree is
>>>> partially stored in the database, and I have a DB connection object in
>>>> my tree class, then I can't use opEquals because I can't modify the DB
>>>> state (which is impractical if I have to actually use it to make DB
>>>> queries -- the DB engine may have to cache DB pages, etc.). Any
>>>> abstraction of opEquals beyond the bitwise level cannot be implemented.
>>>
>>> How about the static hash/cache?
>>>
>>> Andrei
>>
>> Will break horribly as soon as it is discovered that the methods should
>> be pure as well.
>
> I don't think they should be pure. Do you have reasons to think otherwise?
>
> Andrei

I think they should. Comparing the same object 2 time should definitively have the same result back, otherwise things will go horribly wrong soon enough.
July 11, 2012
On 7/11/12 1:49 PM, deadalnix wrote:
> I think they should. Comparing the same object 2 time should
> definitively have the same result back, otherwise things will go
> horribly wrong soon enough.

Yah, but e.g. a comparison may log something.

Andrei
July 11, 2012
On Wednesday, 11 July 2012 at 17:47:41 UTC, deadalnix wrote:
> To be fair, I know nothing about LUA.

It's "Lua".

> But you are talking here about discussing with another language, so, by definition, don't have the same semantic than D.

This is irrelevant. The Lua API is a C library like any other.

Feel free to imagine that the example is one of a class mapping to data in a database, and the equality test includes accessing the database.

> You'll have to do unsafe things at jointures point in such case, I seems obvious to me.

No, I don't have to do this, your assertion is baseless. The LuaD library is fairly complete (though there's still a lot of room for higher-level features), and the example posted works fine and will work fine for the time being because the aggregate is a struct, not a class, and will remain so. I don't have to subvert the type system in that module at all.
July 11, 2012
On 11/07/2012 19:49, Andrei Alexandrescu wrote:
> On 7/11/12 1:40 PM, Jakob Ovrum wrote:
>> Some classes don't lend themselves to immutability. Let's take something
>> obvious like a class object representing a dataset in a database. How is
>> an immutable instance of such a class useful?
>
> This is a good point. It seems we're subjecting all classes to certain
> limitations for the benefit of a subset of those classes.
>
> Andrei

Did you saw the proposal of feep/tgehr on #d ?

It basically state that you can overload a const method with a non const one if :
 - You don't mutate any data that belong to the parent.
 - You are prevented to create any immutable instance of that classe or any subclasse.
July 11, 2012
On 11/07/2012 19:58, Jakob Ovrum wrote:
> No, I don't have to do this, your assertion is baseless. The LuaD
> library is fairly complete (though there's still a lot of room for
> higher-level features), and the example posted works fine and will work
> fine for the time being because the aggregate is a struct, not a class,
> and will remain so. I don't have to subvert the type system in that
> module at all.

I don't say you have to. I say, you may need to. Because the language you are interfacing with have different semantics.