www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - question on map

reply Alain De Vos <devosalain ymail.com> writes:
As oppposed to what i expect code below prints nothing nothing on 
the screen. What is wrong and how to fix it ?
```
import std.stdio;
import std.range:iota;
import std.algorithm:map;

bool mywriteln(int x){
	writeln(x);
	return true;
}

void main(){
	5.iota.map!mywriteln;
}

```
May 12
next sibling parent Berni44 <someone somemail.com> writes:
On Wednesday, 12 May 2021 at 09:52:52 UTC, Alain De Vos wrote:
 As oppposed to what i expect code below prints nothing nothing 
 on the screen. What is wrong and how to fix it ?
 ```
 import std.stdio;
 import std.range:iota;
 import std.algorithm:map;

 bool mywriteln(int x){
 	writeln(x);
 	return true;
 }

 void main(){
 	5.iota.map!mywriteln;
 }

 ```
You've got a *lazy* range here. Try `5.iota.map!mywriteln.array` (you need to import std.array). With that it is not lazy anymore and will print. The way, I'm thinking about lazy ranges is in terms of vouchers, like you sometimes have to buy vouchers on sport festivals to get sausages. Now you go to the stand with the sausages and hand in that voucher, you get the sausage. But if you throw the voucher in a waste paper basket, you'll get no sausages, they are not even roasted, as long as you do not query them. What you do above is to buy that voucher and throw it away. That's why nothing happens. So in more detail, `5.iota` gives you a voucher (A) for the 5 numbers from 0 to 4. You hand that voucher (A) to `map` together with a function `mywriteln` and get back a new voucher (B), this time for applying the numbers to your function. And that voucher (B) is discarded, because it is never used. If you would write `5.iota.map!mywriteln.front`, you would say something like: "Hey `map`, here is my voucher (B), please give me the first element you promised to me. `map` now takes the voucher (A) you gave it earlier and does the same, it asks `iota`: "Hey `iota`, here is my voucher (A), please give me the first element." And iota hands `0` to `map`, which now calls `mywriteln(0)`. `mywriteln` now prints the expected `0` and hands a `true` to `map` and then `map` gives you that `true` (which you still discard). Hope, this analogy helps.
May 12
prev sibling next sibling parent visitor <pierredavant gmail.com> writes:
On Wednesday, 12 May 2021 at 09:52:52 UTC, Alain De Vos wrote:
 As oppposed to what i expect code below prints nothing nothing 
 on the screen. What is wrong and how to fix it ?
 ```
 import std.stdio;
 import std.range:iota;
 import std.algorithm:map;

 bool mywriteln(int x){
 	writeln(x);
 	return true;
 }

 void main(){
 	5.iota.map!mywriteln;
 }

 ```
On Wednesday, 12 May 2021 at 09:52:52 UTC, Alain De Vos wrote: think lazy :)) 5.iota.map!mywriteln.array;
May 12
prev sibling parent Mike Parker <aldacron gmail.com> writes:
On Wednesday, 12 May 2021 at 09:52:52 UTC, Alain De Vos wrote:
 As oppposed to what i expect code below prints nothing nothing 
 on the screen. What is wrong and how to fix it ?
 ```
 import std.stdio;
 import std.range:iota;
 import std.algorithm:map;

 bool mywriteln(int x){
 	writeln(x);
 	return true;
 }

 void main(){
 	5.iota.map!mywriteln;
 }

 ```
Berni44 and visitor are correct about the laziness, but you don't need to use `array` to trigger the operations. That's a needless allocation. `std.algorithm.each` will do the same thing, without the allocation. So you could do this: ```d import std.algorithm : each, map; 5.iota.map!mywriteln.each; ``` But given a function, `each` behaves like an eager `map`, so this has the same result: ```d import std.algorithm : each; 5.iota.each!mywriteln; ```
May 12