PROPOSAL: opSeq()
Russell Lewis
webmaster at villagersonline.com
Tue Apr 8 06:56:07 PDT 2008
Bill Baxter wrote:
> Russell Lewis wrote:
>> PROPOSAL: A way to handle sequences of expressions which otherwise
>> would have been syntax errors
>>
>>
>> EXAMPLE CODE:
>> my_for(i=0, i<10, i++) { <code> }
>
> Are you familiar with the "trailing delegates" proposal?
>
> Basically the idea there is that any {<code>} block following a function
> call would be treated as an extra argument to the function.
>
> So if you write the function:
> void my_for(lazy void init, lazy bool test, lazy void inc, void delegate())
> { ... }
>
> then your EXAMPLE_CODE above would call that function.
Yes, I am familiar with the concept. My proposal is a generalization of
that which is able to handle any type of expression, and also to handle
multiple expressions.
OPEN QUESTION: What happens if an opSeq-type struct is *not* followed by
anything? Do we need syntax to indicate whether that is legal or not?
You asked how opSeq is better than trailing delegates, so here are some
more examples of things that opSeq can do:
1) Bare statements. Take a look at my implementation of the MyFor
struct from the original post. One of the overloads of opSeq takes
"lazy void block", which means that this syntax is also legal:
my_for(i=0, i<10, i++)
a = a+1;
2) Suffixes. People have suggested that the expression
3 + 2i
be something that can be implemented entirely as a library. If i was a
variable and we supported "opSeqRev", then it would be easy!
3) Multiple arguments. Trailing delegates can't implement complex
syntaxes, such as do...while. opSeq can. At the bottom of this post,
I'll post code that will handle all of the following:
MyWhile(a != b) <bare statement>;
MyWhile(a != b) { <block>}
MyDo <bare statement> MyWhile(a != b);
MyDo { <block> } MyWhile(a != b);
4) Generalized syntax. The examples above indicate to me that a lot of
D's syntax could be implemented in a library using opSeq. Would that
allow many of D's constructs to be first class entities? Might that
allow us to implement more functional-language type features?
Here's the example code I promised:
BEGIN CODE
struct While
{
bool delegate() cond;
void opSeq(lazy void bareStatement)
{
opSeq({ bareStatement(); });
}
void opSeq(void delegate() block)
{
if(cond())
{
BEGIN_LOOP: // so I don't have to use D's while!
block();
if(cond())
goto BEGIN_LOOP;
}
}
}
While MyWhile(lazy bool cond)
{
While ret;
ret.cond = cond;
return ret;
}
struct Do
{
void opSeq(lazy void bareStatement, While the_while)
{
opSeq({ bareStatement(); }, the_while);
}
void opSeq(void delegate() block, While the_while)
{
block();
the_while block;
}
}
// this isn't a function, it's a variable. that's because
// the use of MyDo doesn't use parens.
Do MyDo;
END CODE
More information about the Digitalmars-d
mailing list