October 16, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sunday, October 16, 2011 19:13:09 Timon Gehr wrote:
> I don't agree that 'old' is very difficult to implement. Just evaluate what is inside the 'old' before you enter the in contract, store somewhere, maybe in hidden local variables, and make the data available in the out contract. Eiffel's 'old' does not do more than that.
>
> (but perhaps there are implementation details in DMD that make this more difficult than necessary. I don't know.)
What if you're dealing with a class? You'd need to deep copy the entire object for it to work. There's no way built into the language to do that (not to mention that it would be horrifically inefficient).
- Jonathan M Davis
|
October 16, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 10/16/2011 07:31 PM, Jonathan M Davis wrote:
> On Sunday, October 16, 2011 19:13:09 Timon Gehr wrote:
>> I don't agree that 'old' is very difficult to implement. Just evaluate
>> what is inside the 'old' before you enter the in contract, store
>> somewhere, maybe in hidden local variables, and make the data available
>> in the out contract. Eiffel's 'old' does not do more than that.
>>
>> (but perhaps there are implementation details in DMD that make this more
>> difficult than necessary. I don't know.)
>
> What if you're dealing with a class? You'd need to deep copy the entire object
> for it to work. There's no way built into the language to do that (not to
> mention that it would be horrifically inefficient).
>
> - Jonathan M Davis
Eiffel does not do that either.
(even though it _does_ have a built in deep copy feature)
We don't have to over-engineer the feature, if somebody needs to deep-copy an object they can implement it themselves and use old(obj.deepCopy()).
|
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Timon Gehr:
> Eiffel does not do that either.
> (even though it _does_ have a built in deep copy feature)
>
> We don't have to over-engineer the feature, if somebody needs to deep-copy an object they can implement it themselves and use old(obj.deepCopy()).
I agree. A shallow prestate is quite better than not having it at all in D.
Lately C# has implemented DbC, prestate too. I don't know how, but it's worth taking a look.
Bye,
bearophile
|
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On 17-10-2011 02:43, bearophile wrote: > Timon Gehr: > >> Eiffel does not do that either. >> (even though it _does_ have a built in deep copy feature) >> >> We don't have to over-engineer the feature, if somebody needs to >> deep-copy an object they can implement it themselves and use >> old(obj.deepCopy()). > > I agree. A shallow prestate is quite better than not having it at all in D. > > Lately C# has implemented DbC, prestate too. I don't know how, but it's worth taking a look. > > Bye, > bearophile Just for the record, the documentation is at: http://download.microsoft.com/download/C/2/7/C2715F76-F56C-4D37-9231-EF8076B7EC13/userdoc.pdf I agree that having old would be great, even if without deep copying (which is probably a terrible idea anyway). Also note that C# doesn't do deep copying here. - Alex |
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On 10/16/2011 9:35 PM, Alex Rønne Petersen wrote:
> On 17-10-2011 02:43, bearophile wrote:
>> Timon Gehr:
>>
>>> Eiffel does not do that either.
>>> (even though it _does_ have a built in deep copy feature)
>>>
>>> We don't have to over-engineer the feature, if somebody needs to
>>> deep-copy an object they can implement it themselves and use
>>> old(obj.deepCopy()).
>>
>> I agree. A shallow prestate is quite better than not having it at all
>> in D.
>>
>> Lately C# has implemented DbC, prestate too. I don't know how, but
>> it's worth taking a look.
>>
>> Bye,
>> bearophile
>
> Just for the record, the documentation is at:
> http://download.microsoft.com/download/C/2/7/C2715F76-F56C-4D37-9231-EF8076B7EC13/userdoc.pdf
>
>
> I agree that having old would be great, even if without deep copying
> (which is probably a terrible idea anyway). Also note that C# doesn't do
> deep copying here.
>
> - Alex
Remember, efficiency is not the point, correctness is. Contract code goes away in the release build. (Arguably you might want to keep *preconditions* in library code, since they vet your input parameters. But in practice those usually go away in release builds as well, even in Eiffel.)
-- Dai
|
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Monday, October 17, 2011 00:29:30 Timon Gehr wrote:
> On 10/16/2011 07:31 PM, Jonathan M Davis wrote:
> > On Sunday, October 16, 2011 19:13:09 Timon Gehr wrote:
> >> I don't agree that 'old' is very difficult to implement. Just evaluate
> >> what is inside the 'old' before you enter the in contract, store
> >> somewhere, maybe in hidden local variables, and make the data
> >> available
> >> in the out contract. Eiffel's 'old' does not do more than that.
> >>
> >> (but perhaps there are implementation details in DMD that make this
> >> more
> >> difficult than necessary. I don't know.)
> >
> > What if you're dealing with a class? You'd need to deep copy the entire object for it to work. There's no way built into the language to do that (not to mention that it would be horrifically inefficient).
> >
> > - Jonathan M Davis
>
> Eiffel does not do that either.
> (even though it _does_ have a built in deep copy feature)
>
> We don't have to over-engineer the feature, if somebody needs to
> deep-copy an object they can implement it themselves and use
> old(obj.deepCopy()).
I don't see how you could really expect to test the current state against the initial state when you don't actually save the initial state. And as far as implementing it yourself goes, you could go and do that that right now. You don't need compiler support to save the initial state somewhere and then test against it afterwards. It's just nicer if the compiler gives you support for it.
- Jonathan M Davis
|
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Davidson Corry | On 17-10-2011 07:59, Davidson Corry wrote:
> On 10/16/2011 9:35 PM, Alex Rønne Petersen wrote:
>> On 17-10-2011 02:43, bearophile wrote:
>>> Timon Gehr:
>>>
>>>> Eiffel does not do that either.
>>>> (even though it _does_ have a built in deep copy feature)
>>>>
>>>> We don't have to over-engineer the feature, if somebody needs to
>>>> deep-copy an object they can implement it themselves and use
>>>> old(obj.deepCopy()).
>>>
>>> I agree. A shallow prestate is quite better than not having it at all
>>> in D.
>>>
>>> Lately C# has implemented DbC, prestate too. I don't know how, but
>>> it's worth taking a look.
>>>
>>> Bye,
>>> bearophile
>>
>> Just for the record, the documentation is at:
>> http://download.microsoft.com/download/C/2/7/C2715F76-F56C-4D37-9231-EF8076B7EC13/userdoc.pdf
>>
>>
>>
>> I agree that having old would be great, even if without deep copying
>> (which is probably a terrible idea anyway). Also note that C# doesn't do
>> deep copying here.
>>
>> - Alex
>
> Remember, efficiency is not the point, correctness is. Contract code
> goes away in the release build. (Arguably you might want to keep
> *preconditions* in library code, since they vet your input parameters.
> But in practice those usually go away in release builds as well, even in
> Eiffel.)
>
> -- Dai
Right, but you don't want your debug builds to be so slow that it makes you unproductive either. Either way, an initial lightweight old() would already be much better than having nothing. :)
- Alex
|
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 10/17/2011 08:04 AM, Jonathan M Davis wrote: > On Monday, October 17, 2011 00:29:30 Timon Gehr wrote: >> On 10/16/2011 07:31 PM, Jonathan M Davis wrote: >>> On Sunday, October 16, 2011 19:13:09 Timon Gehr wrote: >>>> I don't agree that 'old' is very difficult to implement. Just evaluate >>>> what is inside the 'old' before you enter the in contract, store >>>> somewhere, maybe in hidden local variables, and make the data >>>> available >>>> in the out contract. Eiffel's 'old' does not do more than that. >>>> >>>> (but perhaps there are implementation details in DMD that make this >>>> more >>>> difficult than necessary. I don't know.) >>> >>> What if you're dealing with a class? You'd need to deep copy the entire >>> object for it to work. There's no way built into the language to do >>> that (not to mention that it would be horrifically inefficient). >>> >>> - Jonathan M Davis >> >> Eiffel does not do that either. >> (even though it _does_ have a built in deep copy feature) >> >> We don't have to over-engineer the feature, if somebody needs to >> deep-copy an object they can implement it themselves and use >> old(obj.deepCopy()). > > I don't see how you could really expect to test the current state against the > initial state when you don't actually save the initial state. There are practical examples where this would be required but most of the time the tests are simple enough that the old expression can carry all the state you need. Remember that all implementations of DbC that have prestate (and I am aware of) don't perform a deep copy automatically. Eg: abstract class Set{ @property int size(); bool contains(int x); void insert(int x) out{ assert( old(contains(x)) && size == old(size) || !old(contains(x)) && size == old(size)+1); assert(contains(old(x))); // possibly also require that everything that was // in the set before is still there [...] } } > And as far as > implementing it yourself goes, you could go and do that that right now. You > don't need compiler support to save the initial state somewhere and then test > against it afterwards. It's just nicer if the compiler gives you support for > it. > > - Jonathan M Davis As far as implementing it myself goes I could even do contract programming in the brainF programming language. =) The feature adds a lot of value to contract programming. I use contract programming occasionally and almost every contract I add eventually detects small bugs during the testing of new code parts. BTW: "Somewhere" would have to be on the execution stack because the function could be recursive. There is no way to refer to variables defined in the in contract from the out contract and doing the saving at any other place than in a contract is not acceptable for obvious reasons. |
October 17, 2011 Re: An old topic (pun intended) | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On Sun, 16 Oct 2011 19:09:46 +0200, Timon Gehr wrote: > On 10/13/2011 07:14 PM, Ali Çehreli wrote: >> On Thu, 13 Oct 2011 09:18:46 -0700, Jonathan M Davis wrote: >>> IIRC, old was rejected because it added extra complication for little value. >> >> Yes, there were technical difficulties in making the stack frame at the call point available to the stack frame at the exit point. >> >> > Why would that be required? I am not sure myself. I find this thread where Andrei says "Walter tried to implement that but it turned out to be very difficult implementation- wise": http://www.digitalmars.com/d/archives/digitalmars/D/ Communicating_between_in_and_out_contracts_98252.html Ali |
Copyright © 1999-2021 by the D Language Foundation