www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - map with void fun

reply "cal" <callumenator gmail.com> writes:
Should the code below print anything (it currently doesn't)? I'm 
not sure I understand map:

import std.stdio, std.algorithm;	

void main() {
     int[] a = [1,2,3,4,5];
     auto r = a.map!( i => writeln(i) );
     while(!r.empty) r.popFront();
}
Apr 06 2013
parent reply "bearophile" <bearophileHUGS lycos.com> writes:
cal:

 Should the code below print anything (it currently doesn't)? 
 I'm not sure I understand map:

 import std.stdio, std.algorithm;	

 void main() {
     int[] a = [1,2,3,4,5];
     auto r = a.map!( i => writeln(i) );
     while(!r.empty) r.popFront();
 }
The code is working as requested. But there are problems at various levels. First, to see the side effects you have also to call front: import std.stdio, std.algorithm; void main() { auto a = [1, 2, 3, 4, 5]; auto r = a.map!(x => writeln(x)); while(!r.empty) { r.front; r.popFront; } } That prints: 1 2 3 4 5 But this is wrong still. map() is a higher order function, it's meant to take a function and an iterable and produce a new lazy iterable that contains the ordered results of applying the given function on each item. writeln() returns nothing (void, it's a type with just one value, void itself). So one more meaningful way to do that is: import std.stdio, std.algorithm, std.conv; void main() { auto a = [1, 2, 3, 4, 5]; a.map!text.writeln; } That prints: ["1", "2", "3", "4", "5"] But writeln is well designed, so it's able to take a range, so this is better: import std.stdio, std.algorithm; void main() { auto a = [1, 2, 3, 4, 5]; a.writeln; } Bye, bearophile
Apr 06 2013
parent reply "cal" <callumenator gmail.com> writes:
On Saturday, 6 April 2013 at 21:40:37 UTC, bearophile wrote:
 First, to see the side effects you have also to call front:
Ah thank you, I did not realize a call to front was required.
 But this is wrong still. map() is a higher order function, it's 
 meant to take a function and an iterable and produce a new lazy 
 iterable that contains the ordered results of applying the 
 given function on each item. writeln() returns nothing (void, 
 it's a type with just one value, void itself).
Yes, I understand, the example was just a reduced bit of code. Thanks again
Apr 06 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
cal:

 Ah thank you, I did not realize a call to front was required.
Whenever you can, don't create side effects inside a map(). It will not work reliably. A higher order function like map is not meant to be used that way. Bye, bearophile
Apr 06 2013