November 22, 2016
On Tuesday, 22 November 2016 at 15:11:04 UTC, Sönke Ludwig wrote:
> Am 21.11.2016 um 22:19 schrieb Timon Gehr:
>> 3 is ambiguous.
>
> Can you give an example?

I'm curious as well. I considered that option 3 might be ambiguous but I managed to convince myself that it wouldn't be. I'm guessing you're referring to the fact that:

{
    //function body
}

Is a delegate literal, which could conceivably conflict with Option 3's syntax?

void fun(ref int n)
in { assert(n > 0); }
out { assert(n > 0); }
{ //Is this a syntax error or an immediately executed delegate literal?
    n += 1;
}()
November 22, 2016
On 22.11.2016 20:05, Meta wrote:
> On Tuesday, 22 November 2016 at 15:11:04 UTC, Sönke Ludwig wrote:
>> Am 21.11.2016 um 22:19 schrieb Timon Gehr:
>>> 3 is ambiguous.
>>
>> Can you give an example?
>
> I'm curious as well. I considered that option 3 might be ambiguous but I
> managed to convince myself that it wouldn't be. I'm guessing you're
> referring to the fact that:
>
> {
>     //function body
> }
>
> Is a delegate literal, which could conceivably conflict with Option 3's
> syntax?
>
> void fun(ref int n)
> in { assert(n > 0); }
> out { assert(n > 0); }
> { //Is this a syntax error or an immediately executed delegate literal?
>     n += 1;
> }()


Function declarations don't necessarily have a body, but they might have contracts. (This is currently not allowed for technical reasons, but it should/will be.) But this is a rather minor point (usually you don't want to have contracts without implementation in a context where something starting with '{' is allowed).

The more important point is that there is no precedent where {...}{...} are two components of the same entity, it looks ugly even with the space-wasting convention where '{' is put on its own line. Not all contracts are one-liners like in your example above (which looks almost tolerable).
November 23, 2016
int div(int a, int b)
in { assert(b != 0); }
do
{
    return a / b;
}
November 23, 2016
Am 22.11.2016 um 23:37 schrieb Timon Gehr:
> On 22.11.2016 20:05, Meta wrote:
>> On Tuesday, 22 November 2016 at 15:11:04 UTC, Sönke Ludwig wrote:
>>> Am 21.11.2016 um 22:19 schrieb Timon Gehr:
>>>> 3 is ambiguous.
>>>
>>> Can you give an example?
>>
>> I'm curious as well. I considered that option 3 might be ambiguous but I
>> managed to convince myself that it wouldn't be. I'm guessing you're
>> referring to the fact that:
>>
>> {
>>     //function body
>> }
>>
>> Is a delegate literal, which could conceivably conflict with Option 3's
>> syntax?
>>
>> void fun(ref int n)
>> in { assert(n > 0); }
>> out { assert(n > 0); }
>> { //Is this a syntax error or an immediately executed delegate literal?
>>     n += 1;
>> }()
>
>
> Function declarations don't necessarily have a body, but they might have
> contracts. (This is currently not allowed for technical reasons, but it
> should/will be.) But this is a rather minor point (usually you don't
> want to have contracts without implementation in a context where
> something starting with '{' is allowed).

Okay, but that doesn't sound like there is a technical ambiguity here, then? Since there must be a full (block) statement after the in/out, it should always resolve naturally.

>
> The more important point is that there is no precedent where {...}{...}
> are two components of the same entity, it looks ugly even with the
> space-wasting convention where '{' is put on its own line. Not all
> contracts are one-liners like in your example above (which looks almost
> tolerable).

It can happen all the time with normal block statements. Especially something like 'scope' that works outside of the normal program flow has a certain similarity:

    scope (exit) { assert(n > 0); }
    {
        n += 1;
    }

What I personally dislike more is that adding something that should be an independent component of the function signature (e.g. an "int" contract) changes the syntax of the body definition. That always strikes me as an odd non-orthogonal part of the syntax.
November 23, 2016
On Tuesday, 22 November 2016 at 22:37:03 UTC, Timon Gehr wrote:
> The more important point is that there is no precedent where {...}{...} are two components of the same entity, it looks ugly even with the space-wasting convention where '{' is put on its own line. Not all contracts are one-liners like in your example above (which looks almost tolerable).

Templated functions have
T!( .... lots and lots of stuff .... ) f!( .... lots and lots of stuff .... )( .... lots and lots of stuff .... ) if ( .... lots and lots of stuff .... )

And yes, it's ugly.
November 23, 2016
Must be
T!( .... lots and lots of stuff .... ) f( .... lots and lots of stuff .... )( .... lots and lots of stuff .... ) if ( .... lots and lots of stuff .... )
November 23, 2016
On 23.11.2016 11:15, Sönke Ludwig wrote:
>>
>> Function declarations don't necessarily have a body, but they might have
>> contracts. (This is currently not allowed for technical reasons, but it
>> should/will be.) But this is a rather minor point (usually you don't
>> want to have contracts without implementation in a context where
>> something starting with '{' is allowed).
>
> Okay, but that doesn't sound like there is a technical ambiguity here,
> then? Since there must be a full (block) statement after the in/out, it
> should always resolve naturally.

Technically, there is an ambiguity (technically, ambiguity means that there are multiple grammar derivations resulting in the same sentence).
Pragmatically, the greedy parse-the-body-if-possible-approach will work.
November 23, 2016
On 23.11.2016 11:15, Sönke Ludwig wrote:
>>
>> The more important point is that there is no precedent where {...}{...}
>> are two components of the same entity, it looks ugly even with the
>> space-wasting convention where '{' is put on its own line. Not all
>> contracts are one-liners like in your example above (which looks almost
>> tolerable).
>
> It can happen all the time with normal block statements. Especially
> something like 'scope' that works outside of the normal program flow has
> a certain similarity:
>
>     scope (exit) { assert(n > 0); }
>     {
>         n += 1;
>     }

This is not a counterexample, because the block statement following the scope statement is not part of the scope statement. I.e. if anything, it is bad that this looks similar, because it is grammatically different.

(Also, in my code there are usually exactly zero block statements nested directly in block statements.)
November 24, 2016
On Wednesday, 23 November 2016 at 20:24:13 UTC, Timon Gehr wrote:
> Technically, there is an ambiguity (technically, ambiguity means that there are multiple grammar derivations resulting in the same sentence).
> Pragmatically, the greedy parse-the-body-if-possible-approach will work.

I see no ambiguity even if parsing is not greedy.
November 24, 2016
As to contracts without body we have https://issues.dlang.org/show_bug.cgi?id=4720