foreach for ranges?

2012-07-17 Thread Mike L.
How exactly does the compiler know how to do foreach on ranges 
(for example, ones returned by std.algorithm.map ?) I've looked 
around in std.algorithm and std.range, but can't seem to figure 
it out.


Re: foreach for ranges?

2012-07-17 Thread Ali Çehreli

On 07/17/2012 11:59 AM, Mike L. wrote:

How exactly does the compiler know how to do foreach on ranges (for
example, ones returned by std.algorithm.map ?) I've looked around in
std.algorithm and std.range, but can't seem to figure it out.


The spec mentions it under 'Foreach over Structs and Classes with Ranges':

  http://dlang.org/statement.html#ForeachStatement

There are two methods:

a) opApply() member functions (and opApplyReverse(), which is rumored to 
be deprecated in the future)


b) empty, front, and popFront() member functions

Ali

--
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html


Re: foreach for ranges?

2012-07-17 Thread Jonathan M Davis
On Tuesday, July 17, 2012 20:59:12 Mike L. wrote:
> How exactly does the compiler know how to do foreach on ranges
> (for example, ones returned by std.algorithm.map ?) I've looked
> around in std.algorithm and std.range, but can't seem to figure
> it out.

It translates

foreach(e; range)
{}

into something like

foreach(auto __range = range; !__range.empty; __range.popFront())
{
auto e = __range.front;
}

The compiler knows just enough about ranges to enable foreach, but beyond 
that, ranges are entirely a library construct.

- Jonathan M Davis


Re: foreach for ranges?

2012-07-17 Thread Eyyub

On Tuesday, 17 July 2012 at 19:27:54 UTC, Jonathan M Davis wrote:


It translates

foreach(e; range)
{}

into something like

foreach(auto __range = range; !__range.empty; 
__range.popFront())

{
auto e = __range.front;
}

The compiler knows just enough about ranges to enable foreach, 
but beyond

that, ranges are entirely a library construct.


The spec' says "If the foreach range properties do not exist, the 
opApply method will be used instead.", does this mean that range 
properties take precedence over opApply ?




Re: foreach for ranges?

2012-07-17 Thread Jonathan M Davis
On Tuesday, July 17, 2012 21:38:51 Eyyub wrote:
> On Tuesday, 17 July 2012 at 19:27:54 UTC, Jonathan M Davis wrote:
> > It translates
> > 
> > foreach(e; range)
> > {}
> > 
> > into something like
> > 
> > foreach(auto __range = range; !__range.empty;
> > __range.popFront())
> > {
> > 
> > auto e = __range.front;
> > 
> > }
> > 
> > The compiler knows just enough about ranges to enable foreach,
> > but beyond
> > that, ranges are entirely a library construct.
> 
> The spec' says "If the foreach range properties do not exist, the
> opApply method will be used instead.", does this mean that range
> properties take precedence over opApply ?

This post gives the current precedence, but there was some discussion of 
adjusting it a bit:

http://forum.dlang.org/post/mailman.275.1342019430.31962.digitalmars-
d...@puremagic.com

>From the looks of it, opApply gets precedence right now. But mixing ranges and 
opApply isn't a good idea in most cases, so it doesn't come up very often.

- Jonathan M Davis


Re: foreach for ranges?

2012-07-17 Thread Eyyub

On Tuesday, 17 July 2012 at 19:45:45 UTC, Jonathan M Davis wrote:


This post gives the current precedence, but there was some 
discussion of

adjusting it a bit:

http://forum.dlang.org/post/mailman.275.1342019430.31962.digitalmars-
d...@puremagic.com

From the looks of it, opApply gets precedence right now. But 
mixing ranges and
opApply isn't a good idea in most cases, so it doesn't come up 
very often.


- Jonathan M Davis


Ok, thanks !



Re: foreach for ranges?

2012-07-17 Thread Mike L.
Thanks for the reply. Not sure how I missed it there. Interesting 
that the compiler has to be made aware of a concept that I had 
thought was only supposed to be part of phobos. Would it be 
possible to implement it in std.range using the new UFCs?


On Tuesday, 17 July 2012 at 19:17:47 UTC, Ali Çehreli wrote:

On 07/17/2012 11:59 AM, Mike L. wrote:
How exactly does the compiler know how to do foreach on ranges 
(for
example, ones returned by std.algorithm.map ?) I've looked 
around in

std.algorithm and std.range, but can't seem to figure it out.


The spec mentions it under 'Foreach over Structs and Classes 
with Ranges':


  http://dlang.org/statement.html#ForeachStatement

There are two methods:

a) opApply() member functions (and opApplyReverse(), which is 
rumored to be deprecated in the future)


b) empty, front, and popFront() member functions

Ali





Re: foreach for ranges?

2012-07-17 Thread Jonathan M Davis
On Wednesday, July 18, 2012 06:27:28 Mike L. wrote:
> Thanks for the reply. Not sure how I missed it there. Interesting
> that the compiler has to be made aware of a concept that I had
> thought was only supposed to be part of phobos. Would it be
> possible to implement it in std.range using the new UFCs?

You can do

for(; !range.empty; range.popFront())
{
auto e = range.front;
}

without the compiler doing anything at all. But if you want

for(e; range)
{}

you need a way in the language for the compiler to translate that into the 
above. UFCS has nothing to do with it. All UFCS does is take a.b(c, d) and 
make it b(a, c, d).

- Jonathan M Davi


Re: foreach for ranges?

2012-07-17 Thread Kapps
On Wednesday, 18 July 2012 at 04:54:51 UTC, Jonathan M Davis 
wrote:

On Wednesday, July 18, 2012 06:27:28 Mike L. wrote:
Thanks for the reply. Not sure how I missed it there. 
Interesting

that the compiler has to be made aware of a concept that I had
thought was only supposed to be part of phobos. Would it be
possible to implement it in std.range using the new UFCs?


You can do

for(; !range.empty; range.popFront())
{
auto e = range.front;
}

without the compiler doing anything at all. But if you want

for(e; range)
{}

you need a way in the language for the compiler to translate 
that into the
above. UFCS has nothing to do with it. All UFCS does is take 
a.b(c, d) and

make it b(a, c, d).

- Jonathan M Davi


If UFCS worked on operators, you would be able to make ranges 
without any compiler support.


int opApply(T)(T Range) if(isInputRange!T) {
// Stuff.
}


Re: foreach for ranges?

2012-07-17 Thread Jonathan M Davis
On Wednesday, July 18, 2012 07:19:59 Kapps wrote:
> If UFCS worked on operators, you would be able to make ranges
> without any compiler support.
> 
> int opApply(T)(T Range) if(isInputRange!T) {
>  // Stuff.
> }

You can't overload operators externally to a user-defined type. They must be 
part of the user-defined type that they operate on.

Also, UFCS makes no sense on overloaded operators, because they don't get 
called with ".", and all UFCS is is changing obj.func(params) to func(obj, 
params).

- Jonathan M Davis


Re: foreach for ranges?

2012-07-18 Thread Mike L.
Also, UFCS makes no sense on overloaded operators, because they 
don't get
called with ".", and all UFCS is is changing obj.func(params) 
to func(obj,

params).

- Jonathan M Davis


Ok, that's basically what I was wondering. I had assumed 
foreach(e; someThing) {} could possibly have been converted to 
someThing.opApply() . Thanks for clarifying.


Re: foreach for ranges?

2012-07-18 Thread Ali Çehreli

On 07/18/2012 08:21 AM, Mike L. wrote:
>> Also, UFCS makes no sense on overloaded operators, because they 
don't get

>> called with ".", and all UFCS is is changing obj.func(params) to
>> func(obj,
>> params).
>>
>> - Jonathan M Davis
>
> Ok, that's basically what I was wondering. I had assumed foreach(e;
> someThing) {} could possibly have been converted to someThing.opApply()
> . Thanks for clarifying.

But that is still true and opApply receives the body of the foreach loop 
as a delegate:


someThing.opApply(delegate int(/* loop variables */) {
// ... the body of foreach ...
return terminationCode; // whether the user did 'break;'
});

Also, the following bug (that is already fixed) is somewhat related to 
this discussion:


  http://d.puremagic.com/issues/show_bug.cgi?id=5605

Ali