View mode: basic / threaded / horizontal-split · Log in · Help
October 17, 2006
Re: DMD 0.170 release
On Tue, 17 Oct 2006 14:03:46 +0300, Lars Ivar Igesund  
<larsivar@igesund.net> wrote:

> Kristian wrote:
>
>> On Tue, 17 Oct 2006 13:08:06 +0300, Lars Ivar Igesund
>> <larsivar@igesund.net> wrote:
>>
>>> Walter Bright wrote:
>>>
>>>> Added foreach_reverse, which addresses a serious shortcoming.
>>>>
>>>> http://www.digitalmars.com/d/changelog.html
>>>
>>> But foreach_reverse is such an ugly name, then I like 'reveach'
>>> (courtesy of
>>> Mr Panek) much better :P
>>
>> 'reveach' sounds good; I too think that 'foreach_reverse' is a bit  
>> awkward
>> and lengthy.
>
> I'm not sure reveach is that good ;) I'd really like something else,
> though. 'rforeach' maybe?
>

Too bad that special characters cannot be used...
E.g.

foreach<<()

foreach>>()  //== foreach(); optional syntax for 'foreach'

...But then, what's stopping them to be used?
October 17, 2006
Re: DMD 0.170 release
Bruno Medeiros wrote:

> Walter Bright wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>> 
>> http://www.digitalmars.com/d/changelog.html
> 
> foreach_reverse addresses a serious shortcoming? What is that, if
> instead of:
>    foreach_reverse(Foo f; aggregate) { ...
> I can do:
>    foreach(Foo f; &aggregate.opApplyReverse) { ...
> 
> The latter form is both more general (allows any kind of iterators) and
> more simple/orthogonal (no extra special statements are needed).
> 

Good point and ties in with Tom's post; both of these features
(foreach_reverse and delegate-as-aggregate) could be easily implemented
using other constructs with some "fixes" to the core language.

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
October 17, 2006
Re: DMD 0.170 release
Walter Bright wrote:
> Walter Bright wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>>
>> http://www.digitalmars.com/d/changelog.html
> 
> 
> Lots of background for the foreach improvements in:
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/17320.html

What about trees? Now I want foreach_inorder, foreach_preorder and 
foreach_postorder. :-)

What about classes having a function that returns the "opApply" needed? 
Something like this:

---
class Tree {
	
	int delegate(int delegate(inout int)) inorder() {
		return delegate int(int delegate(inout uint) dg) {
			// inorder traversal
		};
	}

        int delegate(int delegate(inout int)) preorder() {
		return delegate int(int delegate(inout int) dg) {
			// preorder traversal
		};
	}

        int delegate(int delegate(inout int)) postorder() {
		return delegate int(int delegate(inout int) dg) {
			// postorder traversal
		};
	}

	// This still works, it is the default traversal
        int opApply(int delegate(inout int) dg) {
		// default traversal
	}
	
}

void main() {
	Tree t = giveMeSomeTree();
	
	foreach(int i : t.inorder) {
		// something
        }

	foreach(int i : t.preorder) {
		// something
        }

	foreach(int i : t.postorder) {
		// something
        }

	foreach(int i : t) {
		// something
        }

}
---

Could something like this be done? I think it has the clearest syntax: 
no new keywords needed and very flexible. The compiler should check that 
the right side of the foreach is an array, or a class or struct having 
opApply, or a delegate of the singature I mentioned before.

Ary
October 17, 2006
Re: DMD 0.170 release
Ary Manzana wrote:
> Walter Bright wrote:
>> Walter Bright wrote:
>>> Added foreach_reverse, which addresses a serious shortcoming.
>>>
>>> http://www.digitalmars.com/d/changelog.html
>>
>>
>> Lots of background for the foreach improvements in:
>>
>> http://www.digitalmars.com/d/archives/digitalmars/D/17320.html
> 
> What about trees? Now I want foreach_inorder, foreach_preorder and 
> foreach_postorder. :-)

You know I was thinking about this a bit last night, but couldn't come 
up with a good syntax.  But the basic idea was that since "for each" 
doesn't imply an order in which elements will be visited, perhaps the 
order could somehow be specified separately from the 'foreach' symbol. 
However, for classes an obvious alternative would be to use proxy 
objects, similar to iterators, that expose the correct algorithm in 
their opApply.

> What about classes having a function that returns the "opApply" needed? 
> Something like this:
> 
> ---
> class Tree {
>     
>     int delegate(int delegate(inout int)) inorder() {
>         return delegate int(int delegate(inout uint) dg) {
>             // inorder traversal
>         };
>     }
> 
>         int delegate(int delegate(inout int)) preorder() {
>         return delegate int(int delegate(inout int) dg) {
>             // preorder traversal
>         };
>     }
> 
>         int delegate(int delegate(inout int)) postorder() {
>         return delegate int(int delegate(inout int) dg) {
>             // postorder traversal
>         };
>     }
> 
>     // This still works, it is the default traversal
>         int opApply(int delegate(inout int) dg) {
>         // default traversal
>     }
>     
> }
> 
> void main() {
>     Tree t = giveMeSomeTree();
>     
>     foreach(int i : t.inorder) {
>         // something
>         }
> 
>     foreach(int i : t.preorder) {
>         // something
>         }
> 
>     foreach(int i : t.postorder) {
>         // something
>         }
> 
>     foreach(int i : t) {
>         // something
>         }
> 
> }
> ---
> 
> Could something like this be done? I think it has the clearest syntax: 
> no new keywords needed and very flexible. The compiler should check that 
> the right side of the foreach is an array, or a class or struct having 
> opApply, or a delegate of the singature I mentioned before.

Yeah, something like that :-)


Sean
October 17, 2006
Re: DMD 0.170 release
Walter Bright wrote:
> Walter Bright wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>>
>> http://www.digitalmars.com/d/changelog.html
> 
> 
> Lots of background for the foreach improvements in:
> 
> http://www.digitalmars.com/d/archives/digitalmars/D/17320.html

I just go an idea.
How about adding new statements:
skip;
reverse;

They can be used inside the foreach body to skip over the next iteration 
or reverse the order of iteration (dynamically at runtime).

Also, since foreach already takes two arguments (int i, T t) that is, 
index and element, you can add a third argument, of bool type, with the 
meaning "start in reverse mode"
foreach( true, i, d; "Hello" )
{
    writefln( d );
}

should print:
o
l
l
e
H
October 17, 2006
Re: DMD 0.170 release
"Lars Ivar Igesund" <larsivar@igesund.net> wrote in message 
news:eh2fl7$2n9g$1@digitaldaemon.com...
> Walter, you always say that new features shouldn't be added if they fairly
> easily can be done with existing language constructs. Now, the post below
> is about possible new features in D (of general interest and with many
> possible applications), and it is shown how they can be used to implement
> an existing (and specific) feature in D. I'm not sure if this should be
> used as an argument for removing the new delegate-as-aggregate feature, 
> but
> it certainly shows that the proposed features have merit.

While I agree that foreach_reverse seems superfluous with the ability to 
pass in any delegate as the container, the delegate-as-container is just 
_too damn cool_ not to implement.  I don't know about you, but I'd rather 
use a single ampersand than go through all that mixin-in and aliasing just 
to get it to work.  That, and with the delegate-as-container, you're no 
longer limited to just class members - you could have just a nested function 
which you pass in.  Without delegate-as-container, you'd have to create a 
dummy class with the appropriate mixed-in opApply to get it to work.
October 17, 2006
Re: DMD 0.170 release
On Tue, 17 Oct 2006 05:58:47 -0400, Walter Bright  
<newshound@digitalmars.com> wrote:

> Walter Bright wrote:
>> Added foreach_reverse, which addresses a serious shortcoming.
>>  http://www.digitalmars.com/d/changelog.html
>
>
> Lots of background for the foreach improvements in:
>
> http://www.digitalmars.com/d/archives/digitalmars/D/17320.html

Just to clarify, the OP in that thread was attempting to violate the  
restrictions placed on foreach ("The aggregate itself must not be  
resized..." - http://www.digitalmars.com/d/statement.html#foreach).

To further clarify, there is a simple way to remove all selected items in  
a DFL ListBox:
   while(listBox.selectedIndices.count)
   {
      listBox.items.remove(listBox.selectedIndices[0]);
   }
October 17, 2006
Re: DMD 0.170 release
Jarrett Billingsley wrote:

> "Lars Ivar Igesund" <larsivar@igesund.net> wrote in message
> news:eh2fl7$2n9g$1@digitaldaemon.com...
>> Walter, you always say that new features shouldn't be added if they
>> fairly easily can be done with existing language constructs. Now, the
>> post below is about possible new features in D (of general interest and
>> with many possible applications), and it is shown how they can be used to
>> implement an existing (and specific) feature in D. I'm not sure if this
>> should be used as an argument for removing the new delegate-as-aggregate
>> feature, but
>> it certainly shows that the proposed features have merit.
> 
> While I agree that foreach_reverse seems superfluous with the ability to
> pass in any delegate as the container, the delegate-as-container is just
> _too damn cool_ not to implement.  I don't know about you, but I'd rather
> use a single ampersand than go through all that mixin-in and aliasing just
> to get it to work.  That, and with the delegate-as-container, you're no
> longer limited to just class members - you could have just a nested
> function
> which you pass in.  Without delegate-as-container, you'd have to create a
> dummy class with the appropriate mixed-in opApply to get it to work.

I'm just trying to play the devil's (that's Tom) advocate here ;) What I
think was shown by Tom, wasn't that the new feature isn't damn useful, but
that there might be better, more flexible and more powerful ways to
implement the feature, if it is possible with templates, then the sugar
shouldn't be any worse, and the possibilities one could gain for D in
general could be substantial.

-- 
Lars Ivar Igesund
blog at http://larsivi.net
DSource & #D: larsivi
October 17, 2006
Re: DMD 0.170 release
Bruno Medeiros wrote:
> Walter Bright wrote:
> 
>> Added foreach_reverse, which addresses a serious shortcoming.
>>
>> http://www.digitalmars.com/d/changelog.html
> 
> 
> foreach_reverse addresses a serious shortcoming? What is that, if 
> instead of:
>   foreach_reverse(Foo f; aggregate) { ...
> I can do:
>   foreach(Foo f; &aggregate.opApplyReverse) { ...
> 
> The latter form is both more general (allows any kind of iterators) and 
> more simple/orthogonal (no extra special statements are needed).

I agree.  Allowing any delegate to be used is a good move I think.  But 
the incremental value added by 'foreach_reverse' and 'opApplyReverse' 
are minimal once you can already use any delegate as the aggregate.

It would be nice to be able to write a function like "reversed" and then 
just do
    foreach(Foo f; reversed(aggregate)) { ...

To me that seems like a more clean and natural way to support a variety 
of iteration strategies without adding special-cased reverse iterators 
to the language.

Here's a somewhat limited version of that idea:
It's limited by my lack of template-fu, so it just works for arrays, and 
you have to explicitly pass too many template parameters:

class _rev_proxy(AggregateT, ElemT)
{
    this(AggregateT theObj) {
        obj = theObj;
    }
    int opApply(int delegate(inout ElemT) dg)
    {
        int done = 0;
        for (int i = obj.length-1; i >=0; i--)
        {
            done = dg(obj[i]);
            if (done)
                break;
        }
        return done;
    }
  private:
    AggregateT obj;
}

_rev_proxy!(AggregateT,ElemT) reversed(AggregateT,ElemT)(AggregateT array)
{
    return new _rev_proxy!(AggregateT,ElemT)(array);
}

unittest
{
    void testrev() {
        int[] aint = [1,2,3,4,5,6,7];
        real[] areal = [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0];

        foreach(int i; reversed!(int[],int)(aint))
        {
            printf("%d\n",i);
        }

        foreach(real r; reversed!(real[],real)(areal))
            //foreach(real r; areal)
        {
            printf("%f\n",cast(float)(r));
        }
    }
    testrev();
}


I would guess this could probably be expanded with more template-fu so 
that any class which supports a particular protocol (e.g. has a .length 
and [] operator, or a reversed() method) can automatically be reversed. 
 And then as a last resort you could always write your own 
specialization of reversed!() particularly for your class.

--bb
October 17, 2006
Re: DMD 0.170 release
Agree with you, foreach_reverse is unnecessary feature, so it should not
exist.
1 2 3 4 5 6
Top | Discussion index | About this forum | D home