On Sunday, 13 May 2012 at 22:51:05 UTC, Jonathan M Davis wrote:
> Walter fully intends to require that opEquals, opCmp, toHash,
> and toString all be const @safe pure nothrow - on both classes
> and structs. And the reality of the matter is, if that
> requirement _isn't_ there on classes, then the usage of any of
> those functions in @safe, const, pure, or nothrow code is
> seriously hampered - especially const and pure. This has been
> discussed quite a bit before, and we're pretty much stuck
> thanks to transitivity.
I've been wondering sometimes, if beta builds could be made (but
not official release builds) that enforce the way it's suppose to
be, and then we can try to compile against that version and see
how much difference or how much breaks. The problem may not be
quite as bad as we think it is. Honestly I don't see why oEquals,
opCmp and toHash can't be const (as the data shouldn't change).
toString and toHash may want to cache it's current result
(perhaps?).

On Monday, May 14, 2012 02:11:21 Era Scarecrow wrote:
> On Sunday, 13 May 2012 at 22:51:05 UTC, Jonathan M Davis wrote:
> > Walter fully intends to require that opEquals, opCmp, toHash,
> > and toString all be const @safe pure nothrow - on both classes
> > and structs. And the reality of the matter is, if that
> > requirement _isn't_ there on classes, then the usage of any of
> > those functions in @safe, const, pure, or nothrow code is
> > seriously hampered - especially const and pure. This has been
> > discussed quite a bit before, and we're pretty much stuck
> > thanks to transitivity.
>
> I've been wondering sometimes, if beta builds could be made (but
> not official release builds) that enforce the way it's suppose to
> be, and then we can try to compile against that version and see
> how much difference or how much breaks. The problem may not be
> quite as bad as we think it is.
It doesn't work right now due to issues with druntime and Phobos. For
instance, format and to!string can't be pure yet due to lower level constructs
that they use which aren't marked pure. Appender has similar problems. Without
those, toString really can't be const. I think that there are some issues with
toHash as well due to the state of the AA implementation in druntime. Some of
those issues are being addressed, but there's still a ways to go.
But in a way, it doesn't matter how much making those 4 functions const @safe
pure nothrow will break, because we _have_ to do it. So, what will break, will
break. When they're made const @safe pure nothrow on Object, it'll
_immediately_ break code, and there's _no_ way around it. So, at this point,
I'd say that it's really a matter of figuring out exactly what needs to be fixed
in druntime and Phobos to make it possible, and once that's been fixed, we
immediately change Object and and require that those 4 functions have those 4
attributes. Then everyone can take care of it in their code at once and we
won't have to worry about it anymore. Lacking a means of phasing it in (like
we're doing with other stuff like -property), I don't see any other way of
doing it.
> Honestly I don't see why oEquals,
> opCmp and toHash can't be const (as the data shouldn't change).
> toString and toHash may want to cache it's current result
> (perhaps?).
They can be in almost all cases. The problem is the folks who want to have
caching and/or lazy initiailization in their classes/structs. You can't cache
the result of any of those functions (toHash being the main target for it) if
they're const and pure except in overloads which _aren't_ const, making those
functions more expensive in comparison to what they could be if they weren't
required to be const. And lazy initialization becomes almost impossible,
because if the member variables needed in those functions haven't been
initialized yet when they're called, then you _can't_ initialize them. If
getting the value that it _would_ be without actually initializing the member
variable works, then you can do that if it hasn't been initialized, but if you
can't do that (e.g. the variable _must_ be set only once), then you're
screwed. And regardless of whether you can make it work with const, it _will_
be less efficient.
So, the folks who really like to use lazy initialization and caching are _not_
going to be happy about this. They've complained every time that it's been
discussed. But that's just one of the costs of const in D. Whether its pros
outweigh that cost is a matter of opinion.
- Jonathan M Davis

On Monday, 14 May 2012 at 02:48:20 UTC, Jonathan M Davis wrote:
> But that's just one of the costs of const in D.
The problem is that it's unavoidable.
i.e. you can't say "don't mark it as const if it isn't const",
because, practically speaking, it's being forced onto the
programmers by the language.

On Monday, 14 May 2012 at 02:57:57 UTC, Mehrdad wrote:
> On Monday, 14 May 2012 at 02:48:20 UTC, Jonathan M Davis wrote:
>> But that's just one of the costs of const in D.
>
> The problem is that it's unavoidable.
>
> I.e. you can't say "don't Mark it as const if it isn't const",
> because, practically speaking, it's being forced onto the
> programmers by the language.
With const and immutable being transitive, there are cases when
there's things you want to do with an object after you've made it
and it's in a const structure. I know I've made a struct that was
intended to hold immutable data, however it refused to allow
methods to until const was appended to the signatures of the
functions. At first it was annoying; But when I see bigger
picture of why it makes much more sense.
Nothing we make 'has' to have const on it but inevitably they
may be used in a read-only way. I'm trying to think of it as my
structs and classes being as const-friendly as possible in those
cases.

On Monday, May 14, 2012 05:09:28 Era Scarecrow wrote:
> On Monday, 14 May 2012 at 02:57:57 UTC, Mehrdad wrote:
> > On Monday, 14 May 2012 at 02:48:20 UTC, Jonathan M Davis wrote:
> >> But that's just one of the costs of const in D.
> >
> > The problem is that it's unavoidable.
> >
> > I.e. you can't say "don't Mark it as const if it isn't const",
> > because, practically speaking, it's being forced onto the
> > programmers by the language.
>
> With const and immutable being transitive, there are cases when
> there's things you want to do with an object after you've made it
> and it's in a const structure. I know I've made a struct that was
> intended to hold immutable data, however it refused to allow
> methods to until const was appended to the signatures of the
> functions. At first it was annoying; But when I see bigger
> picture of why it makes much more sense.
>
> Nothing we make 'has' to have const on it but inevitably they
> may be used in a read-only way. I'm trying to think of it as my
> structs and classes being as const-friendly as possible in those
> cases.
In general, you _can_ avoid const completely if you want to. However, with
opEquals, opCmp, toHash, and toString being const @safe pure nothrow, you
_can't_ avoid it completely - at least not entirely cleanly.
You could have non-const overloads which did what you wanted and make the
normal const ones assert(0) if they're called. But you're basically forced to
work around const in this case. This is in definite contrast to C++ where you
_can_ avoid const completely if you want to.
But with the way const in D works, I suspect that the folks who are looking
for absolutely every CPU cycle and want caching and lazy-loading in their
types are going to avoid const as completely as possible and figure out how to
work around it for those 4 functions, whereas in C++, they'd probably use
const liberally and use mutable where necessary.
- Jonathan M Davis

On Monday, 14 May 2012 at 03:19:57 UTC, Jonathan M Davis wrote:
> But with the way const in D works, I suspect that the folks who
> are looking for absolutely every CPU cycle and want caching and
> lazy-loading in their types are going to avoid const as
> completely as possible and figure out how to work around it for
> those 4 functions, whereas in C++, they'd probably use const
> liberally and use mutable where necessary.>
Seems like perhaps the opposite approach (limited of course)
could be taken. Assume a 'mutable' keyword was used, where in the
case an object/struct was made const, it would allow you to break
the const system only for that variable. Could work, assuming
it's not accessing ROM or something.
struct A {
string st;
mutable uint hash; //always mutable
uint toHash() {
if (!hash)
hash = st.toHash();
return hash;
}
}
unittest{
A a = A("TEST");
immutable A b = A("TEST");
assert(a.toHash() == b.toHash());
}
But that seems like a badly done workaround, and if you really
wanted the hash cached, you would have it calculated during
construction before it was returned. Something like that is
likely more trouble than it's worth, plus it would easily be
abused.

On 5/13/2012 8:19 PM, Jonathan M Davis wrote:
> This is in definite contrast to C++ where you
> _can_ avoid const completely if you want to.
That's because C++ const is just documentation for the programmer, and offers no
reliable enforcement.

On 14-05-2012 05:19, Jonathan M Davis wrote:
> On Monday, May 14, 2012 05:09:28 Era Scarecrow wrote:
>> On Monday, 14 May 2012 at 02:57:57 UTC, Mehrdad wrote:
>>> On Monday, 14 May 2012 at 02:48:20 UTC, Jonathan M Davis wrote:
>>>> But that's just one of the costs of const in D.
>>>
>>> The problem is that it's unavoidable.
>>>
>>> I.e. you can't say "don't Mark it as const if it isn't const",
>>> because, practically speaking, it's being forced onto the
>>> programmers by the language.
>>
>> With const and immutable being transitive, there are cases when
>> there's things you want to do with an object after you've made it
>> and it's in a const structure. I know I've made a struct that was
>> intended to hold immutable data, however it refused to allow
>> methods to until const was appended to the signatures of the
>> functions. At first it was annoying; But when I see bigger
>> picture of why it makes much more sense.
>>
>> Nothing we make 'has' to have const on it but inevitably they
>> may be used in a read-only way. I'm trying to think of it as my
>> structs and classes being as const-friendly as possible in those
>> cases.
>
> In general, you _can_ avoid const completely if you want to. However, with
> opEquals, opCmp, toHash, and toString being const @safe pure nothrow, you
> _can't_ avoid it completely - at least not entirely cleanly.
Don't forget contracts. The this reference is now const inside those
too. This can get painful sometimes when you really don't want the this
reference to be const inside your invariants. With 2.058, I had to
insert a lot of cast()s to throw const away inside those. So...
effectively, it's pretty hard to avoid const unless you don't use
contracts at all.
>
> You could have non-const overloads which did what you wanted and make the
> normal const ones assert(0) if they're called. But you're basically forced to
> work around const in this case. This is in definite contrast to C++ where you
> _can_ avoid const completely if you want to.
>
> But with the way const in D works, I suspect that the folks who are looking
> for absolutely every CPU cycle and want caching and lazy-loading in their
> types are going to avoid const as completely as possible and figure out how to
> work around it for those 4 functions, whereas in C++, they'd probably use
> const liberally and use mutable where necessary.
>
> - Jonathan M Davis
It's kinda funny that something which on dlang.org's FAQ is described as
a compiler optimization hint (http://dlang.org/const-faq.html#const)
isn't useful at all for this purpose...
--
- Alex

On Monday, 14 May 2012 at 02:57:57 UTC, Mehrdad wrote:
> The problem is that it's unavoidable.
>
> i.e. you can't say "don't mark it as const if it isn't const",
> because, practically speaking, it's being forced onto the
> programmers by the language.
You're really against const in this language, huh?
Let me ask you something: Could you try to name 2 or 3 good
things about const/immutable without looking it up? If not,
you've really not given enough effort to learning about the
benefits of it.

On Monday, May 14, 2012 05:47:54 Alex Rønne Petersen wrote:
> It's kinda funny that something which on dlang.org's FAQ is described as
> a compiler optimization hint (http://dlang.org/const-faq.html#const)
> isn't useful at all for this purpose...
Oh, it's definitely useful for optimizations. It just doesn't work with a
couple of idioms that some programmers like to use in order to optimize their
code.
- Jonathan M Davis