View mode: basic / threaded / horizontal-split · Log in · Help
August 15, 2011
Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Re: Possible enhancement: Concise return statements
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
Top | Discussion index | About this forum | D home