May 16, 2017
On Tue, May 16, 2017 at 08:43:01PM +0200, Timon Gehr via Digitalmars-d wrote:
> On 16.05.2017 20:06, Andrei Alexandrescu wrote:
> > On 05/16/2017 01:59 PM, Random D user wrote:
> > > 
> > > int foo()
> > > in
> > > {
> > > }
> > > out
> > > {
> > > }
> > > do
> > > {
> > >   bar();
> > > }
> > 
> > Can't deny I like that. -- Andrei
> 
> Beats options 2 and 3.

To me, it's actually worse, because now you have a visual conflation with do-loops.

Overall, what I don't like about contract syntax is that it is so unbearably verbose. It's not just the in and out blocks and the (IMO redundant) marking of the function body; it's also the repeated 'assert's that occur in the in and out blocks.

	int foo(T, U)(T t, U u)
	if (sigContraints!T && sigConstraints!U)
	in
	{
		assert(t > 0 && u < 10);
	}
	out(val)
	{
		assert(val > 1 && val < 5);
	}
	body
	{
		// function body here
	}

I understand this DIP is only to address the `body` part of this ugly verbosity, but imagine how much better it would be if we could write something like this instead:

	int foo(T, U)(T t, U u)
	if (sigConstraints!T && sigConstraints!U)
	in (t > 0 && u < 10)
	out(foo > 1 && foo < 5 )
	{
		// function body here
	}

This is just tentative example syntax, of course.  We can argue over its fine points later, but the point is that the current syntax is far too verbose, and can easily be reduced to half the number of lines.  Merely changing `body` to `do` does nothing to address this, and seems to me to be just more useless churn, replacing one bit of verbosity with another bit of verbosity. (Not to mention the IMO very ugly syntax clash with do-loops, which will reduce code readability even more.)


T

-- 
I think the conspiracy theorists are out to get us...
May 16, 2017
On Tuesday, 16 May 2017 at 18:57:37 UTC, H. S. Teoh wrote:
> this ugly verbosity, but imagine how much better it would be if we could write something like this instead:
>
> 	int foo(T, U)(T t, U u)
> 	if (sigConstraints!T && sigConstraints!U)
> 	in (t > 0 && u < 10)
> 	out(foo > 1 && foo < 5 )
> 	{
> 		// function body here
> 	}
>
> This is just tentative example syntax, of course.

Why not just use the terminology the rest of the world has landed on?

int foo(T, U)(T t, U u)
if (sigConstraints!T && sigConstraints!U)
requires(t > 0 && u < 10)
ensures(foo > 1 && foo < 5 )
{
   // function body here
}

Or is there some value in being cryptic?

May 16, 2017
On Tuesday, 16 May 2017 at 19:18:43 UTC, Ola Fosheim Grøstad wrote:
> On Tuesday, 16 May 2017 at 18:57:37 UTC, H. S. Teoh wrote:
>> this ugly verbosity, but imagine how much better it would be if we could write something like this instead:
>>
>> 	int foo(T, U)(T t, U u)
>> 	if (sigConstraints!T && sigConstraints!U)
>> 	in (t > 0 && u < 10)
>> 	out(foo > 1 && foo < 5 )
>> 	{
>> 		// function body here
>> 	}
>>
>> This is just tentative example syntax, of course.
>
> Why not just use the terminology the rest of the world has landed on?
>
> int foo(T, U)(T t, U u)
> if (sigConstraints!T && sigConstraints!U)
> requires(t > 0 && u < 10)
> ensures(foo > 1 && foo < 5 )
> {
>    // function body here
> }
>
> Or is there some value in being cryptic?

What about error messages. With asserts I get the line where the assert failed. Can I get an information which condition failed (sorry for the question, I don't know how it works in other languages)?
May 16, 2017
On Tuesday, 16 May 2017 at 19:23:28 UTC, Eugene Wissner wrote:
> What about error messages. With asserts I get the line where the assert failed. Can I get an information which condition failed (sorry for the question, I don't know how it works in other languages)?

Use multiple requires/ensures clauses?


May 16, 2017
On 5/16/17 2:48 PM, Eugene Wissner wrote:
> On Tuesday, 16 May 2017 at 18:34:06 UTC, Steven Schveighoffer wrote:
>> On 5/12/17 12:17 PM, Mike Parker wrote:
>>> The first stage of the formal review for DIP 1003 [1], "Remove body as a
>>> Keyword", is now underway. From now until 11:59 PM ET on May 26 (3:59 AM
>>> GMT on May 27), the community has the opportunity to provide last-minute
>>> feedback. If you missed the preliminary review [2], this is your chance
>>> to provide input.
>>>
>>> At the end of the feedback period, I will submit the DIP to Walter and
>>> Andrei for their final decision. Thanks in advance to those of you who
>>> participate.
>>>
>>> [1]
>>> https://github.com/dlang/DIPs/blob/fbb797f61ac92300eda1d63202157cd2a30ba555/DIPs/DIP1003.md
>>>
>>>
>>>
>>> [2] http://forum.dlang.org/thread/qgxvrbxrvkxtimzvnetu@forum.dlang.org
>>
>> Before we go down endlessly debating which keywords would work best to
>> replace body here, can someone please inform the crowd why just having
>> body remain as it is now, but *not* be a keyword is unworkable?
>>
>> The more I think about it, the more I think that option 1 is the far
>> far far superior option. Zero existing code breaks, and we now have
>> access to our own body symbols (and we don't even have to go through a
>> deprecation period). However, if there is a missing lynch pin that
>> shows why this cannot work, then it's better to take it off the table
>> now.
>>
>
> 1) Consistency with functions without contracts.

This only applies to the "naked" version which has ugly }{ in it. The other options people are asking about are replacing body with a keyword, which I think you agree would be bad for consistency?

> 2) I wouldn't like to have body optional because: it introduces an
> additional style guide rule: there will be people who will omit it and
> people who will say: explicitely is better, always use body.

Currently, body is required. It would still be required. Just not a keyword. I'm specifically asking if just removing the 'keyword-ness' of it is not doable for some reason.

Note: body is optional for non-contract functions (yes, void foo() body { } is valid). I don't see a rash of people promoting having body there.

> 3) Syntax highlighting: Editors that work with regex will mark body in
> all contexts as a keyword.

This is a solved problem. Create a C# file, then write 'get' or 'set' somewhere that's not inside a property, and see if it's highlighted differently.

> 4) I know body isn't reserved anywhere, I can use it without thinking
> abot the contexts (good for new comers who may think body is a reserved
> keyword if it is used as such in some contexts).

I think maybe you misunderstand what I was asking.

-Steve
May 16, 2017
On Tuesday, 16 May 2017 at 19:24:43 UTC, Ola Fosheim Grøstad wrote:
> On Tuesday, 16 May 2017 at 19:23:28 UTC, Eugene Wissner wrote:
>> What about error messages. With asserts I get the line where the assert failed. Can I get an information which condition failed (sorry for the question, I don't know how it works in other languages)?
>
> Use multiple requires/ensures clauses?

That makes sense.
May 16, 2017
On Tuesday, 16 May 2017 at 19:25:25 UTC, Steven Schveighoffer wrote:
> On 5/16/17 2:48 PM, Eugene Wissner wrote:
>> On Tuesday, 16 May 2017 at 18:34:06 UTC, Steven Schveighoffer wrote:
>>
>> 1) Consistency with functions without contracts.
>
> This only applies to the "naked" version which has ugly }{ in it. The other options people are asking about are replacing body with a keyword, which I think you agree would be bad for consistency?
>
Yeah, I think function or something else is a worse alternative. Better leave body as is than replace it with another word. I can name my variables body_ if I need.

>> 2) I wouldn't like to have body optional because: it introduces an
>> additional style guide rule: there will be people who will omit it and
>> people who will say: explicitely is better, always use body.
>
> Currently, body is required. It would still be required. Just not a keyword. I'm specifically asking if just removing the 'keyword-ness' of it is not doable for some reason.
>
> Note: body is optional for non-contract functions (yes, void foo() body { } is valid). I don't see a rash of people promoting having body there.
>
I wasn't aware of it. Mea culpa.

>> 3) Syntax highlighting: Editors that work with regex will mark body in
>> all contexts as a keyword.
>
> This is a solved problem. Create a C# file, then write 'get' or 'set' somewhere that's not inside a property, and see if it's highlighted differently.
>
>> 4) I know body isn't reserved anywhere, I can use it without thinking
>> abot the contexts (good for new comers who may think body is a reserved
>> keyword if it is used as such in some contexts).
>
> I think maybe you misunderstand what I was asking.
>
> -Steve

What I meant If I read a documentation on dlang.org that some identifier is reserved for some purpose I automatically think it can't be used as variable name. I don't want to check the list of reserved keywords every time I doubt. The same I never named my variables linux or Windows because they are used in version blocks. I have never tested if I can name my variable linux or Windows. Don't know if it makes sense.
May 16, 2017
On 16.05.2017 21:25, Steven Schveighoffer wrote:
> I'm specifically asking if just removing the 'keyword-ness' of it is not
> doable for some reason.

It's easy to do technically. (The bad thing about option 1 is that it's the kind of thing that would probably not arise from an up-front language design and requires history to explain.)


May 16, 2017
On 16.05.2017 20:57, H. S. Teoh via Digitalmars-d wrote:
> On Tue, May 16, 2017 at 08:43:01PM +0200, Timon Gehr via Digitalmars-d wrote:
>> On 16.05.2017 20:06, Andrei Alexandrescu wrote:
>>> On 05/16/2017 01:59 PM, Random D user wrote:
>>>>
>>>> int foo()
>>>> in
>>>> {
>>>> }
>>>> out
>>>> {
>>>> }
>>>> do
>>>> {
>>>>   bar();
>>>> }
>>>
>>> Can't deny I like that. -- Andrei
>>
>> Beats options 2 and 3.
>
> To me, it's actually worse, because now you have a visual conflation
> with do-loops.
>

It's worse than option 1, but not worse than options 2 and 3. I prefer a visual conflation with do loops over a visual conflation with any of the constructs having 'function' in it, and I'm saying no to this:

...
{

}{

}

> Overall, what I don't like about contract syntax is that it is so
> unbearably verbose.

It's quite verbose, but certainly not unbearably so.

> It's not just the in and out blocks and the (IMO
> redundant)  marking of the function body;

There are many redundant elements in the D grammar. It's not a bad thing per se.

> it's also the repeated
> 'assert's that occur in the in and out blocks.
>
> 	int foo(T, U)(T t, U u)
> 	if (sigContraints!T && sigConstraints!U)
> 	in
> 	{
> 		assert(t > 0 && u < 10);
> 	}
> 	out(val)
> 	{
> 		assert(val > 1 && val < 5);
> 	}
> 	body
> 	{
> 		// function body here
> 	}
>
> I understand this DIP is only to address the `body` part of this ugly
> verbosity,

Actually, the goal of the DIP is to make 'body' not a keyword. Nothing more.

> but imagine how much better it would be if we could write
> something like this instead:
>
> 	int foo(T, U)(T t, U u)
> 	if (sigConstraints!T && sigConstraints!U)
> 	in (t > 0 && u < 10)
> 	out(foo > 1 && foo < 5 )
> 	{
> 		// function body here
> 	}
>
> This is just tentative example syntax, of course.  We can argue over its
> fine points later, but the point is that the current syntax is far too
> verbose, and can easily be reduced to half the number of lines.  Merely
> changing `body` to `do` does nothing to address this, and seems to me to
> be just more useless churn, replacing one bit of verbosity with another
> bit of verbosity.

It's a good option to have, but D is not an expression-based language, so this can be painful, as you cannot declare intermediate variables nor use statements.

> (Not to mention the IMO very ugly syntax clash with
> do-loops, which will reduce code readability even more.)
>...

Do you think your new syntax is significantly more readable? (Just curious.)
May 16, 2017
On Tue, May 16, 2017 at 09:48:07PM +0200, Timon Gehr via Digitalmars-d wrote: [...]
> I'm saying no to this:
> 
> ...
> {
> 
> }{
> 
> }

It doesn't have to be formatted that way. For example:

	int foo()
	in { assert(blah); }
	{
		// not so bad after all
	}


[...]
> > 	int foo(T, U)(T t, U u)
> > 	if (sigConstraints!T && sigConstraints!U)
> > 	in (t > 0 && u < 10)
> > 	out(foo > 1 && foo < 5 )
> > 	{
> > 		// function body here
> > 	}
> > 
> > This is just tentative example syntax, of course.  We can argue over its fine points later, but the point is that the current syntax is far too verbose, and can easily be reduced to half the number of lines.  Merely changing `body` to `do` does nothing to address this, and seems to me to be just more useless churn, replacing one bit of verbosity with another bit of verbosity.
> 
> It's a good option to have, but D is not an expression-based language, so this can be painful, as you cannot declare intermediate variables nor use statements.

Yes, I'm aware that one of the reasons for the current syntax was the desire to allow arbitrary code inside contracts.  In practice, though, I hardly ever encounter a use case that needed this, and even where it was needed, the code was much better off being in a separate function so that you could write, for example:

	bool elementsWithinRange(T)(T[] data, T lower, T upper) {
		foreach (e; data) {
			if (e < lower || e >= upper) return false;
		}
		return true;
	}

	int foo(T)(T[] data)
	in { assert(data.elementsWithinRange(0, 10); }
	body // ugh
	{
		...
	}

In the hypothetical new syntax, you could get rid of the assert altogether for a much more concise expression of the in-contract.

IMO, if your contracts have become complex enough to require variables and statements, then it's time to refactor them into properly-named functions so that the person reading the code doesn't have to mentally parse and execute the contract just to understand what requirements it's trying to express.  D not being an expression-based language is not a problem since contracts can call arbitrary functions. (In fact, I'd argue it's an advantage, since it would require users to refactor their contracts once it starts getting out-of-hand. The result should be better readability.)


> > (Not to mention the IMO very ugly syntax clash with do-loops, which will reduce code readability even more.) ...
> 
> Do you think your new syntax is significantly more readable? (Just
> curious.)

It at least gets rid of the verbosity of the current syntax.  I don't claim it's necessarily *significantly* more readable, but I'd consider it to be one step closer.  Getting all the way there would be another topic, and a very long, protracted one, given our track record.


T

-- 
"No, John.  I want formats that are actually useful, rather than over-featured megaliths that address all questions by piling on ridiculous internal links in forms which are hideously over-complex." -- Simon St. Laurent on xml-dev