dotnet / dotnet/reactive

Inconsistent behavior of the Scan operator

Open
#1,672 1 comment 4 reactions 0 assignees View on GitHub
[area] Ix
Dominant language
C#
Stars
7.2k
Forks
798
PR merge metrics
No merged PRs in 30d

Description

The implementation of the `Scan` operator differs between Ix (both sync and async) and Rx with regards to the first element.

The source code contains a comment explaining the behavior for Ix stating it's compatible with Rx (but that's not actually the case):
```
// NB: Implementations of Scan never yield the first element, unlike the behavior of Aggregate on a sequence with one
// element, which returns the first element (or the seed if given an empty sequence). This is compatible with Rx
// but one could argue whether it was the right default.
```

This test code demonstrates the issue:
```
var ob = Enumerable.Range(0, 3).ToObservable();
var ae = Enumerable.Range(0, 3).ToAsyncEnumerable();

var obResult = await ob.Scan((acc, i) => i).ToList(); // 0, 1, 2
var aeResult = await ae.Scan((acc, i) => i).ToListAsync(); // 1, 2

var isSame = aeResult.SequenceEqual(obResult); // false
```

Furthermore, the implementation of `Scan` in MoreLINQ yield the first element, adding to the confusion when switching between libraries.

I understand that it's less than ideal to change the behavior of existing operators, but in this case I think it's worth considering due to the current inconsistency.

I would be happy to make a PR if you agree it should be changed.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.