foreach and filter

Jakob Ovrum jakobovrum at gmail.com
Wed Apr 11 09:32:05 PDT 2012


On Wednesday, 11 April 2012 at 16:08:25 UTC, Russel Winder wrote:
> Doing something along the lines of:
>
> 	const a = array ( filter! ... ) ;
> 	foreach ( i ; a ) { ... }
>
> works fine.  Question 1 though is why I can't use immutable 
> here, why I
> have to use const.

An array/slice has indirection, you can't implicitly convert it 
to immutable.

(IIRC, there is actually an exception for the return type of 
strongly pure functions, but your instantiation of 'array' is 
evidently not pure enough)

> Question 2 is why I can't do:
>
> 	const a = filter! ... ;
> 	foreach ( i ; a ) { ... }
>
> if I try this I get messages along the lines of:
>
> ./signatures_sequential.d(33): Error: function 
> signatures_sequential.main.filter!(delegate @system bool(string 
> item)
> {
> return isDir(cast(const(char[]))item);
> }
> ).filter!(const(immutable(char)[])[]).filter.Result.empty () is 
> not callable using argument types ()
> ./signatures_sequential.d(33): Error: function 
> signatures_sequential.main.filter!(delegate @system bool(string 
> item)
> {
> return isDir(cast(const(char[]))item);
> }
> ).filter!(const(immutable(char)[])[]).filter.Result.popFront () 
> is not callable using argument types ()
> ./signatures_sequential.d(33): Error: function 
> signatures_sequential.main.filter!(delegate @system bool(string 
> item)
> {
> return isDir(cast(const(char[]))item);
> }
> ).filter!(const(immutable(char)[])[]).filter.Result.front () is 
> not callable using argument types ()
>
> which, it has to be said, isn't exactly informative to the user.

Ranges are iterated in-place. You can't mutate a const range, 
hence you cannot advance it by one (`popFront`), which is 
required by the lowering of foreach using the range interface.

> Thanks.

You should be using the D.learn group for these questions.


More information about the Digitalmars-d mailing list