November 24, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Am 23.11.2016 um 21:32 schrieb Timon Gehr: > On 23.11.2016 11:15, Sönke Ludwig wrote: >> >> 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. The function body isn't part of the "in"/"out" contract either. I don't see the point here. > (Also, in my code there are usually exactly zero block statements nested > directly in block statements.) The whole topic in general so far seems to be mainly hinged around personal taste (me included). Not sure if we'll be able to reach consent for anything but option 1. | |||
November 24, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Saturday, November 19, 2016 21:16:15 Dicebot via Digitalmars-d-announce wrote:
> DIP 1003 is merged to the queue and open for public informal feedback.
>
> PR: https://github.com/dlang/DIPs/pull/48
> Initial merged document:
> https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md
>
> If you want the change to be approved and have ideas how to improve it to better match on https://github.com/dlang/DIPs/blob/master/GUIDELINES.md and existing published reviews - please submit new PR with editorial and ping original author.
Personally, I don't care much about having body as a usable symbol. It occasionally would be useful, but I can live without it. However, I _do_ find it very annoying that it's required for the function body when you have contracts. After all, it's not required when you write the function normally. Why should it be required when you have contracts on the function? The braces after the contracts are clearly for the function body. They couldn't be for anything else. The compiler always requires that the body be last after the in and out contracts, making the body keyword totally redundant. So, I've never understood why the body keyword was required. As far as I can tell, it fixes no ambiguity. It's just extra typing, and it makes contracts that much more verbose, which makes me that much more inclined to just not bother with them and put the assertions in the function body - particularly when I'm already of the opinion that they add no value outside of inheritance, because assertions at the beginning of the function take care of in contracts, and unit tests are really what covers the out contract case anyway (particularly since it's very rare that you can have a general test for the out contract rather than testing that specific input results in specific output).
That being said, I don't care about option 1. Adding a contextual keyword just to get the body keyword is not worth the tradeoff as far as I'm concerned.
Option 2 is also pointless IMHO, because you _still_ have a pointless keyword sitting on the function body. All it's doing is trying to get the body keyword back for general use, which might be nice, but it seems to me that the important thing here is to get rid of the pointless and annoying keyword on the function body, and swapping one keyword for another, longer keyword is most definitely not an improvement in that regard.
IMHO, option 3 is what we should have done ages ago. Even if the keyword had been something like xyzzy rather than something that a number of folks want to use for a symbol name, it still shouldn't have been there, because it adds no value and helps to make contracts even more verbose.
- Jonathan M Davis
| |||
November 24, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | Indentation syntax
If we have an optional indentation syntax one day, those anonymous looking scopes behind functions may become weird things.
int div(int a, int b)
in { assert(b != 0); }
{
return a / b;
}
indentation:
int div( int a, int b)
in:
assert( b != 0)
:
return a / b
And i like two proposals of this thread here who are not part of the DIP:
Kagamin's proposal to just use a shorter keyword than "body" or "function".
> int div(int a, int b)
> in { assert(b != 0); }
> do
> {
> return a / b;
> }
Sönke Ludwigs suggestion:
> Really nice would be if "in" and "out" would then also take a general statement instead of just a block statement, so that a syntax like this would become possible for simple contracts:
>
> void foo(int a, int b)
> in assert(0 <= a && a < b);
> out(ret) assert(ret < b);
> {
> return b - 1 - a;
> }
| |||
November 24, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Saturday, 19 November 2016 at 21:16:15 UTC, Dicebot wrote:
> DIP 1003 is merged to the queue and open for public informal feedback.
>
> PR: https://github.com/dlang/DIPs/pull/48
> Initial merged document: https://github.com/dlang/DIPs/blob/master/DIPs/DIP1003.md
>
> If you want the change to be approved and have ideas how to improve it to better match on https://github.com/dlang/DIPs/blob/master/GUIDELINES.md and existing published reviews - please submit new PR with editorial and ping original author.
This DIP fixes the problem for "body" but not for the other keywords. After all the problem may exist for other keywords. Was a new pragma considered ? For example an identifier alias.
pragma(idAlias, "body", "body_" )
would mean that any "body_" will be treated as "body" identifier. The translation would happen just after the grammatical parsing, because at this phase keywords don't matter anymore.
example:
====
module module_;
pragma(idAlias, "function", "function_" );
pragma(idAlias, "module", "module_" )
int function_()
{
pragma(msg, __PRETTY_FUNCTION__);
return 0;
}
====
prints "int module.function()" during compilation.
| |||
November 24, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sönke Ludwig | On 24.11.2016 12:35, Sönke Ludwig wrote: > Am 23.11.2016 um 21:32 schrieb Timon Gehr: >> On 23.11.2016 11:15, Sönke Ludwig wrote: >>> >>> 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. > > The function body isn't part of the "in"/"out" contract either. I don't > see the point here. > ... There can be no free-standing contract, it's part of the function signature. >> (Also, in my code there are usually exactly zero block statements nested >> directly in block statements.) > > The whole topic in general so far seems to be mainly hinged around > personal taste (me included). Not sure if we'll be able to reach consent > for anything but option 1. That's understood (this is about syntax). BTW, a point against option 2 is: "body" is actually one of the few keywords that D has that have adequate names. It's the body that follows, not the function. | |||
November 25, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On 24.11.2016 10:47, Kagamin wrote: > As to contracts without body we have > https://issues.dlang.org/show_bug.cgi?id=4720 There is even this: https://github.com/dlang/dmd/pull/3611 (Only works for interfaces and abstract classes though. Note that the parser didn't change.) | |||
November 25, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Kagamin | On 24.11.2016 10:24, Kagamin wrote: > 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. import std.stdio; pragma(mangle,"_D2tt4mainFZ3fooUZv") void foo()in{ assert(true); }{ writeln("Hello World!"); } void main(){ static extern(C) void foo()in{ assert(true); } { foo(); } } Removing contracts, is this this code (printing "Hello World!"): import std.stdio; pragma(mangle,"_D2tt4mainFZ3fooUZv") void foo(){ writeln("Hello World!"); } void main(){ static extern(C) void foo(); { foo(); } } Or this code (linker error): import std.stdio; pragma(mangle,"_D2tt4mainFZ3fooUZv") void foo(){ writeln("Hello World!"); } void main(){ static extern(C) void foo() { foo(); } } | |||
November 25, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Am 25.11.2016 um 12:39 schrieb Timon Gehr:
> On 24.11.2016 10:24, Kagamin wrote:
>> I see no ambiguity even if parsing is not greedy.
>
> import std.stdio;
> pragma(mangle,"_D2tt4mainFZ3fooUZv")
> void foo()in{ assert(true); }{
> writeln("Hello World!");
> }
> void main(){
> static extern(C) void foo()in{ assert(true); }
> { foo(); }
> }
>
> Removing contracts, is this this code (printing "Hello World!"):
>
> import std.stdio;
> pragma(mangle,"_D2tt4mainFZ3fooUZv")
> void foo(){
> writeln("Hello World!");
> }
> void main(){
> static extern(C) void foo();
> { foo(); }
> }
Not without explicitly adding that ";".
| |||
November 25, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Sönke Ludwig | On 25.11.2016 22:18, Sönke Ludwig wrote: > Am 25.11.2016 um 12:39 schrieb Timon Gehr: >> On 24.11.2016 10:24, Kagamin wrote: >>> I see no ambiguity even if parsing is not greedy. >> >> import std.stdio; >> pragma(mangle,"_D2tt4mainFZ3fooUZv") >> void foo()in{ assert(true); }{ >> writeln("Hello World!"); >> } >> void main(){ >> static extern(C) void foo()in{ assert(true); } >> { foo(); } >> } >> >> Removing contracts, is this this code (printing "Hello World!"): >> >> import std.stdio; >> pragma(mangle,"_D2tt4mainFZ3fooUZv") >> void foo(){ >> writeln("Hello World!"); >> } >> void main(){ >> static extern(C) void foo(); >> { foo(); } >> } > > Not without explicitly adding that ";". ? The point here was to illustrate what the two possible interpretations are in terms of code that is compatible with current D. The syntax for body-less function declarations with contracts proposed in pull 3611 [1] does not require a ';' to be present. [1] https://github.com/dlang/dmd/pull/3611 The interpretation you are complaining about is in fact the standard interpretation without option 3, but with contracts on function declarations. | |||
November 26, 2016 Re: DIP 1003: remove `body` as a keyword | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | Am 25.11.2016 um 23:28 schrieb Timon Gehr:
> On 25.11.2016 22:18, Sönke Ludwig wrote:
>> Am 25.11.2016 um 12:39 schrieb Timon Gehr:
>>> On 24.11.2016 10:24, Kagamin wrote:
>>>> I see no ambiguity even if parsing is not greedy.
>>>
>>> import std.stdio;
>>> pragma(mangle,"_D2tt4mainFZ3fooUZv")
>>> void foo()in{ assert(true); }{
>>> writeln("Hello World!");
>>> }
>>> void main(){
>>> static extern(C) void foo()in{ assert(true); }
>>> { foo(); }
>>> }
>>>
>>> Removing contracts, is this this code (printing "Hello World!"):
>>>
>>> import std.stdio;
>>> pragma(mangle,"_D2tt4mainFZ3fooUZv")
>>> void foo(){
>>> writeln("Hello World!");
>>> }
>>> void main(){
>>> static extern(C) void foo();
>>> { foo(); }
>>> }
>>
>> Not without explicitly adding that ";".
>
> ?
>
> The point here was to illustrate what the two possible interpretations
> are in terms of code that is compatible with current D. The syntax for
> body-less function declarations with contracts proposed in pull 3611 [1]
> does not require a ';' to be present.
>
> [1] https://github.com/dlang/dmd/pull/3611
>
> The interpretation you are complaining about is in fact the standard
> interpretation without option 3, but with contracts on function
> declarations.
Okay, *that's* the missing piece, thanks for clarifying. I somehow expected that function declarations would always have to end with a semicolon. But admittedly, even then, with my proposal to allow non-block statements for contracts, that would still leave this ambiguity for local function declarations.
The same mechanic unfortunately also makes the "do" suggestion annoying to implement.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply