June 18, 2013
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
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
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
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
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
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
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
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
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
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.
1 2
Next ›   Last »