February 26, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #20 from timon.gehr@gmx.ch 2012-02-26 10:30:17 PST ---
(In reply to comment #19)
> (In reply to comment #17)
> > That assumption is bogus, because this is almost never the case. It makes contract programming basically unusable.  Such a strong weakening of the 'in' contract should not be the default.
> 
> It depends on how you look at it.

I look at it in a pragmatic way. Have you ever used the feature in any language?

> A function can, by default, accept
> any arguments of the types specified. I think the view taken is that
> the in contract supplements the parameter list,
> and the absence of an
> in contract with a given parameter list denotes an absence of further
> restrictions on what may be passed into the function.
> 

By symmetry, the view would have to be taken that the out contract supplements the return type. Do you see how that is problematic?

Whatever reason for the current behavior there might be come up with when thinking hard about it: The current behavior of DMD is not useful, and I refuse to believe that it is by design. I am not aware of any language that specifies such non-useful semantics for their contract inheritance.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 27, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856


Jesse Phillips <Jesse.K.Phillips+D@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |Jesse.K.Phillips+D@gmail.co
                   |                            |m


--- Comment #21 from Jesse Phillips <Jesse.K.Phillips+D@gmail.com> 2012-02-26 19:34:51 PST ---
(In reply to comment #15)
> There is no "B's in". That is the point. The bug is that an implicit 'in' contract that always passes is added to B.foo.

If I didn't supply an 'in' to the derived class function, I would expect not abiding by the base class contract to be an error. So I agree that an explicate foo() in{} should be used and that foo() in { assert(0); } looks like an ugly workaround, and would prefer not to restate the inherited class contract.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 27, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #22 from Don <clugdbug@yahoo.com.au> 2012-02-27 02:44:28 PST ---
(In reply to comment #17)
> > However, Don's proposal make sense (defining how contract is executed at callee's place instead of caller's place).
> 
> Don's proposal is to remove 'in' contract widening completely. That does not make a lot of sense to me.

I did NOT propose that. I merely stated that it's a niche feature, because it only applies when calling a derived function directly, which is unusual behaviour.

To restate:
If you call any function f, your call MUST satisfy the in contracts of that
function. If that function f has inherited a precondition from another function
fbase, then the precondition may be weaker than the precondition of fbase.

If f happens to ultimately be a call to fderived, with an even weaker precondition, that's irrelevant. You're not allowed to know that, it's an implementation detail -- you called f, not fderived. Only if you call fderived directly, are you allowed to take advantage of fderived's weaker precondition.

I think that DMD's precondition widening algorithm may be OK. It can even be OK for fderived to have no in contract. That means, that if you call it *directly*, there are no rules about parameters. But, this should not obviate the callers requirements inherited from fbase.

What this means in practice is that in contracts must be BEFORE the vtable lookup, rather than being in the body of the function.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 27, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #23 from timon.gehr@gmx.ch 2012-02-27 04:44:18 PST ---
(In reply to comment #22)
> (In reply to comment #17)
> > > However, Don's proposal make sense (defining how contract is executed at callee's place instead of caller's place).
> > 
> > Don's proposal is to remove 'in' contract widening completely. That does not make a lot of sense to me.
> 
> I did NOT propose that. I merely stated that it's a niche feature, because it only applies when calling a derived function directly, which is unusual behaviour.
> 

It is not very unusual. It may be infrequent in some systems but it is not unusual.

> To restate:
> If you call any function f, your call MUST satisfy the in contracts of that
> function. If that function f has inherited a precondition from another function
> fbase, then the precondition may be weaker than the precondition of fbase.
> 
> If f happens to ultimately be a call to fderived, with an even weaker precondition, that's irrelevant. You're not allowed to know that, it's an implementation detail -- you called f, not fderived. Only if you call fderived directly, are you allowed to take advantage of fderived's weaker precondition.
> 
> I think that DMD's precondition widening algorithm may be OK. It can even be OK for fderived to have no in contract.

Yes, but in that case the existing contract from the overridden method must be inherited. It is quite unusual that a child method has no constraints whatsoever on its input when there were reasons to constrain the valid input to the parent class.

> That means, that if you call it
> *directly*, there are no rules about parameters. But, this should not obviate
> the callers requirements inherited from fbase.

That is not what is wanted in practice.

> 
> What this means in practice is that in contracts must be BEFORE the vtable lookup, rather than being in the body of the function.

Yes, that is issue 6857.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 28, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #24 from Don <clugdbug@yahoo.com.au> 2012-02-27 22:14:03 PST ---
(In reply to comment #23)
> (In reply to comment #22)
> > What this means in practice is that in contracts must be BEFORE the vtable lookup, rather than being in the body of the function.
> 
> Yes, that is issue 6857.

OK, then this issue is quite simple.
All that seems to be required is, to define "no in() contract" to mean "use
default precondition". So that if a derived class has no in(), instead of
getting

base.in() || true

(which means that the precondition gets stripped away) it gets

base.in() || false.

(which means it uses the precondition from the base class). As now, an explicit
in{} strips the precondition away.
And nothing else needs to change.

Works?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 28, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #25 from timon.gehr@gmx.ch 2012-02-27 23:28:16 PST ---
Yes, I think that works. The issue can be resolved by making the default 'in' contract empty if the method is introduced without overriding another and 'assert(false)' if the method overrides another.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
May 03, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=6856


timon.gehr@gmx.ch changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |adam.chrapkowski@gmail.com


--- Comment #27 from timon.gehr@gmx.ch 2012-05-03 14:32:27 PDT ---
*** Issue 8027 has been marked as a duplicate of this issue. ***

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=6856


Stewart Gordon <smjg@iname.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement


--- Comment #28 from Stewart Gordon <smjg@iname.com> 2013-01-21 16:42:41 PST ---
Not sure why this wasn't flagged as INVALID before.  But now that the summary line's changed and some comments to the effect of it have been posted, it's essentially an enhancement request.  But it'll probably be rejected because the code breakage that would result.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=6856


bearophile_hugs@eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs@eml.cc


--- Comment #29 from bearophile_hugs@eml.cc 2013-01-21 17:12:25 PST ---
(In reply to comment #28)

> But it'll probably be rejected because the code breakage that would result.

In several cases breaking some code is the best solution. Is this one of those cases?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
January 22, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=6856



--- Comment #30 from timon.gehr@gmx.ch 2013-01-21 21:45:01 PST ---
(In reply to comment #28)
> Not sure why this wasn't flagged as INVALID before.  But now that the summary line's changed and some comments to the effect of it have been posted, it's essentially an enhancement request.

This issue makes the feature basically useless. About half the point of contracts is that they are inherited. The spec contains a bug. This is not a valid implementation of dbc.

> But it'll probably be rejected because the code breakage that would result.

Code is broken now, without contracts catching it because people do not care about tracking down all methods that override a method that specifies an in-contract and adding an in { assert(0); } contract.

It is basically never the case that a overridden method does not need to rely on any in-contract if the super class method does. This is stupid, and everyone actually using the feature will agree with me.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------