June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Tuesday, 18 June 2013 at 05:27:57 UTC, deadalnix wrote:
> On Saturday, 15 June 2013 at 21:45:16 UTC, TommiT wrote:
>> "Simple things should be simple, complex things should be possible." -Alan Kay
>>
>> I'd like to simplify the syntax of function pre- and post-conditions when the contract block consists of a single assert statement. A special syntax for this special case would omit all of the following:
>> 1) the block's curly braces
>> 2) the assert keyword
>> 3) the semi-colon ending the assert statement
>> 4) the body keyword (if and only if it follows right after the block)
>>
>> So, instead of writing this:
>>
>> int func(int i)
>> in
>> {
>> assert(i < 5);
>> }
>> out(r)
>> {
>> assert(r < 9);
>> }
>> body
>> {
>> return i * 2;
>> }
>>
>> ...you'd be able to write this:
>>
>> int func(int i)
>> in (i < 5)
>> out(r) (r < 9)
>> {
>> return i * 2;
>> }
>
> I'd rather reserve this kind of syntax for static contract checking or something similar.
Isn't signature constraint (the if clause) good enough for all static contract checking purposes?
|
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | Or the comma operator:
int x = (5, 3); // x is 3
Arrays:
int[] x = [3, 5];
Struct initializers:
struct t { int x, y };
auto z = t(3, 5);
Variable declarations:
int x = 5, y = 3;
I'm not sure which would be more idiomatic though... I'm leaning more towards commas though, to keep with the syntax of the initializers.
On Tuesday, 18 June 2013 at 05:28:07 UTC, Manu wrote:
> What about the argument list only 3 characters earlier?
>
>
> On 18 June 2013 15:16, Aleksandar Ruzicic <aleksandar@ruzicic.info> wrote:
>
>> On Sunday, 16 June 2013 at 00:19:37 UTC, Manu wrote:
>>
>>> Super awesome idea! How about coma separated expressions to perform
>>> multiple asserts?
>>>
>>> int func(int i, int j) in(i<5, j<10)
>>> {
>>> return i + j;
>>> }
>>>
>>
>> I find use of comma inside of parentheses of a statement a bit unusual.
>> Correct me if I'm wrong but I don't think there is a single statement in D
>> that separates it's "parts" with a comma. It's always a semi-colon.
>>
>> So I think it should be:
>>
>> int func(int i, int j) in (i < 5; j < 10)
>> {
>> return i + j;
>> }
>>
>>
>> But either comma or a semi-colon used as a separator, this is a really
>> nice syntactic sugar!
|
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Tyler Jameson Little | Well, that's why I've said we don't have a statement that uses comma to separate it's part. We have lists (argument list, initializer list, array literals, etc) and I would keep comma for separating list items.
In for and foreach we use semi-colons, so I tought that using semi-colon in in would be more consistent than comma.
But that's just my opinion and if this feature got implemented I would be happy with commas also. :)
On Tuesday, 18 June 2013 at 05:46:35 UTC, Tyler Jameson Little wrote:
> Or the comma operator:
>
> int x = (5, 3); // x is 3
>
> Arrays:
>
> int[] x = [3, 5];
>
> Struct initializers:
>
> struct t { int x, y };
> auto z = t(3, 5);
>
> Variable declarations:
>
> int x = 5, y = 3;
>
> I'm not sure which would be more idiomatic though... I'm leaning more towards commas though, to keep with the syntax of the initializers.
>
> On Tuesday, 18 June 2013 at 05:28:07 UTC, Manu wrote:
>> What about the argument list only 3 characters earlier?
>>
>>
>> On 18 June 2013 15:16, Aleksandar Ruzicic <aleksandar@ruzicic.info> wrote:
>>
>>> On Sunday, 16 June 2013 at 00:19:37 UTC, Manu wrote:
>>>
>>>> Super awesome idea! How about coma separated expressions to perform
>>>> multiple asserts?
>>>>
>>>> int func(int i, int j) in(i<5, j<10)
>>>> {
>>>> return i + j;
>>>> }
>>>>
>>>
>>> I find use of comma inside of parentheses of a statement a bit unusual.
>>> Correct me if I'm wrong but I don't think there is a single statement in D
>>> that separates it's "parts" with a comma. It's always a semi-colon.
>>>
>>> So I think it should be:
>>>
>>> int func(int i, int j) in (i < 5; j < 10)
>>> {
>>> return i + j;
>>> }
>>>
>>>
>>> But either comma or a semi-colon used as a separator, this is a really
>>> nice syntactic sugar!
|
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to TommiT | One small issue is that 'in' and 'if' look quite similar, so the compiler should probably issue a warning if you test for a compile time constant inside a pre-condition. void foo(T)(T v) in (isIntegral!T) // Warning: did you mean 'if' { } |
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 6/16/13 8:42, Timon Gehr wrote:
> On 06/16/2013 02:19 AM, Manu wrote:
>> Super awesome idea! How about coma separated expressions to perform
>> multiple asserts?
>>
>> int func(int i, int j) in(i<5, j<10)
>> {
>> return i + j;
>> }
>> ...
>
> Use &&.
>
Not the same. && won't tell you which one failed.
|
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Aleksandar Ruzicic | On Tuesday, 18 June 2013 at 06:00:49 UTC, Aleksandar Ruzicic wrote:
> Well, that's why I've said we don't have a statement that uses comma to separate it's part. We have lists (argument list, initializer list, array literals, etc) and I would keep comma for separating list items.
>
> In for and foreach we use semi-colons, so I tought that using semi-colon in in would be more consistent than comma.
>
> But that's just my opinion and if this feature got implemented I would be happy with commas also. :)
The content inside a simplified pre/post-condition would be a list of runtime boolean expressions, therefore comma is a more logical separator than a semi-colon, which indicates a statement. Semi-colon would invite newbies try to write code inside contracts that looks like it might work but doesn't:
void fun(double x)
in (double squared = x * x; squared < 10; squared > -2)
{ }
Another list of boolean expressions:
bool[] arr = [ true, false, 0, 1, isSomething() ];
...separated by commas alright.
|
June 18, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Manu | On Tuesday, 18 June 2013 at 02:38:28 UTC, Manu wrote:
> On 16 June 2013 12:22, TommiT <tommitissari@hotmail.com> wrote:
>
>> On Sunday, 16 June 2013 at 00:19:37 UTC, Manu wrote:
>>
>>> Super awesome idea! How about coma separated expressions to perform
>>> multiple asserts?
>>>
>>> int func(int i, int j) in(i<5, j<10)
>>> {
>>> return i + j;
>>> }
>>>
>>
>> Do you mean ...to get more specific error messages than with in(i<5 &&
>> j<10) ?
>>
>
> Error messages would be more useful, and it may be much easier for the
> compiler/optimiser to use this information in the future as separated out
> into distinct expressions.
I don't really know about this stuff, but since assert and enforce are built-in things, why couldn't they be smart enough to tell me which ones of the sub-expressions returned false.
a = 4;
b = false;
c = 11;
d = true;
assert(a < 5 && (b || c < 10) && d);
AssertError: { true && (false || false) && ? }
It doesn't know the last expression because it didn't evaluate it.
|
June 19, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to TommiT | I have implemented in CTFE, what I'd like asserts to look like: http://dpaste.1azy.net/2ec082c0 It prints at runtime: "x > y && x < 10" (x must be a digit and larger than y) failed with x: 2, y: 3 ---------------- <stack trace> When you write a contract like this: void foo(uint x, uint y) in { mixin(q{ x > y && x < 10 }.holds ("x must be a digit and larger than y")); } body { … } -- Marco |
June 20, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Marco Leise | On Wednesday, 19 June 2013 at 19:21:20 UTC, Marco Leise wrote:
> I have implemented in CTFE, what I'd like asserts to look like:
> http://dpaste.1azy.net/2ec082c0
>
> It prints at runtime:
>
> "x > y && x < 10" (x must be a digit and larger than y) failed with x: 2, y: 3
> ----------------
> <stack trace>
>
>
> When you write a contract like this:
>
> void foo(uint x, uint y)
> in { mixin(q{ x > y && x < 10 }.holds ("x must be a digit and larger than y")); }
> body { … }
>
>
>
> -- Marco
I think you should make a separate bugzilla enhancement request (or DIP. I don't know which one's more appropriate) for incorporating these better assert messages. It's a separate issue from contracts' syntax after all.
I like the fact that we wouldn't need any new (comma-separated-booleans) syntax for asserts then.
|
June 20, 2013 Re: Feature request: Optional, simplified syntax for simple contracts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Lionello Lunesu | On 06/18/2013 08:52 AM, Lionello Lunesu wrote:
> On 6/16/13 8:42, Timon Gehr wrote:
>> On 06/16/2013 02:19 AM, Manu wrote:
>>> Super awesome idea! How about coma separated expressions to perform
>>> multiple asserts?
>>>
>>> int func(int i, int j) in(i<5, j<10)
>>> {
>>> return i + j;
>>> }
>>> ...
>>
>> Use &&.
>>
>
> Not the same. && won't tell you which one failed.
QoI issue.
|
Copyright © 1999-2021 by the D Language Foundation