Jump to page: 1 2 3
Thread overview
Possible enhancement: Concise return statements
Aug 15, 2011
Timon Gehr
Aug 15, 2011
simendsjo
Aug 15, 2011
Jacob Carlborg
Aug 15, 2011
Mafi
Aug 15, 2011
Jacob Carlborg
Aug 15, 2011
Mehrdad
Aug 15, 2011
bearophile
Aug 15, 2011
David Nadlinger
Aug 15, 2011
Walter Bright
Aug 15, 2011
Andrej Mitrovic
Aug 15, 2011
Jacob Carlborg
Aug 15, 2011
Walter Bright
Aug 15, 2011
Walter Bright
Aug 15, 2011
Jonathan M Davis
Aug 15, 2011
Walter Bright
Aug 15, 2011
David Nadlinger
Aug 15, 2011
bearophile
Aug 15, 2011
Jacob Carlborg
Aug 15, 2011
Walter Bright
Aug 16, 2011
Jacob Carlborg
Aug 16, 2011
Jacob Carlborg
Aug 17, 2011
pillsy
Aug 15, 2011
Andrew Wiley
Aug 15, 2011
Timon Gehr
Aug 16, 2011
Jacob Carlborg
August 15, 2011
Currently, when using delegates in D, there is 'return' all over the place.
Eg:
map!((a){return a*foo(a);})(arr);

Many delegates consist of only one return statement. Writing 'return' is rather inconvenient and adds to the general noise.

Now, I would like to propose to enhance the language in the following way:

'When the last ExpressionStatement in a function body is missing the ';', it is implicitly returned.'

The example above would become:

map!((a){a*foo(a)})(arr);

Multi-statement delegates would also be supported:
{auto y=x;++x;y}();

Probably, it would be best to disallow to use both forms of return statement simultaneously:

{if(x) return y; z} // error

I feel that this would add much to the language for both code readability and pleasure of writing code, especially in a functional style. As it is a purely additive change (currently, such code is always a syntax error), no existing code would be broken.


(One indirect benefit would be that we could then require lazy arguments to be pure. Call by name would then be implemented by eg:

int x;
foo({x<100},{x++}); // it is evident at the call site what is going on)



Any thoughts on this?

August 15, 2011
On 15.08.2011 12:54, Timon Gehr wrote:
> Currently, when using delegates in D, there is 'return' all over the place.
> Eg:
> map!((a){return a*foo(a);})(arr);
>
> Many delegates consist of only one return statement. Writing 'return' is
> rather inconvenient and adds to the general noise.
>
> Now, I would like to propose to enhance the language in the following way:
>
> 'When the last ExpressionStatement in a function body is missing the
> ';', it is implicitly returned.'

Seems a bit error prone. I'd rather have a rule that, "If the delegate body only consists of a single expression, it's implicitly returned".


> The example above would become:
>
> map!((a){a*foo(a)})(arr);

"a*foo(a);"

> Multi-statement delegates would also be supported:
> {auto y=x;++x;y}();

Error, need return y;

> Probably, it would be best to disallow to use both forms of return
> statement simultaneously:
>
> {if(x) return y; z} // error

Error, use "x ? y : z;"

> I feel that this would add much to the language for both code
> readability and pleasure of writing code, especially in a functional
> style. As it is a purely additive change (currently, such code is always
> a syntax error), no existing code would be broken.
>
>
> (One indirect benefit would be that we could then require lazy arguments
> to be pure. Call by name would then be implemented by eg:
>
> int x;
> foo({x<100},{x++}); // it is evident at the call site what is going on)
>
>
>
> Any thoughts on this?
>

August 15, 2011
On 2011-08-15 12:54, Timon Gehr wrote:
> Currently, when using delegates in D, there is 'return' all over the place.
> Eg:
> map!((a){return a*foo(a);})(arr);
>
> Many delegates consist of only one return statement. Writing 'return' is
> rather inconvenient and adds to the general noise.
>
> Now, I would like to propose to enhance the language in the following way:
>
> 'When the last ExpressionStatement in a function body is missing the
> ';', it is implicitly returned.'
>
> The example above would become:
>
> map!((a){a*foo(a)})(arr);
>
> Multi-statement delegates would also be supported:
> {auto y=x;++x;y}();
>
> Probably, it would be best to disallow to use both forms of return
> statement simultaneously:
>
> {if(x) return y; z} // error
>
> I feel that this would add much to the language for both code
> readability and pleasure of writing code, especially in a functional
> style. As it is a purely additive change (currently, such code is always
> a syntax error), no existing code would be broken.
>
>
> (One indirect benefit would be that we could then require lazy arguments
> to be pure. Call by name would then be implemented by eg:
>
> int x;
> foo({x<100},{x++}); // it is evident at the call site what is going on)
>
>
>
> Any thoughts on this?

Yes, please. In fact I would like that the last expression in all functions and delegates to be automatically returned.

When we're talking about improving the delegate syntax I would like to have these two syntaxes for delegates:

foo(x => x * x)

and

foo(x) {
    x * x
}

-- 
/Jacob Carlborg
August 15, 2011
On 8/15/2011 3:54 AM, Timon Gehr wrote:
> Currently, when using delegates in D, there is 'return' all over the place.
> Eg:
> map!((a){return a*foo(a);})(arr);
>
> Many delegates consist of only one return statement. Writing 'return' is rather inconvenient and adds to the general noise

This is precisely the reason for C#'s  a => b notation. Maybe it's time to adopt it?
August 15, 2011
Am 15.08.2011 16:01, schrieb Jacob Carlborg:
> On 2011-08-15 12:54, Timon Gehr wrote:
>> Currently, when using delegates in D, there is 'return' all over the
>> place.
>> Eg:
>> map!((a){return a*foo(a);})(arr);
>>
>> Many delegates consist of only one return statement. Writing 'return' is
>> rather inconvenient and adds to the general noise.
>>
>> Now, I would like to propose to enhance the language in the following
>> way:
>>
>> 'When the last ExpressionStatement in a function body is missing the
>> ';', it is implicitly returned.'
>>
>> The example above would become:
>>
>> map!((a){a*foo(a)})(arr);
>>
>> Multi-statement delegates would also be supported:
>> {auto y=x;++x;y}();
>>
>> Probably, it would be best to disallow to use both forms of return
>> statement simultaneously:
>>
>> {if(x) return y; z} // error
>>
>> I feel that this would add much to the language for both code
>> readability and pleasure of writing code, especially in a functional
>> style. As it is a purely additive change (currently, such code is always
>> a syntax error), no existing code would be broken.
>>
>>
>> (One indirect benefit would be that we could then require lazy arguments
>> to be pure. Call by name would then be implemented by eg:
>>
>> int x;
>> foo({x<100},{x++}); // it is evident at the call site what is going on)
>>
>>
>>
>> Any thoughts on this?
>
> Yes, please. In fact I would like that the last expression in all
> functions and delegates to be automatically returned.
>
> When we're talking about improving the delegate syntax I would like to
> have these two syntaxes for delegates:
>
> foo(x => x * x)
>
> and
>
> foo(x) {
> x * x
> }
>

I personally don't like number one but that's subjective.
The second has a serious problem: it makes the grammer context sensitive. You can't distinguish such a call from a local function definition.
Therefore I suggest:
foo(x) do (...){
...
}

'do' is already a keyword but only once ten years used for a do...while loop. If the functions are named correctly it reads perfectly:
when!SomeEvent do (ev) {
}

where when is:
void when(T : Event)(void delegate(T) reaction) {...}

August 15, 2011
Timon Gehr:

> 'When the last ExpressionStatement in a function body is missing the ';', it is implicitly returned.'

I remember others in past suggest the same idea. This is a good sign because it means it's a natural enough syntax for D programmers.


> map!((a){a*foo(a)})(arr);

You have picked a suboptimal example, because D/Phobos already allows you write this (because the delegate uses only global names beside its arguments):

map!q{ a * foo(a) }(arr);


> Multi-statement delegates would also be supported:
> {auto y=x;++x;y}();

Optional return keyword for multi-statement code is not a good idea in D, despite similar blocks give in Ruby. Decreasing tidiness for a small syntactical convenience is often a bad idea.


> Any thoughts on this?

Time ago someone (me too) has suggested a syntax like this:
map!({ a => a * foo(a) })(arr);

To replace this syntax:
map!((a){ return a * foo(a); })(arr);

But overall I don't see this as a large improvement. It's just nice. Maybe for D3.

In my opinion a good "yield" (and generators) is syntax sugar that's rather more important than optionally omitting return. It changes the way you write code. Omitting a return doesn't change my way of using delegates, it just makes it a bit shorter.

Bye,
bearophile
August 15, 2011
On 8/15/11 7:53 PM, bearophile wrote:
> Timon Gehr:
>> map!((a){a*foo(a)})(arr);
>
> You have picked a suboptimal example, because D/Phobos already allows you write this (because the delegate uses only global names beside its arguments):
>
> map!q{ a * foo(a) }(arr);

No! As long as foo() is not in the »blessed« set of modules imported by std.functional, there is no way to access it from a string literal lambda.

David
August 15, 2011
On 2011-08-15 17:04, Mafi wrote:
> Am 15.08.2011 16:01, schrieb Jacob Carlborg:
>> Yes, please. In fact I would like that the last expression in all
>> functions and delegates to be automatically returned.
>>
>> When we're talking about improving the delegate syntax I would like to
>> have these two syntaxes for delegates:
>>
>> foo(x => x * x)
>>
>> and
>>
>> foo(x) {
>> x * x
>> }
>>
>
> I personally don't like number one but that's subjective.
> The second has a serious problem: it makes the grammer context
> sensitive. You can't distinguish such a call from a local function
> definition.
> Therefore I suggest:
> foo(x) do (...){
> ...
> }

How is that? A function definition requires a type and a name, not just a name. BTW, it works find in Scala, but that might be because functions start with the "def" keyword.

> 'do' is already a keyword but only once ten years used for a do...while
> loop. If the functions are named correctly it reads perfectly:
> when!SomeEvent do (ev) {
> }
>
> where when is:
> void when(T : Event)(void delegate(T) reaction) {...}

I would rather not have the "do" keyword there.

-- 
/Jacob Carlborg
August 15, 2011
On 8/15/2011 3:54 AM, Timon Gehr wrote:
> 'When the last ExpressionStatement in a function body is missing the ';', it is
> implicitly returned.'

This has been proposed several times before, it was also proposed for C++0x. The difficulty is it makes having a ; or not substantially alter the semantics. The history of these languages is that the presence or absence of ; can be hard to spot, as in:

   for (int i = 0; i < 10; i++);
      ... do this ...

which has cost at least one expert developer I know an entire afternoon staring at it convinced there was a compiler bug because his loop executed only once.

(And this is why D disallows this syntax.)
August 15, 2011
On 8/15/11, Walter Bright <newshound2@digitalmars.com> wrote:
>
>     for (int i = 0; i < 10; i++);
>        ... do this ...
>
> which has cost at least one expert developer I know an entire afternoon
> staring
> at it convinced there was a compiler bug because his loop executed only
> once.
>
> (And this is why D disallows this syntax.)
>

I've been meaning to say, DMD caught me doing this at least 2 dozen times over the last year or so. Adding this to the language was a great move.
« First   ‹ Prev
1 2 3