Is it possible to handle 'magic' property assignments a'la PHP?
H. S. Teoh
hsteoh at quickfur.ath.cx
Tue Jan 7 12:44:12 PST 2014
On Tue, Jan 07, 2014 at 09:18:48PM +0100, Jacob Carlborg wrote:
> On 2014-01-07 16:58, H. S. Teoh wrote:
>
> >Y'know, I've always wanted "trailing delegate syntax":
> >
> > func(x, y, z; p, q, r) {
> > // body
> > }
> >
> >gets translated into:
> >
> > func(p, q, r, (x, y, z) => /* body */);
> >
> >Since we already have UFCS, which translates a leading fragment into
> >the first argument (x.func(y) --> func(x,y)), it seems perfectly
> >reasonable to do something with the final argument too, like the
> >above.
> >
> >This would allow one to implement, for example, foreach_reverse as a
> >library function instead of a language keyword:
> >
> > void foreach_reverse(I, R)(R range, void delegate(I) dg)
> > {
> > ...
> > dg(idx);
> > ...
> > }
> >
> > // Gets translated to:
> > // foreach_reverse(range, (uint i) => /* body */);
> > foreach_reverse (uint i; range) {
> > ... // body
> > }
> >
> > // And you can use UFCS too:
> > range.foreach_reverse(uint i) {
> > ... // body
> > }
>
> Exactly, that's what it is for. Perhaps supporting an alias
> parameter would be good as well, since those are inlined:
>
> void foo (alias dg) ();
>
> foo {
> // body
> }
>
> Translated to:
>
> foo!({
> // body
> });
>
> >I'm not holding my breath on this one, though. It's a rather big
> >change and ultimately is just syntactic sugar. Maybe it can go on the
> >list of features for D3... ;-)
>
> I've brought this up before. If I recall correctly, it didn't was
> that much resistance as one could think. Although this was before we
> had the lambda syntax.
[...]
If you have a good motivating use case in favor of this addition that
can be used in a DIP, I'd vote for it.
I like the alias idea, so here's the revised proposal:
1) Argumentless trailing-delegate syntax:
// Given this declaration:
void foo(alias dg)();
// We can write this:
foo {
// body
}
// which will get translated into:
foo!({ /* body */ });
2) With arguments:
// Given this declaration:
void foo(alias dg, A...)(A args);
// Or its non-template equivalent:
void foo(alias dg)(A arg1, B arg2, C arg3, ...);
// We can write this:
foo(a,b,c,...) {
// body
}
// which gets translated into:
foo!({ /* body */})(a,b,c,...);
3) With indexing arguments:
// Given this declaration:
void foo(alias dg, I..., A...)(A args)
if (is(typeof(dg(I))));
// Or its non-template equivalent:
void foo(alias dg)(A arg1, B arg2, C arg3, ...) {
...
dg(i, j, k);
...
}
// We can write this:
foo(i,j,k,... ; a,b,c,...) {
// body
}
// which gets translated into:
foo!((i,j,k,...) { /* body */ })(a,b,c,...);
EXAMPLE:
void for_every_other(alias loopBody, R)(R range)
if (is(typeof(loopBody(ElementType!R.init))))
{
while (!range.empty) {
loopBody(range.front);
range.popFront();
if (!range.empty)
range.popFront();
}
}
// Prints:
// ---
// 1
// 3
// 5
// ---
for_every_other (i; [1,2,3,4,5,6]) {
writeln(i);
}
EXTENDED EXAMPLE:
void for_every_other(alias loopBody, R)(R range)
if (is(typeof(loopBody(size_t.init, ElementType!R.init))))
{
size_t i=0;
while (!range.empty) {
loopBody(i, range.front);
range.popFront();
if (!range.empty) {
range.popFront();
i += 2;
}
}
}
// Prints:
// ---
// 0: "a"
// 2: "c"
// 4: "e"
// ---
for_every_other (i, j; ["a", "b", "c", "d", "e", "f"]) {
writefln("%s: %s", i, j);
}
T
--
Error: Keyboard not attached. Press F1 to continue. -- Yoon Ha Lee, CONLANG
More information about the Digitalmars-d-learn
mailing list