Thread overview
Custom control flow statements
Feb 13, 2007
Michiel
Feb 13, 2007
Mikola Lysenko
Feb 13, 2007
Michiel
Feb 13, 2007
Mikola Lysenko
Feb 13, 2007
Michiel
February 13, 2007
I was thinking it might be useful if you could create custom control flow statements like:

foreach_random (element, array) { ... }

Might just be an idea for the future of D. It could be declared like this:

void foreach_random(T)(T element, T[] array, void delegate() statements) { ... }

It would work kind of like those array functions, where the first array parameter can also be placed in front of the function with a . inbetween. In this case the last delegate parameter can also be placed after (without a .).

In theory you could also create things like:

threeway (x, 3) { ... } { ... } { ... }

What do you think?
February 13, 2007
Michiel wrote:
> I was thinking it might be useful if you could create custom control flow
> statements like:
> 
> foreach_random (element, array) { ... }
> 
> Might just be an idea for the future of D. It could be declared like this:
> 
> void foreach_random(T)(T element, T[] array, void delegate() statements) { ... }
> 
> It would work kind of like those array functions, where the first array
> parameter can also be placed in front of the function with a . inbetween. In
> this case the last delegate parameter can also be placed after (without a .).
> 
> In theory you could also create things like:
> 
> threeway (x, 3) { ... } { ... } { ... }
> 
> What do you think?

To an extent, this is already possible.  DCSP does this for stuff like parallel code blocks and alternative statements.

http://assertfalse.com

However, any syntactic sugar like this needs to be very carefully thought out.  Consider the following:

void a()
{
	writefln("starting");

	{
		scope(exit) writefln("blah");
	}
}

This is valid code and there are many times where something like this is needed.  Unfortunately, if we implement what you suggest, then the second block would get convereted to a delegate and passed as a variadic argument to writefln!

-Mik
February 13, 2007
> However, any syntactic sugar like this needs to be very carefully thought out.  Consider the following:
>
> void a()
> {
>  writefln("starting");
>
>  {
>   scope(exit) writefln("blah");
>  }
> }
>
> This is valid code and there are many times where something like this is needed.  Unfortunately, if we implement what you suggest, then the second block would get convereted to a delegate and passed as a variadic argument to writefln!

I think the semicolon would be in the way. I don't think this syntactic sugar is in conflict with any existing syntax. You can never create a function with the name 'scope' or 'for' or 'if', so there's no problem there either.

Or am I missing something?
February 13, 2007
Michiel wrote:
>> void a()
>> {
>>  writefln("starting");
>>
>>  {
>>   scope(exit) writefln("blah");
>>  }
>> }
>>
> 
> I think the semicolon would be in the way. I don't think this syntactic sugar is
> in conflict with any existing syntax. You can never create a function with the
> name 'scope' or 'for' or 'if', so there's no problem there either.
> 
> Or am I missing something?

No, you're absolutely right.  My mistake about the semicolon.


I guess my main concern is what happens when semicolon typos occur.  If something like this is valid:

if(true)
	writefln("foo");

Would the same logic apply in situations like:

writefln("foo")
writefln("bar");
February 13, 2007
> I guess my main concern is what happens when semicolon typos occur.  If something like this is valid:
>
> if(true)
>  writefln("foo");
>
> Would the same logic apply in situations like:
>
> writefln("foo")
> writefln("bar");

I tried this: writefln("foo", writefln("bar"));

It gives a compiler error. So it may be a bad example. But you do have a point. Maybe a special keyword should be used to tell the compiler you want the special behavior. Like:

void functionName(int param1, loose void delegate() statements) { ... }