even more delegate sugar

Tom S h3r3tic at remove.mat.uni.torun.pl
Tue Aug 22 05:27:17 PDT 2006


Oskar Linde wrote:
> Don Clugston wrote:
>> Oskar Linde wrote:
>>> Don Clugston wrote:
>>>> Tom S wrote:
>>>>> Then e.g. the 'dotimes' example from 'Lazy Evaluation of Function 
>>>>> Arguments' would become:
>>>>>
>>>>> void foo() {
>>>>>     int x = 0;
>>>>>     dotimes(10) {
>>>>>         writef(x++);
>>>>>     }
>>>>> }
>>>>>
>>>>>
>>>>> Which eliminates the need for lazy evaluation in this case, as it 
>>>>> simply uses a delegate. Moreover, it is more readable and concise 
>>>>> at the same time.
>>>>
>>>> Sounds nice, but nowhere near enough visual cues.
>>>> If you leave off a semicolon, the meaning completely changes.
>>>>   dotimes(10); {
>>>>    writef(x++);
>>>>  }
>>>>
>>>>   and
>>>>
>>>>   dotimes(10)
>>>>
>>>>   {
>>>>     writef(x++);
>>>>   }
>>>>
>>>> would both be valid code.
>>>
>>> Would they? (assuming there is no dotimes overload with only one 
>>> argument)
>>
>> I was not making that assumption. There's also:
>>
>> dotimes(int x, void delegate(void) y = { writefln("Surprise"); });
>>
>> (I think that providing a default values for any such trailing 
>> delegate would always create this situation).
> 
> You are correct, of course.

I think the proposed syntax should only be allowed only when the 
delegate param doesn't have a default value. Even if only for the sake 
of clarity.


>> I don't know if this would be a big problem in practice - but it makes 
>> me a bit nervous.
> 
> The fact that C has had this very same issue with if, while, for, et.al. 
> for centuries should work in favor of the proposal though.
> 
>> What would you do with
>>
>> methodName (int, void delegate(void) ... )

I'm not sure what you mean with the ... there, but if you mean
methodName(arg, arg, ..., arg, {}, arg, ..., arg)

then perhaps it should not be allowed to use the shorthand. But more on 
that later.


> Yes, that is an interesting case. One could either:
> a) live with the ; changing the meaning of the code
> b) forbid the proposed syntax in the cases where a ; would change the   
> meaning of the code.

I'd opt for b)


>>>> But an amazing feature of your proposal is that you could write
>>>> a function
>>>> void If(bool b, void delegate (void) f);
>>>>
>>>> and then write
>>>>   If( cond) { writef(xxxx); }
>>>>
>>>> which would behave just like the built-in 'if' statement (albeit 
>>>> without an 'else' clause). Interesting.
>>>
>>> Indeed.
>>
>> On reflection, an even more interesting example is variants of 
>> foreach, which I think would become completely redundant.
> 
> break would pose a problem though.

Right, but it's not always needed :)


Anyway, it's not the only option to go for. For instance, if the 
semicolon wasn't implicit, one might try some more twists, e.g.:

myIf (cond) {
}
.myElif (cond) {
}
.myElse (cond) {
};


Or the construct
methodName([arg, ..., arg, {}], ..., [arg, ..., arg, {}])

could be allowed to expand to
methodName(arg, ..., arg) {
}
...
(arg, ..., arg) {
};


or, as Ivan Senji suggested, named args could make it become

methodName(arg, ..., arg) {
}
namedDg = {
}
...
namedDg = {
};


I can immediately imagine writing code like:

glPushMatrix {
	glTranslatef(...);

	glBegin(GL_TRIANGLES) {
		glVertex(...);
		...
		glVertex(...);
	}
}


Note that this code would also be possible in a similar form:

glPushMatrix = {
	glTranslatef(...);

	glBegin(GL_TRIANGLES) = {
		glVertex(...);
		...
		glVertex(...);
	};
};

... just if opAssign worked for structs. /* Yet it would be noticeably 
harder to implement */


--
Tomasz Stachowiak



More information about the Digitalmars-d mailing list