www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Making preconditions better specified and faster

reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
https://issues.dlang.org/show_bug.cgi?id=16975
Dec 15 2016
next sibling parent reply qznc <qznc web.de> writes:
On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
Alexandrescu wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
Whenever I think about preconditions and speed, I think that they should actually be put into the caller instead of into the function/callee. The chance that intra-procedural optimization can remove the checks increases. Of course, inlining voids the discussion, but think about the non-inline case. pragma(inline, false) int twice(int x) in { assert(x < int.max / 2); } body { return x + x; } void main() { int x = 42; int y = twice(x); } You can put the check at the front of twice, which makes it necessary to evaluate the check at runtime. Alternatively, put the check into the main function, where constant propagation and folding can easily remove the check. Obviously, the downside is code size when precondition-functions are called from more than one point. (This is probably off-topic for the issue, thus my comment here)
Dec 16 2016
parent deadalnix <deadalnix gmail.com> writes:
On Friday, 16 December 2016 at 10:28:03 UTC, qznc wrote:
 On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
 Alexandrescu wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
Whenever I think about preconditions and speed, I think that they should actually be put into the caller instead of into the function/callee.
Not only faster, but this is the right thing to do. Failing precondition is a caller error, not a callee. Beside optimization: - The error will be reported at the right place. - The compilation flags of the caller decide if the contract is checked, not the callee.
Dec 18 2016
prev sibling next sibling parent Marco Leise <Marco.Leise gmx.de> writes:
Am Thu, 15 Dec 2016 13:48:22 -0500
schrieb Andrei Alexandrescu <SeeWebsiteForEmail erdani.org>:

 https://issues.dlang.org/show_bug.cgi?id=16975
Here is what I understood. While currently a contract that has a failing assert would be treated differently from one that throws an exception, in the future all kinds of errors would make it return false instead of true. What's not explicitly mentioned is what happens from there on, but I assume that 'false' leads to some handler function in druntime being invoked? Also when you write that unrecoverable errors "cannot be the case" in contracts, what do you mean by that? A) Consider all contracts to have no side-effects. In case of 'false' return, throw a ContractFailedException and continue execution in the caller. B) That was meant to read "may not be the case". A failed assert would cause the contract to return 'false', while an Exception would be propagated to the outside. The former is unrecoverable, the latter is recoverable. (Note: That contradicts what I understood above.) C) Something else. (I bet that's the correct answer.) -- Marco
Dec 16 2016
prev sibling parent reply Caspar Kielwein <caspar kielwein.de> writes:
On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
Alexandrescu wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
I like it. It's a step in the right direction of making contracts more powerful. I'd love if preconditions where available at the caller. This would make it possible to use preconditions for input scrubbing, even in release builds with disabled asserts.
Dec 18 2016
parent reply Stefan Koch <uplink.coder googlemail.com> writes:
On Sunday, 18 December 2016 at 09:32:53 UTC, Caspar Kielwein 
wrote:
 On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
 Alexandrescu wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
I'd love if preconditions where available at the caller. This would make it possible to use preconditions for input scrubbing, even in release builds with disabled asserts.
That is exactly what they are not for.
Dec 18 2016
parent reply Caspar Kielwein <Caspar Kielwein.de> writes:
On Sunday, 18 December 2016 at 10:47:42 UTC, Stefan Koch wrote:
 On Sunday, 18 December 2016 at 09:32:53 UTC, Caspar Kielwein 
 wrote:
 On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
 Alexandrescu wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
I'd love if preconditions where available at the caller. This would make it possible to use preconditions for input scrubbing, even in release builds with disabled asserts.
That is exactly what they are not for.
I know that contracts are for specifying guarantees and conditions in regards to correctness of a program. Still, at the first point where I call a function with user inputs, I often have to pretty much repeat the precondition of that function (but react different on violation) to scrub the inputs. I think it would be nice to be able to make the conscious choice of using the specified precondition for that.
Dec 18 2016
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/18/2016 04:24 PM, Caspar Kielwein wrote:
 On Sunday, 18 December 2016 at 10:47:42 UTC, Stefan Koch wrote:
 On Sunday, 18 December 2016 at 09:32:53 UTC, Caspar Kielwein wrote:
 On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei Alexandrescu
 wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
I'd love if preconditions where available at the caller. This would make it possible to use preconditions for input scrubbing, even in release builds with disabled asserts.
That is exactly what they are not for.
I know that contracts are for specifying guarantees and conditions in regards to correctness of a program.
A simple way to look at this is: a program may build and run with all contracts disabled. If correct, there should be no change in semantics. Is a contract therefore a right place to make sure your files are not corrupt etc? -- Andrei
Dec 18 2016
parent Caspar Kielwein <Caspar Kielwein.de> writes:
On Sunday, 18 December 2016 at 21:58:57 UTC, Andrei Alexandrescu 
wrote:
 On 12/18/2016 04:24 PM, Caspar Kielwein wrote:
 On Sunday, 18 December 2016 at 10:47:42 UTC, Stefan Koch wrote:
 On Sunday, 18 December 2016 at 09:32:53 UTC, Caspar Kielwein 
 wrote:
 On Thursday, 15 December 2016 at 18:48:22 UTC, Andrei 
 Alexandrescu
 wrote:
 https://issues.dlang.org/show_bug.cgi?id=16975
I'd love if preconditions where available at the caller. This would make it possible to use preconditions for input scrubbing, even in release builds with disabled asserts.
That is exactly what they are not for.
I know that contracts are for specifying guarantees and conditions in regards to correctness of a program.
A simple way to look at this is: a program may build and run with all contracts disabled. If correct, there should be no change in semantics. Is a contract therefore a right place to make sure your files are not corrupt etc? -- Andrei
I'll try clarify what I mean. I absolutely agree that contracts assert the correctness of the program and not of user inputs. When I pass user inputs to functions with preconditions, I need to validate these inputs to make sure the function call and thus my program is correct. The code for this validation is often redundant to the specification of the precondition in it's logic. It of cause has a very different effect and often different syntax. I'd like to write something like: try{ foo.verified(x); } catch { ... } To manually call the check of the precondition and avoid the duplication and possibility of missing a case. Another case (which hits me in my job writing c++) is when I call performance critical code from (legacy) code with dubious correctness. I'd like to have all asserts enabled at the caller side to catch bugs, without the performance hit of enabling asserts within a numeric kernel.
Dec 18 2016