When join lazy sequence map functions invoked multiple times
Closed this issue · 1 comments
yeyan commented
Issue description
When joining lazy sequences, it seems each mapper function was invoked twice. For pure code this seems ok but slow. But for Mapper Functions with side effects (IO actions) this will certainly results an error. The following code demonstrates this issue.
Sequence<Integer> nums = sequence(1,2,3,4,5,6).take(3).map(new Callable1<Integer, Integer>() {
@Override
public Integer call(Integer integer) throws Exception {
logger.debug("side effect with int = {}", integer);
return integer + 10;
}
});
logger.debug("seq = {}", empty(Integer.class).join(nums));
script output
side effect with int = 1
side effect with int = 2
side effect with int = 3
side effect with int = 1
side effect with int = 2
side effect with int = 3
seq = 11,12,13
possible workaround
Eagerly evaluate the list will eliminate this problem like the following code demonstrates:
Sequence<Integer> nums = sequence(1,2,3,4,5,6).take(3).map(new Callable1<Integer, Integer>() {
@Override
public Integer call(Integer integer) throws Exception {
logger.debug("side effect with int = {}", integer);
return integer + 10;
}
}).realise();
logger.debug("seq = {}", empty(Integer.class).join(nums));
script output
SampleFactory:53 - side effect with int = 1
SampleFactory:53 - side effect with int = 2
SampleFactory:53 - side effect with int = 3
SampleFactory:58 - seq = 11,12,13
danielbodart commented
I've tried this on both java7 and java8 versions and can not reproduce the bug.
StringWriter out = new StringWriter();
PrintWriter writer = new PrintWriter(out);
Sequence<Integer> nums = sequence(1,2,3,4,5,6).take(3).map(integer -> {
writer.printf("side effect with int = %d%n", integer);
return integer + 10;
});
writer.printf("seq = %s%n", empty(Integer.class).join(nums).toString());
assertThat(out.toString(), is("side effect with int = 1\n" +
"side effect with int = 2\n" +
"side effect with int = 3\n" +
"seq = 11,12,13\n"));
I think we might have fixed this with a previous change to the default toString implementation.