Thread overview | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
August 03, 2012 Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Hi,
This:
$ cat test.d
class A
{
int i;
invariant()
{
i = 42;
}
}
Currently doesn't compile:
$ dmd test.d
test.d(7): Error: can only initialize const member i inside constructor
(Obviously this example is silly, but it's just meant to illustrate the point of this thread.)
I believe this behavior is too strict. I don't agree that the language should dictate what *my* invariant can and cannot do. Not to mention that the standard library is far from const-friendly enough for this strictness to be practically reasonable today (I have tons of cast()s in my programs today due to this - not cool).
Does anyone else find this behavior too strict?
--
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
|
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On 03-08-2012 21:19, Alex Rønne Petersen wrote: > Hi, > > This: > > $ cat test.d > class A > { > int i; > > invariant() > { > i = 42; > } > } > > Currently doesn't compile: > > $ dmd test.d > test.d(7): Error: can only initialize const member i inside constructor > > (Obviously this example is silly, but it's just meant to illustrate the > point of this thread.) > > I believe this behavior is too strict. I don't agree that the language > should dictate what *my* invariant can and cannot do. Not to mention > that the standard library is far from const-friendly enough for this > strictness to be practically reasonable today (I have tons of cast()s in > my programs today due to this - not cool). > > Does anyone else find this behavior too strict? > I should also mention that invariants weren't const until very recently, so this is also quite the breaking change... -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Fri, 03 Aug 2012 21:19:22 +0200, Alex Rønne Petersen <alex@lycus.org> wrote: > Hi, > > This: > > $ cat test.d > class A > { > int i; > > invariant() > { > i = 42; > } > } > > Currently doesn't compile: > > $ dmd test.d > test.d(7): Error: can only initialize const member i inside constructor > > (Obviously this example is silly, but it's just meant to illustrate the point of this thread.) > > I believe this behavior is too strict. I don't agree that the language should dictate what *my* invariant can and cannot do. Not to mention that the standard library is far from const-friendly enough for this strictness to be practically reasonable today (I have tons of cast()s in my programs today due to this - not cool). > > Does anyone else find this behavior too strict? Votes++ In a perfect world... -- Simen |
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Fri, Aug 03, 2012 at 09:19:22PM +0200, Alex Rønne Petersen wrote: [...] > class A > { > int i; > > invariant() > { > i = 42; > } > } > > Currently doesn't compile: > > $ dmd test.d > test.d(7): Error: can only initialize const member i inside constructor [...] > I believe this behavior is too strict. [...] IMO, if you need to be changing stuff inside invariants, then you're using it wrong. Invariants are intended to verify program logic, not to do things like altering object state. The point is to be able to compile with invariant code turned off, and still have the program work exactly as before. T -- Be in denial for long enough, and one day you'll deny yourself of things you wish you hadn't. |
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | H. S. Teoh:
> IMO, if you need to be changing stuff inside invariants, then you're using it wrong. Invariants are intended to verify program logic, not to do things like altering object state. The point is to be able to compile with invariant code turned off, and still have the program work exactly as before.
I agree, modifying the state of the struct/class instance is not the job of contracts and invariants. D contract programming is already not tidy, so better to not make it even more messy.
In a perfect world invariants and contracts should be pure too!
Bye,
bearophile
|
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
On Fri, 03 Aug 2012 21:36:41 +0200, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote: > IMO, if you need to be changing stuff inside invariants, then you're > using it wrong. Invariants are intended to verify program logic, not to > do things like altering object state. The point is to be able to compile > with invariant code turned off, and still have the program work exactly > as before. True. Then add in a (standard) library that's not const-correct, and you have invariants that are outright unusable. -- Simen |
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to H. S. Teoh | On 03-08-2012 21:36, H. S. Teoh wrote: > On Fri, Aug 03, 2012 at 09:19:22PM +0200, Alex Rønne Petersen wrote: > [...] >> class A >> { >> int i; >> >> invariant() >> { >> i = 42; >> } >> } >> >> Currently doesn't compile: >> >> $ dmd test.d >> test.d(7): Error: can only initialize const member i inside constructor > [...] >> I believe this behavior is too strict. > [...] > > IMO, if you need to be changing stuff inside invariants, then you're > using it wrong. Invariants are intended to verify program logic, not to > do things like altering object state. The point is to be able to compile > with invariant code turned off, and still have the program work exactly > as before. > > > T > So what if, for whatever reason, the invariant needs to track and maintain some state in order to catch some kind of ugly bug? I agree that ideally an invariant should not ever need to change state. But I think in some cases it can be a useful debugging tool. But even ignoring that, making invariants const at this point in time is just not practical. We seem to be doing things in the completely wrong order. The library should be made const-friendly and *then* invariants could be made const (not that I want them to be anyway). -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjaeraas | On Friday, 3 August 2012 at 19:43:18 UTC, Simen Kjaeraas wrote:
> On Fri, 03 Aug 2012 21:36:41 +0200, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:
>
>> IMO, if you need to be changing stuff inside invariants, then you're
>> using it wrong. Invariants are intended to verify program logic, not to
>> do things like altering object state. The point is to be able to compile
>> with invariant code turned off, and still have the program work exactly
>> as before.
>
> True. Then add in a (standard) library that's not const-correct, and you
> have invariants that are outright unusable.
Personally I feel D's contracts are still a bit off of what Eiffel, .NET and Ada 2012 offer.
--
Paulo
|
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 8/3/2012 12:40 PM, bearophile wrote:
> H. S. Teoh:
>
>> IMO, if you need to be changing stuff inside invariants, then you're
>> using it wrong. Invariants are intended to verify program logic, not
>> to do things like altering object state. The point is to be able to
>> compile with invariant code turned off, and still have the program
>> work exactly as before.
>
> I agree, modifying the state of the struct/class instance is not the job
> of contracts and invariants. D contract programming is already not tidy,
> so better to not make it even more messy.
>
> In a perfect world invariants and contracts should be pure too!
Absolutely. Invariant clauses (and contract clauses generally) must not
have side effects, lest the class behavior change depending upon whether
or not they are compiled into the build. Assigning a value within the
invariant clause is definitely a side effect.
It is the job of the *constructor* to establish the invariant state,
not of the invariant clause (which only *verifies* it).
The compiler *should* be catching a side effect in the invariant clause,
if it can do so statically.
|
August 03, 2012 Re: Let's not make invariants const | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On 8/3/2012 1:14 PM, Paulo Pinto wrote: > Personally I feel D's contracts are still a bit off of what Eiffel, .NET and Ada 2012 offer. On 8/3/2012 1:01 PM, Alex Rønne Petersen wrote: > So what if, for whatever reason, the invariant needs to track and > maintain some state in order to catch some kind of ugly bug? > > I agree that ideally an invariant should not ever need to change state. > But I think in some cases it can be a useful debugging tool. The "track and maintain some state" bit usually means capturing some state at entry to the class (via a public method), so that the invariant can at exit from the class compare the new, possibly modified, state to the previous one. This is the purpose of Eiffel's 'old' construct, which D does not have. (Yet.) (One hopes.) (And it would be nice to be able to capture an old *expression* and not just an old variable.) 'old' is used more often with postconditions than with invariants, but it can be useful in both. > But even ignoring that, making invariants const at this point in time is > just not practical. We seem to be doing things in the completely wrong > order. The library should be made const-friendly and *then* invariants > could be made const (not that I want them to be anyway). Certainly the libraries should be made as const-correct as possible. But it's not like we are forced to do only the one or the other (except for the insufficient supply of Walters, perhaps...). IMO, invariants should "be made const" (i.e. statically check for side effects) as discussed elsewhere. In fact, I believe that having more rigorous contract checks could *help* improve library code, by making it harder for loose code to get into the library. |
Copyright © 1999-2021 by the D Language Foundation